I want multiple servos to be controlled through pic18f4550 microcontroller.

I know for a single servo I can use the following code.

unsigned int angle=0,i;
void cs_delay(unsigned int);
void main()
      for(angle=0;angle<=180;angle+=45) // Loop to increase the angle by 45°
         for(i=0;i<50;i++) // Loop to provide continuous train of pulse
             LATB.F0=1; // Send high to control signal terninal
             cs_delay(angle); // Call delay function
             LATB.F0=0; // Send low to control signal terninal

void cs_delay(unsigned int count)
   int j=0;
   Delay_us(550); // Delay to move the servo at 0°
   for(j=0;j<count;j++) // Repeat the loop equal to as much as angle
      Delay_us(6); // Delay to displace servo by 1°

But I cannot figure out how it can be used for multiple servos..

BTW, using MikroC v8.2 for programming.

Any help?


Not easily.

You see, you have written there what is known as blocking code. The PIC can't do anything else while it's processing your software PWM signal because you are using delays.

Instead you need to step away from that whole concept and instead to things based on time, not waiting.

For instance, when you get up in the morning, do you lie there awake all night staring at your clock until it's time to get up, or do you set the alarm for 7:30 then go to sleep, until the clock wakes you up?

Most PICs make it even easier, by allowing you to tie a timer to an output compare module, which will generate your PWM waveform purely in hardware. The more output compare modules and timers you have the more servos you can drive with it.

Even without using output compare, there are ways of using a timer to trigger an alarm the next time an output is due to change state. It's up to you to come up with how best to decide when that is, and change the timer's time accordingly.

  • \$\begingroup\$ thanks... can u explain a little bit on how it can be done.. i'm a bit new to pic programming.. the code i've stated above is my first try at pic... on an unrelated topic.. i wake up at 9:30 am :P \$\endgroup\$ – Suraj Bhawal Dec 13 '14 at 14:22
  • \$\begingroup\$ best-microcontroller-projects.com/pic-pwm-interrupt.html \$\endgroup\$ – Majenko Dec 13 '14 at 14:23
  • 1
    \$\begingroup\$ For some of the concepts you could try understanding this: github.com/chipKIT32/chipKIT32-MAX/tree/master/hardware/pic32/… It's written for the PIC32 using the chipKIT API, but if you can understand the code it demonstrates how to work with multiple channels and one timer. \$\endgroup\$ – Majenko Dec 13 '14 at 14:26
  • \$\begingroup\$ in general this kind of thing goes into the realm of real-time control/multitasking, and there is a huge amount of theory and framework you can take advantage of @SurajBhawal . But basically Majenko's timer-based hardware solution, if you have enough timers, is the most direct and less prone to issues/jitter. \$\endgroup\$ – KyranF Dec 13 '14 at 17:50

If you want to use delays and control the servos you can see my code, which is written using mplab.

     PORTD=0b00000001;        //servo0 

     PORTD=0b00000110;  //servo 1,2

     PORTD=0b00001000;  //servo 3

     PORTD=0b00100000;  //servo 4

     PORTD=0b00000000;  //pulse down

I have 5 servos connected to portD and servo 1 and 2 work on same pulse.

Ok here is how it works, the width of entire pulse cycle of servo is 20ms, but servo have tolerance of + or - 2ms.

out of 20ms the positive pulse is only 2ms and rest 18ms is zero. I have cascaded all positive signals to servos, rest of the time all pins are set to zero.

My pic had 4MHz crystal and the below code worked to control 90 degree sweep of servo.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.