Changed offset handling and calculation

Offset calculation is started now if a connection is established only.
Recalculation gets started now if MAX_ALLOWED_FAILED_OFFSETS is reached.
This commit is contained in:
Fenoglio 2018-07-09 16:45:37 +02:00
parent 70e3778db0
commit 6989862dc4
3 changed files with 79 additions and 61 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

View file

@ -71,6 +71,7 @@ const float LEDStates[][3] =
#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 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 REQUIRED_NUMBER_MEANVALS 100 // we need at least this number of meanvalues to be ready to start a run
#define MAX_ALLOWED_FAILED_OFFSETS 3 // if more than this number of offsets are out of the specified MAX_DIFFERENCE_OFFSET_MS value, offset calcultion will be restarted
#define STARTSEQ_LENGTH_MS 3100 // the length of the start sequence from the time the button was pressed ... includes the 3 tones #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 #define STARTSEQ_STARTPAUSE_MS 1000
@ -88,6 +89,7 @@ const float LEDStates[][3] =
#define TIMER_TIMEOUT 20000 #define TIMER_TIMEOUT 20000
//--------------------------------------- function declarations ---------------------------------------------- //--------------------------------------- function declarations ----------------------------------------------
void receive_values(void);
void false_start_isr(void); void false_start_isr(void);
void update_screen(timer_state_e state); void update_screen(timer_state_e state);
void set_state_LEDs(timer_state_e state, boolean warn); void set_state_LEDs(timer_state_e state, boolean warn);

View file

