Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
shimniok
Date:
Mon Apr 04 20:35:19 2011 +0000
Commit message:
Initial release

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Apr 04 20:35:19 2011 +0000
@@ -0,0 +1,220 @@
+#include "mbed.h"
+
+/** CHR-6dm test program 
+ * http://www.chrobotics.com/index.php?main_page=product_info&cPath=1&products_id=2
+ * The CH Robotics 6dm is an AHRS that transmits data over serial port
+ *
+ * Michael Shimniok - http://bot-thoughts.com/
+ *
+ * For now all this code does is parses broadcast output and prints out yaw data
+ * Some of the framework is in place to print more.  I'll be workign on a
+ * library for the device in the near future.
+ */
+
+#define sbi(byte, bit)      ((byte) |= _BV(bit))
+#define cbi(byte, bit)      ((byte) &= ~_BV(bit))
+#define _BV(bit)            (0x01<<(bit))    
+
+Serial pc(USBTX, USBRX);
+Serial ahrs(p26, p25);
+
+typedef unsigned char uint8;
+typedef unsigned int uint;
+
+/** Rx packet types (commands) */
+
+/** Tx packet types (responses) */
+#define PT_COMMAND_COMPLETE             0xB0
+#define PT_COMMAND_FAILED               0xB1
+#define PT_BAD_CHECKSUM                 0xB2
+#define PT_BAD_DATA_LENGTH              0xB3
+#define PT_UNRECOGNIZED_PACKET          0xB4  
+#define PT_BUFFER_OVERFLOW              0xB5
+#define PT_STATUS_REPORT                0xB6
+#define PT_SENSOR_DATA                  0xB7
+#define PT_GYRO_BIAS_REPORT             0xB8
+#define PT_GYRO_SCALE_REPORT            0xB9
+#define PT_START_CAL_REPORT             0xBA
+#define PT_ACCEL_BIAS_REPORT            0xBB
+#define PT_ACCEL_REF_VECTOR_REPORT      0xBC
+#define PT_ACTIVE_CHANNEL_REPORT        0xBD
+#define PT_ACCEL_COVARIANCE_REPORT      0xBE
+#define PT_MAG_COVARIANCE_REPORT        0xBF
+#define PT_PROCESS_COVARIANCE_REPORT    0xC0
+#define PT_STATE_COVARIANCE_REPORT      0xC1
+#define PT_EKF_CONFIG_REPORT            0xC2
+#define PT_GYRO_ALIGNMENT_REPORT        0xC3
+#define PT_ACCEL_ALIGNMENT_REPORT       0xC4
+#define PT_MAG_REF_VECTOR_REPORT        0xC5
+#define PT_MAG_CAL_REPORT               0xC6
+#define PT_MAG_BIAS_REPORT              0xC7
+#define PT_BROADCAST_MODE_REPORT        0xC8
+
+
+/* flags for SENSOR_DATA, ACTIVE_CHANNEL_REPORT */
+/* D1 */
+#define YAW_FLAG                0x80
+#define PITCH_FLAG              0x40
+#define ROLL_FLAG               0x20
+#define YAW_RATE_FLAG           0x10
+#define PITCH_RATE_FLAG         0x08
+#define ROLL_RATE_FLAG          0x04
+#define MX_FLAG                 0x02
+#define MY_FLAG                 0x01
+/* D2 */
+#define MZ_FLAG                 0x80
+#define GX_FLAG                 0x40
+#define GY_FLAG                 0x20
+#define GZ_FLAG                 0x10
+#define AX_FLAG                 0x08
+#define AY_FLAG                 0x04
+#define AZ_FLAG                 0x02
+#define ZERO_FLAG               0x01
+
+
+#define MAX_BYTES 32
+
+enum _states { WAIT_S, WAIT_N, WAIT_P, RX_TYPE, RX_N, RX_PACKET, PROCESS_PACKET };
+
+int _state = WAIT_S;
+char c;
+int d;
+uint8 pt;
+uint n;
+char data[MAX_BYTES];
+int yaw;
+
+int chksum(uint8 pt, uint8 n, char data[])
+{
+    int sum = pt + n;
+    
+    for (int i=0; i < n; i++) {
+        sum += data[i];
+    }
+    
+    return sum;
+}
+    
+void send_packet(uint8 pt, uint8 n, char data[])
+{
+    char s[MAX_BYTES];
+    
+    ahrs.printf(s, "snp");
+    ahrs.putc(pt);
+    ahrs.putc(n);
+    
+    /** Checksum
+     * Datasheet:
+     * After the CHR6-dm receives a full  acket, it checks to ensure that the checksum
+     * given in the last two bytes matches the sum of all preceding bytes in the packet. 
+     */
+    int chksum = 's'+'n'+'p'+pt+n;
+    for (int i=0; i < n; i++) {
+        ahrs.putc(data[i]);
+        chksum += data[i];
+    }
+    ahrs.putc((char) (chksum >> 8));   // MSByte
+    ahrs.putc((char) (chksum & 0x0F)); // LSByte
+}
+
+
+void process_packet(void) {
+    switch (pt) {
+        /** SENSOR_DATA 
+         * Datasheet:
+         * If all channels are active, then data is given in the following order: { yaw, pitch, roll, yaw_rate, 
+         * pitch_rate, roll_rate, mag_z, mag_y, mag_x, gyro_z, gyro_y, gyro_x, accel_z, accel_y, accel_x }.  
+         * Data bytes D3 and D4 correspond to the yaw angle, D5 and D6 to the pitch angle, etc.  Data is 
+         * returned as 16-bit two's complement integers. 
+         *
+         * When one or more channel is inactive, then the data is returned in the same order, but skipping the 
+         * inactive channels.  For example, if all magnetic field and rate gyro channels are disabled, then the 
+         * data is given in the following order: { yaw, pitch, roll, accel_z, accel_y, accel_x } 
+         */
+        case PT_SENSOR_DATA :
+            pc.printf("SENSOR_DATA\n");
+            if ((data[0] & YAW_FLAG) == YAW_FLAG) {
+                yaw = data[2] << 8 | data[3];       
+                pc.printf("Yaw: %d\n", yaw);
+            }
+            break;
+        case PT_COMMAND_COMPLETE :
+            pc.printf("Command Complete\n");
+            break;
+        case PT_COMMAND_FAILED :
+            pc.printf("Command Failed\n");
+            break;
+        case PT_BAD_CHECKSUM :
+            pc.printf("Bad Checksum\n");
+            break;
+        case PT_BAD_DATA_LENGTH :
+            pc.printf("Bad Data Length\n");
+            break;
+        case PT_UNRECOGNIZED_PACKET :
+            pc.printf("Unrecognized Packet\n");
+            break;
+        case PT_BUFFER_OVERFLOW :
+            pc.printf("Buffer Overflow\n");
+            break;            
+        default :
+            break;
+    }
+}
+
+
+int main() {
+
+    pc.baud(115200);
+    ahrs.baud(115200);
+
+    pc.printf("Hello!\nCHR-6dm Test Program\nMichael Shimniok - http://bot-thoughts.com/");
+
+    while (1) { 
+        if (ahrs.readable()) {
+
+            c = ahrs.getc();
+            switch (_state) {
+                case WAIT_S :
+                    ///pc.printf("WAIT_S\n");
+                    if (c == 's') _state = WAIT_N;
+                    break;
+                case WAIT_N :
+                    //pc.printf("WAIT_N\n");
+                    _state = (c == 'n') ? WAIT_P : WAIT_S;
+                    break;
+                case WAIT_P :
+                    //pc.printf("WAIT_P\n");
+                    _state = (c == 'p') ? RX_TYPE : WAIT_S;
+                    break;
+                case RX_TYPE :
+                    pt = c;
+                    _state = RX_N;
+                    pc.printf("PT = %02x\n", pt);
+                    break;
+                case RX_N :
+                    n = ((uint8) c) - 2;
+                    d = 0;
+                    _state = (n < MAX_BYTES) ? RX_PACKET : WAIT_S;
+                    pc.printf("N = %d\n", n);
+                    break;
+                case RX_PACKET :
+                    //pc.printf("data[%d] = %02x\n", d, c);
+                    data[d++] = c;
+                    if (d >= n || d >= MAX_BYTES) _state = PROCESS_PACKET;
+                    break;
+                case PROCESS_PACKET :
+                    pc.printf("PROCESS_PACKET\n");
+                    process_packet();
+                    _state = WAIT_S;
+                    break;
+                default :
+                    _state = WAIT_S;
+                    break;
+            }
+
+            //pc.printf("%02x\n", c);
+
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Apr 04 20:35:19 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912