RFM69 invalid return code at initialization

Started by Robert, May 20, 2017, 01:04:15 PM

Robert

Hi,

This is probably a small detail, but the initialisation boolean check when a RFM transceiver is not connected or faulty, doesn't work, this because there is no actual check if the transceiver is present or responding before initialisation, most of the time initialisation status returns true.

I came to this issue trying to debug why my RFM transceiver of my gateway was not responding from time to time (once or twice a year).
Currently my solution is to check regularly the status of one RFM register (in my case the  RegOpMode 0x01  that should be in receive mode) and if not I to reinitialise the transceiver.

This workaround works perfectly unless the transceiver is really dead or not present. In this case, any attempt to send data locks the execution of the sketch.

This may not be an issue using a Moteino, because it is useless without RFM transceiver, so it should be repaired anyway. However it is an issue when the transceiver (and the RFM library) is used with other configurations, typically an Arduino with Ethernet shield or a WEMOS.  In this case the Ethernet interface doesn't respond and all subsequents activities is blocked.

So my suggestion is to add a check in the RFM69 library at initialisation time to verify the status of one register, that should have a predefined value. If the transceiver is not present or not responding it is more likely that this value will be 0xFF and a false status shall be returned. In this case it will be possible to actually check the initialisation status to avoid to send data and continue with normal processing.
This small modification will probably not be sufficient if for any reason the transceiver stops responding after a read or send data, but at least it protects the sketch at initialisation time.

Robert

Proposal to modify the RFM69 library:

bool RFM69::initialize(uint8_t freqBand, uint8_t nodeID, uint8_t networkID)
{  
  const uint8_t CONFIG[][2] =
  {
<cut> ......
  digitalWrite(_slaveSelectPin, HIGH);
  pinMode(_slaveSelectPin, OUTPUT);
  SPI.begin();
//!!! ROB Correction for initialisation without RFM installed
  if (readReg(REG_IRQFLAGS1) == 255) return false;
//!!!
  unsigned long start = millis();
  uint8_t timeout = 50;
  do writeReg(REG_SYNCVALUE1, 0xAA); while (readReg(REG_SYNCVALUE1) != 0xaa && millis()-start < timeout);
  start = millis();
  do writeReg(REG_SYNCVALUE1, 0x55); while (readReg(REG_SYNCVALUE1) != 0x55 && millis()-start < timeout);
......

perky


Robert

Perky,

Sorry, I didn't look at that topic.
As mentioned  checking 255 (0xFF) may not be enough if the signals are floating, however it is less probable that the value returned reading the register is equal to 0x80 (so instead of testing == 0xFF it could be modified by !=0x80) .
But I agree, writing and reading back a register is better.
So I will modify my code according to your proposal even if it doesn't guarantee to cover all RFM failures, but probably will cover most of the initialisation issues.
Some extra tests shall be done while sending (reading) messages to avoid the sketch to hang in case of RFM failure. Maybe an improvement for the future ...

Thanks again
Robert
Robert