11 years, 3 months ago.

Hexapod problem

Hello everyone, I'm a French student so forgive me for my english ;) I am currently working on a hexapod with servomotor HS-475HB (3 per leg) I wanted to know what is the code in C to move several feet at the same time? Thank you!

2 Answers

11 years, 3 months ago.

Servomotors typically need pulsewidth modulated (PWM) controlsignals to move to a certain position. The mbed lpc1768 has several hardware PWM outputs. All you need to do is set each output to the desired dutycycle (one function call per output) and the servos will start moving to the new position.

See http://mbed.org/cookbook/Servo

Setting the new dutycycle will be almost instantly and takes no significant time compared to the slow motors. You should be able to just set all outputs sequentially at regular intervals. When you need more PWM channels than available on the mbed you could simulate them in software using timers or you could use some relatively cheap external PWM devices (eg Texas Instruments has some with 16 channels) that are controlled by mbed via SPI or I2C.

Accepted Answer
11 years, 3 months ago.

You can also create a 'bus' of mbed IO pins where each pin controls a single servo. (I did something similar like this a long time ago on a 8051 to control 6 servos at once)

// Create the bus
BusOut servobus(p5, p6, p7 etc...);

Next step is to create an array of 100 values to create a pseudo pwm list.

uint16_t servobits[100];

Use a timer or interrupt to emit each value of the array to that bus, the internal delay will be so small (and constant) that all servo's will be set in one go.

You need a function to fill the array with the corresponding number of bits set to 0 or 1, each bit of each array value controls a single servo (with 16 bits you can control 16 servos)

Since the list contains 100 sequential bit values you need to setup a repetition timer (say about 20 ms, not critical), then start by writing all '1' bits to your servobus ( servobus=0xffff; ), wait 1 ms and then put out the 100 values of the array to the bus waiting 0.01 ms in between writing the values. This way you get a nice adjustable pulsewidth from 1 to 2 ms.

Something like this:

// this routine needs to be called regularly
// start all servobits at '1'
servobus=0xffff;
// wait 1 ms
usleep(1000);

// now send the bits from the array
for (n=0; n<100; n++){
    servobus=servobits[n];
    usleep(10);
}

// reset bus
servobus=0x0000;

If you initially fill the array from 0-49 with 0xffff and the 50-99 with 0x0000 all servos will start in neutral position. The more bits you set to 1 the longer the pulse will be for that servo.

I hope this makes some sense :-)

If you want to control more servos just create a larger 'bus' and use uint32_t for the array, the principle will stay the same.