Maker Pro
Maker Pro

Programming PIC to sontrol 6x SERVOs

Hi,
I'm programming PICs for a transmitter/receiver project. The program for the receiver needs to output 6x SERVO controls (standard RC SERVOs) I kind of understand the theory, of the 20ms PERIOD and within that time the SERVO bursts are outputted, but I would like a clearer explanation of the timings to include the controlling program also, please. e,g, time for 20ms PERIOD, then time for program, repeated.

I have included a 6CH image.

Camerart.
 

Attachments

  • PWM.jpg
    PWM.jpg
    64.8 KB · Views: 67
Hi B,
What I'm actually looking for is a clearer understanding of timings when it comes to SERVO control (Not PWM) as my initial question.
Thanks.
C.
 
Servos are pwm however there is some conflicting understanding as reference to speed control of motors.
For a standard explanation, Wiki has a reasonable breakdown under "servo control" should get you over the hump.
 
Servos are pwm however there is some conflicting understanding as reference to speed control of motors.
For a standard explanation, Wiki has a reasonable breakdown under "servo control" should get you over the hump.
Hi B,

Here is a section from the Wikipedia explanation:

Modern RC servo position is not defined by the PWM duty cycle (i.e., ON vs OFF time) but only by the width of the pulse. (This is different from the PWM used, for example, in some DC motor speed control).

I am hoping that someone with RC SERVO experience, where multiple SERVOs are used together, can explain in a clear way, so that I understand how to program a PIC. This will also include some time for the controlling program LOOP.

Thanks, C.
 
I could explain it all to you but I see no point.
There is vast amounts of info out there you can research without my having to repeat it and argue the point into the bargain ( plenty else for me to do)
Suffice to say there is a basic explanation on the timing and an advanced arrangement depending on system used.
 
Hi B,
Ok, thanks. sorry to have wasted your time.

(Note, I have mild dyslexia, and have read over and over many times a lot of information about PWM PPM and find it most difficult to understand what I imagine is a simple timeline, if it was outlined in simple terms.)

Something like: PIN1 ON--waitus 1000--PIN1 OFF---waitus 1900......PIN2 ON--waitus 1500 ETC ETC.

C.
 
You need only develop a timing routine that takes a parameter you 'send' and incorporates it to the 'size' of the delay.

i.e. if you decide on a maximum position accuracy of 1/255th of a (swing of the servo rotor) rotation then send a number between 00 and FF to be included in a timer routine that has a fullscale value of 255 for the MAXIMUM pulse duration where the value (between 00 and FF) determines the actual timer routine delay.

If you are using a PIC then have a look at PICBasic Pro as it incorporates specific instructions for ease of timing routines and is (imho) one of the easiest ways to get a PIC up and running.
 
You need only develop a timing routine that takes a parameter you 'send' and incorporates it to the 'size' of the delay.

i.e. if you decide on a maximum position accuracy of 1/255th of a (swing of the servo rotor) rotation then send a number between 00 and FF to be included in a timer routine that has a fullscale value of 255 for the MAXIMUM pulse duration where the value (between 00 and FF) determines the actual timer routine delay.

If you are using a PIC then have a look at PICBasic Pro as it incorporates specific instructions for ease of timing routines and is (imho) one of the easiest ways to get a PIC up and running.
Hi K,
Contrary to apparent lack of skill, I have been programming PICs for a long time, using Oshonsofts simulator, which I find indispensable. Sadly each time I start a project, I almost have to start from scratch, and have a library of programs to call on, and of course hopefully help from forums like these.

Looking at the image I posted in #1 it shows the 20Ms PERIOD, with 6x SERVO outputs between 1000us and 2000us within it. I have an oscilloscope reading from the output of a Transmitter, before the radio part, where it shows just that, but I assume this is split into 6 so there are 6x separate outputs from 6x PINs. I'm puzzled as to whether each PIN has a PERIOD of 20ms complete or just it's ON/OFF time, so that all 6x PINs are completed within the 20ms PERIOD?

Thanks,
C.
 
