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

Dependencies:   mbed SDFileSystem

Dependents:   z00_NSYS_CAR_1220

main.cpp

Committer:
dyson_rey
Date:
2020-10-07
Revision:
0:36c81e7b1032

File content as of revision 0:36c81e7b1032:

/*=========================================
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
    }
}