Shang-Shian Liu
/
New_Time_Recorder
To Record the time of the car
main.cpp
- Committer:
- Dennis40816
- Date:
- 2020-08-11
- Revision:
- 3:70ce5fd299bb
- Parent:
- 2:c9889e740474
- Child:
- 4:1300ca51fc75
File content as of revision 3:70ce5fd299bb:
//Include #include "mbed.h" #include "TextLCD.h" //Define-USER SET #define DEBUG 2 // 0: formal , 1: all information, 2: only delay time #define NO_DELAY 0 //if define RESULT == 1, ignore delay time of RF , if DEBUG == 2, this must be 0 #define RX_MODE 1 //1 for scanf ; 2 for getc #define BUTTON_DEBOUNCE 0.3f #define LCD_SHOW_PERIOD 3.0f //show last cycle for 2 sec #define SENSOR_IN_DEBOUNCE 0.2f #define NVIC_RESET_PROTECT 4.0f //all sys reset by pull blue button(button 2) for more than 4 seconds //Define-Don't Change #if(DEBUG == 2 && NO_DELAY == 1) #define NO_DELAY 0 #endif #define m_1 1000000.0f #define TX_SIZE 16 #define RX_SIZE 16 #if (DEBUG != 1) #define CYCLE_TIME_PROTECT 2.0f //used in formal , protect someone trigger the sensor #else #define CYCLE_TIME_PROTECT 1.0f #endif #define ENDURANCE_CYCLE 20 #define SKIDPAD_CYCLE 4 //RF CMD #define ACCEPT 0 #define DENY 1 #define CHECK 2 #define MASTER 3 #define SLAVE 4 #define RESULT 5 #define DELAY 6 #define RESET 7 //cycle reset #define RESTART 8 //mode all reset /* ############################### # Pin Init # # functions # ############################### */ //simulate the sensor // Serial Tutorial : http://www.stmcu.org.cn/module/forum/thread-608234-1-1.html //PC Serial pc(USBTX,USBRX,115200); //Wireless Serial RF(PC_10,PC_11,9600); //Default , product url: http://www.wenshing.com.tw/upload/file/1537953630.pdf //LCD I2C i2c_lcd(PB_9,PB_8); // SDA,SCL TextLCD_I2C lcd(&i2c_lcd, 0x40, TextLCD::LCD16x2); //0x40 for all short(blue lcd) , 0x4E for A1 to A3 open(green lcd) - I2C Address //Sensor //#if(DEBUG) DigitalOut sensor_com(PA_8,1); // D7 InterruptIn SENSOR_IT(PB_4,PullDown); // D5 //#else // DigitalOut sensor_com(PB_2,1); // InterruptIn SENSOR_IT(PB_1,PullDown); //#endif //BT Serial bt (PA_0,PA_1,115200); // Serial_4 tx,rx DigitalOut key(PC_1,0); // not AT Mode DigitalIn bt_state(PA_4,PullDown); // high when connected with terminal //Mode Button DigitalOut button_high(PA_11,1); // 最右7 InterruptIn MY_BUTTON(PB_12,PullDown); // 最右8 //Reset Button DigitalOut button_high_2(PA_6,1); // Mode的左邊 InterruptIn MY_BUTTON_2(PA_7,PullDown); /* ############################### # Global # # Variable # ############################### */ // main process // /**/ -> need reset volatile int mode = 0; //mode 0:Single 1:ACC 2:SkidPad 3:Endurance /**/ volatile int process = 0; //process 0:for ready ; 1:sensor in/confirm master or slave ; 2:calculation : 3:bt show 4 lcd show // time record /**/ Timer this_cycle_timer; //keep running timer float sensor_in_debounce = 0.0; /**/ float total_time = 0.0; /**/ float last_cycle_time = 0.0; //for LC print /**/ float best_cycle_time = 0.0; // cycle /**/ int cycle = 1; /**/ int best_cycle = 1; // button debounce float button_RTC = 0.0; float button_LTC = 0.0; float button_RTC_2 = 0.0; float button_LTC_2 = 0.0; // RF related bool rf_state = 0; //0 for disconnect bool last_rf_state = 1; bool Rx_flag = 0; //1 when receive a cmd over /**/ int role = 0; /**/ int this_tcmd = 0; /**/ int last_tcmd = 0; /**/ int this_rcmd = 0; int rf_interval_cnt = 0; /**/ float rf_delay_time = 0.0; /**/ Timer rf_check_timer; // RF Data /**/ char TX_buffer[TX_SIZE]; /**/ char RX_buffer[RX_SIZE]; /**/ int tx_cnt = 0; /**/ int rx_cnt = 0; // LCD /**/ bool lcd_print_flag = 0; bool lcd_end_flag = 0; float lcd_life_check_time = 0.0; float lcd_show_result_time = 0.0; float lcd_end_time = 0.0; // BT /**/ bool bt_print_flag = 0; bool bt_end_flag = 0; /* ############################### # Declaration # ############################### */ // Initial void Initial_All(void); void Initial_Hardware(void); void Initial_IT(void); //main function void ALL_SYS_RESET_CHECK(void); void reset_parameters(void); void show_all(void); void lcd_show(void); void bt_show(void); void show_flag_check(void); void time_cal(void); void RF_Send(int); void RF_Receive(int); void RF_Check(void); // IT Functions void sensor_in(void); void button_fall(void); void button_fall_2(void); void test_button(void); void RxCallback(void); //protect parameters void parameters_protect(void); /* ############################### # Main # # function # ############################### */ int main() { Initial_All(); while(1) { ALL_SYS_RESET_CHECK(); RF_Check(); time_cal(); show_all(); } } /* ############################### # Functions # # Implementation # ############################### */ //Initial void Initial_All(){ Initial_Hardware(); Initial_IT(); } void Initial_Hardware(){ //lcd lcd.setCursor(TextLCD::CurOff_BlkOff); lcd.setBacklight(TextLCD::LightOn); lcd.locate(0,0); lcd.printf("NTHU RACING"); lcd.locate(0,1); lcd.printf("Initializing"); //bt if(bt_state.read()) { bt.printf("######################################\r\n"); bt.printf("NTHU RACING TIME RECORDER INITIALIZING\r\n\r\n"); } else{ lcd.locate(12,0); lcd.printf("b0"); pc.printf("######################################\r\n"); pc.printf("NTHU RACING TIME RECORDER INITIALIZING\r\n\r\n"); } wait(1.5); } void Initial_IT(){ //BUTTON MY_BUTTON.rise(&button_fall); MY_BUTTON_2.rise(&button_fall_2); //SENSOR SENSOR_IT.rise(&sensor_in); //RF RF.attach(&RxCallback,Serial::RxIrq); lcd.cls(); lcd.locate(0,0); lcd.printf("Set up ok!"); if(bt_state.read()){ bt.printf("NTHU RACING TIME RECORDER SET UP DONE\r\n"); bt.printf("#####################################\r\n"); } else{ pc.printf("NTHU RACING TIME RECORDER SET UP DONE\r\n"); pc.printf("#####################################\r\n"); } wait(1); } //while loop void ALL_SYS_RESET_CHECK(){ if(MY_BUTTON_2.read()){ if(us_ticker_read()/m_1 - button_RTC_2 > NVIC_RESET_PROTECT) NVIC_SystemReset(); } } void RF_Check(){ if(role == 0 && mode == 1) { rf_check_timer.start(); if(rf_check_timer.read() > 1){ rf_interval_cnt++; rf_check_timer.reset(); } if(rf_interval_cnt % 5 == 0 && rf_interval_cnt) { RF_Send(CHECK); } if(rf_interval_cnt > 5) rf_state = 0; if(rf_interval_cnt > 20000) rf_interval_cnt = 0; } else rf_check_timer.stop(); } void reset_parameters() { process = 0; lcd_print_flag = 0; bt_print_flag = 0; this_cycle_timer.stop(); this_cycle_timer.reset(); lcd_end_flag = 0; bt_end_flag = 0; if( mode != 1 || (mode == 1 && this_rcmd == RESTART) || (mode == 1 && last_tcmd == RESTART) ){ cycle = 1; best_cycle = 1; last_cycle_time = 0.0; best_cycle_time = 0.0; total_time = 0.0; } if(mode == 1){ memset(TX_buffer,0,TX_SIZE); memset(RX_buffer,0,RX_SIZE); tx_cnt = 0; rx_cnt = 0; rf_delay_time = 0.0; role = 0; this_tcmd = 0; last_tcmd = 0; this_rcmd = 0; } if(bt_state.read() ) bt.printf("#####################################\r\n"); else pc.printf("#####################################\r\n"); } void show_all(){ parameters_protect(); lcd_show(); bt_show(); show_flag_check(); } void parameters_protect(){ if(cycle >= 99){ cycle = 0; if(bt_state.read()) bt.printf("Cycle Protect \r\n"); else pc.printf("Cycle Protect \r\n"); } if(last_cycle_time >= 9999.99f ){ last_cycle_time = 0.0; if(bt_state.read()) bt.printf("Last Cycle Time Protect \r\n"); else pc.printf("Last Cycle Time Protect \r\n"); } if(total_time >= 9999.99f){ total_time = 0.0; if(bt_state.read()) bt.printf("Total Time Protect \r\n"); else pc.printf("Total Time Protect \r\n"); } } void lcd_show(){ //process 4 update lcd.locate(0,0); if( (!lcd_print_flag) && last_cycle_time > 0.0f && process == 4){ //print out last cycle time flag lcd_print_flag = 1; lcd_show_result_time = us_ticker_read()/m_1; } else if((!lcd_end_flag) && ( (cycle > SKIDPAD_CYCLE && mode == 2 || cycle > ENDURANCE_CYCLE && mode == 3) || #if(NO_DELAY == 1) (last_tcmd == RESULT || this_rcmd == RESULT && mode == 1) ) #else (last_tcmd == DELAY || this_rcmd == DELAY && mode == 1) ) #endif ){ //mode end if(us_ticker_read()/m_1 - lcd_show_result_time > LCD_SHOW_PERIOD){ lcd_end_flag = 1; lcd_end_time = us_ticker_read()/m_1; } } //row 1 show if(us_ticker_read()/m_1 - lcd_show_result_time < LCD_SHOW_PERIOD && last_cycle_time != 0 && mode != 1) lcd.printf("LCT : %.2f sec ",last_cycle_time); else if(us_ticker_read()/m_1 - lcd_end_time < LCD_SHOW_PERIOD && last_cycle_time != 0 && mode != 1) lcd.printf("BC :%d ",best_cycle); else{ switch(mode){ case 0 : lcd.printf("SING b%dn%d C%d ",bt_state.read(),rf_state,cycle); break; case 1: lcd.printf("ACC b%dn%d C%d ",bt_state.read(),rf_state,cycle); break; case 2: lcd.printf("SKID b%dn%d C%d ",bt_state.read(),rf_state,cycle); break; case 3: lcd.printf("ENDU b%dn%d C%d ",bt_state.read(),rf_state,cycle); break; } } lcd.locate(0,1); //row 2 show if(cycle == 1 && this_cycle_timer.read() == 0) lcd.printf("Ready to Go !"); //first in else if(mode == 1 && lcd_print_flag)lcd.printf ("TC:%.2f sec ",last_cycle_time); else if(mode == 1) lcd.printf("TC:%.2f sec ",this_cycle_timer.read()); else if(lcd_end_flag && mode!=1) lcd.printf("BCT :%.2f sec",best_cycle_time); else if((cycle > SKIDPAD_CYCLE && mode == 2 || cycle > ENDURANCE_CYCLE && mode == 3)) lcd.printf("Mode %d End! ",mode); else lcd.printf("%.2f,%.2f ",this_cycle_timer.read(),this_cycle_timer.read()+total_time); //lcd life check lcd.locate(15,1); if(us_ticker_read()/m_1 - lcd_life_check_time < 1.0f) lcd.printf("."); else if(us_ticker_read()/m_1 - lcd_life_check_time < 2.0f) lcd.printf(" "); else lcd_life_check_time = us_ticker_read()/m_1; } void bt_show(){ //process 3 update and print if(bt_state.read() && process == 3){ //process change process = 4; bt_print_flag = 1; if (last_cycle_time == 0.0f) bt.printf("First in\r\n"); else { bt.printf("Mode:%d,cycle: %d,last cycle time:%.2f sec\r\n",mode,cycle,last_cycle_time); if(cycle == SKIDPAD_CYCLE && mode == 2 || cycle == ENDURANCE_CYCLE && mode == 3 ){ bt.printf("Best Cycle:%d\r\n",best_cycle); bt.printf("Best Cycle Time:%.2f sec\r\n",best_cycle_time); bt.printf("Mode %d End & Reset\r\n",mode); bt_end_flag = 1; } else if(mode == 1) bt_end_flag = 1; } } else if(process == 3){ process = 4; bt_print_flag = 1; if (last_cycle_time == 0.0f) pc.printf("First in\r\n"); else { pc.printf("Mode:%d,cycle: %d,last cycle time:%.2f sec\r\n",mode,cycle,last_cycle_time); if(cycle == SKIDPAD_CYCLE && mode == 2 || cycle == ENDURANCE_CYCLE && mode == 3){ pc.printf("Mode %d End & Reset\r\n",mode); bt_end_flag = 1; } } } if(last_rf_state != rf_state){ last_rf_state = rf_state; if(rf_state){ if(bt_state.read()) bt.printf("RF Connected!\r\n"); else pc.printf("RF Connected!\r\n"); } else{ if(bt_state.read()) bt.printf("RF Disconnected!\r\n"); else pc.printf("RF Disonnected!\r\n"); } } } void show_flag_check(){ //cycle update for mode != ACC if(lcd_print_flag && bt_print_flag && mode != 1){ //print ok process = 0; lcd_print_flag = 0; bt_print_flag = 0; cycle++; } if(lcd_end_flag && bt_end_flag){ //notice reset if(mode == 1 && us_ticker_read()/m_1 - lcd_end_time > LCD_SHOW_PERIOD && lcd_end_flag ) RF_Send(RESET); //including local reset else if(us_ticker_read()/m_1 - lcd_end_time > LCD_SHOW_PERIOD) reset_parameters(); } } void time_cal(){ if(process == 1){ process = 2; //calculation time variable //last_cycle_time update in sensor in if(mode != 1) total_time += last_cycle_time; if(cycle == 1){ best_cycle = cycle; best_cycle_time = last_cycle_time; } else if(last_cycle_time < best_cycle_time){ best_cycle = cycle; best_cycle_time = last_cycle_time; } //get in update show period process = 3; } } //RF communication function , must end with \n ; //cycle update for mode ACC void RF_Send(int rf_tcmd){ if(rf_tcmd != ACCEPT) this_tcmd = rf_tcmd; switch(rf_tcmd){ case ACCEPT: RF.printf("%d\n",ACCEPT); rf_state = 1; rf_interval_cnt = -4; break; case DENY: RF.printf("%d\n",DENY); break; case CHECK: //以後加上cycle check RF.printf("%d\n",CHECK); break; case MASTER: role = 1; RF.printf("%d\n",MASTER); if(bt_state.read()) bt.printf("Car in \r\n"); else pc.printf("Car in \r\n"); break; case SLAVE: RF.printf("%d&%.2f\n",SLAVE,this_cycle_timer.read()); break; case RESULT: RF.printf("%d&%.2f\n",RESULT,this_cycle_timer.read()); break; case DELAY: //delay time abnormal detect if(rf_delay_time < 1.0f) { RF.printf("%d&%.4f\n",DELAY,rf_delay_time); #if (DEBUG == 1 || DEBUG == 2) if(bt_state.read()) bt.printf("Delay time:%.4f\r\n",rf_delay_time); else pc.printf("Delay time:%.4f\r\n",rf_delay_time); #endif } else if(bt_state.read()) bt.printf("rf delay time > 1sec \r\n"); else pc.printf("rf delay time > 1 sec\r\n"); break; case RESET: cycle++; reset_parameters(); if(bt_state.read()) bt.printf("ACC Set \r\n"); else pc.printf("ACC Set \r\n"); break; case RESTART: RF.printf("%d\n",RESTART); //reset_parameters at button_fall_2 break; default: if(bt_state.read()) bt.printf("Unknown Tcmd\r\n"); else pc.printf("Unknown Tcmd\r\n"); break; } last_tcmd = this_tcmd; } void RF_Receive(int rf_rcmd){ if(mode == 1){ this_rcmd = rf_rcmd; #if(DEBUG == 1) //if(bt_state.read()) bt.printf("this rcmd:%d\r\n",this_rcmd); //else pc.printf("this rcmd:%d\r\n",this_rcmd); #endif switch(rf_rcmd){ case ACCEPT: rf_state = 1; rf_interval_cnt = 0; break; case DENY: switch(last_tcmd){ //master case MASTER: bt.printf("MASTER Request Denied!\r\n"); break; //slave //發送時間待補 case SLAVE: bt.printf("SLAVE Request Denied!\r\n"); break; //result case RESULT: bt.printf("RESULT Request Denied!\r\n"); break; } break; case CHECK: RF_Send(ACCEPT); break; case MASTER: //will become Slave End if(role == 0){ role = 2; if(bt_state.read()) bt.printf("Car in \r\n"); else pc.printf("Car in \r\n"); } else RF_Send(DENY); break; case SLAVE: /*should be Master End*/ //calculate Delay time char slave_time[5]; for(int i=0;i<5;i++) slave_time[i] = RX_buffer[i+2]; rf_delay_time = (float)(( this_cycle_timer.read()-atof(slave_time) )/2); last_cycle_time = this_cycle_timer.read()-rf_delay_time; //send back Delay time wait_ms(10); RF_Send(DELAY); wait_ms(10); //Role off and interval = 0 ->maybe at reset? process = 3; break; case RESULT: //should be Master End char result_time[5]; for(int i=0;i<5;i++) result_time[i] = RX_buffer[i+2]; last_cycle_time = atof(result_time); process = 3; break; case DELAY: // should be Slave End char delay_time [5]; for(int i=0;i<5;i++) delay_time[i] = RX_buffer[i+2]; rf_delay_time = atof(delay_time); last_cycle_time = this_cycle_timer.read()+ rf_delay_time; process = 3; #if(DEBUG == 1 || DEBUG == 2) if(bt_state.read()) bt.printf("Delay time:%.4f \r\n",rf_delay_time); else pc.printf("Delay time:%.4f \r\n",rf_delay_time); #endif break; case RESET: cycle++; reset_parameters(); if(bt_state.read()) bt.printf("ACC Set\r\n"); else pc.printf("ACC Set\r\n"); break; case RESTART: reset_parameters(); if(bt_state.read()) bt.printf("ACC Restart\r\n"); else pc.printf("ACC Restart\r\n"); break; default: if(bt_state.read()) bt.printf("Unknown Rcmd\r\n"); else pc.printf("Unknown Rcmd\r\n"); break; } } } //IT void sensor_in(){ if(us_ticker_read()/m_1 - sensor_in_debounce > SENSOR_IN_DEBOUNCE){ sensor_in_debounce = us_ticker_read()/m_1; if(mode!=1){ if(cycle == 1){ this_cycle_timer.start(); process = 1; } if(this_cycle_timer.read() > CYCLE_TIME_PROTECT){ process = 1; last_cycle_time = this_cycle_timer.read(); this_cycle_timer.reset(); } //check mode2,3 if((cycle > SKIDPAD_CYCLE && mode == 2 || cycle > ENDURANCE_CYCLE && mode == 3)){ process = 0; } } else if(mode == 1){ //mode acc if(!role && rf_state){ //MASTER this_cycle_timer.start(); RF_Send(MASTER); } if(role == 2 && this_cycle_timer.read() > CYCLE_TIME_PROTECT){ this_cycle_timer.stop(); //SLAVE #if (NO_DELAY == 1) //this_cycle_timer.start() at RxCallback RF_Send(RESULT); last_cycle_time = this_cycle_timer.read(); process = 3; #else //with delay calculation in Master End RF_Send(SLAVE); #endif } } } } void button_fall(void){ //debounce button_RTC = us_ticker_read()/m_1; if(button_RTC - button_LTC > BUTTON_DEBOUNCE){ button_LTC = button_RTC; (mode >= 3 || mode < 0) ? mode = 0 : mode++ ; (mode == 1)?RF.attach(&RxCallback,Serial::RxIrq):RF.attach(NULL,Serial::RxIrq); if(mode != 1) rf_state = 0; last_tcmd = RESTART; reset_parameters(); last_tcmd = ACCEPT; if(bt_state.read()) bt.printf("Mode change to :%d \r\n",mode); else pc.printf("Mode change to :%d \r\n",mode); } } void button_fall_2(void){ //send reset cmd button_RTC_2 = us_ticker_read()/m_1; if(button_RTC_2 - button_LTC_2 > BUTTON_DEBOUNCE){ button_LTC_2 = button_RTC_2; if(mode == 1) RF_Send(RESTART); reset_parameters(); if(bt_state.read() ){ if(mode == 1) bt.printf("ACC Restart\r\n"); else { bt.printf("Restart!\r\n\r\n\r\n"); bt.printf("#####################\r\n"); } } else{ pc.printf("Restart!\r\n\r\n\r\n"); pc.printf("#####################\r\n"); } } } void RxCallback(){ //read from buffer #if(RX_MODE == 1) // by scanf ,printf RF.scanf("%s",RX_buffer); if(RX_buffer[0]-'0' == MASTER) this_cycle_timer.start(); else if(RX_buffer[0]-'0' == SLAVE || RX_buffer[0]-'0' == RESULT) this_cycle_timer.stop(); Rx_flag = 1; #elif(RX_MODE == 2) //by getc , printf while(RF.readable()){ char new_char = RF.getc(); if(new_char != '\n') { RX_buffer[rx_cnt++] = new_char; if(rx_cnt == 1){ //timer management if(RX_buffer[0]-'0' == MASTER) this_cycle_timer.start(); else if(RX_buffer[0]-'0' == SLAVE || RX_buffer[0]-'0' == RESULT) this_cycle_timer.stop(); } } else if(new_char == '\n') { rx_cnt = 0; Rx_flag = 1; } } #endif #if(DEBUG == 1) if(bt_state.read()&& !rx_cnt) bt.printf("RX Callback,'%s' has been received\r\n",RX_buffer); #endif if(Rx_flag == 1){ RF_Receive(RX_buffer[0]-'0'); Rx_flag = 0; } }