This project logs 6-axis data to a connected SD card for later analysis. This project demonstrates the use of the SD file system, I2C as well as interrupt input and digital input/output.

Dependencies:   SDFileSystem mbed

Revision:
0:fe17733d483f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Jul 27 17:20:03 2015 +0000
@@ -0,0 +1,284 @@
+#include "mbed.h"
+#include "SDFileSystem.h"
+
+//FXOS8700CQ
+#define FXOS_ADDRESS_W              0x3C
+#define FXOS_ADDRESS_R              0x3D
+#define FXOS_STATUS                 0x00
+#define FXOS_OUT_X_MSB              0x01
+#define FXOS_F_SETUP                0x09
+#define FXOS_TRIG_CFG               0x0A
+#define FXOS_SYS_MOD                0x0B
+#define FXOS_INT_SOURCE             0x0C
+#define FXOS_WHO_AM_I               0x0D
+#define FXOS_ID                     0xC7
+#define FXOS_XYZ_DATA_CFG           0x0E
+#define FXOS_TRANSIENT_CFG          0x1D
+#define FXOS_TRANSIENT_SRC          0x1E
+#define FXOS_ASLP_COUNT             0x29
+#define FXOS_CTRL_REG_1             0x2A
+#define FXOS_CTRL_REG_2             0x2B
+#define FXOS_CTRL_REG_3             0x2C
+#define FXOS_CTRL_REG_4             0x2D
+#define FXOS_CTRL_REG_5             0x2E
+#define FXOS_OFF_X                  0x2F
+#define FXOS_OFF_Y                  0x30
+#define FXOS_OFF_Z                  0x31
+#define FXOS_TEMP                   0x51
+#define FXOS_M_CTRL_REG_1           0x5B
+#define FXOS_M_CTRL_REG_2           0x5C
+#define FXOS_M_CTRL_REG_3           0x5D
+
+//FXAS21002C
+#define FXAS_ADDRESS_W              0x40
+#define FXAS_ADDRESS_R              0x41
+#define FXAS_STATUS                 0x00
+#define FXAS_OUT_X_MSB              0x01
+#define FXAS_F_SETUP                0x09
+#define FXAS_F_EVENT                0x0A
+#define FXAS_INT_SRC_FLAG           0x0B
+#define FXAS_WHO_AM_I               0x0C
+#define FXAS_ID                     0xD7
+#define FXAS_CTRL_REG_0             0x0D
+#define FXAS_RT_CFG                 0x0E
+#define FXAS_TEMP                   0x12
+#define FXAS_CTRL_REG_1             0x13
+#define FXAS_CTRL_REG_2             0x14
+#define FXAS_CTRL_REG_3             0x15
+
+//Global variables
+int FXAS_FIFO_FULL_FLAG = 0;
+int FXOS_FIFO_FULL_FLAG = 0;
+char fxos_data_1[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+char fxas_data_1[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+//Setup UART to PC
+Serial pc(USBTX, USBRX);
+
+//Setup I2C
+I2C sensors(PTE0, PTE1);
+
+//FXOS8700C Control Pins
+InterruptIn fxos_int1_8700(PTD4); //INT1-8700
+InterruptIn fxos_int2_8700(PTA4); //INT2-8700
+
+//FXAS21002C Control Pins
+InterruptIn fxas_int1_21002(PTA5);  //INT1-21002
+InterruptIn fxas_int2_21002(PTA13); //INT2-21002
+
+//SD File System
+SDFileSystem sd(PTD2, PTD3, PTD1, PTD0, "sd");
+
+////LED Setup                               
+DigitalOut led_1(LED1, 1); //red
+DigitalOut led_2(LED2, 1); //green
+//DigitalOut led_3(LED3, 1); //blue         <- NB!! Wont play nice with SDFileSystem
+
+//****************************************************************//
+//Functions
+int i2c_write(char address, char device_register, char data){
+    sensors.start();
+    sensors.write((char)address);
+    sensors.write((char)device_register);
+    sensors.write((char)data);
+    sensors.stop();
+    return 0;
+}
+
+int i2c_write(char address, char device_register, int stop){
+    sensors.start();
+    sensors.write((char)address);
+    sensors.write((char)device_register);
+    if(stop == 1){
+        sensors.stop();
+    }
+    return 0;
+}
+
+char i2c_read(char address, char device_register){
+    char data;
+    
+    sensors.start();
+    sensors.write(address);
+    sensors.write(device_register);
+    sensors.start();
+    sensors.write(address | 0x01);
+    data = (char)sensors.read(0);
+    sensors.stop();
+    return data;
+}
+
+int i2c_write_verify(char address, char device_register, char data){
+    char return_data;
+    int return_val;
+    
+    sensors.start();
+    sensors.write((char)address);
+    sensors.write((char)device_register);
+    sensors.write((char)data);
+    sensors.stop();
+    
+    sensors.start();
+    sensors.write(address);
+    sensors.write(device_register);
+    sensors.start();
+    sensors.write(address | 0x01);
+    return_data = sensors.read(0);
+    sensors.stop();
+    
+    if (return_data == data){
+        return_val = 0;
+    }
+    else{
+        return_val = -1;
+    }
+    return return_val;
+}
+
+int fxas_init() {
+    int return_val = 0;
+    int sensor_id = 0;
+  
+    sensor_id = i2c_read(FXAS_ADDRESS_W, FXAS_WHO_AM_I);
+//    pc.printf("Expected ID from FXAS21002C is 0xD7\n\r");
+//    pc.printf("Returned value: %X\n\n\r", sensor_id);
+    
+    if (sensor_id == FXAS_ID){
+        return_val = 0;
+        return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_CTRL_REG_1, 0x00);
+        return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_F_SETUP, 0x00);
+        return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_F_SETUP, 0x57);
+        return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_CTRL_REG_0, 0x03);
+        
+        return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_CTRL_REG_2, 0xC2);
+        return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_CTRL_REG_3, 0x08);
+        return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_CTRL_REG_1, 0x13);       
+    }
+    else{
+        return_val = -1;    
+    }    
+    return return_val;
+}
+    
+int fxos_init() {
+    int return_val = 0;
+    int sensor_id = 0;
+     
+    sensor_id = i2c_read(FXOS_ADDRESS_W, FXOS_WHO_AM_I);
+//    pc.printf("Expected ID from FXOS8700CQ is 0xC7\n\r");
+//    pc.printf("Returned value: %X\n\n\r", sensor_id);
+    
+    if (sensor_id == FXOS_ID){
+        return_val = 0;
+        return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_CTRL_REG_1, 0x00);
+        return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_F_SETUP, 0x00);
+        return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_F_SETUP, 0x57);
+        return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_ASLP_COUNT, 0xFF);
+        return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_XYZ_DATA_CFG, 0x02);
+        return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_CTRL_REG_2, 0x00);
+        return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_CTRL_REG_3, 0x02);
+        return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_CTRL_REG_4, 0x41);  //Enable FIFO & DRDY Interrupts
+        return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_CTRL_REG_5, 0x40);  //FIFO -> Int_1, DRDY -> Imt_2
+        return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_M_CTRL_REG_1, 0x00);
+        return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_CTRL_REG_1, 0x21);
+    }
+    else{
+        return_val = -1;    
+    } 
+    return return_val;
+}
+
+//Interrupt for FXAS21002 INT_1
+void read_fxas_data(){
+//    //Read data from FXAS21002 sensor
+    if(FXAS_FIFO_FULL_FLAG != 2){
+        FXAS_FIFO_FULL_FLAG = 1;
+    }
+}
+
+//Interrupt for FXOS8700S INT_1
+void read_fxos_data(){
+    //Read data from FXOS8700C sensor
+    if(FXOS_FIFO_FULL_FLAG != 2){
+        FXOS_FIFO_FULL_FLAG = 1;
+    }
+}
+
+int main() {
+    int initilised = 0;
+    int index = 0;
+    int test_index = 0;
+    int fxos_data_flag_1 = 0;
+    int fxas_data_flag_1 = 0;
+    
+    //Configure interrupts
+    fxas_int1_21002.rise(&read_fxas_data);//FIFO -> Int_1
+//    fxas_int2_21002.rise(&read_fxas_data);//DRDY -> Int_2
+    fxos_int1_8700.rise(&read_fxos_data);//FIFO -> Int_1
+//    fxos_int2_8700.rise(&read_fxos_data);//DRDY -> Int_2
+    
+    sensors.frequency(450000);
+    pc.baud(115200);      
+ 
+    mkdir("/sd/sensor_data", 0777);
+    FILE *fp = fopen("/sd/sensor_data/data.txt", "w");
+    if(fp == NULL) {
+        error("Could not open file for write\n");
+    }
+    fprintf(fp, "Gyro X,\tGyro Y,\tGyro Z,\t\tAcc X,\tACC Y,\tACC Z\n\r\n\r\n\r\n\r");
+    fclose(fp); 
+    
+    //Initlilise the FXOS8700CQ Accelorometer & the FXAS21002C Gyroscope
+    initilised = fxas_init() & fxos_init();
+//    pc.printf("Returned value: %d\n\n\r", initilised);
+  
+    while(1) {
+        if (FXOS_FIFO_FULL_FLAG == 1){//0.976mg * (fxos_data >> 2) = total g force (8g scale)
+            FXOS_FIFO_FULL_FLAG = 0;
+            i2c_write(FXOS_ADDRESS_W, FXOS_STATUS, 0);
+            sensors.read(FXOS_ADDRESS_R, fxos_data_1, 139, false);//Reads the status register on every pass 0x06 -> 0x00
+            fxos_data_flag_1 = 1;
+        }
+        
+        if (FXAS_FIFO_FULL_FLAG == 1){//7.8125mdps * fxas_data = total degrees per second (250dps scale)
+            FXAS_FIFO_FULL_FLAG = 0;
+            i2c_write(FXAS_ADDRESS_W, FXAS_STATUS, 0);
+            sensors.read(FXAS_ADDRESS_R, fxas_data_1, 139, false);//Reads the status register on the first if set to otherwise 0x06 -> 0x01
+            fxas_data_flag_1 = 1;
+        }
+        
+        
+        if ((fxos_data_flag_1 == 1) && (fxas_data_flag_1 == 1)){
+        //Store data on SD card    
+            if (test_index == 0){// <--------- Just till a proper file closing system can be implemented
+                fp = fopen("/sd/sensor_data/data.txt", "a");
+                if(fp == NULL) {
+                    error("Could not open file for write\n");
+                }
+            }
+            
+            for (index = 1; index < 139; index += 6){
+                //move data to SD card 
+                fprintf(fp, "%d\t%d\t%d\t\t", ((int16_t)((fxos_data_1[(index + 0)] << 8) | fxos_data_1[(index + 1)]) >> 2),
+                    ((int16_t)((fxos_data_1[(index + 2)] << 8) | fxos_data_1[(index + 3)]) >> 2),
+                    ((int16_t)((fxos_data_1[(index + 4)] << 8) | fxos_data_1[(index + 5)]) >> 2));
+                    
+                fprintf(fp, "%d\t%d\t%d\n\r\n\r", ((int16_t)((fxas_data_1[(index + 0)] << 8) | fxas_data_1[(index + 1)])),
+                    ((int16_t)((fxas_data_1[(index + 2)] << 8) | fxas_data_1[(index + 3)])),
+                    ((int16_t)((fxas_data_1[(index + 4)] << 8) | fxas_data_1[(index + 5)])));
+            }
+            
+            fxos_data_flag_1 = 0;
+            fxas_data_flag_1 = 0;
+            test_index++;
+            if (test_index == 30){// <--------- Just till a proper file closing system can be implemented
+                fclose(fp);
+                test_index = 0;
+            }
+            for (int i = 0; i < 210; i++){
+                fxos_data_1[i] = 0;
+                fxas_data_1[i] = 0;
+            }
+        }  
+    }
+}
\ No newline at end of file