Improved failure handling, especially in radio.
This commit is contained in:
parent
06b36ed3d0
commit
91653e197f
|
@ -62,7 +62,7 @@ void Display::begin(void) {
|
||||||
setLargeTextSize();
|
setLargeTextSize();
|
||||||
u8g2.drawStr(0,16,"Booting FastClock");
|
u8g2.drawStr(0,16,"Booting FastClock");
|
||||||
u8g2.sendBuffer();
|
u8g2.sendBuffer();
|
||||||
delay(200);
|
delay(400);
|
||||||
//addLogMessage("Display initialized");
|
//addLogMessage("Display initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +141,6 @@ void Display::showDashboard(void) {
|
||||||
lastBlinkChange_ms = lastDisplayUpdate_ms;
|
lastBlinkChange_ms = lastDisplayUpdate_ms;
|
||||||
blinkOnCycle = !blinkOnCycle;
|
blinkOnCycle = !blinkOnCycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8g2.clearBuffer();
|
u8g2.clearBuffer();
|
||||||
u8g2.setDrawColor(1);
|
u8g2.setDrawColor(1);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
// avoid flickering of the display:
|
// avoid flickering of the display:
|
||||||
#define TIME_BETWEEN_DISPLAY_UPDATES_ms 200
|
#define TIME_BETWEEN_DISPLAY_UPDATES_ms 300
|
||||||
#define BLINK_ON_OFF_TIME_ms 1000
|
#define BLINK_ON_OFF_TIME_ms 1000
|
||||||
|
|
||||||
|
|
||||||
|
|
21
src/main.cpp
21
src/main.cpp
|
@ -28,7 +28,7 @@ char static_ip[16] = "10.0.1.56";
|
||||||
char static_gw[16] = "10.0.1.1";
|
char static_gw[16] = "10.0.1.1";
|
||||||
char static_sn[16] = "255.255.255.0";
|
char static_sn[16] = "255.255.255.0";
|
||||||
|
|
||||||
char clockName[MAX_CLOCK_NAME_LEN] = "fastclk";
|
char clockName[MAX_CLOCK_NAME_LEN+1] = "fastclk";
|
||||||
uint8_t clockChannel = DEFAULT_CLOCK_CHANNEL;
|
uint8_t clockChannel = DEFAULT_CLOCK_CHANNEL;
|
||||||
|
|
||||||
//flag for saving data
|
//flag for saving data
|
||||||
|
@ -230,6 +230,7 @@ void checkForPowerOffRequest() {
|
||||||
}
|
}
|
||||||
if (millis() - powerOffButtonPressed_ts > 2000) {
|
if (millis() - powerOffButtonPressed_ts > 2000) {
|
||||||
// pressed for longer than 2 seconds, now turn off
|
// pressed for longer than 2 seconds, now turn off
|
||||||
|
Serial.println(F("OFF"));
|
||||||
ESP.deepSleep(ESP.deepSleepMax());
|
ESP.deepSleep(ESP.deepSleepMax());
|
||||||
delay(200);
|
delay(200);
|
||||||
}
|
}
|
||||||
|
@ -266,8 +267,20 @@ void loop(void)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fastclock.loop();
|
// we do not want to call every task on every cycle:
|
||||||
radio.loop();
|
switch (millis() & 0x03) {
|
||||||
display.showDashboard();
|
case 0:
|
||||||
|
fastclock.loop();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
display.showDashboard();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
yield();
|
||||||
|
radio.loop(); // called always
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
136
src/radio.cpp
136
src/radio.cpp
|
@ -9,43 +9,39 @@ static RF24 rf24(PIN_NRF24_CE, PIN_NRF24_CSN); // 10, 8
|
||||||
static byte addresses[][6] = {NETWORK_ADDRESS_MASTER_SEND, NETWORK_ADDRESS_MASTER_RECEIVE};
|
static byte addresses[][6] = {NETWORK_ADDRESS_MASTER_SEND, NETWORK_ADDRESS_MASTER_RECEIVE};
|
||||||
|
|
||||||
static int sendFailedCounter = 0;
|
static int sendFailedCounter = 0;
|
||||||
static unsigned long stopTime = 0, pauseTime = 0;
|
//static unsigned long stopTime = 0;
|
||||||
|
static unsigned long pauseTime = 0;
|
||||||
static char thisClockName[MAX_CLOCK_NAME_LEN];
|
static char thisClockName[MAX_CLOCK_NAME_LEN];
|
||||||
|
|
||||||
#define MAX_CLIENTS_MANAGED 20
|
#define MAX_CLIENTS_MANAGED 20
|
||||||
static uint8_t numberOfKnownClients = 0;
|
static uint8_t numberOfKnownClients = 0;
|
||||||
static struct {
|
static struct {
|
||||||
uint8_t clientNetworkAddress;
|
uint8_t clientNetworkAddress;
|
||||||
char clientName[MAX_CLIENT_NAME_LEN];
|
char clientName[MAX_CLIENT_NAME_LEN+1];
|
||||||
} client[MAX_CLIENTS_MANAGED];
|
} client[MAX_CLIENTS_MANAGED];
|
||||||
static uint8_t nextClientNetworkAddress = 1;
|
static uint8_t nextClientNetworkAddress = 1;
|
||||||
|
|
||||||
void Radio::switchToSenderRole(void)
|
void Radio::checkRadioFailure(void) {
|
||||||
{
|
if (rf24.failureDetected) {
|
||||||
Serial.println("*** changing to Tx role");
|
Serial.println(F("Radio failure detected!"));
|
||||||
rf24.openWritingPipe(addresses[1]);
|
rf24.failureDetected = 0;
|
||||||
rf24.openReadingPipe(1,addresses[0]);
|
radioInit();
|
||||||
rf24.stopListening();
|
}
|
||||||
role = inTX; // Become the primary transmitter (ping out)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Radio::switchToReceiverRole(void)
|
void Radio::radioInit(void) {
|
||||||
{
|
|
||||||
Serial.println("*** changing to Rx role");
|
|
||||||
rf24.openWritingPipe(addresses[0]);
|
|
||||||
rf24.openReadingPipe(1,addresses[1]);
|
|
||||||
rf24.startListening();
|
|
||||||
role = inRX; // Become the primary receiver (pong back)
|
|
||||||
}
|
|
||||||
|
|
||||||
void Radio::begin(void) {
|
|
||||||
display->addLogMessage("Start RF24 radio");
|
display->addLogMessage("Start RF24 radio");
|
||||||
pinMode(PIN_NRF24_CSN, OUTPUT);
|
pinMode(PIN_NRF24_CSN, OUTPUT);
|
||||||
pinMode(PIN_NRF24_CE, OUTPUT);
|
pinMode(PIN_NRF24_CE, OUTPUT);
|
||||||
|
|
||||||
rf24.begin();
|
rf24.begin();
|
||||||
if (rf24.isChipConnected()) { display->addLogMessage("*** RF chip found"); }
|
if (rf24.isChipConnected()) {
|
||||||
else { display->addLogMessage("*** ERROR: RF chip not found!"); }
|
display->addLogMessage("*** RF chip found");
|
||||||
|
Serial.println(F("*** RF chip found"));
|
||||||
|
} else {
|
||||||
|
display->addLogMessage("*** ERROR: RF chip not found!");
|
||||||
|
Serial.println(F("*** ERROR: RF chip not found!"));
|
||||||
|
}
|
||||||
rf24.setChannel(clockChannel);
|
rf24.setChannel(clockChannel);
|
||||||
rf24.setPALevel(RF24_PA_MAX);
|
rf24.setPALevel(RF24_PA_MAX);
|
||||||
rf24.setDataRate(RF24_2MBPS);
|
rf24.setDataRate(RF24_2MBPS);
|
||||||
|
@ -55,69 +51,103 @@ void Radio::begin(void) {
|
||||||
rf24.openWritingPipe(addresses[0]);
|
rf24.openWritingPipe(addresses[0]);
|
||||||
rf24.openReadingPipe(1, addresses[1]);
|
rf24.openReadingPipe(1, addresses[1]);
|
||||||
rf24.startListening();
|
rf24.startListening();
|
||||||
Serial.println("*** Check");
|
|
||||||
//rf24.printDetails();
|
|
||||||
rf24.powerUp();
|
rf24.powerUp();
|
||||||
// @TODO: real random seed!
|
// @TODO: real random seed!
|
||||||
//randomSeed(analogRead(0));
|
//randomSeed(analogRead(0));
|
||||||
//randomSeed(22);
|
//randomSeed(22);
|
||||||
Serial.print("*** RF payload size="); Serial.print(rf24.getPayloadSize()); Serial.println(" bytes");
|
}
|
||||||
if (rf24.testCarrier() || rf24.testRPD()) { display->addLogMessage("*** Carrier/RPD seen on radio"); }
|
|
||||||
if (rf24.failureDetected) { display->addLogMessage("*** Radio error detected!"); }
|
void Radio::powerDown(void) {
|
||||||
|
rf24.powerDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio::switchToSenderRole(void)
|
||||||
|
{
|
||||||
|
Serial.println(F("# Tx"));
|
||||||
|
rf24.openWritingPipe(addresses[1]);
|
||||||
|
rf24.openReadingPipe(1,addresses[0]);
|
||||||
|
rf24.stopListening();
|
||||||
|
role = inTX; // Become the primary transmitter (ping out)
|
||||||
|
pauseTime = millis();
|
||||||
|
checkRadioFailure();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio::switchToReceiverRole(void)
|
||||||
|
{
|
||||||
|
Serial.println(F("# Rx"));
|
||||||
|
rf24.openWritingPipe(addresses[0]);
|
||||||
|
rf24.openReadingPipe(1,addresses[1]);
|
||||||
|
rf24.startListening();
|
||||||
|
role = inRX; // Become the primary receiver (pong back)
|
||||||
|
checkRadioFailure();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio::begin(void) {
|
||||||
|
display->addLogMessage("Start RF24 radio");
|
||||||
|
pinMode(PIN_NRF24_CSN, OUTPUT);
|
||||||
|
pinMode(PIN_NRF24_CE, OUTPUT);
|
||||||
|
|
||||||
|
radioInit();
|
||||||
|
Serial.print(F("*** RF payload size=")); Serial.print(rf24.getPayloadSize()); Serial.println(F(" bytes"));
|
||||||
|
if (rf24.testCarrier() || rf24.testRPD()) {
|
||||||
|
display->addLogMessage("*** Carrier/RPD seen on radio");
|
||||||
|
Serial.println(F("*** Carrier/RPD seen on radio"));
|
||||||
|
}
|
||||||
|
if (rf24.failureDetected) {
|
||||||
|
display->addLogMessage("*** Radio error detected!");
|
||||||
|
Serial.println(F("*** ERROR: Radio error detected!"));
|
||||||
|
}
|
||||||
|
|
||||||
// Start the radio listening for data
|
|
||||||
//rf24.startListening();
|
|
||||||
switchToReceiverRole();
|
switchToReceiverRole();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Radio::broadcastMessageOnChannel(void *msg, int len, uint8_t channel) {
|
void Radio::broadcastMessageOnChannel(void *msg, int len, uint8_t channel) {
|
||||||
Serial.print("# set channel "); Serial.println(channel);
|
Serial.print(F("# set channel ")); Serial.println(channel);
|
||||||
rf24.setChannel(channel);
|
rf24.setChannel(channel);
|
||||||
broadcastMessage(msg, len);
|
broadcastMessage(msg, len);
|
||||||
Serial.print("# set channel "); Serial.println(clockChannel);
|
Serial.print(F("# set channel ")); Serial.println(clockChannel);
|
||||||
rf24.setChannel(clockChannel); // switch back
|
rf24.setChannel(clockChannel); // switch back
|
||||||
Serial.println("# done");
|
Serial.println(F("# done"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Radio::broadcastMessage(void *msg, int len) {
|
void Radio::broadcastMessage(void *msg, int len) {
|
||||||
uint8_t *m = (uint8_t *) msg;
|
uint8_t *m = (uint8_t *) msg;
|
||||||
Serial.print("*** Tx: ts="); Serial.print(millis());
|
Serial.print(F("ts=")); Serial.println(millis());
|
||||||
Serial.print(", len="); Serial.print(len);
|
|
||||||
Serial.print(", typ=");
|
|
||||||
Serial.print((uint8_t) m[0], HEX); Serial.print(" ("); Serial.print((char) m[0]);
|
|
||||||
Serial.print("), to="); Serial.print((uint8_t) m[1], HEX);
|
|
||||||
Serial.print(", from="); Serial.print((uint8_t) m[2], HEX);
|
|
||||||
Serial.print(", msg="); Serial.print((uint8_t) m[3], HEX);
|
|
||||||
Serial.print(", "); Serial.print((uint8_t) m[4], HEX);
|
|
||||||
Serial.print(", "); Serial.print((uint8_t) m[5], HEX);
|
|
||||||
Serial.print(", "); Serial.print((uint8_t) m[6], HEX);
|
|
||||||
Serial.print(", "); Serial.print((uint8_t) m[7], HEX);
|
|
||||||
Serial.print(", "); Serial.println((uint8_t) m[8], HEX);
|
|
||||||
switchToSenderRole();
|
switchToSenderRole();
|
||||||
Serial.print("#1");
|
|
||||||
if (!rf24.writeFast(msg, len, true /*multicast*/)) {
|
if (!rf24.writeFast(msg, len, true /*multicast*/)) {
|
||||||
sendFailedCounter++;
|
sendFailedCounter++;
|
||||||
Serial.print("*** ERROR: failed to send msg type=");
|
Serial.println(F("*** ERROR: failed to send msg"));
|
||||||
Serial.print(*((char *) msg));
|
|
||||||
Serial.print(" for to=0x");
|
|
||||||
Serial.println(m[1], HEX);
|
|
||||||
}
|
}
|
||||||
Serial.print("ts="); Serial.println(millis());
|
Serial.print(F("ts=")); Serial.println(millis());
|
||||||
//This is only required when NO ACK ( enableAutoAck(0) ) payloads are used
|
//This is only required when NO ACK ( enableAutoAck(0) ) payloads are used
|
||||||
if (millis() - pauseTime > 3) {
|
if (millis() - pauseTime > 3) {
|
||||||
pauseTime = millis();
|
pauseTime = millis();
|
||||||
Serial.print("pauseTime="); Serial.println(pauseTime);
|
Serial.println(F("@TODO: tx-pause"));
|
||||||
//rf24.txStandBy(); // Need to drop out of TX mode every 4ms if sending a steady stream of multicast data
|
//rf24.txStandBy(); // Need to drop out of TX mode every 4ms if sending a steady stream of multicast data
|
||||||
//delayMicroseconds(130); // This gives the PLL time to sync back up
|
//delayMicroseconds(130); // This gives the PLL time to sync back up
|
||||||
}
|
}
|
||||||
stopTime = millis();
|
//stopTime = millis();
|
||||||
Serial.print("stopTime="); Serial.println(stopTime);
|
//Serial.print(F("stopTime=")); Serial.println(stopTime);
|
||||||
//This should be called to wait for completion and put the radio in standby mode after transmission, returns 0 if data still in FIFO (timed out), 1 if success
|
//This should be called to wait for completion and put the radio in standby mode after transmission, returns 0 if data still in FIFO (timed out), 1 if success
|
||||||
//if (!rf24.txStandBy()) { sendFailedCounter += 3; } //Standby, block only until FIFO empty or auto-retry timeout. Flush TX FIFO if failed
|
//if (!rf24.txStandBy()) { sendFailedCounter += 3; } //Standby, block only until FIFO empty or auto-retry timeout. Flush TX FIFO if failed
|
||||||
//radio.txStandBy(1000); //Standby, using extended timeout period of 1 second
|
//radio.txStandBy(1000); //Standby, using extended timeout period of 1 second
|
||||||
|
|
||||||
Serial.print("*** send finished, failed="); Serial.println(sendFailedCounter);
|
|
||||||
listenOnlyFor_ms(MIN_TIME_BETWEEN_TRANSMISSIONS_ms);
|
listenOnlyFor_ms(MIN_TIME_BETWEEN_TRANSMISSIONS_ms);
|
||||||
|
switchToReceiverRole();
|
||||||
|
|
||||||
|
Serial.print(F("*** sent: len=")); Serial.print(len);
|
||||||
|
Serial.print(F(", typ="));
|
||||||
|
Serial.print((uint8_t) m[0], HEX); Serial.print(" ("); Serial.print((char) m[0]);
|
||||||
|
Serial.print(F("), to=")); Serial.print((uint8_t) m[1], HEX);
|
||||||
|
Serial.print(F(", from=")); Serial.print((uint8_t) m[2], HEX);
|
||||||
|
Serial.print(F(", msg=")); Serial.print((uint8_t) m[3], HEX);
|
||||||
|
Serial.print(' '); Serial.print((uint8_t) m[4], HEX);
|
||||||
|
Serial.print(' '); Serial.print((uint8_t) m[5], HEX);
|
||||||
|
Serial.print(' '); Serial.print((uint8_t) m[6], HEX);
|
||||||
|
Serial.print(' '); Serial.print((uint8_t) m[7], HEX);
|
||||||
|
Serial.print(' '); Serial.println((uint8_t) m[8], HEX);
|
||||||
|
Serial.print(F("*** send failed=")); Serial.println(sendFailedCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Radio::broadcastClockAdvertisement(const char *clockName, uint8_t channel) {
|
void Radio::broadcastClockAdvertisement(const char *clockName, uint8_t channel) {
|
||||||
|
|
|
@ -75,7 +75,7 @@ public:
|
||||||
clockChannel = DEFAULT_CLOCK_CHANNEL;
|
clockChannel = DEFAULT_CLOCK_CHANNEL;
|
||||||
strncpy(clockName, "defclk", MAX_CLOCK_NAME_LEN);
|
strncpy(clockName, "defclk", MAX_CLOCK_NAME_LEN);
|
||||||
};
|
};
|
||||||
|
|
||||||
void setClockName(const char *_clockName) {
|
void setClockName(const char *_clockName) {
|
||||||
strncpy(clockName, _clockName, MAX_CLOCK_NAME_LEN);
|
strncpy(clockName, _clockName, MAX_CLOCK_NAME_LEN);
|
||||||
};
|
};
|
||||||
|
@ -94,13 +94,16 @@ public:
|
||||||
void avoidChannelSwitchesFor_ms(unsigned int duration_ms);
|
void avoidChannelSwitchesFor_ms(unsigned int duration_ms);
|
||||||
void listenOnlyFor_ms(unsigned int duration_ms);
|
void listenOnlyFor_ms(unsigned int duration_ms);
|
||||||
bool allowedToSendNow(void);
|
bool allowedToSendNow(void);
|
||||||
|
void checkRadioFailure(void);
|
||||||
|
void powerDown(void);
|
||||||
private:
|
private:
|
||||||
Display *display;
|
Display *display;
|
||||||
bool isMaster;
|
bool isMaster;
|
||||||
|
void radioInit(void);
|
||||||
void switchToSenderRole(void);
|
void switchToSenderRole(void);
|
||||||
void switchToReceiverRole(void);
|
void switchToReceiverRole(void);
|
||||||
bool inTX, inRX, role;
|
bool inTX, inRX, role;
|
||||||
char clockName[MAX_CLOCK_NAME_LEN];
|
char clockName[MAX_CLOCK_NAME_LEN+1];
|
||||||
void broadcastMessage(void *msg, int len);
|
void broadcastMessage(void *msg, int len);
|
||||||
void broadcastMessageOnChannel(void *msg, int len, uint8_t channel);
|
void broadcastMessageOnChannel(void *msg, int len, uint8_t channel);
|
||||||
void broadcastClockAdvertisement(const char *clockName, uint8_t channel);
|
void broadcastClockAdvertisement(const char *clockName, uint8_t channel);
|
||||||
|
|
Loading…
Reference in New Issue