Society of Robots - Robot Forum
Software => Software => Topic started by: Rebelgium on August 28, 2008, 02:11:40 PM
-
Hello everybody,
I'm building a robot with a servo on top of it, which has Sharp IR (distance) sensors mounted on top of the servo.
I want this servo to rotate from one side to another.
To control the servo I use a timer peripheral of my PIC, And I don't want to use polling, only interrupts.
In my code I determin the position of the servo with by changing the value on a variable called "Servo_pos". (It can be -180 to 180)
How would I go about doing this?
My though is to have two arrays, array_up and array_low, these contain hexadecimal values to fill in the period register of the timer.
Depending on the value of Servo_Pos, two values are chosen(out of the arrays) to fill in the timer period registers to create the required pulse width every 20ms .
What do you think of this idea? Have better ideas?
Tnx in advance
-
if I understand your question correctly , you would figure out how far the servo moves per instruction to move and then from there just subtract. It will never be perfect though because you really don't know how much it turned ( e.g. if it stalls or slips)
Why not use hardware that will run the servo control in the background?
-
Why not use hardware that will run the servo control in the background?
Like A 555? Because then I have no way of knowing where my servo is at a specific time. And I need to know it's position...
if I understand your question correctly , you would figure out how far the servo moves per instruction to move and then from there just subtract. It will never be perfect though because you really don't know how much it turned ( e.g. if it stalls or slips)
Hmm I'm not sure what you mean by that... :/
I'll explain my idea a bit better: (remember, this is just an idea, if anyone has a better idea please tell me)
I have a timer, and I need to set the time it counts down to zero from in the period register.
And I have a variable called Servo_Pos, which should determin the position of my servo.
To do this, I have two arrays filled with hex values to fill into the period register of my timer. I select what value I want out of the arrays, depending on the value of servo_pos.
-
you will never know your servos position since you are telling it where to go but not where it actually is . If I hold it and you tell it to go to 0 degrees , the servo could be in the same position as last time unless I let go of the servo wheel.
You could use encoders or maybe take an ADC reading off the internal potentiometer of the servo
You could assume the servo position after a certain amount of time though - is that what you want?
-
Yes I know that, And that is what I assumed to do. But it's not what I asked. :)
In short:
I want to know the best method to control a servo with a timer, without using polling.
I did a proposal in my posts above, but If you or anyone has a better idea, please tell me.
-
Yes, but that's what you let us understood you want to know.
Anyway, IMO, the best option to control servos is to let a MCU alone do it, in software. Each cycle, it will sort out at what interval some lines should be dropped. Then, It raises all lines high, counts, and drops them as sorted. In the remaining time, it can increase their position in a controlled fashion, so it would also take care of controlling speed. This way allows you to use each output to control many servos at a high resolution.
But since this is not always doable, nor cheap, you could set up a timer in pwm mode (instead of a simple timer), and calculate your duty cycle in such a manner that some value goes to the lowest position (1000us - 5% out of 20ms refresh) and another one goes to about 10% (2ms out of the 20ms refresh required). This has the disadvantage of eating up one PWM channel. The distance between these two value will give you the resolution (how many intermediate positions the servo can reach). Careful, PWM channels can't count over 0xFFFF.
-
if i'm working on something that only needs a few servos i usually just use a 16bit timer (like Timer1 on an ATmega8) and set it up to have OC1A and OC1B change state on OCR1A and OCR1B match.
this way you only need to put your servo position in OCR1A and OCR1B.
no messy ISRs or polling.
rather than work out the timer configuration again for my self every time i need it i have this excellent page bookmarked:
http://members.shaw.ca/climber/avrtimers.html/servo (http://members.shaw.ca/climber/avrtimers.html/servo)
scroll down to the "Servo control with timer1" section.
you can only control up to 2 servos per 16bit timer this way though so not suitable for every application.
dunk.
-
interesting site Dunk, your link doesn't work though, I found what youwere talking about here:
http://members.shaw.ca/climber/avrtimers.html