Swimate V2 without RTOS code

Dependencies:   Adafruit_GFX_128x64 DS3231 PinDetect SDFileSystem USBDevice mbed RealtimeMath MODSERIAL

Files at this revision

API Documentation at this revision

Comitter:
ellingjp
Date:
Thu May 08 20:01:10 2014 +0000
Child:
1:93723df61425
Child:
2:a28cc676a454
Child:
4:b962f5a783a1
Commit message:
Initial commit. Ready for data gathering.

Changed in this revision

Adafruit_GFX.lib Show annotated file Show diff for this revision Revisions of this file
MPU6050-DMP.lib Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
USBDevice.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h 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/Adafruit_GFX.lib	Thu May 08 20:01:10 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/ellingjp/code/Adafruit_GFX_128x64/#27f1eda5cc57
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MPU6050-DMP.lib	Thu May 08 20:01:10 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/paulbartell/code/MPU6050-DMP/#e61356440739
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.lib	Thu May 08 20:01:10 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/SDFileSystem/#7b35d1709458
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice.lib	Thu May 08 20:01:10 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/USBDevice/#5b7d31d9d3f3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu May 08 20:01:10 2014 +0000
@@ -0,0 +1,218 @@
+#include "main.h"
+#include "mbed.h"
+#include "USBSerial.h"
+#include "Adafruit_SSD1306.h"
+#include "MPU6050_6Axis_MotionApps20.h"
+#include "SDFileSystem.h"
+
+//Virtual serial port over USB
+#ifdef PC_DEBUG
+USBSerial pc;
+#endif
+
+// Display
+#ifdef OLED_DEBUG
+SPI spi0(P0_9, NC, P0_10); // mosi, miso, sclk
+Adafruit_SSD1306 oled(spi0, P0_11, P0_12, P0_13); // MOSI, MISO, SCLK SPI0
+#endif
+
+// MPU
+MPU6050 mpu;
+InterruptIn dataReady(P0_15);
+
+// SD Card
+SDFileSystem sd(P0_21, P0_22, P1_15, P1_19, "sd"); // MOSI, MISO, SCLK, SSEL SPI1
+
+// LED for debug
+DigitalOut led(LED1);
+
+// Logging vars
+FILE *logFile;
+
+// Timer
+Timer totalTime;
+Timer captureTime;
+
+// Switch
+InterruptIn captureSwitch(P0_16);
+
+
+// State
+enum state {IDLE, CAPTURE};
+enum state State;
+
+// MPU control/status vars
+bool dmpReady = false;  // set true if DMP init was successful
+uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
+uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
+uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
+uint16_t fifoCount;     // count of all bytes currently in FIFO
+uint8_t fifoBuffer[64]; // FIFO storage buffer
+
+// orientation/motion vars
+Quaternion q;           // [w, x, y, z]         quaternion container
+VectorInt16 aa;         // [x, y, z]            accel sensor measurements
+VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
+VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
+VectorFloat gravity;    // [x, y, z]            gravity vector
+float euler[3];         // [psi, theta, phi]    Euler angle container
+float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
+
+// Forward declarations
+void die(int flash_rate_s);
+bool log_open();
+void log_acceleration(VectorInt16 data);
+void log_close();
+void mpu_init();
+void get_data();
+
+volatile bool mpuInterrupt = false;
+void dataReadyISR() {
+    mpuInterrupt = true;
+}
+
+void captureSwitchISR() {
+    // used for debouncing
+    static int prev_time = 0;
+
+    if (totalTime.read_ms() - prev_time < 200)
+        return;
+        
+    State = (State == IDLE) ? CAPTURE : IDLE;
+    prev_time = totalTime.read_ms();
+}
+
+int main(void)
+{
+    totalTime.start();
+    
+    State = IDLE;
+    captureSwitch.mode(PullUp);
+    captureSwitch.rise(captureSwitchISR);   
+    
+    OLED_PRINTP("Waiting to capture.     ",0,0);
+    while (true) {
+        if (State == CAPTURE) {
+            PC_PRINTLN("Start capture button pressed!");
+            OLED_CLEAR();
+            OLED_PRINTPR("Starting capture.       ",0,0);
+            
+            // Start receiving data
+            PC_PRINTLN("Opening log file...");
+            if (!log_open()) {
+                OLED_CLEAR();
+                OLED_PRINTP("ERROR: SD (retry)", 0, 50);
+                State = IDLE;
+                continue;
+            }
+            
+            PC_PRINTLN("Initializing MPU...");
+            mpu_init();
+            
+            PC_PRINTLN("Starting capture...");
+            OLED_PRINTPR("Capturing data...       ",0,0);
+            captureTime.start();
+            while (State == CAPTURE)
+                get_data();
+            OLED_PRINTPR("Finished capture.",0,0);
+            
+            log_close();
+            captureTime.stop();
+        }
+    
+        PC_PRINTLN("Idling...");
+    }
+}
+
+/* Halts program and flashes LED at specified rate */
+void die(int flash_rate_s) {
+    while (1) {
+        led = 1;
+        wait(flash_rate_s/2);
+        led = 0;
+        wait(flash_rate_s/2);
+    }
+}
+
+/* Returns false on failure, true otherwise */
+bool log_open() {
+    logFile = fopen(LOG_FILE, "a");
+    if (logFile == NULL) {
+        PC_PRINTLNF("SD card initialization error: Failed to open %s", LOG_FILE);
+        return false;
+    }
+    fprintf(logFile, "---- BEGIN NEW DATASET ----\n");
+    return true;
+}
+
+void log_close() {
+    if (logFile != NULL)
+        fclose(logFile);
+}
+
+void mpu_init() {
+    PC_PRINTLN("Initializing MPU");
+    mpu.initialize();
+    devStatus = mpu.dmpInitialize();
+    
+    if (devStatus == 0) {
+        mpu.setDMPEnabled(true);
+        packetSize = mpu.dmpGetFIFOPacketSize();
+        
+        PC_PRINTLN("DMP Initialized successfully!");
+        dmpReady = true;
+        dataReady.rise(dataReadyISR);
+    } else { // ERROR
+        PC_PRINTLNF("Error initializing MPU (code %d)", devStatus);
+        die(DMP_ERROR_RATE);
+    }
+}
+
+/* Requires the log to be open and mpu to be initialized*/
+void get_data() {
+    //while (true) {
+        //if (!dmpReady) break;   // do nothing if dmp not ready
+        if (!dmpReady) return;
+        
+        while (!mpuInterrupt && fifoCount < packetSize);
+        
+        // Reset interrupt
+        mpuInterrupt = false;
+        mpuIntStatus = mpu.getIntStatus();
+
+        // get current FIFO count
+        fifoCount = mpu.getFIFOCount();
+    
+        // check for overflow (this should never happen unless our code is too inefficient)
+        if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
+            PC_PRINTLNF("**** FIFO OVERFLOW @ %d ms ****", captureTime.read_ms());
+            // reset so we can continue cleanly
+            mpu.resetFIFO();
+            // otherwise, check for DMP data ready interrupt (this should happen frequently)
+        } else if (mpuIntStatus & 0x02) {
+            // Wait for a full packet - should be very short wait
+            while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
+    
+            // read a packet from FIFO
+            mpu.getFIFOBytes(fifoBuffer, packetSize);
+            fifoCount -= packetSize;
+            
+            // Get acceleration data
+            mpu.dmpGetAccel(&aa, fifoBuffer);
+            mpu.dmpGetQuaternion(&q, fifoBuffer);
+            mpu.dmpGetGravity(&gravity, &q);
+            mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
+            mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
+            
+            PC_PRINTF("%d, ", aaWorld.x); PC_PRINTF("%d, ", aaWorld.y); PC_PRINTLNF("%d", aaWorld.z);
+            
+//            OLED_SETCURS(0, 10); OLED_PRINTF("%d, ", aaWorld.x); OLED_PRINTF("%d, ", aaWorld.y); OLED_PRINTLNF("%d", aaWorld.z);
+            
+            log_acceleration(aaWorld);
+        //}
+    }
+}
+
+void log_acceleration(VectorInt16 data) {
+    fprintf(logFile, "%d, %d,%d,%d\n", captureTime.read_ms(), data.x, data.y, data.z);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.h	Thu May 08 20:01:10 2014 +0000
@@ -0,0 +1,59 @@
+#define DMP_ERROR_RATE 1
+#define SD_ERROR_RATE 2
+
+#define LOG_FILE "/sd/data.log"
+
+//#define PC_DEBUG
+#ifdef PC_DEBUG
+    #define PC_PRINT(x) pc.printf("%s", x);
+    #define PC_PRINTF(x,y) pc.printf(x, y);
+    #define PC_PRINTLN(x) pc.printf("%s\r\n", x);
+    #define PC_PRINTLNF(x,y) pc.printf(x,y); pc.printf("\r\n");
+    #define PC_PRINTR(x) pc.printf("%s\r",x);
+    #define PC_PRINTFR(x,y) pc.printf(x,y); pc.printf("\r");
+#else
+    #define PC_PRINT(x)
+    #define PC_PRINTF(x,y)
+    #define PC_PRINTLN(x)
+    #define PC_PRINTLNF(x,y)
+    #define PC_PRINTR(x)
+    #define PC_PRINTFR(x,y)
+#endif
+
+#define OLED_DEBUG
+#ifdef OLED_DEBUG
+    #define OLED_SETCURS(xpos,ypos) oled.setCursor(xpos,ypos);
+    #define OLED_CLEAR() oled.clearDisplay();
+    
+    #define OLED_PRINT(x) oled.printf("%s", x); oled.display();
+    #define OLED_PRINTF(x,y) oled.printf(x, y); oled.display();
+    #define OLED_PRINTLN(x) oled.printf("%s\r\n", x); oled.display();
+    #define OLED_PRINTLNF(x,y) oled.printf(x,y); oled.printf("\r\n"); oled.display();
+    #define OLED_PRINTR(x) oled.printf("%s\r",x); oled.display();
+    #define OLED_PRINTFR(x,y) oled.printf(x,y); oled.printf("\r"); oled.display();
+
+    // Specify position
+    #define OLED_PRINTP(x,xpos,ypos) oled.setCursor(xpos,ypos); oled.printf("%s", x); oled.display();
+    #define OLED_PRINTPF(x,y,xpos,ypos) oled.setCursor(xpos,ypos); oled.printf(x, y); oled.display();
+    #define OLED_PRINTPLN(x,xpos,ypos) oled.setCursor(xpos,ypos); oled.printf("%s\r\n", x); oled.display();
+    #define OLED_PRINTPLNF(x,y,xpos,ypos) oled.setCursor(xpos,ypos); oled.printf(x,y); oled.printf("\r\n"); oled.display();
+    #define OLED_PRINTPR(x,xpos,ypos) oled.setCursor(xpos,ypos); oled.printf("%s\r",x); oled.display();
+    #define OLED_PRINTPFR(x,y,xpos,ypos) oled.setCursor(xpos,ypos); oled.printf(x,y); oled.printf("\r"); oled.display();
+#else
+    #define OLED_SETCURS(xpos,ypos)
+
+    #define OLED_PRINT(x)
+    #define OLED_PRINTF(x,y)
+    #define OLED_PRINTLN(x)
+    #define OLED_PRINTLNF(x,y)
+    #define OLED_PRINTR(x)
+    #define OLED_PRINTFR(x,y)
+    
+    // Specify position
+    #define OLED_PRINTP(x,xpos,ypos)
+    #define OLED_PRINTPF(x,y,xpos,ypos)
+    #define OLED_PRINTPLN(x,xpos,ypos)
+    #define OLED_PRINTPLNF(x,y,xpos,ypos)
+    #define OLED_PRINTPR(x,xpos,ypos)
+    #define OLED_PRINTPFR(x,y,xpos,ypos)
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu May 08 20:01:10 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/8a40adfe8776
\ No newline at end of file