Multiple Servo Control Atmega32

Hi, i´m trying to control 18 servos using ATMEGA32 Microcontroler with Codevision.
Each servo is connected to an specific pin of the controler, so i´m not using any Latch or Shift-Register circuit.
I´m trying to do this using interrupt of the PWM mode from Timer 1.
As i want to control a lot of servos with diferent speeds, i need a very low resolution so i can update each output pin in the right time.
So i create an interrupt that overflows each 10 us, and in every oveflow the interrupt routine is executed.
In each routine execution i have 18 “if” instructions to compare the time passed with the time preset and when its true that pin goes to 0 until the next 20ms cycle.
This works fine for a few servos, like 2 or 3, but when i put all the comparisons doens´t work, maybe because the instructions time take too long and the processor skip it.
So i want to know if there´s any other way to do that, and how the interrupt routine works, cause when the counter overflows it starts the routine, but if the code its too long i think that the processor skip to start the new count. So maybe i need to count until the overflow and then disable the interrupt until the complete execution of the code and then enable it again? Somebody can help me? Thanks!

It’s gonna be hard to program 18 servos without using banks. You can’t just use 18 if’s, as far as I can tell. Takes too long. I’ve done 8 R/C servos with a PIC (all I needed). I’d try do them in banks of 4 or 8, in parallel as it were, and then the if’s won’t stack up as much.

Remember, you don’t have to pulse all of them at the same time! you can do them in banks and thus have less to handle.

HTH

Alan KM6VV

You are correct in that with a 10uS interrupt rate you are most likely running out of time in your service routine when you try to process more than a couple statements. It does make a nice 8-bit resolution for the servos though. There are a couple things you can do to make this easier. First off consider the timing requirements of the servos. Every 20mS you need to send a pulse of at most 2.5mS duration. Once you have completed a pulse you sit around for the remainder of the 20ms. Consider that you don’t have to be running all 18 servos in the same 2.5ms… you could time servos 0-2 in the first 2.5ms, then servos 3-5 in the second 2.5ms, then servos 6-8 in the third 2.5ms, etc you should get the idea. Once you have updated all 18 outputs you should have used six of your eight 2.5ms windows and you can use the remaining 5ms to setup for the next update interval. Got enough of the idea to give it a try?

edit: ya know sitting here looking at it I think I said the same thing Alan did… maybe with a little more specifics on the idea. :wink:

Yeah, but with a complex concept like that, it may take a few descriptions to get the main points across. Not easy to absorb it all at once. And the numbers help!

Alan KM6VV

Hi, thank you both for the reply! I got the idea, it´s a very good idea, but i was trying to get an individual movement for each servo!
In this way i´ll have the same movement for goups of 3 servos.
But based in this idea i figure something out!
Timer 1 in PWM mode has OCR1A and OCR1B registers, so i can setup the count to overflow in each 2.5 ms and i can setup this two registers to overflow earlier individually, in the cases that i need smal pulse, like 1.5 ms for example.
Doing this i can update 2 servos individually to any position each 2.5 ms, so i´ll have individual movement for each; the problem is that in this case i´ll take 22.5 ms to update all 18 servos instead 20 ms.
There are some servos that accept pulses between 15 ms and 30 ms, it depends of the servo.
Anyway, i´ll try this with the servos that i have and then i´ll post the result, if doesn´t work i´ll try the 3 servos bank idea.
Thank you for the support!

Hello again!

I´m writing just to inform you that my idea worked fine! :smiley:
Now i´m able to control all 18 servos individually, using the system described before.
Thanks!

congratulations.

question: digital servos or analog servos?

reason: digital servos will typically protect their end points of rotation… that is it is difficult to drive most of them beyond the mechanical endstops of the servo. they also typically look at the pulse width and not the pulse width as a percentage of frame width. this is nice so 1.5mS pulse should still be zero degrees even though the frame period is shifted out to 22.5ms.

many analog servos, on the other hand, will happily go right to the mechanical stop and grind out against it. sometimes this destroys the servo. where you are using longer than a 20ms frame your zero degree reference at 1.5mS is most likely shifted a few degrees to one end. this means the normal pulse width limits of 0.5ms to 2.5ms “could” drive your servo into its mechanical stop… possibly damaging it.

So if you are using analog servos you should probably go through an exercise of determining the time values corresponding to end points of rotation so you don’t inadvertently damage them.

22.5 mS isn’t much of a change from 20 mS, I doubt if you’ll have any problem with that. However stretching out the refresh (frame) rate of the servos may cause some loss in torque.

In fact, the technique of stretching out the frame to something like 30-40 mS is being used as a means of making servo motion a little “softer” for foot falls. Something I’d like to work into my servo work. And with a little extra gating, it should be possible to only send alternate refresh pulses to a servo driven by the SSC-32, and hence modify the torque to selected servos. Further investigation needed.

Alan KM6VV

My testing of using wider spaced pulses only resulted in stuttering and jittery operation. I found no value created the so called “soft start” for powering up servos. You saying people really think that works?

Yes, or so I’ve heard. How long was your refresh frame rate?

Others seem to be quite keen on it. We’ve been discussing compliance over on the SeattleRobotics list.

I have performed no tests to this point. I’m personally theorizing that a two-level power supply to the servos (“pick” and “hold” stuff) might be useful. I’m wondering if a BEC can be made to switch it’s power level outputs.

I’d like to suggest that the SSC-32 be able to change the refresh rate, but from what little I know of the code, I really doubt this would be possible. Maybe a “double” of from 20 mS to 40 mS on selected servos, but that’s quite a bit to request. That of course assumes that this is desirable. I can do logic to get the “doubling” of the frame refresh period.

Alan KM6VV

Dunno been many moons ago. But I experimented extensively with it. It’s a wild goose chase if ya ask me.

Of course another option is to go to digital servos. I’m told they can handle a torque parameter. $$$

Alan KM6VV