Servo motor using PIC24FJ64
Quick tutorial on how to use the PIC24FJ64 Curiosity Nano development board to control a servo motor.
Tools required:
- The development board
- Servo motor
- 5V power supply
Software required:
- MPLABX IDE
Servo basics
The servo motors come in two categories,
- Continuous servo
- Standard servo
The continuous servo is a servo that continuously rotates on valid control signal,
whereas, the standard servo is the one that stops at specific angles (ie: 0 to 180 degrees).
The servo motors come with three wires.
- A red wire for the 5 V input voltage
- A brown wire for the GND connection
- A orange/yellow wire for the control signal
The control signal traditionally is a PWM signal with a period of 20 ms. The pulse width is in the range of 1 ms to 2 ms.
For continuous servo motors:
- A pulse of 1 ms turns the motor continuously clockwise.
- A pulse of 2 ms turns the motor continuously anti-clockwise.
- A pulse of 1.5 ms stops the motor.
For standard servo motors:
- A pulse of 1 ms turns and latches the shaft at 0-degrees.
- A pulse of 1.5 ms turns and latches the shaft at 90-degrees.
- A pulse of 2 ms turns and latches the shaft at 180-degrees.
When I tested this on the cheap servo I bought from aliexpress, I observed that the pulse duration is from 0.5 ms to 2.5 ms. I don’t have an official datasheet to verify the values.
Driving the servo using the PIC24FJ64
It has been a while since I used any PIC device, therefore, it took me a few hours to figure things out.
- Create a new MPLABX project for the PIC24FJ64GU205 micro-controller.
- Use the MPLAB Code Configurator to configure a MCCP peripheral. I didn’t read the datasheet to understand all the capabilities of the peripheral. Instead, I just played with different options until I could generate the PWM signal I wanted.
Basically, I used 
- This sets up the PWM to generate a 20 ms period and 1 ms pulse.
- Then in the
main.c, I used the following code to test the servo.
MCCP1_COMPARE_Start();
int values[] = {17500, 18000, 18500, 19000, 19500, 19000, 18500, 18000};
while (1)
{
for (int idx = 0; idx < sizeof(values) / sizeof(int); idx++)
{
MCCP1_COMPARE_SingleCompare16ValueSet(values[idx]);
int j = 0xFFFFFF;
for (int k = 0; k < 5; k++)
{
j = 0xFFFFFF;
while(j--);
}
}
}