Each pulse is from 1 to 2 msec. The entire period is 20ms. So, in one period, there is enough time to put out a 1 to 2 msec pulse for each of the 6 servos then repeat.

Easiest way to do it is like this (pseuddcode)

Code:
while (1)
{
     turn on output for 1'st servo
     delay for on time for 1'st servo
     turn off output for 1'st servo
     delay 2mS - on time for first servo

     repeat above for other 5 servos
 
     delay 8 msec (the remainder of the 20 msec period
}
 
Each pulse is from 1 to 2 msec. The entire period is 20ms. So, in one period, there is enough time to put out a 1 to 2 msec pulse for each of the 6 servos then repeat.

Easiest way to do it is like this (pseuddcode)

Code:
while (1)
{
     turn on output for 1'st servo
     delay for on time for 1'st servo
     turn off output for 1'st servo
     delay 2mS - on time for first servo

     repeat above for other 5 servos
 
     delay 8 msec (the remainder of the 20 msec period
}

Hi B,
That looks promising!

I had tried similar, but didn't have each SERVO OFF time, and I had delay of 14 msecs instead of 8.

Thanks, I'll give it a go.
C
 
That probably should have worked. The 50 msec is not critical.

Do remember that the on time starts at 1 msec and is up to 2 msec.

Bob
 
That probably should have worked. The 50 msec is not critical.

Do remember that the on time starts at 1 msec and is up to 2 msec.

Bob
Hi B,
I presume by 50 msec you mean 20, is this correct?

You code is working---GREAT! Thanks a lot.

I found that to get the full throw of the SERVOs I need to use between 510ms and 2600 ms , Is this just a timing thing?

Now i need to add the rest of the program, (MAIN LOOP) If I put your code in it's own (SERVO LOOP), how long can the SERVO LOOP be left without updating before the SERVOs judder?
C.
 
RC Servos require positive pulses of 800 - 2200 microseconds. Period between the pulses should be about 20 - 25 mS. If you are using modern digital servos the pulse frequency may be higher, that means the period may be shorter. For analog servos 20 - 25 mS is required.
You have many choices to produce this signals for the servos.
You can produce the servo output signal in your program loop. Set the output1 to HIGH. Wait x uS. Set the output2 to LOW. After producing six outputs your program can deal with other things and check a global timer until the frame time of 20 - 25 mS is over and start again.
Let's say that all six servos are set to 2200 uS. 6 times 2200 is 13200 uS. If your frame is 20 mS you will have 6800 uS for your program to make the necessary calculations. If your application is OK with this you can use this method.
There is a more elegant method to produce servo signals. Using interrupts. I'm not familiar with PICs but I think there are a couple of timers and timer interrupts in these microcontrollers (I always use Atmel chips).
You need to define a volatile array for the six servo values. The interrupt subroutine will read them and arrange the pulse output accordingly. This method makes the servo signal generation transparent to the main program and this increases the overall efficiency.
If you have further questions or need some examples please feel free to ask me.
 
Yes, 50 was a typo, I meant 20.

Glad to hear that it is working.

1.5 msec to 2.0 msec will move the servo over 180 degrees. Operation outside that is undefined and may or may not work on another model of servo.

Bob
 
Hi B and S,
I'll do some tests to see what the max PERIOD time possible before errors or jumping, then shorten it a little, or simply use 2500us max for safety.

I am familiar with TIMER INTERRUPTS in PICs and will set-up a TIMER LOOP of the PERIOD length.

Thanks to all.
C.
 
The loop as you have it must be executed continually. If you go more than 20 msec without updating the servo will be erratic. If you need to so something else during each loop, the simplest was is, instead of the 8 msec delay at the end, go off and do what you need as use a timer to start the next servo update. Set up a timer for 20 msec and during your other processing, check frequently for it's expiration.

If you are going to use interrupts, I would interrupt every 2 msec and then handle 1 servo in each of the first 6 and do nothing for the next eight. You would turn on the servo you are handling at the interrupt, then schedule a timer interrupt for when to turn it off.

This would leave nearly all the processing time for other tasks without having to check for timing.

Bob
 
Top