In this project, I will show you how to interface a Servo Motor with STM32F103C8T6 Blue Pill Board and control it using a potentiometer and the MCU’s built-in PWM function. By understanding how to control a Servo Motor with STM32, you can use this knowledge in several advanced STM32 based projects.
Servo Motors are work horses of industrial automation. They are often used in industrial robotics, automation equipment, CNC machines, etc. The advantage of Servo Motors over other motors like Stepper Motors, for example, is its precision control of either linear or angular position (depending on the application).
Coming to Embedded Systems, small plastic gear type Servo Motors are very popular among hobbyists and beginners. They are used in small robots, robotic arms, solar panel positioning and other related projects.
The TowerPro SG90 is one of the most popular types of Servo Motors used in small embedded applications. Even I have used the same in several Arduino based applications.
In this project, I will demonstrate the interfacing of a Servo Motor with STM32F103C8T6 Blue Pill board. At the time of implementing this project, I do not have access to the commonly used TowerPro SG90 Servo Motor.
But I have a slightly bigger TowerPro MG 996R Metal Gear Servo Motors, which I have been using in another robotic application. I will explain the specifications of this servo motor and you can follow this project as it is even with the smaller SG 90 Servo Motors.
A Brief Note on MG 996R Servo Motor
The MG 996R Digital Servo Motor by TowerPro is a high torque servo motor with metal gears. It can provide an average stalling torque of 10kg compared to 1.8kg of SG90.
The angle of rotation of MG996R is approximately 120 degrees i.e. 60 degrees in either direction. This is less compared to the 180 degrees of rotation of the SG90 Servo.
Following is a list of specifications of the MG996R Servo Motor.
- Weight – 55g
- Stall Torque – 9.4 kgf-cm at 4.8V and 11 kgf-cm at 6V
- Voltage – 4.8V – 7.2V
- Running Current – 500mA – 900mA at 6V
- Stall Current – 2.5A at 6V
Like the SG90, the MG996R also has three pins, Orange PWM pin, Red VCC pin and Brown Ground Pin. The period of the PWM signal is 20ms and the positions 0, 60 and -60 can be set at pulse 1.5ms, 2ms and 1ms.
Interfacing Servo Motor with STM32F103C8T6
Even though the MG 996R Servo Motor is bigger and powerful, the connections with respect to the MCU are similar to that of a SG90 Servo Motor. The Orange Wire must be connected to any PWM pin of the MCU.
For controlling the position, a potentiometer can be used and as per the readings from the ADC (whose input is the POT), the angle of rotation can be adjusted.
The following image shows the circuit diagram of interfacing a Servo Motor with STM32F103C8T6 Blue Pill board.
- STM32F103C8T6 Blue Pill Board
- Servo Motor
- 10KΩ Potentiometer
- Connecting Wires
- USB to UART Adapter (if programming via UART)
For this project, we have to use the ADC and PWM pins of the STM32F103C8T6 MCU. The following image shows the pin layout of STM32F103C8T6 MCU.
As you can see, there are 10 ADC pins (PA0 – PA7 & PB0 – PB1) and 15 PWM Pins (PA0 – PA3, PA6 – PA10, PB0 – PB1, PB6 – PB9).
So, PA3 is used as ADC pin for connecting the POT and PA0 is used as PWM pin for connecting the Servo Motor’s PWM Pin.
Programming STM32 for Servo Motor Control
The code for Controlling a Servo Motor with STM32F103C8T6 Blue Pill is very simple and in fact, if you have any experience of interfacing Servo Motor with Arduino, then writing the code is very similar. But there is one thing you need to remember about the ADC.
If you refer to the data sheet of the STM32F103C8T6 MCU, then you will notice that the ADC has a 12-bit resolution. This means that the output of the ADC of STM32F103C8T6 will have a value between 0 and 2^12 i.e. 0 – 4096.
Coming to the specification of the MG 996R Servo Motor, the maximum rotation angle is 120 degrees. So, in the program, in order to map the 0 – 4096 to the angle 0 – 120, we have to divide the output value of the ADC by 4096/120 i.e. 34.
If you have SG90 Servo Motor, whose maximum angle is 180 degrees, you have to divide the output of the ADC by 22.
The following is the simple code implementation for interfacing a Servo Motor with STM32F103C8T6 MCU.
int servoPin = PA0;
int potPin = PA3;
int potValue = 0;
int servoAngle = 0;
potValue = analogRead(potPin);
servoAngle = (potValue/34);
The working of the project is very simple. First, the value of the potentiometer is read by the ADC of the STM32 Blue Pill MCU. The output of the ADC is then scaled to angle of rotation of the Servo Motor.
Using this value, the servo motor is driven to that particular angle. Alternatively, you can implement a full sweep functionality between the angles 0 degrees and 120 degrees (in case of MG 996R Servo).
A simple project for Controlling a Servo Motor with STM32F103C8T6 Blue Pill Board is implemented here. An advanced Servo Motor called the MG 996R by TowerPro is used in this project for demonstration.