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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "FXOS8700CQ.h"
00003 #include "SDFileSystem.h"
00004 
00005 #define DATA_RECORD_TIME_MS 20000
00006 
00007 Serial pc(USBTX, USBRX); // for diagnostic output, beware blocking on long text
00008 
00009 // Pin names for FRDM-K64F
00010 SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd");  // MOSI, MISO, SCLK, SSEL, "name"
00011 FXOS8700CQ fxos(PTE25, PTE24, FXOS8700CQ_SLAVE_ADDR1); // SDA, SCL, (addr << 1)
00012 
00013 DigitalOut green(LED_GREEN);
00014 DigitalOut blue(LED_BLUE);
00015 DigitalOut red(LED_RED);
00016 
00017 Timer t; // Microsecond timer, 32 bit int, maximum count of ~30 minutes
00018 InterruptIn fxos_int1(PTC6);
00019 InterruptIn fxos_int2(PTC13);
00020 InterruptIn start_sw(PTA4); // switch SW3
00021 
00022 bool fxos_int1_triggered = false;
00023 bool fxos_int2_triggered = false;
00024 uint32_t us_ellapsed = 0;
00025 bool start_sw_triggered = false;
00026 
00027 uint32_t sample_count = 0;
00028 
00029 SRAWDATA accel_data;
00030 SRAWDATA magn_data;
00031 
00032 char sd_buffer[BUFSIZ * 2]; // create an appropriately sized buffer
00033 
00034 void trigger_fxos_int1(void)
00035 {
00036     fxos_int1_triggered = true;
00037 }
00038 
00039 void trigger_fxos_int2(void)
00040 {
00041     fxos_int2_triggered = true;
00042     us_ellapsed = t.read_us();
00043 }
00044 
00045 void trigger_start_sw(void)
00046 {
00047     start_sw_triggered = true;
00048 }
00049 
00050 void print_reading(void)
00051 {
00052     pc.printf("A X:%5d,Y:%5d,Z:%5d   M X:%5d,Y:%5d,Z:%5d\r\n",
00053               accel_data.x, accel_data.y, accel_data.z,
00054               magn_data.x, magn_data.y, magn_data.z);
00055 }
00056 
00057 void write_reading(FILE* fp)
00058 {
00059     fprintf(fp, "%d, %d,%d,%d, %d,%d,%d\r\n",
00060             us_ellapsed,
00061             accel_data.x, accel_data.y, accel_data.z,
00062             magn_data.x, magn_data.y, magn_data.z);
00063 }
00064 
00065 void write_csv_header(FILE* fp)
00066 {
00067     fprintf(fp, "timestamp, acc-x, acc-y, acc-z, magn-x, magn-y, magn-z, scale: %d\r\n",
00068             fxos.get_accel_scale());
00069 }
00070 
00071 /*
00072  * Writing binary to the file:
00073  * Timestamp: uint32_t written B0 B1 B2 B3
00074  * Raw data: int16_t written B0 B1
00075  * Packed resulting format, 16 bytes:
00076  * TS0 TS1 TS2 TS3 AX0 AX1 AY0 AY1 AZ0 AZ1 MX0 MX1 MY0 MY1 MZ0 MZ1
00077  */
00078 void write_binary(FILE* fp)
00079 {
00080     uint8_t out_buffer[16] = {
00081         (uint8_t)(us_ellapsed), (uint8_t)(us_ellapsed >> 8),
00082         (uint8_t)(us_ellapsed >> 16), (uint8_t)(us_ellapsed >> 24),
00083 
00084         (uint8_t)(accel_data.x), (uint8_t)(accel_data.x >> 8),
00085         (uint8_t)(accel_data.y), (uint8_t)(accel_data.y >> 8),
00086         (uint8_t)(accel_data.z), (uint8_t)(accel_data.z >> 8),
00087 
00088         (uint8_t)(magn_data.x), (uint8_t)(magn_data.x >> 8),
00089         (uint8_t)(magn_data.y), (uint8_t)(magn_data.y >> 8),
00090         (uint8_t)(magn_data.z), (uint8_t)(magn_data.z >> 8)
00091     };
00092 
00093     fwrite( (const uint8_t*) out_buffer, sizeof(uint8_t), 16, fp);
00094 }
00095 
00096 void read_binary(FILE* fp)
00097 {
00098     uint8_t in_buffer[16];
00099     fread( in_buffer, sizeof(uint8_t), 16, fp);
00100     us_ellapsed = (in_buffer[0]) | (in_buffer[1] << 8)|
00101                   (in_buffer[2] << 16) | (in_buffer[3] << 24);
00102                   
00103     accel_data.x = in_buffer[4] | (in_buffer[5] << 8);
00104     accel_data.y = in_buffer[6] | (in_buffer[7] << 8);
00105     accel_data.z = in_buffer[8] | (in_buffer[9] << 8);
00106     
00107     magn_data.x = in_buffer[10] | (in_buffer[11] << 8);
00108     magn_data.y = in_buffer[12] | (in_buffer[13] << 8);
00109     magn_data.z = in_buffer[14] | (in_buffer[15] << 8);
00110 }
00111 
00112 int main(void)
00113 {
00114     // Setup
00115     t.reset();
00116     pc.baud(115200); // Move pc.printf's right along
00117     green.write(1); // lights off
00118     red.write(1);
00119     blue.write(1);
00120 
00121     pc.printf("\r\nTime to start setup!\r\n");
00122 
00123     // Prepare file stream for saving data
00124     FILE* fp_raw = fopen("/sd/data.bin", "w");
00125 
00126     if(0 == setvbuf(fp_raw, &sd_buffer[0], _IOFBF, BUFSIZ)) {
00127         pc.printf("Buffering \"/sd/\" with %d bytes.\r\n", BUFSIZ);
00128     } else {
00129         pc.printf("Failed to buffer SD card with %d bytes.\r\n", BUFSIZ);
00130     }
00131 
00132     // Iterrupt for active-low interrupt line from FXOS
00133     fxos_int2.fall(&trigger_fxos_int2);
00134     fxos.enable(); // enable our device, configured in constructor
00135 
00136     // Interrupt for active-high trigger
00137     start_sw.mode(PullUp); // Since the FRDM-K64F doesn't have its SW2/SW3 pull-ups populated
00138     start_sw.fall(&trigger_start_sw);
00139     green.write(0); // light up ready-green
00140 
00141     // Example data printing
00142     fxos.get_data(&accel_data, &magn_data);
00143     print_reading();
00144 
00145     pc.printf("Waiting for timed data collection trigger on SW3\r\n");
00146 
00147     while(true) {
00148         if(start_sw_triggered) {
00149             start_sw_triggered = false;
00150             break; // Received start button press
00151         }
00152         wait_ms(50); // short wait will have little effect on UX
00153     }
00154 
00155     green.write(1); // ready-green off
00156     blue.write(0); // working-blue on
00157 
00158     pc.printf("Started data collection\r\n");
00159 
00160     sample_count = 0;
00161     fxos.get_data(&accel_data, &magn_data); // clear interrupt from device
00162     fxos_int2_triggered = false; // un-trigger
00163 
00164     t.start(); // start timer and enter collection loop
00165     while (t.read_ms() <= DATA_RECORD_TIME_MS) {
00166         if(fxos_int2_triggered) {
00167             fxos_int2_triggered = false; // un-trigger
00168             fxos.get_data(&accel_data, &magn_data);
00169             // pc.printf("S: %d\r\n", us_ellapsed); // complex status printout
00170             pc.putc('.'); // show that a sample was taken
00171             write_binary(fp_raw); // needs to take <5ms to avoid blocking next transfer
00172             ++sample_count; // successfully sampled and wrote!
00173         }
00174     }
00175 
00176     red.write(0); // red on, display purple for file reprocessing
00177 
00178     pc.printf("Done collecting. Reprocessing data to CSV.\r\n");
00179     fflush(fp_raw);
00180     fclose(fp_raw);
00181 
00182     // Reopen the binary data as read, open CSV for write
00183     fp_raw = fopen("/sd/data.bin", "r");
00184     FILE* fp_csv = fopen("/sd/data.csv", "w");
00185 
00186     write_csv_header(fp_csv); // write out CSV header
00187 
00188     // Split the buffer between the two
00189     setvbuf(fp_csv, &sd_buffer[0], _IOFBF, BUFSIZ);
00190     setvbuf(fp_raw, &sd_buffer[BUFSIZ], _IOFBF, BUFSIZ);
00191 
00192     for(uint32_t i = sample_count; i > 0; --i) {
00193         read_binary(fp_raw);
00194         write_reading(fp_csv);
00195     }
00196     
00197     fclose(fp_csv);
00198     fclose(fp_raw);
00199     
00200     pc.printf("Done processing. Wrote binary into CSV.");
00201 
00202     red.write(1); // red off, green on, display yellow for done
00203     green.write(0);
00204 
00205     while(true) {
00206         pc.putc('.');
00207         wait(1.0);
00208     }
00209 }