Library 42- Control RC servo with STM32F4

Library 42 allows you to simple connect and interface RC servo motors with STM32F4. They are small, cheap motors, commonly used for RC (Radio Control), small scale robotics and more.

Servos are really simple to interface. They expect 50Hz signal on the input. According to the pulse length (duty cycle) they rotate between 0 and 180 degrees. If signal has 1ms pulse length, motor rotation will be 0 degrees and if signal has 2ms length, then it will have 180degrees rotation. Any pulse length between will set degrees linear to the value.

Equation for pulse length to get specific rotation is:

Pulse length (degrees) = (MAX – MIN) * degrees / 180 + MIN


  • MAX: maximum pulse length for servo, 2000us
  • MIN: minimum pulse length for servo, 1000us

If you want to get rotation in degrees from know pulse length:

Degrees (pulse_length) = (pulse_length – MIN) * 180 / (MAX – MIN)



  • Control RC servo motors
  • Number of available servos depends on STM32F4xx chip you will use
    • More timers means more servos possible


    • STM32F4xx
    • STM32F4xx RCC
    • STM32F4xx GPIO
    • STM32F4xx TIM
  • TM
    • TM PWM
    • defines.h


Pinout is the same, as in my PWM library. To get full table of pins, check it here.


By default, MIN and MAX pulses are set in my library. They are set to work with most servos, so between 1000us and 2000us. Some china servos (fake) are going also from 700us to 2300us, so you can test your servo for proper values. If you need to set your custom min and max pulses, then you can edit them. Add lines below in your defines.h file and edit them.

Functions and enumerations


Example below produces:

  • 2 servos
    • One on pin PA5
    • Second on pin PB3
  • First servo rotates from 0° to 90° and then to 180° each 2 seconds
  • Second servo rotates from 180° to 90° and then to 0° each 2 seconds

Project is available on Github, download library below.

TM STM32F4 Servo Library

