changeset 76:a16884812b83

Huge refactoring of the arduino code.
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Sun, 14 Sep 2014 13:12:28 +0200
parents d89650206f92
children c104b318ec34
files servo/accel.ino servo/battery.ino servo/beep.ino servo/legs.ino servo/servo.ino servo/servos.ino
diffstat 6 files changed, 224 insertions(+), 232 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servo/accel.ino	Sun Sep 14 13:12:28 2014 +0200
@@ -0,0 +1,53 @@
+// 3.3V maximum for the acceleration sensor.
+#define ACCEL_MAX 676
+
+// How many acceleration measurements to cache.
+#define MAX_ACCEL_BUFFER 16
+
+
+int accel_buffer[MAX_ACCEL_BUFFER][3];
+
+
+void read_accel() {
+    static unsigned char accel_buffer_index = 0;
+    accel_buffer[accel_buffer_index][0] = analogRead(A2);
+    accel_buffer[accel_buffer_index][1] = analogRead(A1);
+    accel_buffer[accel_buffer_index][2] = analogRead(A0);
+    accel_buffer_index += 1;
+    if (accel_buffer_index >= MAX_ACCEL_BUFFER) {
+        accel_buffer_index = 0;
+    }
+}
+
+void do_accel() {
+    /* Report the readings of the acceleration sensor. */
+    int avg_x = 0;
+    int avg_y = 0;
+    int avg_z = 0;
+    int min_x = 676;
+    int min_y = 676;
+    int min_z = 676;
+    int max_x = 0;
+    int max_y = 0;
+    int max_z = 0;
+    for (unsigned char i = 0; i < MAX_ACCEL_BUFFER; i += 1) {
+        for (unsigned char axe = 0; axe < 3; ++axe) {
+            avg_x += accel_buffer[i][axe];
+            min_x = min(min_x, accel_buffer[i][axe]);
+            max_x = max(max_x, accel_buffer[i][axe]);
+        }
+    }
+    avg_x /= MAX_ACCEL_BUFFER;
+    avg_y /= MAX_ACCEL_BUFFER;
+    avg_z /= MAX_ACCEL_BUFFER;
+    Serial.write(0xff);
+    Serial.write(map(avg_x, 0, 676, 0, 255));
+    Serial.write(map(avg_y, 0, 676, 0, 255));
+    Serial.write(map(avg_z, 0, 676, 0, 255));
+    Serial.write(map(min_x, 0, 676, 0, 255));
+    Serial.write(map(min_y, 0, 676, 0, 255));
+    Serial.write(map(min_z, 0, 676, 0, 255));
+    Serial.write(map(max_x, 0, 676, 0, 255));
+    Serial.write(map(max_y, 0, 676, 0, 255));
+    Serial.write(map(max_z, 0, 676, 0, 255));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servo/battery.ino	Sun Sep 14 13:12:28 2014 +0200
@@ -0,0 +1,24 @@
+
+void check_battery() {
+    static int battery_fail = 0;
+    int reading = analogRead(A7);
+    if (reading < 762) {
+        /* At about 3.74V start worrying. */
+        battery_fail += 1;
+    } else {
+        battery_fail = max(0, battery_fail - 1);
+    }
+    if (battery_fail > 10) {
+        /* If it doesn't improve for a second, beep. */
+        tone(A3, 880, 100);
+    }
+    if (battery_fail > 40) {
+        /* If it stays bad for 4s, shut down. */
+        fold();
+    }
+}
+
+void do_battery() {
+    Serial.write(0xff);
+    Serial.write(map(analogRead(A7), 0, 1023, 0, 255));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servo/beep.ino	Sun Sep 14 13:12:28 2014 +0200
@@ -0,0 +1,17 @@
+
+void beep_setup() {
+    pinMode(A3, OUTPUT);
+    delay(50);
+    tone(A3, 440, 200);
+    delay(200);
+    tone(A3, 523, 100);
+    delay(150);
+    tone(A3, 880, 100);
+}
+
+void do_beep() {
+    /* Emit a beep of specified frequency and duration. */
+    int frequency = _serial_read_word();
+    int duration = Serial.read();
+    tone(A3, frequency, duration * 10);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servo/legs.ino	Sun Sep 14 13:12:28 2014 +0200
@@ -0,0 +1,27 @@
+// Leg dimensions.
+#define LEG_COXA 22.5
+#define LEG_FEMUR 38.0
+#define LEG_TIBIA 30.0
+#define LEG_BASE 15.0
+
+const unsigned char LEG_HIP[4] = {11, 8, 9, 10};
+const unsigned char LEG_KNEE[4] = {4, 7, 6, 5};
+const unsigned char LEG_ANKLE[4] = {0, 3, 2, 1};
+const char LEG_X[4] = {-1, -1, 1, 1};
+const char LEG_Y[4] = {-1, 1, 1, -1};
+
+
+void fold() {
+    /* Folds the robots and shut downs all servos. Doesn't return. */
+    for (int leg = 0; leg < 4; leg += 1) {
+        int d = LEG_X[leg] * LEG_X[leg];
+        servo_degrees(LEG_HIP[leg], 90 + 45 * d);
+        servo_degrees(LEG_KNEE[leg], 90 - 90 * d);
+        servo_degrees(LEG_ANKLE[leg], 90 + 90 * d);
+    }
+    delay(250);
+    servo_shutdown();
+    while (1) {
+        delay(1000);
+    }
+}
--- a/servo/servo.ino	Thu Sep 11 18:17:21 2014 +0200
+++ b/servo/servo.ino	Sun Sep 14 13:12:28 2014 +0200
@@ -1,192 +1,17 @@
-/*
-A very simple servo controller code.
-*/
-
-#include <Servo.h>
-
 // Time of a signle frame, in milliseconds.
 #define FRAME_TIME 10
 
-// Number of servos in legs.
-#define MAX_SERVO 12
-
-// Range of the servos.
-#define SERVO_FREQ_MIN 600
-#define SERVO_FREQ_MAX 2400
-#define SERVO_PIN_MIN 2
-
-// 3.3V maximum for the acceleration sensor.
-#define ACCEL_MAX 676
-
-// How many acceleration measurements to cache.
-#define MAX_ACCEL_BUFFER 16
-
 // Speed of the serial port.
 #define SERIAL_SPEED 115200
 // 115200
 // 38400
 // 9600
 
-// Leg dimensions.
-#define LEG_COXA 22.5
-#define LEG_FEMUR 38.0
-#define LEG_TIBIA 30.0
-#define LEG_BASE 15.0
-
-
-int joints[12][2] {
-//  reverse, trim
-    // ankles
-    {1, -50},  // front right
-    {-1, 0}, // front left
-    {1, -50},   // hind left
-    {-1, -50},  // hind right
-
-    // knees
-    {1, -70},
-    {-1, 50},
-    {1, 30},
-    {-1, 50},
-
-    // hips
-    {-1, 0},
-    {1, 0},
-    {1, 0},
-    {-1, 0},
-};
-int legs[4][5] = {
-//  hip, knee, ankle, x_direction, y_direction
-    {11, 4, 0, -1, -1},  // front right
-    {8, 7, 3, -1, 1},  // front left
-    {9, 6, 2, 1, 1},  // hind left
-    {10, 5, 1, 1, -1},  // hind right
-};
-Servo servos[MAX_SERVO];
-int serial_command = 0;
-int accel_buffer[MAX_ACCEL_BUFFER][3];
-int accel_buffer_index = 0;
-int battery_fail = 0;
-unsigned long last_tick = 0;
-
-
-void read_accel() {
-    accel_buffer[accel_buffer_index][0] = analogRead(A2);
-    accel_buffer[accel_buffer_index][1] = analogRead(A1);
-    accel_buffer[accel_buffer_index][2] = analogRead(A0);
-    accel_buffer_index += 1;
-    if (accel_buffer_index >= MAX_ACCEL_BUFFER) {
-        accel_buffer_index = 0;
-    }
-}
-
-
-int _serial_read_word() {
-    /* Read two bytes from the serial port and make an int from them. */
-    int low;
-    int high;
-    low = Serial.read();
-    high = Serial.read();
-    return low | (high << 8);
-}
-
-void servo_write(int servo, int us) {
-    int pos = min(max(us + joints[servo][1], SERVO_FREQ_MIN), SERVO_FREQ_MAX);
-    if (joints[servo][0] < 0) {
-        pos = SERVO_FREQ_MAX + SERVO_FREQ_MIN - pos;
-    }
-    servos[servo].writeMicroseconds(pos);
-}
-
-
-void do_servo_degrees() {
-    /* Move a single servo by degrees. */
-    int servo = Serial.read();
-    int pos = Serial.read();
-    if (servo >= 0 && servo < MAX_SERVO && pos >= 0 && pos <= 180) {
-        servos[servo].write(pos);
-    }
-}
-
-void do_servos_degrees() {
-    /* Move all servos by degrees. */
-    for (int servo = 0; servo < MAX_SERVO; servo += 1) {
-        int pos = Serial.read();
-        if (pos >= 0 && pos <= 180) {
-            servos[servo].write(pos);
-        }
-    }
-}
-
-void do_servo_microseconds() {
-    /* Move a single servo by microseconds. */
-    int servo = Serial.read();
-    int pos = _serial_read_word();
-    if (servo >= 0 && servo < MAX_SERVO &&
-        pos >= SERVO_FREQ_MIN && pos <= SERVO_FREQ_MAX) {
-        servo_write(servo, pos);
-    }
-}
-
-void do_servos_microseconds() {
-    /* Move all servos by microseconds. */
-    for (int servo = 0; servo < MAX_SERVO; servo += 1) {
-        int pos = _serial_read_word();
-        if (pos >= SERVO_FREQ_MIN && pos <= SERVO_FREQ_MAX) {
-            servo_write(servo, pos);
-        }
-    }
-}
-
-void do_accel() {
-    /* Report the readings of the acceleration sensor. */
-    int avg_x = 0;
-    int avg_y = 0;
-    int avg_z = 0;
-    int min_x = 676;
-    int min_y = 676;
-    int min_z = 676;
-    int max_x = 0;
-    int max_y = 0;
-    int max_z = 0;
-    for (int i = 0; i < MAX_ACCEL_BUFFER; i += 1) {
-        avg_x += accel_buffer[i][0];
-        avg_y += accel_buffer[i][1];
-        avg_z += accel_buffer[i][2];
-        min_x = min(min_x, accel_buffer[i][0]);
-        min_y = min(min_y, accel_buffer[i][1]);
-        min_z = min(min_z, accel_buffer[i][2]);
-        max_x = max(max_x, accel_buffer[i][0]);
-        max_y = max(max_y, accel_buffer[i][1]);
-        max_z = max(max_z, accel_buffer[i][2]);
-    }
-    avg_x /= MAX_ACCEL_BUFFER;
-    avg_y /= MAX_ACCEL_BUFFER;
-    avg_z /= MAX_ACCEL_BUFFER;
-    Serial.write(0xff);
-    Serial.write(map(avg_x, 0, 676, 0, 255));
-    Serial.write(map(avg_y, 0, 676, 0, 255));
-    Serial.write(map(avg_z, 0, 676, 0, 255));
-    Serial.write(map(min_x, 0, 676, 0, 255));
-    Serial.write(map(min_y, 0, 676, 0, 255));
-    Serial.write(map(min_z, 0, 676, 0, 255));
-    Serial.write(map(max_x, 0, 676, 0, 255));
-    Serial.write(map(max_y, 0, 676, 0, 255));
-    Serial.write(map(max_z, 0, 676, 0, 255));
-}
-
-void do_beep() {
-    /* Emit a beep of specified frequency and duration. */
-    int frequency = _serial_read_word();
-    int duration = Serial.read();
-    tone(A3, frequency, duration * 10);
-}
-
-void do_battery() {
-    Serial.write(0xff);
-    Serial.write(map(analogRead(A7), 0, 1023, 0, 255));
-}
+// Total number of servos.
+#define MAX_SERVO 12
 
 void do_serial_command() {
+    static int serial_command = 0;
     /* Read and execute a command from the serial port's buffer. */
     switch (serial_command) {
         case 0x00:
@@ -232,65 +57,14 @@
     serial_command = 0;
 }
 
-void unfold() {
-    for (int servo = MAX_SERVO - 1; servo >= 0; servo -= 1) {
-        /* First 2 pins are used for the serial. */
-        servos[servo].attach(servo + SERVO_PIN_MIN,
-                             SERVO_FREQ_MIN, SERVO_FREQ_MAX);
-        servo_write(servo, 1500);
-        /* Don't set all servos at once, save power. */
-        delay(150);
-    }
-    delay(50);
-    tone(A3, 440, 200);
-    delay(200);
-    tone(A3, 523, 100);
-    delay(150);
-    tone(A3, 880, 100);
-}
-
-void fold() {
-    /* Folds the robots and shut downs all servos. Doesn't return. */
-    for (int leg = 0; leg < 4; leg += 1) {
-        int d = legs[leg][3] * legs[leg][4];
-        servos[legs[leg][0]].write(90 + 45 * d);
-        servos[legs[leg][1]].write(90 - 90 * d);
-        servos[legs[leg][2]].write(90 + 90 * d);
-    }
-    delay(250);
-    for (int servo = 0; servo < MAX_SERVO; servo += 1) {
-        servos[servo].detach();
-    }
-    while (1) {
-        delay(1000);
-    }
-}
-
-void check_battery() {
-    int reading = analogRead(A7);
-    if (reading < 762) {
-        /* At about 3.74V start worrying. */
-        battery_fail += 1;
-    } else {
-        battery_fail = max(0, battery_fail - 1);
-    }
-    if (battery_fail > 10) {
-        /* If it doesn't improve for a second, beep. */
-        tone(A3, 880, 100);
-    }
-    if (battery_fail > 40) {
-        /* If it stays bad for 4s, shut down. */
-        fold();
-    }
-}
-
 void setup() {
     Serial.begin(SERIAL_SPEED);
-    pinMode(A3, OUTPUT);
-    unfold();
+    servo_setup();
+    beep_setup();
 }
 
 void loop() {
+    static unsigned long last_tick = 0;
     unsigned long now = millis();
 
     do_serial_command();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/servo/servos.ino	Sun Sep 14 13:12:28 2014 +0200
@@ -0,0 +1,97 @@
+#include <Servo.h>
+
+
+// Range of the servos.
+#define SERVO_FREQ_MIN 600
+#define SERVO_FREQ_MAX 2400
+
+const unsigned char SERVO_PIN[MAX_SERVO] = {
+    2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
+};
+const char SERVO_REVERSE[MAX_SERVO] = {
+    1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1
+};
+const char SERVO_TRIM[MAX_SERVO] = {
+    -50, 0, -50, -50, -70, 50, 30, 50, 0, 0, 0, 0
+};
+const double US_PER_DEG = double(SERVO_FREQ_MAX - SERVO_FREQ_MIN) / 180;
+
+Servo servos[MAX_SERVO];
+
+
+void servo_write(unsigned char servo, unsigned int us) {
+    int pos = min(max(us + SERVO_TRIM[servo], SERVO_FREQ_MIN), SERVO_FREQ_MAX);
+    if (SERVO_REVERSE[servo] < 0) {
+        pos = SERVO_FREQ_MAX + SERVO_FREQ_MIN - pos;
+    }
+    servos[servo].writeMicroseconds(pos);
+}
+
+void servo_degrees(unsigned char servo, double angle) {
+    servo_write(servo, SERVO_FREQ_MIN + angle * US_PER_DEG);
+}
+
+void servo_setup() {
+    for (int servo = MAX_SERVO - 1; servo >= 0; servo -= 1) {
+        /* First 2 pins are used for the serial. */
+        servos[servo].attach(SERVO_PIN[servo], SERVO_FREQ_MIN, SERVO_FREQ_MAX);
+        servo_write(servo, 1500);
+        /* Don't set all servos at once, save power. */
+        delay(150);
+    }
+}
+
+void servo_shutdown() {
+    for (int servo = 0; servo < MAX_SERVO; servo += 1) {
+        servos[servo].detach();
+    }
+}
+
+int _serial_read_word() {
+    /* Read two bytes from the serial port and make an int from them. */
+    int low;
+    int high;
+    low = Serial.read();
+    high = Serial.read();
+    return low | (high << 8);
+}
+
+
+void do_servo_degrees() {
+    /* Move a single servo by degrees. */
+    int servo = Serial.read();
+    int pos = Serial.read();
+    if (servo >= 0 && servo < MAX_SERVO && pos >= 0 && pos <= 180) {
+        servos[servo].write(pos);
+    }
+}
+
+void do_servos_degrees() {
+    /* Move all servos by degrees. */
+    for (int servo = 0; servo < MAX_SERVO; servo += 1) {
+        int pos = Serial.read();
+        if (pos >= 0 && pos <= 180) {
+            servos[servo].write(pos);
+        }
+    }
+}
+
+void do_servo_microseconds() {
+    /* Move a single servo by microseconds. */
+    int servo = Serial.read();
+    int pos = _serial_read_word();
+    if (servo >= 0 && servo < MAX_SERVO &&
+        pos >= SERVO_FREQ_MIN && pos <= SERVO_FREQ_MAX) {
+        servo_write(servo, pos);
+    }
+}
+
+void do_servos_microseconds() {
+    /* Move all servos by microseconds. */
+    for (int servo = 0; servo < MAX_SERVO; servo += 1) {
+        int pos = _serial_read_word();
+        if (pos >= SERVO_FREQ_MIN && pos <= SERVO_FREQ_MAX) {
+            servo_write(servo, pos);
+        }
+    }
+}