This is a almost done version

Interrupt for STOP implemented - TOP-STATION is based on a state machine now.
This commit is contained in:
Fenoglio 2018-07-24 16:57:35 +02:00
parent 465afd91bc
commit d95ea905f8
2 changed files with 133 additions and 100 deletions

View file

@ -20,7 +20,7 @@ typedef enum {BASESTATION = 0, TOPSTATION} radio_type_e;
typedef struct transcv_struct{ typedef struct transcv_struct{
unsigned long topstationtime; // the top station sends its time (millis()) continously to the base station unsigned long topstationtime; // the top station sends its time (millis()) continously to the base station
unsigned long topbuttonpressedtime; // the top station sends the time in millis() when the button was pressed - this is already the calculated time volatile unsigned long topbuttonpressedtime; // the top station sends the time in millis() when the button was pressed - this is already the calculated time
}transcv_s; }transcv_s;
#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 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.
@ -38,7 +38,7 @@ const uint8_t BUTTONPins[NO_LAST_BUTTON] = {
[BUTTON_FAIL] = 3, // stop button input pin [BUTTON_FAIL] = 3, // stop button input pin
}; };
#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_PRESSED_MS 500 // this defines the time in milliseconds before the button is expected to be pressed again. We do this to avaoid keybouncing
#define PIEZO_PIN 6 // piezo speaker #define PIEZO_PIN 6 // piezo speaker
@ -102,7 +102,7 @@ void failSequence(void);
void wait(unsigned long ms); void wait(unsigned long ms);
void start_isr(void); void start_isr(void);
void update_buttons(void); void update_buttons(void);
void send_values(void);
void stop_isr(void);
#endif #endif

View file

