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

main.cpp

Committer:
Kas_Lewis
Date:
2015-07-27
Revision:
0:fe17733d483f

File content as of revision 0:fe17733d483f:

#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;
            }
        }  
    }
}