Servo motor using PIC24FJ64

Quick tutorial on how to use the PIC24FJ64 Curiosity Nano development board to control a servo motor.

Tools required:

  1. The development board
  2. Servo motor
  3. 5V power supply

Software required:

  1. MPLABX IDE

Servo basics

The servo motors come in two categories,

  1. Continuous servo
  2. 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.

  1. Create a new MPLABX project for the PIC24FJ64GU205 micro-controller.
  2. 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 code configuration

  1. This sets up the PWM to generate a 20 ms period and 1 ms pulse.
  2. 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--);
        }
    }
}

video