A data logger for the FRDM-K64F taking readings from the FXOS8700CQ accelerometer/magnometer at 200Hz.

Dependencies:   FXOS8700CQ SDFileSystem mbed

Fork of Hello_FXOS8700Q by Jim Carver

Files at this revision

API Documentation at this revision

Comitter:
trm
Date:
Fri May 30 21:02:54 2014 +0000
Parent:
6:02bfeec82bc1
Commit message:
Initial commit of 20 second, 4g logger. Binary to SD card, converted Binary to CSV on SD card.

Changed in this revision

FXOS8700CQ.lib Show annotated file Show diff for this revision Revisions of this file
FXOS8700Q.lib Show diff for this revision Revisions of this file
SDFileSystem.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
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/FXOS8700CQ.lib	Fri May 30 21:02:54 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/trm/code/FXOS8700CQ/#2ce85aa45d7d
--- a/FXOS8700Q.lib	Fri Apr 25 16:47:00 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/JimCarver/code/FXOS8700Q/#c53dda05b8cf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.lib	Fri May 30 21:02:54 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/SDFileSystem/#7b35d1709458
--- a/main.cpp	Fri Apr 25 16:47:00 2014 +0000
+++ b/main.cpp	Fri May 30 21:02:54 2014 +0000
@@ -1,53 +1,209 @@
 #include "mbed.h"
-#include "FXOS8700Q.h"
+#include "FXOS8700CQ.h"
+#include "SDFileSystem.h"
+
+#define DATA_RECORD_TIME_MS 20000
+
+Serial pc(USBTX, USBRX); // for diagnostic output, beware blocking on long text
 
