Mercurial > pkubik
changeset 1:db1f05f1a2e4
servo controller
| author | Radomir Dopieralski <sheep-devel@sheep.art.pl> |
|---|---|
| date | Wed, 19 Nov 2014 21:39:25 +0100 |
| parents | 57ed31973588 |
| children | ca16b2fe3eb3 |
| files | controller/controller.ino controller/misc.h controller/serial.h controller/serial.ino controller/servos.h controller/servos.ino |
| diffstat | 6 files changed, 149 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/controller/controller.ino Wed Nov 19 21:39:25 2014 +0100 @@ -0,0 +1,13 @@ +#include "servos.h" +#include "serial.h" + + +void setup() { + serial_setup(); + servo_setup(); +} + + +void loop() { + do_serial_command(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/controller/misc.h Wed Nov 19 21:39:25 2014 +0100 @@ -0,0 +1,8 @@ +#ifndef MISC_H +#define MISC_H + +const double PI2 = PI / 2; +const double PI4 = PI / 4; +const double TAU = PI * 2; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/controller/serial.h Wed Nov 19 21:39:25 2014 +0100 @@ -0,0 +1,7 @@ +#ifndef SERIAL_H +#define SERIAL_H + +void serial_setup(void); +void do_serial_command(void); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/controller/serial.ino Wed Nov 19 21:39:25 2014 +0100 @@ -0,0 +1,43 @@ +void serial_setup() { + Serial.begin(115200); +} + + +int16_t _serial_read_word() { + /* Read two bytes from the serial port and make an int from them. */ + int16_t high = Serial.read(); + int16_t low = Serial.read(); + int16_t value = high << 8 | low; + return value; +} + + +void _serial_write_word(int16_t value) { + /* Take an int and send it through the serial port as two bytes. */ + int16_t high = (value & 0xff00) >> 8; + int16_t low = value & 0xff; + Serial.write(high); + Serial.write(low); +} + + +void do_serial_command() { + static unsigned char serial_command = 0; + /* Read and execute a command from the serial port's buffer. */ + switch (serial_command) { + case 0x00: + /* No command, read one. */ + if (Serial.available() < 1) { return; } + serial_command = Serial.read(); + return; + case 0xff: + /* Move all servos by 1/1000 of radians. */ + if (Serial.available() < SERVOS * 2) { return; } + for (unsigned char servo = 0; servo < SERVOS; ++servo) { + double pos = _serial_read_word(); + servo_move(servo, pos / 1000.0); + } + break; + } + serial_command = 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/controller/servos.h Wed Nov 19 21:39:25 2014 +0100 @@ -0,0 +1,11 @@ +#ifndef SERVOS_H +#define SERVOS_H + +// Number of servos. +#define SERVOS 12 + +void servo_move(unsigned char servo, double rads); +void servo_setup(void); +void servo_shutdown(void); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/controller/servos.ino Wed Nov 19 21:39:25 2014 +0100 @@ -0,0 +1,67 @@ +#include "misc.h" +#include "servos.h" +#include <Servo.h> + +// Range of the servos. +#define SERVO_FREQ_MIN 600 +#define SERVO_FREQ_MAX 2400 + +static const unsigned char SERVO_PINS[SERVOS] = { +// ankle, knee, hip + 2, 3, 5, // front left + 9, 8, 6, // hind left + 10, 11, 13, // hind right + 17, 16, 14 // front right +}; +static const char SERVO_REVERSE[SERVOS] = { +// ankle, knee, hip + 1, 1, 1, // front left + 1, 1, 1, // hind left + 1, 1, 1, // hind right + 1, 1, 1 // front right +}; +static const char SERVO_TRIM[SERVOS] = { +// ankle, knee, hip + 0, 0, 0, // front left + 0, 0, 0, // hind left + 0, 0, 0, // hind right + 0, 0, 0 // front right +}; +static Servo servos[SERVOS]; + + +void servo_move(unsigned char servo, double rads) { + // Move a servo to a position in radians between -PI/2 and PI/2. + if (servo >= SERVOS) { + return; + } + rads = rads * SERVO_REVERSE[servo] + PI2; + while (rads > TAU) { + rads -= TAU; + } + while (rads < 0) { + rads += TAU; + } + int freq = (SERVO_FREQ_MAX - + SERVO_FREQ_MIN) * rads / PI + SERVO_FREQ_MIN; + freq = min(SERVO_FREQ_MAX, + max(SERVO_FREQ_MIN, + freq + SERVO_TRIM[servo] * 10)); + servos[servo].writeMicroseconds(freq); +} + +void servo_setup() { + // Initialize all servos. + for (unsigned char servo = 0; servo < SERVOS; ++servo) { + servos[servo].attach(SERVO_PINS[servo], + SERVO_FREQ_MIN, SERVO_FREQ_MAX); + delay(150); + } +} + +void servo_shutdown() { + // Power down all servos. + for (unsigned char servo = 0; servo < SERVOS; ++servo) { + servos[servo].detach(); + } +}