Servo library for STM32F4xx


Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • Veli


    I have erors that stm32f4xx_rcc.c(1376): warning: #223-D: function “assert_param” declared implicitly

    What is the worng?

    • do you have set USE_STDPERIPH_DRIVERS in your preprocessor defines?
      Somewhere under proejct settings in your IDE you should have this.

      I’m not sure, but I think that this is the problem.

  • Jack

    Hello ,

    I have a problem about my practice.I want to do that for example when PC 7 is logical 1,servo 1 is work.How can I do it?Can you help me please?

    • Simple, read pc7 and if it is 1,then set your servo position.

      • Jack

        ‘read pc7 and if it is 1,then set your servo position’
        which code how can I read pc7

        • Beginner right? Under my tutorials section find how to drive leds and read buttons.

          • Jack

            Hi I am beginner.I examine this link :

            But I don`t do it.Please can you help me which code how can I read PC7.I need this function.I need your help.

          • Jack

            Hi again,

            I use servo control code with that code :

            GPIO_InitTypeDef GPIO_InitDef;

            RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);

            GPIO_InitDef.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;

            GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT;

            GPIO_InitDef.GPIO_OType = GPIO_OType_PP;

            GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL;

            GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;

            //Initialize pins

            GPIO_Init(GPIOG, &GPIO_InitDef);

            RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

            GPIO_InitDef.GPIO_Pin = GPIO_Pin_0;

            GPIO_InitDef.GPIO_Mode = GPIO_Mode_IN;

            GPIO_InitDef.GPIO_OType = GPIO_OType_PP;

            GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_DOWN;

            GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;

            //Initialize pins

            GPIO_Init(GPIOA, &GPIO_InitDef);

            But I have this eror why?

          • The error says to you everything.

            All variable declarations must be at beginning of function.

          • Jack

            I try it but a lot of errors.Anyways I want to ask that I want to be my practice When I firstly press the button my int i is =1( This is counter) then When I secondly press the button my int i is =2 .I used TM_DISCO_ButtonPressed()) function.

            My code is :
            int i;
            if (TM_DISCO_ButtonPressed()) {i=1;


            if (i==1) {

            if (TM_DISCO_ButtonPressed()) {i=2;


            But doesn`t work as I want.Where are my errors?

  • kais

    i tried this library on two different servos one HXT 9g servo and the second one is
    HXT 6.9kg. the first one is working at random (some times it makes 3 or 2 rotations from 0 to 180 before waiting 2sec but the second one is Ok and works perfectly.

    i dont know what is the problem with the microservo 9g as i tried it on a remote control and it is OK so the problem comes from my stm config ? Do you have any idea about changing frequency or sthg else to make the micro servo work naturally. thank you

  • Guest
  • Pingback: All STM32F4 libraries - STM32F4 Discovery()

  • achraf

    do that programme works with my Micro Servo SG90 !! it looks not :/

    • If your pll clock is set correct and your servo is designed in standard, then yes, it works.

      • achraf

        I copy the same programme ! do i have to do some thing with clock ?

        • Just calm down.
          You have to set it yes.

          Which board, everything you use?
          Any info is useful!!

  • bou6

    Can you provide us with some informations on how to connect the motor to the stm32 card

  • Masato Kumai


    I’m trying TM STM32F4 Servo Library.

    I succeeded build, but there are sysntax errors in tm_stm32f4_delay.h.

    This is the following error.

    static __INLINE void Delay(uint32_t micros) {

    #if defined(TM_DELAY_TIM)

    volatile uint32_t timer = TM_DELAY_TIM->CNT;

    do {

    /* Count timer ticks */

    while ((TM_DELAY_TIM->CNT – timer) == 0);

    /* Increase timer */

    timer = TM_DELAY_TIM->CNT;

    /* Decrease microseconds */

    } while (–micros);


    uint32_t amicros;

    /* Multiply micro seconds */

    amicros = (micros) * (mult);

    #ifdef __GNUC__

    if (SystemCoreClock == 180000000 || SystemCoreClock == 100000000) {

    amicros -= mult;



    /* If clock is 100MHz, then add additional multiplier */

    /* 100/3 = 33.3 = 33 and delay wouldn’t be so accurate */

    #if defined(STM32F411xE)

    amicros += mult;


    /* While loop */

    while (amicros–);

    #endif /* TM_DELAY_TIM */



    * @param Delays for specific amount of milliseconds

    * @param millis: Time in milliseconds for delay

    * @retval None

    * @note Declared as static inline


    static __INLINE void Delayms(uint32_t millis) {

    volatile uint32_t timer = TM_Time;

    /* Wait for timer to count milliseconds */

    while ((TM_Time – timer) < millis) {

    /* Go sleep, wait systick interrupt */




    Why do errors happen?

    • These __INLINE keywords are standard ARM C so it should work here. Used in many functions.

      • Masato Kumai

        Thank you for replying.

        I use GCC ARM Embedded compiler, so are there problems in the compiler?

        • I don’t know what happens here, but this is my file structure of core_cm4.h (provided by ARM) which is needed to get anything to work..

          • Masato Kumai

            Thank you.

            I re-installed GCC ARM Embedded, so successfully compiled the library without syntax error!!!!
            Thank you for advising very much!!!

            …but, I didn’t connect to RC servo with this library…
            Is this library for STM32F4Discovery?

            In different site, I found the following explanation.

            PA5 is connected in a STM32F4Discovery and cannot use it.

  • Kohei Ogawa


    I’m trying to connect to RC servo with this library.

    I’m troubled with an error same as Masato Kumai, too.

    What should I do??

    • These are arm standard syntax. Which compiler is in use?

      • Kohei Ogawa

        Thank you for early replying.

        I use the following projects.
        1. GCC ARM Embedded
        -Download project files

        2. CoIDE
        -Download through CoCenter

  • Masato Kumai

    Hi !
    I successfully compiled Example file because of your advice.
    Thank you very much !!

    I have a question.
    After measuring the signal voltage with an oscilloscope, it was 30V.
    Can we make the signal voltage 5V?

    • What was 30V? Output from STM?

      • Masato Kumai

        Thank you for early replying.
        Yes, output from STM. I use STM32F4Discovery.
        I tried the following.
        1. compile the servo library example
        2. measure the signal output voltage from PA5.
        →This voltage was 30V.

        Operating voltage of my RC servo is 4.8~6V so my RC servo doesn’t operate…

        • It is 3V not 30. Check scope settings!

          Set vcc to 5V and gnd to gnd. 3V input control signal works OK.

          • Masato Kumai

            Is it 30V not 3V?

          • And probe settings in scope is set to x10 maybe? Sure it is. Or you have amplifier on output.

          • Masato Kumai

            When I switched on the oscilloscope again and measured, it became 3V.


            The Frequency of my RC servo is 20ms, so should I change this function as follows?

            in the “tm_stm32f4_servo.c”
            TM_PWM_InitTimer(TIMx, &ServoStruct ->PWM, 20000)

            I don’t know a lot about program.

          • You don’t need to know.
            Aaa I probably see the problem!

            Do you have PLL settings correct set?


          • Masato Kumai

            I confirmed “stm32f4xx.h” and “system_stm32f4xx.c”.

            In the “stm32f4xx.h”
            #if !defined (HSE_VALUE)
            #define HSE_VALUE ((uint32_t)25000000)

            In the “system_stm32f4xx.c”,
            #define PLL_M 25

            Should I change as follows?

            PLL_M 25
            →PLL_M 8

          • I don’t know which board you have. If you have HSE 8MHz connected, then yes.

          • Masato Kumai

            I use STM32F4Discovery.

          • Then yes.

          • Masato Kumai

            It was possible to move RC servo!!!!!!!!!!!
            Thank you very very very much!!!!!!!!!!

            Next, I tried to move MPU-6050.
            When I have problems, please advises.
            Thank you.

  • Laxus

    I recently started using STM32F4, my version is STM32F417IG of ARM.

    I think on this board to control the stepper motor.

    I would like to ask how to write the code to control.

    I try to write in the process, the problem is that the array declaration, as well as program code, True and False signals the level of use of this standard can not call.

    • Controlling stepper motors is a bit tricky I would say. You need some timer with periodic interrupts and make pin changes there to move motor to direction you want. And then edit timer interrupt period to change speed of motor, for example.

      • Laxus

        Yes! Originally used this Arduino board to control the stepper motor, but transferred to STM32F417IG the ARM, the code is less likely to be compatible, I have more problems in the code, if I want to learn to write programs, what is the entry way to go research, or you help me look at my program written it?

        • Definitelly you can use this site from start and check some of libs and tutorials how they are structured. C language is required to understand usage here.

      • Laxus

        I have another question on the board I see are basic pin shows only 3.3 volts, 5 volts How can I use?

        Is a program written in the manner set GPIO can it?

        • Pins are 3.3 at output, but you can connect 5V to it when using pin as input. Make sure you check datasheet, not all pins are 5V tolerant!

          Not sure if I understand second question.

  • Eko

    hi, what already exists for Dynamixel servo library?

  • Touseef Qamar

    Hi! I started using STM32F407VGT6 and I want to control almost 17-21 DC servo motors (like SG-5010) in one of my project. I just want to know that Can I easily control all these motors directly with this board or i need to use any motor control driver for that? Waiting for your response. Thanks!

    • You can calculate if you can.
      Each motor needs 1 channel on timer. Timers have 4, 2 or 1 channels for output. Check how many timers you have and how channels it has.

      • Touseef Qamar

        OK thanks for your reply. I might be needing more help in future.

  • Nico

    Hi, my question is it possible to control a servo with STM32107VC?
    So what i must change to import this code to this uC.
    Best regards Nico

  • Wassim Hammami

    Hi ! can i use this library for stm32f7 nucleo board ? waiting for your response , thanks !

    • I believe no. At least not directly, but modifying this lib would take more time than using CubeMX and setup timer with 50Hz output and 1-2ms pulse size. Then API functions are easy to implement.

  • Dmitry Kudriavcev

    Hello Majerle!
    how do u guess, it possible to using discovery with 20 servos? or better looking for another device?

    • It can be used. You just need a STM32 with enough timers. Each timer can have up to 4 (not all) outputs so for example I believe with 8-9 timers you can do your job.

  • Mustafa Kiyga

    Hello i downloaded the project from github however when i build project from keil uVision v5 i’m encountering an error that C:Keil_v5ARMPACKKeilSTM32F4xx_DFP2.11.0DriversCMSISDeviceSTSTM32F4xxIncludestm32f429xx.h(191): error: #5: cannot open source input file “core_cm4.h”: No such file or directory How can i fix this error? Thank you.
    Note: I have st link driver

  • Béchir Souli

    hello i’m using HAL library and when i add your library it get me an error in include !! how i can make it work please i need this for my project and i’m in a time problem ! thank u

    • This lib is not compatible with HAL at all. You have to manually set timer and PWM output for your usage.