NSYS for car records vibration data to sd card via wireless command
Dependencies: mbed SDFileSystem
Diff: main.cpp
- 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