This is a almost done version
Interrupt for STOP implemented - TOP-STATION is based on a state machine now.
This commit is contained in:
parent
465afd91bc
commit
d95ea905f8
2 changed files with 133 additions and 100 deletions
|
@ -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
|
||||||
|
|
223
speedclock.ino
223
speedclock.ino
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in a new issue