Controlling an Analog Servo

 Objective

This project will walk you through the process of controlling an analog servo using the PWM module. An analog servo is controlled by a pulse width of 1-2 milliseconds. A one-millisecond pulse drives the servo in one direction and a two-millisecond pulse drives it the other way. A 1.5-millisecond pulse puts the servo in the middle position. For best holding torque, it is recommended that the signal repeat every 20 milliseconds.

ServoSignal.png

 Materials

Hardware Tools

Tool About Purchase
PICkit3-50px.png
PICkit™ 3
In-Circuit Debugger
PICDEMlab2-50px.png
PICDEM™ Lab II
Development Platform

Software Tools

Tool AboutInstallers
Installation
Instructions
Windows Linux Mac OSX
MPLAB® X
Integrated Development Environment
swtool-28px.png
MPLAB® Code Configurator
Dynamic Code Generation
MPLAB® XC8
C Compiler

Exercise Files

FileDownload
Installation
Instructions
Windows Linux Mac OSX
Project and Source Files

 Connection Diagram

circuit.png

 Procedure

The project uses:

PICDEM Lab II Connections:

  • Connect 5 V and Gnd to the power bus of the protoboard.
  • Connect 5 V to the Vdd pin of the PIC16F1508
  • Connect GND to the Vss pin of the PIC16F1508
  • Connect a wire from the RC1 pin (pin 15) to the breadboard Row 7
  • Connect a wire from the ground bus to breadboard Row 9
  • Connect a wire from the power bus to breadboard Row 8
  • Connect Analog Servo to Breadboard with wire or two-sided male header. Signal Row 7, Power Row 8, Ground Row 9.

To follow along with these steps, MPLAB X IDE should be open and the Programmer/Debugger connected to both the computer and the Development Board. The setup is described in more detail here;Setup and Installation, for those that have not used these tools before.

1

Open the MPLAB X IDE and also the MPLAB Code Configurator under theTools > Embedded menu of MPLAB X IDE.

openmcc.png

2

Click on theSystem Module and the MCC screen will show the Easy Setup menu. Select theINTOSC in the Oscillator Select box. Then selectFOSC in theSystem Clock Select window. Finally, select2 MHz_HF in the Internal Clock selection window. This will be the clock for the PIC16F1508. Settings are shown here:

systemservo.png

3

Next, choose thePWM4 andTMR2 blocks underDevice Resources by double-clicking on them. This will add them to the project.

projectresources.png

4

Setting upTimer2 will control the period of the PWM signal.
Click on theTMR2 resource to configure it for PWM. Check theEnable Timer box. UnderTimer Clock set thePrescaler to1:64. Enter20 ms in theTimer Period box. This will configure the PWM for close to a 20 millisecond period.

tmr2servo.png

5

ThePWM peripheral is setup next.

  • Click onPWM4 to open theEasy Setup window.
  • Make sure theEnable PWM and theEnable Pin Output are both checked.
  • In theSelect a Timer box chooseTimer 2.
  • SetDuty Cycle to50%.
  • The PWM Period will show a value close to 20 milliseconds.
pwm4servo.png

6

Click on thePin Module8 resource.
Under thePin Manager graphic, click on the blue lock at the PORT C bit 1 column in the PWM4 row to change it to green.
In thePin Module Easy Setup window, uncheck theAnalog box leaving just theOutput box checked.

pinmoduleservo.png

7

Click on theGenerate button in theProject Resources header to generate the project code.

generateservo.png

8

Add setup code under the// initialize the device section of the generatedmain.c file.

// initialize the device    SYSTEM_Initialize();    uint16_t dutycycle;    //clear out any stored value    dutycycle = 0;

In themainwhile(1) loop add the following code after the**// Add your application code** comment line.

       for( dutycycle = 30; dutycycle < 65; dutycycle ++){  //cycle duty cycle from 30 to 65       PWM4_LoadDutyValue(dutycycle);       __delay_ms(20);    }       for( dutycycle <= 65; dutycycle > 30; dutycycle --){ //cycle duty cycle from 65 to 30       PWM4_LoadDutyValue(dutycycle);       __delay_ms(20);    }

The values fordutycycle are not a percentage of the waveform but rather the values that fill the10-bit register pair PWMxDCH and PWMxDCL in the PWM peripheral. Based on theTimer2 PR2 setting from step 4, a 100% duty cycle has the value of 624, so 30 is roughly 5% of that and 65 is roughly 10%. With a 20 millisecond period, this produces approximately a 1 ms (30) and 2 ms (65) pulse respectively.

9

Click on theMake and Program Device icon. This builds the project and launches the programmer.
In theOutput window you should see a series of messages and, if successful, it ends with a "Programming and Verify Successful" message and the servo connected to RC1 pin begins moving back and forth.

Main_Program_Target_Project.png

10

Success!
The servo moves back and forth from the pulses produced in the PWM peripheral.

servomove.gif

 Conclusions

The PWM module is very useful for power, lighting and robotics applications where the square wave generated by the module should be used. Driving a servo can be a very useful application in many forms.