Improved failure handling, especially in radio.
This commit is contained in:
		@@ -62,7 +62,7 @@ void Display::begin(void) {
 | 
			
		||||
  setLargeTextSize();
 | 
			
		||||
  u8g2.drawStr(0,16,"Booting FastClock");
 | 
			
		||||
  u8g2.sendBuffer();
 | 
			
		||||
  delay(200);
 | 
			
		||||
  delay(400);
 | 
			
		||||
  //addLogMessage("Display initialized");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -141,7 +141,6 @@ void Display::showDashboard(void) {
 | 
			
		||||
    lastBlinkChange_ms = lastDisplayUpdate_ms;
 | 
			
		||||
    blinkOnCycle = !blinkOnCycle;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  u8g2.clearBuffer();
 | 
			
		||||
  u8g2.setDrawColor(1);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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_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;
 | 
			
		||||
 | 
			
		||||
//flag for saving data
 | 
			
		||||
@@ -230,6 +230,7 @@ void checkForPowerOffRequest() {
 | 
			
		||||
    }
 | 
			
		||||
    if (millis() - powerOffButtonPressed_ts > 2000) {
 | 
			
		||||
      // pressed for longer than 2 seconds, now turn off
 | 
			
		||||
      Serial.println(F("OFF"));
 | 
			
		||||
      ESP.deepSleep(ESP.deepSleepMax());
 | 
			
		||||
      delay(200);
 | 
			
		||||
    }
 | 
			
		||||
@@ -266,8 +267,20 @@ void loop(void)
 | 
			
		||||
    #endif
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  fastclock.loop();
 | 
			
		||||
  radio.loop();
 | 
			
		||||
  display.showDashboard();
 | 
			
		||||
  // we do not want to call every task on every cycle:
 | 
			
		||||
  switch (millis() & 0x03) {
 | 
			
		||||
    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 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];
 | 
			
		||||
 | 
			
		||||
#define MAX_CLIENTS_MANAGED 20
 | 
			
		||||
static uint8_t numberOfKnownClients = 0;
 | 
			
		||||
static struct {
 | 
			
		||||
  uint8_t clientNetworkAddress;
 | 
			
		||||
  char clientName[MAX_CLIENT_NAME_LEN];
 | 
			
		||||
  char clientName[MAX_CLIENT_NAME_LEN+1];
 | 
			
		||||
} client[MAX_CLIENTS_MANAGED];
 | 
			
		||||
static uint8_t nextClientNetworkAddress = 1;
 | 
			
		||||
 | 
			
		||||
void Radio::switchToSenderRole(void)
 | 
			
		||||
{
 | 
			
		||||
  Serial.println("*** changing to Tx role");
 | 
			
		||||
  rf24.openWritingPipe(addresses[1]);
 | 
			
		||||
  rf24.openReadingPipe(1,addresses[0]);
 | 
			
		||||
  rf24.stopListening();
 | 
			
		||||
  role = inTX;                  // Become the primary transmitter (ping out)
 | 
			
		||||
void Radio::checkRadioFailure(void) {
 | 
			
		||||
  if (rf24.failureDetected) {
 | 
			
		||||
    Serial.println(F("Radio failure detected!"));
 | 
			
		||||
    rf24.failureDetected = 0;
 | 
			
		||||
    radioInit();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Radio::switchToReceiverRole(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) {
 | 
			
		||||
void Radio::radioInit(void) {
 | 
			
		||||
  display->addLogMessage("Start RF24 radio");
 | 
			
		||||
  pinMode(PIN_NRF24_CSN, OUTPUT);
 | 
			
		||||
  pinMode(PIN_NRF24_CE, OUTPUT);
 | 
			
		||||
 | 
			
		||||
  rf24.begin();
 | 
			
		||||
  if (rf24.isChipConnected()) { display->addLogMessage("*** RF chip found"); }
 | 
			
		||||
  else { display->addLogMessage("*** ERROR: RF chip not found!"); }
 | 
			
		||||
  if (rf24.isChipConnected()) {
 | 
			
		||||
    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.setPALevel(RF24_PA_MAX);
 | 
			
		||||
  rf24.setDataRate(RF24_2MBPS);
 | 
			
		||||
@@ -55,69 +51,103 @@ void Radio::begin(void) {
 | 
			
		||||
  rf24.openWritingPipe(addresses[0]);
 | 
			
		||||
  rf24.openReadingPipe(1, addresses[1]);
 | 
			
		||||
  rf24.startListening();
 | 
			
		||||
  Serial.println("*** Check");
 | 
			
		||||
  //rf24.printDetails();
 | 
			
		||||
  rf24.powerUp();
 | 
			
		||||
  // @TODO: real random seed!
 | 
			
		||||
  //randomSeed(analogRead(0));
 | 
			
		||||
  //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();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
  broadcastMessage(msg, len);
 | 
			
		||||
  Serial.print("# set channel "); Serial.println(clockChannel);
 | 
			
		||||
  Serial.print(F("# set channel ")); Serial.println(clockChannel);
 | 
			
		||||
  rf24.setChannel(clockChannel); // switch back
 | 
			
		||||
  Serial.println("# done");
 | 
			
		||||
  Serial.println(F("# done"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Radio::broadcastMessage(void *msg, int len) {
 | 
			
		||||
  uint8_t *m = (uint8_t *) msg;
 | 
			
		||||
  Serial.print("*** Tx: ts="); Serial.print(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);
 | 
			
		||||
  Serial.print(F("ts=")); Serial.println(millis());
 | 
			
		||||
  switchToSenderRole();
 | 
			
		||||
  Serial.print("#1");
 | 
			
		||||
 | 
			
		||||
  if (!rf24.writeFast(msg, len, true /*multicast*/)) {
 | 
			
		||||
      sendFailedCounter++;
 | 
			
		||||
      Serial.print("*** ERROR: failed to send msg type=");
 | 
			
		||||
      Serial.print(*((char *) msg));
 | 
			
		||||
      Serial.print(" for to=0x");
 | 
			
		||||
      Serial.println(m[1], HEX);
 | 
			
		||||
      Serial.println(F("*** ERROR: failed to send msg"));
 | 
			
		||||
  }
 | 
			
		||||
  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
 | 
			
		||||
  if (millis() - pauseTime > 3) {
 | 
			
		||||
    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
 | 
			
		||||
    //delayMicroseconds(130);     // This gives the PLL time to sync back up
 | 
			
		||||
  }
 | 
			
		||||
  stopTime = millis();
 | 
			
		||||
  Serial.print("stopTime="); Serial.println(stopTime);
 | 
			
		||||
  //stopTime = millis();
 | 
			
		||||
  //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
 | 
			
		||||
  //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
 | 
			
		||||
 | 
			
		||||
  Serial.print("*** send finished, failed="); Serial.println(sendFailedCounter);
 | 
			
		||||
  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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,7 @@ public:
 | 
			
		||||
    clockChannel = DEFAULT_CLOCK_CHANNEL;
 | 
			
		||||
    strncpy(clockName, "defclk", MAX_CLOCK_NAME_LEN);
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  void setClockName(const char *_clockName) {
 | 
			
		||||
    strncpy(clockName, _clockName, MAX_CLOCK_NAME_LEN);
 | 
			
		||||
  };
 | 
			
		||||
@@ -94,13 +94,16 @@ public:
 | 
			
		||||
  void avoidChannelSwitchesFor_ms(unsigned int duration_ms);
 | 
			
		||||
  void listenOnlyFor_ms(unsigned int duration_ms);
 | 
			
		||||
  bool allowedToSendNow(void);
 | 
			
		||||
  void checkRadioFailure(void);
 | 
			
		||||
  void powerDown(void);
 | 
			
		||||
private:
 | 
			
		||||
  Display *display;
 | 
			
		||||
  bool isMaster;
 | 
			
		||||
  void radioInit(void);
 | 
			
		||||
  void switchToSenderRole(void);
 | 
			
		||||
  void switchToReceiverRole(void);
 | 
			
		||||
  bool inTX, inRX, role;
 | 
			
		||||
  char clockName[MAX_CLOCK_NAME_LEN];
 | 
			
		||||
  char clockName[MAX_CLOCK_NAME_LEN+1];
 | 
			
		||||
  void broadcastMessage(void *msg, int len);
 | 
			
		||||
  void broadcastMessageOnChannel(void *msg, int len, uint8_t channel);
 | 
			
		||||
  void broadcastClockAdvertisement(const char *clockName, uint8_t channel);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user