@ -91,6 +91,8 @@ void setup(){
radio.begin(); radio.begin();
radio.setRetries(15, 15); //the first is the time between reties in multiple of 250ms, the second is the numer of attempts radio.setRetries(15, 15); //the first is the time between reties in multiple of 250ms, the second is the numer of attempts
if(stationNumber == TOPSTATION){ if(stationNumber == TOPSTATION){
// Attach the STOP button interrupt
attachInterrupt(digitalPinToInterrupt(BUTTONPins[BUTTON_STOPCANCEL]), stop_isr, FALLING );
// Set the PA Level of the sendin TOP_STATION // Set the PA Level of the sendin TOP_STATION
radio.setPALevel(RF24_PA_LEVEL); radio.setPALevel(RF24_PA_LEVEL);
radio.openWritingPipe(addresses[1]); // Both radios listen on the same pipes by default, but opposite addresses radio.openWritingPipe(addresses[1]); // Both radios listen on the same pipes by default, but opposite addresses
@ -120,113 +122,83 @@ void loop(void) {
blink_on_swiched_at = millis(); blink_on_swiched_at = millis();
blink_on = !blink_on; blink_on = !blink_on;
} }
/****************** Code for the TOPSTATION is here - the stop button is connected to the top station ***************************/
// set state to new_state
if(timer_state != timer_new_state){
Serial.print(millis());
Serial.print("ms : current state:");
Serial.print(timer_state);
Serial.print(" new state:");
Serial.println(timer_new_state);
}
// update button states ...
update_buttons();
/****************** 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. if (stationNumber == TOPSTATION){ // Radio is the top station and sends continously its time and the time the stop button was pressed.
// send data to base_station
send_values();
timer_state = timer_new_state;
if(false == offset_sync_sequence){ // set LEDs
// check for pressed button ... set_state_LEDs(timer_state, false );
if(topbuttonwaspressed == false){
if( (millis() - radio_data.topbuttonpressedtime) > MIN_DELAY_BETWEEN_PRESSED_MS){ switch(timer_state){
// 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 case TIMER_NOCONNECTION:
if(digitalRead(BUTTONPins[BUTTON_STOPCANCEL]) != BUTTON_NOTPRESSED){ // as long as there is no connection to BASE_STATION we will end up here
// button was pressed - store the time if(true == connection_available){
radio_data.topbuttonpressedtime = millis(); timer_new_state = TIMER_INIT;
topbuttonwaspressed = true;
digitalWrite(LEDPins[RUN_LED], LED_ON);
}
} }
} else { offset_sync_sequence = true;
if(digitalRead(BUTTONPins[BUTTON_STOPCANCEL]) == BUTTON_NOTPRESSED){ counter_time_offset = 0;
topbuttonwaspressed = false; break;
digitalWrite(LEDPins[RUN_LED], LED_OFF); case TIMER_INIT:
} if(false == connection_available){
} timer_new_state = TIMER_NOCONNECTION;
} else {
topbuttonwaspressed = false;
digitalWrite(LEDPins[RUN_LED], LED_OFF);
}
// if the button was not pressed only each few second data will be send to BASESTATION ...
if(offset_sync_sequence || 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("senddate_to_base at:");
//Serial.println(millis());
//Serial.print(" -> topstationtime:");
//Serial.print(radio_data.topstationtime);
//Serial.print("ms stoppressedtime:");
//Serial.print(radio_data.topbuttonpressedtime);
//Serial.print("ms offset counter value :");
//Serial.println(counter_time_offset);
// send data ...
if (!radio.write(&radio_data,sizeof(radio_data))){ // Send the counter variable to the other radio
if(((millis() - connection_last_established_at_ms) >= (CONN_TIMEOUT-100)) || (connection_last_established_at_ms == 0)){
connection_available = false;
//Serial.println("Failed to send data to BASESSTATION ... will retry");
digitalWrite(LEDPins[FAIL_LED], LED_ON);
digitalWrite(LEDPins[READY_LED], LED_OFF);
offset_sync_sequence = true;
counter_time_offset = 0;
} else { } else {
if(offset_sync_sequence){ if(false == offset_sync_sequence){
if(counter_time_offset > 0){ if(button_state[BUTTON_STOPCANCEL] == BUTTON_NOTPRESSED){
counter_time_offset--; topbuttonwaspressed = false;
timer_new_state = TIMER_IDLE;
} }
} }
} }
} break;
else case TIMER_IDLE:
{ //check for the pressed button - or better enable the interrupt to handle that
//Serial.print("Data sent to BASESSTATION"); if(false == connection_available){
digitalWrite(LEDPins[FAIL_LED], LED_OFF); timer_new_state = TIMER_NOCONNECTION;
if(offset_sync_sequence){
digitalWrite(LEDPins[FAIL_LED], blink_on);
} else { } else {
digitalWrite(LEDPins[READY_LED], LED_ON); if(true == topbuttonwaspressed){
timer_new_state = TIMER_STOPPED;
}
} }
connection_last_established_at_ms = millis(); break;
connection_available = true; case TIMER_STOPPED:
// check offset sync counter ... // wait a few millis and ... after that go back to idle ...
if(counter_time_offset < (4*REQUIRED_NUMBER_MEANVALS)){ if((signed long)(millis() - radio_data.topbuttonpressedtime) > MIN_DELAY_BETWEEN_PRESSED_MS){
counter_time_offset++; if(button_state[BUTTON_STOPCANCEL] == BUTTON_NOTPRESSED){
} else { timer_new_state = TIMER_IDLE;
// offset sync done topbuttonwaspressed = false;
offset_sync_sequence = false; }
} }
break;
}
} }
//Serial.print("looptime_top ");
//Serial.println(millis());
} }
/****************** 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 ) {
// update button states ...
update_buttons();
// receive data from top_station, calculate offset and set 'last connection' time stamp // receive data from top_station, calculate offset and set 'last connection' time stamp
receive_values(); receive_values();
// update the OLED screen // update the OLED screen
update_screen(timer_new_state); update_screen(timer_new_state);
// set state to new_state
if(timer_state != timer_new_state){
//Serial.print(millis());
//Serial.print("ms : current state:");
//Serial.print(timer_state);
//Serial.print(" new state:");
//Serial.println(timer_new_state);
}
timer_state = timer_new_state; timer_state = timer_new_state;
// set LEDs // set LEDs
@ -238,6 +210,7 @@ void loop(void) {
if(connection_available == true){ if(connection_available == true){
timer_new_state = TIMER_INIT; timer_new_state = TIMER_INIT;
} }
break;
case TIMER_INIT: case TIMER_INIT:
// init the system offset ... // init the system offset ...
if(connection_available == false){ if(connection_available == false){
@ -382,13 +355,16 @@ void loop(void) {
} }
break; break;
} }
//Serial.print("looptime_base ");
//Serial.println(millis());
} }
}
//Serial.print("mean_time_offset ");
//Serial.println(mean_time_offset);
//Serial.print("current_time_offset ");
//Serial.println(current_time_offset);
//Serial.print("looptime ");
//Serial.println(millis());
}
//####################### HELPER FUNCTIONS ########################### //####################### HELPER FUNCTIONS ###########################
void update_buttons(void){ void update_buttons(void){
@ -453,14 +429,16 @@ void receive_values(void){
connection_last_established_at_ms = millis(); connection_last_established_at_ms = millis();
connection_available = true; connection_available = true;
current_time_offset = radio_data.topstationtime - millis(); // the offset between TOP_STATION and BASESTATION 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("Current time on host in millis:");
//Serial.print(" Current time on client in millis: "); Serial.print(millis());
//Serial.println(radio_data.topstationtime); Serial.print(" Current time on client in millis: ");
//Serial.print("Offset is: "); Serial.println(radio_data.topstationtime);
//Serial.println(current_time_offset); Serial.print("Offset is: ");
//Serial.print(" Button was pressed last time on client in millis: "); Serial.println(current_time_offset);
//Serial.println(radio_data.topbuttonpressedtime); Serial.print(" 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 ... // offset calculation ... only needed if the variation is bigger than allowed or not enough values available already ...
if(counter_time_offset == 0){ if(counter_time_offset == 0){
@ -697,7 +675,18 @@ void failSequence(void){
} }
} }
void false_start_isr(void){ void stop_isr(void){
// this is the interrupt routine for the topstation STOP button
// this will save the time when the runner has pushed the button
if(timer_state == TIMER_IDLE){
radio_data.topbuttonpressedtime = millis();
//Serial.print(radio_data.topbuttonpressedtime);
//Serial.println(" ms <- current time ** stop_ISR ** stop button pushed: ");
topbuttonwaspressed = true;
}
}
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
if(timer_new_state != TIMER_READY){ if(timer_new_state != TIMER_READY){
@ -741,3 +730,47 @@ void start_isr(void){
} }
} }
void send_values(void){
if(offset_sync_sequence || 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("senddate_to_base at:");
//Serial.println(millis());
//Serial.print(" -> topstationtime:");
//Serial.print(radio_data.topstationtime);
//Serial.print("ms stoppressedtime:");
//Serial.print(radio_data.topbuttonpressedtime);
//Serial.print("ms offset counter value :");
//Serial.println(counter_time_offset);
// send data ...
if (!radio.write(&radio_data,sizeof(radio_data))){ // Send the counter variable to the other radio
if(((millis() - connection_last_established_at_ms) >= (CONN_TIMEOUT-100))){
connection_available = false;
//Serial.println("Failed to send data to BASESSTATION ... will retry");
} else {
if(offset_sync_sequence){
if(counter_time_offset > 0){
counter_time_offset--;
}
}
}
}
else
{
//Serial.print("Data sent to BASESSTATION");
connection_last_established_at_ms = millis();
connection_available = true;
// check offset sync counter ...
if(counter_time_offset < (4*REQUIRED_NUMBER_MEANVALS)){
counter_time_offset++;
} else {
// offset sync done
offset_sync_sequence = false;
}
}
}
}