diff --git a/speedclock.h b/speedclock.h index b81740e..791a0ac 100644 --- a/speedclock.h +++ b/speedclock.h @@ -24,9 +24,9 @@ typedef struct transcv_struct{ #define STOPBUTTON_IN 2 // this is the input for the button -#define STOPBUTTON_PRESSED HIGH // this the signal level the top button will be at as soon as pressed +#define STOPBUTTON_PRESSED LOW // this the signal level the top button will be at as soon as pressed #define MIN_DELAY_BETWEEN_PRESSED_MS 1000 // this defines the time in milliseconds before the button is expected to be pressed again. We do this to avaoid keybouncing -#define MIN_DELAY_BETWEEN_SEND_MS 1000 // this defines the time in milliseconds before the next set of data will be send to the base station - except the button was pressed. +#define MIN_DELAY_BETWEEN_SEND_MS 100 // this defines the time in milliseconds before the next set of data will be send to the base station - except the button was pressed. #define STARTBUTTON_IN 4 // start button #define STARTBUTTON_PRESSED LOW @@ -68,8 +68,8 @@ const float LEDStates[][3] = [TIMER_FAIL] = {READY_LED_OFF, RUN_LED_OFF, FAIL_LED_ON} }; -#define MAX_DIFFERENCE_OFFSET_MS 10 // 0,001sec is the maximum offset we allow between the current offset and the mean offset. if it is more - restart offset calculation -#define REQUIRED_NUMBER_MEANVALS 10 // we need at least this number of meanvalues to be ready to start a run +#define MAX_DIFFERENCE_OFFSET_MS 100 // 0,001sec is the maximum offset we allow between the current offset and the mean offset. if it is more - restart offset calculation +#define REQUIRED_NUMBER_MEANVALS 100 // we need at least this number of meanvalues to be ready to start a run #define STARTSEQ_LENGTH_MS 3100 // the length of the start sequence from the time the button was pressed ... includes the 3 tones #define STARTSEQ_STARTPAUSE_MS 1000 diff --git a/speedclock.ino b/speedclock.ino index 9614a09..4f0c821 100644 --- a/speedclock.ino +++ b/speedclock.ino @@ -21,16 +21,17 @@ RF24 radio(RF24_CNS,RF24_CE); byte addresses[][12] = {"top_station","basestation"}; // Radio pipe addresses for the 2 nodes to communicate. unsigned long counter_time_offset = 0; // number of used values for the mean value calculation -unsigned long sum_time_offset = 0; // sum of offset values -unsigned long mean_time_offset = 0; // mean value for the offset -unsigned long current_time_offset = 0; // current offset ... -unsigned long running_time_offset = 0; // offset that will be used for this run ... +signed long sum_time_offset = 0; // sum of offset values +signed long mean_time_offset = 0; // mean value for the offset +signed long current_time_offset = 0; // current offset ... +signed long running_time_offset = 0; // offset that will be used for this run ... unsigned long start_time = 0; // if the timer is running this is that start time ... unsigned long runner_start_time = 0; // this is the time the runner left the pad - so the status of the falsetstart pin goes to high again - but this is OK and a real start signed long runner_run_time = 0; // this is the time the runner really needed or the time started to early - depending on sign ... unsigned long run_time = 0; // if the timer is running this is that start time ... boolean warn_during_run = false; // will be set to true if there is a warning during the run - usually an offset sync error +boolean topbuttonwaspressed = false; timer_state_e timer_state = TIMER_WAIT; // timer needs to be initialized ... timer_state_e timer_new_state = TIMER_INIT; // timer needs to be initialized ... @@ -69,10 +70,10 @@ void setup(){ if((radio_sel0 == 1) & (radio_sel1 == 0)){ stationNumber = TOPSTATION; - Serial.print(F("The level of the station select pin makes the current node set to the TOPSTATION.")); + Serial.println(F("The level of the station select pin makes the current node set to the TOPSTATION.")); } else{ - Serial.print(F("The level of the station select pin makes the current node set to the BASESTATION")); + Serial.println(F("The level of the station select pin makes the current node set to the BASESTATION")); } // Setup and configure the NRF radio @@ -86,9 +87,9 @@ void setup(){ }else{ radio.openWritingPipe(addresses[0]); radio.openReadingPipe(1,addresses[1]); + radio.startListening(); } - radio.startListening(); // Start listening - + radio_data.topstationtime = millis(); // set the current milli second count radio_data.topbuttonpressedtime = 0; // set the time the button was pressed last time to 0 @@ -106,26 +107,57 @@ void loop(void) { /****************** Code for the TOPSTATION is here - the stop button is connected to the top station ***************************/ if (stationNumber == TOPSTATION){ // Radio is the top station and sends continously its time and the time the stop button was pressed. - bool topbuttonwaspressed = false; + // check for pressed button ... - if( (millis() - radio_data.topbuttonpressedtime) > MIN_DELAY_BETWEEN_PRESSED_MS){ - // ignore if the button was "pressed" a few millis before - this is keybouncing and would give a false result and if the button is pressed for a longer time that would effect the time as well - if(digitalRead(STOPBUTTON_IN) == STOPBUTTON_PRESSED){ - // button was pressed - store the time - radio_data.topbuttonpressedtime = millis(); - topbuttonwaspressed = true; + if(topbuttonwaspressed == false){ + if( (millis() - radio_data.topbuttonpressedtime) > MIN_DELAY_BETWEEN_PRESSED_MS){ + // ignore if the button was "pressed" a few millis before - this is keybouncing and would give a false result and if the button is pressed for a longer time that would effect the time as well + if(digitalRead(STOPBUTTON_IN) == STOPBUTTON_PRESSED){ + // button was pressed - store the time + radio_data.topbuttonpressedtime = millis(); + topbuttonwaspressed = true; + Serial.print("Stopp button was pressed at:"); + Serial.println(radio_data.topbuttonpressedtime); + digitalWrite(RUN_LED, RUN_LED_ON); + } + } + } else { + if(digitalRead(STOPBUTTON_IN) != STOPBUTTON_PRESSED){ + topbuttonwaspressed = false; + digitalWrite(RUN_LED, RUN_LED_OFF); } } - + // if the button was not pressed only each few second data will be send to BASESTATION ... if(topbuttonwaspressed || ((millis()-radio_data.topstationtime) >= MIN_DELAY_BETWEEN_SEND_MS)){ // store current millis to be send as reference ... radio_data.topstationtime = millis(); // set the current milli second count + Serial.print(millis()); + Serial.print("ms - Send data to bottom station: topstationtime: "); + Serial.print( radio_data.topstationtime ); + Serial.print(" stoppressedtime: "); + Serial.print( radio_data.topbuttonpressedtime ); + if(topbuttonwaspressed) + { + Serial.println(" .Stopp button was pressed."); + } + else { + Serial.println(" .Stopp button was NOT pressed."); + } // send data ... if (!radio.write(&radio_data,sizeof(radio_data) )){ // Send the counter variable to the other radio Serial.println(F("Failed to send data to BASESSTATION ... will retry")); - } + digitalWrite(FAIL_LED, FAIL_LED_ON); + digitalWrite(READY_LED, READY_LED_OFF); + } + else + { + Serial.println("Data sent to BASESSTATION"); + digitalWrite(FAIL_LED, FAIL_LED_OFF); + digitalWrite(READY_LED, READY_LED_ON); + } + } } @@ -134,20 +166,30 @@ void loop(void) { /****************** Code for the BASESTATION is here - the display and the start button is connected here. All caclulation will be done here ***************************/ if ( stationNumber == BASESTATION ) { - + byte pipeNo; // read data from TOP_STATION ... if( radio.available()){ // check if radio data is available - if so read the data - radio.read( &radio_data, sizeof(radio_data) ); // Read the data the TOPSTATION sent + while( radio.available(&pipeNo)){ // Read all available payloads + radio.read( &radio_data, sizeof(radio_data) ); // Read the data the TOPSTATION sent + } current_time_offset = radio_data.topstationtime - millis(); // the offset between TOP_STATION and BASESTATION + Serial.print("Current time on host in millis:"); + Serial.print(millis()); Serial.print(F(" Current time on client in millis: ")); Serial.println(radio_data.topstationtime); + Serial.print("Offset is: "); + Serial.println(current_time_offset); Serial.print(F(" Button was pressed last time on client in millis: ")); - Serial.println(radio_data.topbuttonpressedtime); + Serial.println(radio_data.topbuttonpressedtime); + } // offset calculation ... only needed if the variation is bigger than allowed or not enough values available already ... // check current offset of the TOP_STATIOn and the BASESTATION if more than allowed ... + if(counter_time_offset == 0){ + mean_time_offset = current_time_offset; + } if(abs(current_time_offset - mean_time_offset) < MAX_DIFFERENCE_OFFSET_MS){ // the offset is in range - check if we have already enough values of if we need to add more ... if(counter_time_offset <= REQUIRED_NUMBER_MEANVALS){ @@ -164,6 +206,8 @@ void loop(void) { } } else { // the current offset is out of range so we need to restart the mean calculation and set the timer to unready state ... + Serial.print("Difference current offset is "); + Serial.println( abs(current_time_offset - mean_time_offset) ); Serial.print(F("Will restart offset calculation because the variation of the current offset: ")); Serial.print(current_time_offset); Serial.print(F(" is more than the allowed: ")); @@ -243,7 +287,7 @@ void loop(void) { if(digitalRead(CANCELBUTTON_IN) == CANCELBUTTON_PRESSED){ timer_new_state = TIMER_CANCELLED; } - if((radio_data.topbuttonpressedtime - running_time_offset) > millis()){ + if((radio_data.topbuttonpressedtime - running_time_offset) > start_time){ timer_new_state = TIMER_STOPPED; } break;