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
where:
- 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)
Library
Features
- Control RC servo motors
- Number of available servos depends on STM32F4xx chip you will use
- More timers means more servos possible
Dependencies
- CMSIS
- STM32F4xx
- STM32F4xx RCC
- STM32F4xx GPIO
- STM32F4xx TIM
- TM
- TM PWM
- TM TIMER PROPERTIES
- defines.h
- TM PWM
Pinout
Pinout is the same, as in my PWM library. To get full table of pins, check it here.
MIN and MAX
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.
1 2 3 4 5 6 7 |
/* Minimal pulse length */ /* Uncomment, if you need to set custom pulse length for 0° rotation */ #define SERVO_MICROS_MIN 1000 /* Maximal pulse length */ /* Uncomment, if you need to set custom pulse length for 180° rotation */ #define SERVO_MICROS_MAX 2000 |
Functions and enumerations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
/** * Servo struct * * Parameters: * - TM_PWM_TIM_t PWM: * PWM settings * - TIM_TypeDef* TIM: * Pointer to specific timer you will use for servo * - TM_PWM_Channel_t Channel: * Output channel on specific timer * - TM_PWM_PinsPack_t Pinspack: * Pinspack for specific channel */ typedef struct { TM_PWM_TIM_t PWM; TIM_TypeDef* TIM; TM_PWM_Channel_t Channel; TM_PWM_PinsPack_t Pinspack; } TM_SERVO_t; /** * Results enumeration * * Parameters: * - TM_SERVO_Result_Ok: * Everything OK * - TM_SERVO_Result_Error * An error occured somewhere */ typedef enum { TM_SERVO_Result_Ok = 0, TM_SERVO_Result_Error } TM_SERVO_Result_t; /** * Initialize servo * * Parameters: * - TM_SERVO_t* ServoStruct: * Pointer to an empty servo struct * - TIM_TypeDef* TIMx: * Pointer to TIMx you will use for servo * - TM_PWM_Channel_t PWMChannel: * Channel you will use for timer * - TM_PWM_PinsPack_t Pinspack * Pinspack for channel */ extern TM_SERVO_Result_t TM_SERVO_Init(TM_SERVO_t* ServoStruct, TIM_TypeDef* TIMx, TM_PWM_Channel_t PWMChannel, TM_PWM_PinsPack_t Pinspack); /** * Set rotation degrees for servo. * Degrees can be between 0 and 180. * * Parameters: * - TM_SERVO_t* ServoStruct: * Pointer to servo struct * - float degrees * rotation in degrees, between 0 and 180 */ extern TM_SERVO_Result_t TM_SERVO_SetDegrees(TM_SERVO_t* ServoStruct, float degrees); /** * Set pulse length in microseconds * * Parameters: * - TM_SERVO_t* ServoStruct: * Pointer to servo struct * - uint16_t micros: * pulse length in microseconds */ extern TM_SERVO_Result_t TM_SERVO_SetMicros(TM_SERVO_t* ServoStruct, uint16_t micros); |
Example
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
/** * Keil project for servo example * * Before you start, select your target, on the right of the "Load" button * * @author Tilen Majerle * @email tilen@majerle.eu * @website http://stm32f4-discovery.net * @ide Keil uVision 5 */ /* Include core modules */ #include "stm32f4xx.h" /* Include my libraries here */ #include "defines.h" #include "tm_stm32f4_delay.h" #include "tm_stm32f4_servo.h" int main(void) { /* Servo structs */ TM_SERVO_t Servo1, Servo2; /* Initialize system */ SystemInit(); /* Initialize delay */ TM_DELAY_Init(); /* Initialize servo 1, TIM2, Channel 1, Pinspack 2 = PA5 */ TM_SERVO_Init(&Servo1, TIM2, TM_PWM_Channel_1, TM_PWM_PinsPack_2); /* Initialize servo 2, TIM2, Channel 2, Pinspack 2 = PB3 */ TM_SERVO_Init(&Servo2, TIM2, TM_PWM_Channel_2, TM_PWM_PinsPack_2); while (1) { /* 0 degrees rotation on servo 1 */ TM_SERVO_SetDegrees(&Servo1, 0); /* 180 degrees on servo 2 */ TM_SERVO_SetDegrees(&Servo2, 180); /* 2s delay */ Delayms(2000); /* 90 degrees rotation */ TM_SERVO_SetDegrees(&Servo1, 90); /* 90 degrees on servo 2 */ TM_SERVO_SetDegrees(&Servo2, 90); /* 2s delay */ Delayms(2000); /* 180 degrees rotation */ TM_SERVO_SetDegrees(&Servo1, 180); /* 0 degrees on servo 2 */ TM_SERVO_SetDegrees(&Servo2, 0); /* 2s delay */ Delayms(2000); } } |
Project is available on Github, download library below.
Servo library for STM32F4xx
Recent comments