NSYS for car records vibration data to sd card via wireless command

Dependencies:   mbed SDFileSystem

Dependents:   z00_NSYS_CAR_1220

Revision:
0:36c81e7b1032
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Oct 07 05:00:46 2020 +0000
@@ -0,0 +1,412 @@
+/*=========================================
+Title:NSYS for CAR
+
+Revision:1.0
+
+Editor:Dyson
+
+For GR-PEACH
+Compile using Mbed Online Compiler (revision:130)
+
+THIS IS THE FINAL PRODUCT,in xb mode
+
+reminder:for frontier 3.1
+Last Modified:2019/12/12
+==========================================*/
+#include "mbed.h"//for mbed 
+#include "SDFileSystem.h"//for SD
+
+#define _SDPRESENT 0//LOW for no SD card
+#define _SDNOTPRESENT 1//HIGH for SD card present
+#define _ENABLE    0//LOW for ADC enable
+#define _DISABLE   1//HIGH for ADC disable
+#define _KILLCOUNT  177// for 10 mins
+
+//for teraterm color logging
+//use in pc.printf("%shoge%s",_RED,_END)
+#define _RED     "\e[31m"
+#define _GREEN     "\e[32m"
+#define _YELLOW     "\e[33m"
+#define _END     "\e[m"
+
+//functions
+bool gps_read(bool fix,bool write);
+void data_init(void);
+void end_proc(void);
+int pot_read(void);
+bool sd_init(void);
+void adc_init(void);
+void adc_work(void);
+inline void pps_rise(void);
+void rx(void);
+void report(void);
+void sd_read(void);
+
+//Serial
+Serial pc(USBTX, USBRX);
+Serial xb(P7_4, P7_5);
+
+bool start=false;//turn true to start
+bool status[4];//ready,gps lock,measuring,error
+
+//SD
+FILE *fp;//file pointer
+//SDFileSystem sd(P5_2, P5_3, P5_0, P5_1, "sd");//SD reader on frontier 4.0
+SDFileSystem sd(P8_5, P8_6, P8_3, P8_4, "sd");//SD reader on peach
+//DigitalIn sd_detect(P1_2);//SD detection pin
+char filename[256];//global for using pot_num and start_time
+
+//CONTROL
+// DigitalIn one(P4_4);
+// DigitalIn two(P4_6);
+// DigitalIn four(P4_5);
+// DigitalIn eight(P4_7);
+int pot_num;
+
+InterruptIn pb(P6_0);//user switch on peach
+bool switch_pressed = false;//use this to write alternative routines
+void skip_switch(void) { switch_pressed = true; }
+
+//GPS
+Serial gps(P8_13, P8_11);
+InterruptIn PPS(P2_15);
+volatile float t_pulse;//micom time when PPS rised
+double gps_time;
+double start_time=-1;
+
+//TIMERS
+Timer utime;
+Ticker adc_ticker;
+Ticker stat_ticker;
+
+//ADC
+SPI adc(P10_14, P10_15, P10_12);//mosi,miso,sck
+//DigitalOut cs_adc(P1_3);//Frontier 4.0
+DigitalOut cs_adc(P8_15);//Frontier 2.0
+volatile int rch[3] = {};
+
+//LED
+DigitalOut led_rgb[] = {(LED1), (LED2), (LED3)};
+
+//BUFFERS
+#define BUFF_COUNT 3
+#define BUFF_DEPTH 4096
+int buff_depth = 0;
+int buff_index = 0;
+int cur_buff = 0;
+bool write_ok[BUFF_COUNT];
+
+int kill = 0;
+
+int adcsel = 0;
+
+typedef struct Logdata_t {
+    int axis;
+    int acc;
+    float t_acc;
+    float t_pulse;
+} Logdata;
+Logdata data[BUFF_COUNT][BUFF_DEPTH];
+
+bool gps_read(bool fix,bool write) { //fix 0=no,1 = locked;write 0=no,1 =yes
+    float lat, lng;
+    int stat=0;
+    char ns, ew;
+    while (1) {
+        int gps_num = 0;
+        char gps_data[256];
+        memset(gps_data, '\0' , 256);
+
+        while (gps.getc() != '$') {}//wait until $
+        while ( (gps_data[gps_num] = gps.getc() ) != '\r') {//get string until new line
+            gps_num++;
+            if (gps_num == 125) {
+                //status[3]=1;
+                break;
+            }
+        }
+        gps_data[gps_num] = '\0';
+
+        if (sscanf(gps_data, "GPGGA,%lf,%f,%c,%f,%c,%d", &gps_time, &lat, &ns, &lng, &ew, &stat) >= 1) {//if it is GPGGA sentence
+            gps_time += 90000;//turn in to JST
+            //pc.printf("%lf\r\n",gps_time);
+            if(!start && start_time>0){//if has not started yet and has valid start_time
+                if(start_time>gps_time){
+                    return false;
+                }else if(start_time==gps_time){
+                    fp = fopen(filename, "a");
+                    if (fp == NULL) {
+                        return false;
+                    }else{
+                        fprintf(fp, "gpstime,%lf,lat,%f,lng,%f\r\n", gps_time, lat, lng);
+                        fclose(fp);
+                        start = true;
+                        return true;
+                    }
+                }else if(start_time<gps_time){
+                    status[3]=1;
+                    report();
+                    return false;
+                }
+            }
+            //reach here if not yet started
+            if (!fix || stat > 0) {//if no need to fix or has a valid lock
+                if(write){//need to write
+                    fp = fopen(filename, "a");
+                    fprintf(fp, "gpstime,%lf,lat,%f,lng,%f\r\n", gps_time, lat, lng);
+                    fclose(fp);
+                    return true;
+                }
+                if (stat > 0) {//has lock
+                    status[1] = 1;
+                    report();
+                    return true;
+                } else {
+                    status[1] = 0;
+                    report();
+                    return false;
+                }
+            } else {//if need to write and has no valid lock 
+                continue;
+            }
+        }
+    }
+}
+
+void data_init(void) {//prepare datum
+    //pot_read();
+    sd_read();
+    status[0] = 1;
+    start = false;
+    buff_depth = 0;
+    buff_index = 0;
+    cur_buff = 0;
+    memset(&data, '\0' , sizeof(data));
+    memset(&write_ok, '\0' , sizeof(write_ok));
+}
+
+void end_proc() {//reet it self
+    __disable_irq();
+    status[0] = status[1] = status[2] = 0;
+    report();
+    wait(0.1);
+    __enable_irq();
+    NVIC_SystemReset();
+}
+
+// int pot_read(void) {//read pot value
+//     pot_num += one.read() + 2 * two.read() + 4 * four.read() + 8 * eight.read();
+//     return pot_num;
+// }
+
+void sd_read(void) {//check for inout directory
+    DIR *d;
+    char searchname[32];
+    for(int i=0;i<12;i++){
+        sprintf(searchname, "/sd/%d",i);
+        d = opendir(searchname);
+        if ( d != NULL ){//if there is file
+            pot_num=i;
+            //pc.printf("found file\r\n");
+            return;
+        }else{//if there isnt 
+            //pc.printf("no file\r\n");
+            continue;
+        }
+    }
+    //pc.printf("out\r\n");
+}
+
+bool sd_init(void) {//determine file name and file pointer. must lock gps beforehand
+    mkdir("/sd/wsys", 0777);
+    sprintf(filename, "/sd/wsys/%d-%.0lf.csv",pot_num, start_time);
+    fp = fopen(filename, "a");
+
+    if (fp == NULL) {
+        status[3] = 1;
+        report();
+        return false;
+    } else {
+        fclose(fp);
+        return true;
+    }
+}
+
+void adc_init(void) {
+    cs_adc = _DISABLE; // ADC chip select off
+    adc.format(8, 1); //// SPI Init ////
+    adc.frequency(750000);
+    cs_adc = _ENABLE; // ADC chip select on
+    wait_ms(112);   //55ms:NG 56ms:OK
+    adc.write(0x06);//reset
+    wait_us(32);    //15us:NG 16us:OK
+    adc.write(0x43);// write register 00h-03h
+    //adc.write(0xa1);// AIN2-GND GAIN:1 PGA:off
+    adc.write(0x81);// AIN0-GND GAIN:1 PGA:off
+    //adc.write(0xc0);// 1000sps nomalmode single temp:off burn:off
+    //adc.write(0xc1);// 1000sps nomalmode single temp:off burn:on
+    adc.write(0xd0);// 2000sps turbomode single temp:off burn:off
+    adc.write(0xc0);// ref:AVDD
+    adc.write(0x00);// DOUT/DRDY
+    adc.write(0x08);// START
+    cs_adc = _DISABLE; // ADC chip select off
+}
+
+void adc_work(void) {
+    cs_adc = _ENABLE;
+    adc.write(0x10);
+    for (int j = 0; j < 3; j++) {
+        rch[j] = adc.write(0xff);
+    }
+
+    data[buff_index][buff_depth].axis = adcsel;
+    data[buff_index][buff_depth].acc = (int)((rch[0] << 16) | (rch[1] << 8) | rch[2]);
+    data[buff_index][buff_depth].t_acc = utime.read();
+    data[buff_index][buff_depth].t_pulse = t_pulse;
+    buff_depth++;
+
+    adc.write(0x40);// write register 00h
+    switch(adcsel){
+        case 0:
+            adc.write(0x91);// AIN1-GND GAIN:1 PGA:off
+            adcsel=1;
+            break;
+
+        case 1:
+            adc.write(0xa1);// AIN2-GND GAIN:1 PGA:off
+            adcsel=2;
+            break;
+
+        case 2:
+            adc.write(0xb1);// AIN3-GND GAIN:1 PGA:off
+            adcsel=3;
+            break;
+
+        case 3:
+            adc.write(0x81);// AIN0-GND GAIN:1 PGA:off
+            adcsel=0;
+            break;
+    }
+
+    adc.write(0x08);     //start
+    cs_adc = _DISABLE; // ADC chip select off
+
+    if (buff_depth == BUFF_DEPTH) {
+        buff_index++;
+        if (buff_index == BUFF_COUNT) {
+            buff_index = 0;
+        }
+        buff_depth = 0;
+        write_ok[buff_index] = true;
+    }
+}
+/*
+command pin axis
+81 0
+91 1
+a1 2
+b1 3
+*/
+
+void adc_test(void) {
+    int  zraw;
+    cs_adc = _ENABLE;
+    adc.write(0x10);
+    for (int j = 0; j < 3; j++) {
+        rch[j] = adc.write(0xff);
+    }
+    adc.write(0x08);     //start
+    cs_adc = _DISABLE; // ADC chip select off
+
+    zraw = (int)((rch[0] << 16) | (rch[1] << 8) | rch[2]);
+    if (zraw == 0 || zraw ==  16777215)status[3] = 1;
+    xb.printf("%d,%d\r\n", pot_num, zraw);
+    pc.printf("%d,%d\r\n", pot_num, zraw);
+}
+
+inline void pps_rise(void) {
+    //__disable_irq();
+    t_pulse = utime.read();
+    //__enable_irq();
+}
+
+void rx(void) {
+    char ch[128];
+    int char_num = 0;
+    while((ch[char_num]=xb.getc()) !='\n'){
+        char_num++;
+        if(char_num==127){
+            xb.printf("**ERROR**\r\n");
+            break;
+        }
+    }
+    if (ch[0] == 'r') {
+        end_proc();
+    }else if(ch[0]=='s'){
+        sscanf(ch, "s,%lf", &start_time);
+        //pc.printf("stime:%.0lf\r\n",start_time);
+        if(!start){
+            xb.attach(NULL, Serial::RxIrq);
+            stat_ticker.detach();
+            sd_init();
+            while(!start){
+                gps_read(0,0);
+            }
+            status[2] = 1;
+            report();
+            utime.start();
+            PPS.rise(pps_rise);
+            utime.reset();
+            adc_ticker.attach_us(&adc_work, 833);
+        }
+    }
+}
+
+void report(void) {
+    xb.printf("%d,%d,%d,%d,%d\r\n", pot_num, status[0], status[1], status[2], status[3]); //num,ready,gps lock,measuring,error
+}
+
+int main(void) {
+    wait(0.4);
+    xb.baud(9600);
+
+    data_init();
+    //sd_read();
+    adc_init();
+    stat_ticker.attach(&report,2);
+    
+    wait(2);
+    adc_test();
+
+    //gps_read(0,0);//develop
+    gps_read(1,0);//actual use
+    xb.attach(&rx, Serial::RxIrq);
+
+    led_rgb[1] = 1;
+    while(1){
+        while (start) {
+            led_rgb[0] = 1;
+            if (write_ok[cur_buff]) {
+                fp = fopen(filename, "a");
+                if (fp == NULL || kill == _KILLCOUNT) {
+                    end_proc();
+                } else {
+                    led_rgb[2] = 1;
+                    for (int i = 0; i < BUFF_DEPTH; i++) {
+                        fprintf(fp, "%d,%d,%f,%f\r\n",data[cur_buff][i].axis,data[cur_buff][i].acc, data[cur_buff][i].t_acc, data[cur_buff][i].t_pulse);
+                    }
+                    led_rgb[2] = 0;
+                    write_ok[cur_buff] = false;
+                    kill++;
+                    cur_buff++;
+                    if (cur_buff == BUFF_COUNT)cur_buff = 0;
+                    if(kill==_KILLCOUNT){
+                        gps_read(0,1);//write even if no lock
+                        end_proc();
+                    }
+                }//if fp not null
+                fclose(fp);
+            }//if write_ok is true
+        }//start changes to false
+    }
+}
\ No newline at end of file