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
main.cpp
- Committer:
- trm
- Date:
- 2014-05-30
- Revision:
- 7:169254b6eaf6
- Parent:
- 6:02bfeec82bc1
File content as of revision 7:169254b6eaf6:
#include "mbed.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 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(); } 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); } 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()); } /* * 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); } 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); } }