View previous topic :: View next topic |
Author |
Message |
johnh
Joined: 03 Jan 2004 Posts: 19 Location: UK - Brighton
|
Servo controller |
Posted: Sun Jan 04, 2004 6:12 pm |
|
|
Hello all,
I want to control 3 groups of servo motors, essentially i can just assume as far as the PIC is concerned it is just 3 servo motors..
I am completely new to this and two days ago i didn't have a clue (some of you may still think that after reading what i have written below!! )
I have had some good help from Adrian (hillcraft), thanks for that, i think i am understanding things a bit better, but i still need some pointers.
What i need to do is look for a byte of data coming from a PC between 0 and FF
if the byte is between 0x00 and 0x0F then deactivate all motors
if the byte is between 0x10 and 0x5F then servo group 1 activated and the motor needs to be moved to a position according to the hex value
with - 0x10 = full right ~ 1ms pulse
.
.
- 0x36 = centered ~ 1.5ms pulse
.
.
and - 0x5F = full left ~2ms pulse
if a value outside of this range was received then the motor would continue to hold the last commanded position unless the value received was 0x00 (deactivate all servos)
a repeat of this for motor group 2 between 0x60 - 0xAF
and a repeat for motor group 3 between 0xB0 and 0xFF
Questions now!
1. is this do-able?
2. how do i test the incoming byte to see which servo group i want to control? If the byte is for group 1 then could i use the 'test' result to go to a function that then did the position decoding?
3. Servo motors need a position pulse every 20ms, hence can i just call a function relating to servo group 1 every 20ms and update position data, then call servo group 2, update that position then servo group 3..etc
Cheers
John _________________ There are 10 kinds of people who understand binary, those who do and those who don't |
|
![](templates/subSilver/images/spacer.gif) |
Doug Guest
|
|
Posted: Tue Jan 06, 2004 10:19 am |
|
|
Quote: | 1. is this do-able? |
Of course it is.
Quote: | 2. how do i test the incoming byte to see which servo group i want to control? If the byte is for group 1 then could i use the 'test' result to go to a function that then did the position decoding?
|
This can be accomplished by just a couple IF statements and then calls to functions that do something with the data.
Code: | if (some_byte <= 0x0F)
deactivate_motors(some_byte);
if (some_byte <= 0x10 && some_byte >= 0x5F)
move_group_1(some_byte);
if (some_byte <= 0x60 && some_byte >= 0xAF)
move_group_2(some_byte);
etc......
|
Quote: | 3. Servo motors need a position pulse every 20ms, hence can i just call a function relating to servo group 1 every 20ms and update position data, then call servo group 2, update that position then servo group 3..etc |
You could do something like:
Code: | move_group_1(int data_byte) {
int x;
x=12;
// you know the byte will be between 0x10 and 0x5F
data_byte = data_byte - 0x10;
// data_byte will now be between 0 and 4F
output_high(PIN_CONNECTED_TO_GROUP_1);
delay_ms(1); // the minimum on time for servo
// this loop will delay for a number of microseconds in data_byte 12 times
// which will give a delay between approx. 0 to 1 ms
do {
delay_us(data_byte);
} while(--x);
// now the output pulse will be on for 1 - 2 ms
output_low(PIN_CONNECTED_TO_GROUP_1);
} |
Make a routine for each group and call them repeatedly. Don't forget to store the value for each group separetly. Put a delay of 6 ms (20/3) between each call, that will give you 18ms between each pulse.
Hope this helped. |
|
![](templates/subSilver/images/spacer.gif) |
johnh
Joined: 03 Jan 2004 Posts: 19 Location: UK - Brighton
|
|
Posted: Tue Jan 06, 2004 10:36 am |
|
|
Cheers Doug,
I will have a look at that... Seems easy when someone explains how to do it. I wouldn't have known where to start!!
One question. Where does the value 12 in the last bit of code come from? and what does it do?
Thanks again
John _________________ There are 10 kinds of people who understand binary, those who do and those who don't |
|
![](templates/subSilver/images/spacer.gif) |
johnh
Joined: 03 Jan 2004 Posts: 19 Location: UK - Brighton
|
Ahh! |
Posted: Tue Jan 06, 2004 10:41 am |
|
|
Just figured it out! It is 0x4F times 12 gives 960. So the value in data_byte multiplied by 12 gives the on time for the servo (plus the 1ms delay)
Ta.. _________________ There are 10 kinds of people who understand binary, those who do and those who don't |
|
![](templates/subSilver/images/spacer.gif) |
Doug Guest
|
|
Posted: Tue Jan 06, 2004 10:58 am |
|
|
Oops! Made a mistake in IF statments above.
Should read:
Code: |
if (some_byte >= 0x10 && some_byte <= 0x5F)
move_group_1(some_byte);
|
Had the < and > the wrong way! Meaning if some_byte is greater than or equal to 0x10 and less than or equal to 0x5F.
Sorry! |
|
![](templates/subSilver/images/spacer.gif) |
|