+// Pin names for FRDM-K64F
+SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd");  // MOSI, MISO, SCLK, SSEL, "name"
+FXOS8700CQ fxos(PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // SDA, SCL, (addr << 1)
+
+DigitalOut green(LED_GREEN);
+DigitalOut blue(LED_BLUE);
+DigitalOut red(LED_RED);
+
+Timer t; // Microsecond timer, 32 bit int, maximum count of ~30 minutes
+InterruptIn fxos_int1(PTC6);
+InterruptIn fxos_int2(PTC13);
+InterruptIn start_sw(PTA4); // switch SW3
 
-//FXOS8700Q acc( A4, A5, FXOS8700CQ_SLAVE_ADDR0); // Proper Ports and I2C address for Freescale Multi Axis shield
-//FXOS8700Q mag( A4, A5, FXOS8700CQ_SLAVE_ADDR0); // Proper Ports and I2C address for Freescale Multi Axis shield
-FXOS8700Q_acc acc( PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // Proper Ports and I2C Address for K64F Freedom board
-FXOS8700Q_mag mag( PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // Proper Ports and I2C Address for K64F Freedom board
+bool fxos_int1_triggered = false;
+bool fxos_int2_triggered = false;
+uint32_t us_ellapsed = 0;
+bool start_sw_triggered = false;
+
+uint32_t sample_count = 0;
+
+SRAWDATA accel_data;
+SRAWDATA magn_data;
+
+char sd_buffer[BUFSIZ * 2]; // create an appropriately sized buffer
+
+void trigger_fxos_int1(void)
+{
+    fxos_int1_triggered = true;
+}
+
+void trigger_fxos_int2(void)
+{
+    fxos_int2_triggered = true;
+    us_ellapsed = t.read_us();
+}
 
-Serial pc(USBTX, USBRX);
+void trigger_start_sw(void)
+{
+    start_sw_triggered = true;
+}
+
+void print_reading(void)
+{
+    pc.printf("A X:%5d,Y:%5d,Z:%5d   M X:%5d,Y:%5d,Z:%5d\r\n",
+              accel_data.x, accel_data.y, accel_data.z,
+              magn_data.x, magn_data.y, magn_data.z);
+}
+
+void write_reading(FILE* fp)
+{
+    fprintf(fp, "%d, %d,%d,%d, %d,%d,%d\r\n",
+            us_ellapsed,
+            accel_data.x, accel_data.y, accel_data.z,
+            magn_data.x, magn_data.y, magn_data.z);
+}
 
-MotionSensorDataUnits mag_data;
-MotionSensorDataUnits acc_data;
+void write_csv_header(FILE* fp)
+{
+    fprintf(fp, "timestamp, acc-x, acc-y, acc-z, magn-x, magn-y, magn-z, scale: %d\r\n",
+            fxos.get_accel_scale());
+}
 
-MotionSensorDataCounts mag_raw;
-MotionSensorDataCounts acc_raw;
+/*
+ * Writing binary to the file:
+ * Timestamp: uint32_t written B0 B1 B2 B3
+ * Raw data: int16_t written B0 B1
+ * Packed resulting format, 16 bytes:
+ * TS0 TS1 TS2 TS3 AX0 AX1 AY0 AY1 AZ0 AZ1 MX0 MX1 MY0 MY1 MZ0 MZ1
+ */
+void write_binary(FILE* fp)
+{
+    uint8_t out_buffer[16] = {
+        (uint8_t)(us_ellapsed), (uint8_t)(us_ellapsed >> 8),
+        (uint8_t)(us_ellapsed >> 16), (uint8_t)(us_ellapsed >> 24),
 
+        (uint8_t)(accel_data.x), (uint8_t)(accel_data.x >> 8),
+        (uint8_t)(accel_data.y), (uint8_t)(accel_data.y >> 8),
+        (uint8_t)(accel_data.z), (uint8_t)(accel_data.z >> 8),
+
+        (uint8_t)(magn_data.x), (uint8_t)(magn_data.x >> 8),
+        (uint8_t)(magn_data.y), (uint8_t)(magn_data.y >> 8),
+        (uint8_t)(magn_data.z), (uint8_t)(magn_data.z >> 8)
+    };
+
+    fwrite( (const uint8_t*) out_buffer, sizeof(uint8_t), 16, fp);
+}
 
-int main() {
-float faX, faY, faZ;
-float fmX, fmY, fmZ;
-int16_t raX, raY, raZ;
-int16_t rmX, rmY, rmZ;
-acc.enable();
-printf("\r\n\nFXOS8700Q Who Am I= %X\r\n", acc.whoAmI());
-    while (true) {
-        acc.getAxis(acc_data);
-        mag.getAxis(mag_data);
-        printf("FXOS8700Q ACC: X=%1.4f Y=%1.4f Z=%1.4f  ", acc_data.x, acc_data.y, acc_data.z);
-        printf("    MAG: X=%4.1f Y=%4.1f Z=%4.1f\r\n", mag_data.x, mag_data.y, mag_data.z);
-        acc.getX(&faX);
-        acc.getY(&faY);
-        acc.getZ(&faZ);
-        mag.getX(&fmX);
-        mag.getY(&fmY);
-        mag.getZ(&fmZ);
-        printf("FXOS8700Q ACC: X=%1.4f Y=%1.4f Z=%1.4f  ", faX, faY, faZ);
-        printf("    MAG: X=%4.1f Y=%4.1f Z=%4.1f\r\n", fmX, fmY, fmZ);
-        acc.getAxis(acc_raw);
-        mag.getAxis(mag_raw);
-        printf("FXOS8700Q ACC: X=%d Y=%d Z=%d  ", acc_raw.x, acc_raw.y, acc_raw.z);
-        printf("    MAG: X=%d Y=%d Z=%d\r\n", mag_raw.x, mag_raw.y, mag_raw.z);
-        acc.getX(&raX);
-        acc.getY(&raY);
-        acc.getZ(&raZ);
-        mag.getX(&rmX);
-        mag.getY(&rmY);
-        mag.getZ(&rmZ);                
-        printf("FXOS8700Q ACC: X=%d Y=%d Z=%d  ", raX, raY, raZ);
-        printf("    MAG: X=%d Y=%d Z=%d\r\n\n", rmX, rmY, rmZ);    
+void read_binary(FILE* fp)
+{
+    uint8_t in_buffer[16];
+    fread( in_buffer, sizeof(uint8_t), 16, fp);
+    us_ellapsed = (in_buffer[0]) | (in_buffer[1] << 8)|
+                  (in_buffer[2] << 16) | (in_buffer[3] << 24);
+                  
+    accel_data.x = in_buffer[4] | (in_buffer[5] << 8);
+    accel_data.y = in_buffer[6] | (in_buffer[7] << 8);
+    accel_data.z = in_buffer[8] | (in_buffer[9] << 8);
+    
+    magn_data.x = in_buffer[10] | (in_buffer[11] << 8);
+    magn_data.y = in_buffer[12] | (in_buffer[13] << 8);
+    magn_data.z = in_buffer[14] | (in_buffer[15] << 8);
+}
+
+int main(void)
+{
+    // Setup
+    t.reset();
+    pc.baud(115200); // Move pc.printf's right along
+    green.write(1); // lights off
+    red.write(1);
+    blue.write(1);
+
+    pc.printf("\r\nTime to start setup!\r\n");
+
+    // Prepare file stream for saving data
+    FILE* fp_raw = fopen("/sd/data.bin", "w");
+
+    if(0 == setvbuf(fp_raw, &sd_buffer[0], _IOFBF, BUFSIZ)) {
+        pc.printf("Buffering \"/sd/\" with %d bytes.\r\n", BUFSIZ);
+    } else {
+        pc.printf("Failed to buffer SD card with %d bytes.\r\n", BUFSIZ);
+    }
+
+    // Iterrupt for active-low interrupt line from FXOS
+    fxos_int2.fall(&trigger_fxos_int2);
+    fxos.enable(); // enable our device, configured in constructor
+
+    // Interrupt for active-high trigger
+    start_sw.mode(PullUp); // Since the FRDM-K64F doesn't have its SW2/SW3 pull-ups populated
+    start_sw.fall(&trigger_start_sw);
+    green.write(0); // light up ready-green
+
+    // Example data printing
+    fxos.get_data(&accel_data, &magn_data);
+    print_reading();
+
+    pc.printf("Waiting for timed data collection trigger on SW3\r\n");
+
+    while(true) {
+        if(start_sw_triggered) {
+            start_sw_triggered = false;
+            break; // Received start button press
+        }
+        wait_ms(50); // short wait will have little effect on UX
+    }
+
+    green.write(1); // ready-green off
+    blue.write(0); // working-blue on
+
+    pc.printf("Started data collection\r\n");
+
+    sample_count = 0;
+    fxos.get_data(&accel_data, &magn_data); // clear interrupt from device
+    fxos_int2_triggered = false; // un-trigger
+
+    t.start(); // start timer and enter collection loop
+    while (t.read_ms() <= DATA_RECORD_TIME_MS) {
+        if(fxos_int2_triggered) {
+            fxos_int2_triggered = false; // un-trigger
+            fxos.get_data(&accel_data, &magn_data);
+            // pc.printf("S: %d\r\n", us_ellapsed); // complex status printout
+            pc.putc('.'); // show that a sample was taken
+            write_binary(fp_raw); // needs to take <5ms to avoid blocking next transfer
+            ++sample_count; // successfully sampled and wrote!
+        }
+    }
+
+    red.write(0); // red on, display purple for file reprocessing
+
+    pc.printf("Done collecting. Reprocessing data to CSV.\r\n");
+    fflush(fp_raw);
+    fclose(fp_raw);
+
+    // Reopen the binary data as read, open CSV for write
+    fp_raw = fopen("/sd/data.bin", "r");
+    FILE* fp_csv = fopen("/sd/data.csv", "w");
+
+    write_csv_header(fp_csv); // write out CSV header
+
+    // Split the buffer between the two
+    setvbuf(fp_csv, &sd_buffer[0], _IOFBF, BUFSIZ);
+    setvbuf(fp_raw, &sd_buffer[BUFSIZ], _IOFBF, BUFSIZ);
+
+    for(uint32_t i = sample_count; i > 0; --i) {
+        read_binary(fp_raw);
+        write_reading(fp_csv);
+    }
+    
+    fclose(fp_csv);
+    fclose(fp_raw);
+    
+    pc.printf("Done processing. Wrote binary into CSV.");
+
+    red.write(1); // red off, green on, display yellow for done
+    green.write(0);
+
+    while(true) {
+        pc.putc('.');
         wait(1.0);
     }
 }
\ No newline at end of file
--- a/mbed.bld	Fri Apr 25 16:47:00 2014 +0000
+++ b/mbed.bld	Fri May 30 21:02:54 2014 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/6473597d706e
\ No newline at end of file
+http://mbed.org/users/mbed_official/code/mbed/builds/0b3ab51c8877
\ No newline at end of file