@ -30,7 +30,8 @@ unsigned long runner_start_time = 0; // this is the time the runner lef
signed long runner_run_time = 0; // this is the time the runner really needed or the time started to early - depending on sign ... 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 ... 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 warn_during_run = false; // will be set to true if there is a warning during the run - usually an offset sync error
unsigned long connection_established = 0; unsigned long connection_established = 0; // time the last active connection was established
uint8_t failed_offsets = MAX_ALLOWED_FAILED_OFFSETS; // number of offset values that did not fullfill the MAX_DIFFERENCE_OFFSET_MS criterion
boolean topbuttonwaspressed = false; boolean topbuttonwaspressed = false;
@ -164,62 +165,12 @@ void loop(void) {
} }
/****************** Code for the BASESTATION is here - the display and the start button is connected here. All caclulation will be done here ***************************/ /****************** Code for the BASESTATION is here - the display and the start button is connected here. All caclulation will be done here ***************************/
if ( stationNumber == BASESTATION ) { if ( stationNumber == BASESTATION ) {
byte pipeNo;
// read data from TOP_STATION ...
if( radio.available()){
// check if radio data is available - if so read the data
while( radio.available(&pipeNo)){ // Read all available payloads
connection_established = millis();
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);
}
// offset calculation ... only needed if the variation is bigger than allowed or not enough values available already ... // receive data from top_station, calculate offset and set 'last connection' time stamp
// check current offset of the TOP_STATIOn and the BASESTATION if more than allowed ... receive_values();
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){
//add the next value to meanvalue calculation ...
sum_time_offset = sum_time_offset + current_time_offset;
counter_time_offset++;
mean_time_offset = sum_time_offset/counter_time_offset;
Serial.print(F("Offset calulation. We already have "));
Serial.print(counter_time_offset);
Serial.print(F(" of "));
Serial.print(REQUIRED_NUMBER_MEANVALS);
Serial.print(F(" values used for offset calculation. Mean value of offset based on that is: "));
Serial.println(mean_time_offset);
}
} 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: "));
Serial.print(MAX_DIFFERENCE_OFFSET_MS);
Serial.print(F(" compared to the mean offset: "));
Serial.println(mean_time_offset);
counter_time_offset = 0;
sum_time_offset = 0;
mean_time_offset = 0;
}
// set state to new_state // set state to new_state
if(timer_state != timer_new_state){ if(timer_state != timer_new_state){
@ -347,6 +298,75 @@ void loop(void) {
//####################### HELPER FUNCTIONS ########################### //####################### HELPER FUNCTIONS ###########################
void receive_values(void){
byte pipeNo;
// check if radio data is available - if so read the data
if( radio.available()){
while( radio.available(&pipeNo)){ // Read all available payloads
// read data from TOP_STATION ...
connection_established = millis();
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);
// offset calculation ... only needed if the variation is bigger than allowed or not enough values available already ...
if(counter_time_offset == 0){
// this is the initial setup to start with something - in this case the last offset value that was received
mean_time_offset = current_time_offset;
}
// check current offset of the TOP_STATIOn and the BASESTATION if more than allowed ...
if(abs(current_time_offset - mean_time_offset) < MAX_DIFFERENCE_OFFSET_MS){
// if the current value is in range - decrease the fail counter by 1 if it was not zero already
if(failed_offsets > 0){
failed_offsets--;
}
// 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){
//add the next value to meanvalue calculation ...
sum_time_offset = sum_time_offset + current_time_offset;
counter_time_offset++;
mean_time_offset = sum_time_offset/counter_time_offset;
Serial.print(F("Offset calulation. We have "));
Serial.print(counter_time_offset);
Serial.print(F("/"));
Serial.print(REQUIRED_NUMBER_MEANVALS);
Serial.print(F(" values. Mean offset value based on that is: "));
Serial.println(mean_time_offset);
}
} else {
// the current offset is out of range ...
// if the values before also already failed the criterion but the max allowed number of such fails is not reached ... just increase the counter.
if(failed_offsets < MAX_ALLOWED_FAILED_OFFSETS){
failed_offsets++;
}
else{
// if the values before also already failed the criterion AND the max allowed number of such fails is reached ... we need to restart the mean calculation and set the timer to unready state ...
Serial.print(F("TopStation BaseStation are out off sync. Offset calculation will be restarted. Last "));
Serial.print(MAX_ALLOWED_FAILED_OFFSETS);
//offset "));
Serial.print(current_time_offset);
Serial.print("is to far from the mean offset ");
Serial.println( abs(current_time_offset - mean_time_offset) );
Serial.print(F(" is more than the allowed: "));
Serial.print(MAX_DIFFERENCE_OFFSET_MS);
Serial.print(F(" compared to the mean offset: "));
Serial.println(mean_time_offset);
counter_time_offset = 0;
sum_time_offset = 0;
mean_time_offset = 0;
failed_offsets = 0;
}
}
}
}
void update_statemessage(timer_state_e timer_state){ void update_statemessage(timer_state_e timer_state){
switch(timer_state){ switch(timer_state){
@ -506,8 +526,7 @@ void update_screen(timer_state_e state){
} }
} }
void set_state_LEDs(timer_state_e state, boolean warn) void set_state_LEDs(timer_state_e state, boolean warn){
{
// set the LEDS corresponding to the state of the timer ... as long as the system is not waiting for input ... // set the LEDS corresponding to the state of the timer ... as long as the system is not waiting for input ...
if(TIMER_WAIT != state){ if(TIMER_WAIT != state){
digitalWrite(READY_LED, LEDStates[state][0]); digitalWrite(READY_LED, LEDStates[state][0]);
@ -524,8 +543,7 @@ void set_state_LEDs(timer_state_e state, boolean warn)
} }
} }
void startSequence(void) void startSequence(void){
{
// set the startime - this is the current time plus the length of this sequence // set the startime - this is the current time plus the length of this sequence
running_time_offset = mean_time_offset; running_time_offset = mean_time_offset;
start_time = millis() + STARTSEQ_LENGTH_MS; start_time = millis() + STARTSEQ_LENGTH_MS;
@ -556,8 +574,7 @@ void startSequence(void)
} }
} }
void failSequence(void) void failSequence(void){
{
// first tone // first tone
tone(PIEZO_PIN, FAILSEQ_TON_FREQUENCY,FAILSEQ_TON_LENGTH_MS ); tone(PIEZO_PIN, FAILSEQ_TON_FREQUENCY,FAILSEQ_TON_LENGTH_MS );
delay(FAILSEQ_TONEPAUSE_MS); delay(FAILSEQ_TONEPAUSE_MS);
@ -567,8 +584,7 @@ void failSequence(void)
noTone(PIEZO_PIN); noTone(PIEZO_PIN);
} }
void false_start_isr(void) void false_start_isr(void){
{
// this is the interrupt routine for the FALSESTART button // this is the interrupt routine for the FALSESTART button
// this will save the time when the runner is really started // this will save the time when the runner is really started
Serial.println("** Interrupt service routine started: false_start_ISR **"); Serial.println("** Interrupt service routine started: false_start_ISR **");