This article will continue to control the servo motors of the motor type. I have two types of servo motors (or "steering gears") on hand: MG90S and MG996R. The wiring method is the same. Unlike a motor, the main function of a motor is to rotate, and what needs to be controlled is the speed and direction. The servo motor cares about the angle of rotation and does not need to rotate a full circle. The general angle of rotation ranges from 0 degrees to 180 degrees.
To control the speed of the servo motor or the dimming of the LED, PWM (Pulse Width Modulation) counting is usually used, which can control the speed of the DC motor by changing its input voltage. PWM is a technology that uses a series of ON-OFF pulses to adjust the average value of the input voltage. In easy-to-understand terms, it is a switch that frequently changes the voltage. The program is switched at a high speed within a fixed time. The voltage is switched many times. When the on time is longer, the motor speed will be faster; if the time is off, the motor will be turned off. If the time is longer, the speed of the motor will be slower. We call the proportion of time that the voltage is given as the duty cycle (Duty Cycle). The higher the duty cycle, the higher the average voltage applied to the DC motor (high speed), and the lower the duty cycle, the lower the average voltage applied to the DC motor (low speed). For example: light brightness control, motor speed control, screen brightness control, loudspeaker loudness/sound frequency control, etc.
Take the MG996R in this implementation as an example. Generally speaking, the reference signal cycle of PWM control servo motor is 20ms, and the reference pulse width is 1.5ms (the median). Theoretically, the pulse width should be between 1ms and 2ms. However, in practice, The upper pulse width can be between 0.5ms and 2.5ms, and the pulse width corresponds to the steering angle of 0°~180°. Let's use the following table to see how to calculate the duty cycle.
The angle corresponding to the pulse width of the above signal is converted into a duty cycle, the formula is: 2.5+angle/180*10, and the PWM pin resolution of Pi Pico is 2^16 = 65535, when converted to 0 degrees, its duty cycle The ratio is 65535 * 2.5% = 1638.375. When the angle is 180 degrees, the duty cycle value is 65535 * 12.5% = 8191.875. These two values are related to the program. Taking into account the error and rotation angle, I set the duty cycle Between 1000 and 9000, the steering gear can be rotated smoothly from 0 to 180 degrees.
When using PWM to control the servo motor, it is found that the duty cycle value is different from that of the LED. The reason is that the maximum rotation angle of the servo motor is only 180 degrees, and the brightness of the LED, the duty cycle can range from 0 to 65025. I checked the relevant documents and did not explain how 65025 is calculated? But this value is just 255 * 255. The guess is that the maximum value of 8-bit PWM is 255, and pwm.duty_u16 is the maximum value obtained by multiplying two (2^8-1=255). This means that 65525 will be 100% of the time, keeping the LED or DC motor on or at full value.
The specifications of MG996R servo motor are as follows:
The execution result of program two:
To control the speed of the servo motor or the dimming of the LED, PWM (Pulse Width Modulation) counting is usually used, which can control the speed of the DC motor by changing its input voltage. PWM is a technology that uses a series of ON-OFF pulses to adjust the average value of the input voltage. In easy-to-understand terms, it is a switch that frequently changes the voltage. The program is switched at a high speed within a fixed time. The voltage is switched many times. When the on time is longer, the motor speed will be faster; if the time is off, the motor will be turned off. If the time is longer, the speed of the motor will be slower. We call the proportion of time that the voltage is given as the duty cycle (Duty Cycle). The higher the duty cycle, the higher the average voltage applied to the DC motor (high speed), and the lower the duty cycle, the lower the average voltage applied to the DC motor (low speed). For example: light brightness control, motor speed control, screen brightness control, loudspeaker loudness/sound frequency control, etc.
Take the MG996R in this implementation as an example. Generally speaking, the reference signal cycle of PWM control servo motor is 20ms, and the reference pulse width is 1.5ms (the median). Theoretically, the pulse width should be between 1ms and 2ms. However, in practice, The upper pulse width can be between 0.5ms and 2.5ms, and the pulse width corresponds to the steering angle of 0°~180°. Let's use the following table to see how to calculate the duty cycle.
SIGNAL PULSE WIDTH | SERVO MOTOR ROTATION ANGLE | DUTY CYCLE |
---|---|---|
0.5ms | 0 degree | 2.5% (0.5ms high potential + 19.5 low potential) /td> |
1ms | 45 degree | 5% (1ms high potential + 19.0 low potential) |
1.5ms | 90 degree | 7.5% (1.5ms high potential + 18.5 low potential) |
2.0ms | 135 degree | 10% (2ms high potential + 18.0 low potential) |
2.5ms | 180 degree | 12.5% (2.5ms high potential + 17.5 low potential) |
The angle corresponding to the pulse width of the above signal is converted into a duty cycle, the formula is: 2.5+angle/180*10, and the PWM pin resolution of Pi Pico is 2^16 = 65535, when converted to 0 degrees, its duty cycle The ratio is 65535 * 2.5% = 1638.375. When the angle is 180 degrees, the duty cycle value is 65535 * 12.5% = 8191.875. These two values are related to the program. Taking into account the error and rotation angle, I set the duty cycle Between 1000 and 9000, the steering gear can be rotated smoothly from 0 to 180 degrees.
When using PWM to control the servo motor, it is found that the duty cycle value is different from that of the LED. The reason is that the maximum rotation angle of the servo motor is only 180 degrees, and the brightness of the LED, the duty cycle can range from 0 to 65025. I checked the relevant documents and did not explain how 65025 is calculated? But this value is just 255 * 255. The guess is that the maximum value of 8-bit PWM is 255, and pwm.duty_u16 is the maximum value obtained by multiplying two (2^8-1=255). This means that 65525 will be 100% of the time, keeping the LED or DC motor on or at full value.
The specifications of MG996R servo motor are as follows:
- Dimensions: 54 x 38 x 20 mm
- Weight: 55g
- Working voltage: 4.8V~7.2V
- No-load working current: 120mA
- Locked-rotor working current: 1450mA
- Running speed: 0.13 seconds/60 degrees (6.0V no load)
- Servo torque: 11kg*cm(6.0V)
- Swivel angle: the controllable angle is about 180 degrees/270 degrees (maximum)
- Gear: 5-level metal gear set
- Weight: 55g
[Material]
- Raspberry Pi Pico x1
- MG996 Servo Motor x1
- Variable resistance 10K x1
- Breadboard x1
- Breadboard power module x1
- Wires x N
[Wiring diagram]
Since Pi Pico can only provide 3.3V power, the servo motor needs an external power supply and connect Pi Pico GND to the power ground wire. The outer two pins of the variable resistor are connected to the positive and negative electrodes provided by the breadboard power supply, and the middle Pin is connected to Pico's ADC0. The following chart:Pi Pico | MG996R Servo Motor | 10K Resistance |
---|---|---|
Pin38(GND) | GND | GND |
Pin31(GP26/ADC0) | - | Data(Middle Pin) |
Pin1(GP0) | Data | - |
[Code:one]
The frequency pwm.freq tells Pi Pico how long to switch on and off, and the program is set to the commonly used 50. The following formula divides 9000 by the maximum value of 65025 to calculate a fixed constant, and divides the value read by the variable resistor by this constant to convert it into the duty cycle of the servo motor. The following is the complete program. Although there are only a few lines, the resistance can be used to control the rotation of the servo motor:from machine import Pin, PWM analogvalue = machine.ADC(26) pwm = PWM(Pin(0)) pwm.freq(50) scale = 9000/65025 while True: reading = analogvalue.read_u16() pwm.duty_u16(int(reading*scale))
[Code:two]
This program uses a conversion program to map the input angle to a duty ratio of 1000 ~ 9000, and then let the servo motor rotate to that angle. The loop in the program makes the servo motor continue to rotate forward and backward 180 degrees.from utime import sleep from machine import Pin from machine import PWM pwm = PWM(Pin(0)) pwm.freq(50) # Set the rotation angle of the servo motor def setServoCycle (position): pwm.duty_u16(position) sleep(0.01) # Convert the rotation angle to the duty cycle def convert(x, i_m, i_M, o_m, o_M): return max(min(o_M, (x - i_m) * (o_M - o_m) // (i_M - i_m) + o_m), o_m) while True: for degree in range(0, 180, 1): pos = convert(degree, 0, 180, 1000, 9000) setServoCycle(pos) for degree in range(180, 0, -1): pos = convert(degree, 0, 180, 1000, 9000) setServoCycle(pos)