RFM69HCW trigger action when no data recieved

Hi, I have a setup with 2 RFM69HCW modules where I am reading temp/humidity and if a door is open or closed. This works really well over 433Mhz, but what I want to do is trigger an action / display update if the gateway does not receive data from the sender within xx seconds.

Not sure how to do this.

I tried if (radio.!receiveDone()) but I dontthink it supports this.

The problem I have is that if the sender node fails, the OLED display never updates and still displays the last data it received

thanks

my code is below:


// Include the libraries:
#include <RFM69.h>
#include <SPI.h>
#include <RFM69_ATC.h>     //get it here: https://www.github.com/lowpowerlab/rfm69
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Addresses for this node. CHANGE THESE FOR EACH NODE!
#define NETWORKID     0   // Must be the same for all nodes
#define MYNODEID      1   // My node ID
#define TONODEID      2   // Destination node ID

// RFM69 frequency, uncomment the frequency of your module:
#define FREQUENCY   RF69_433MHZ

// AES encryption (or not):
#define ENCRYPT       true // Set to "true" to use encryption
#define ENCRYPTKEY    "1111111111111111" // Use the same 16-byte key on all nodes
#define IS_RFM69HW_HCW  //uncomment only for RFM69HW/HCW! Leave out if you have RFM69W/CW!
#define ENABLE_ATC    //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI      -80

// Use ACKnowledge when sending messages (or not):

// #define USEACK        true // Request ACKs or not

int togglePin = 3;   // Pin for toggle buzzer off
int buzzer = 5; // the number of the Buzzer pin
int DoorOpen;
int toggleButtonState; // the current state of toggle button
int lastButtonState;        // the previous state of button
int toggleState = LOW;     // tracks the current state of toggle, starts low

// Create a library object for our RFM69HCW module:

#ifdef ENABLE_ATC
  RFM69_ATC radio;
#else
  RFM69 radio;
#endif

typedef struct {
    float h;
    float t;
    int DoorOpen;
} Payload;

Payload myData;

void setup()
{
  // Open a serial port so we can send keystrokes to the module:

  Serial.begin(9600);
  Serial.print("Gateway ");
  Serial.print(MYNODEID,DEC);
  Serial.println(" ready");  

  pinMode(togglePin,INPUT);
  digitalWrite(togglePin,HIGH);
  pinMode(buzzer,OUTPUT);
   
  // Initialize the RFM69HCW:
  radio.setCS(10);  //uncomment this if using Pro Micro
  radio.setIrq(2);
  radio.initialize(FREQUENCY, MYNODEID, NETWORKID);
  radio.setHighPower(); // Always use this for RFM69HCW
    radio.setPowerLevel(1); // power output ranges from 0 (5dBm) to 31 (20dBm)
  // Turn on encryption if desired:

  if (ENCRYPT)
    radio.encrypt(ENCRYPTKEY);

#ifdef ENABLE_ATC
  radio.enableAutoPower(ATC_RSSI);
#endif

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  display.clearDisplay();
  display.setTextSize(1); // Draw 2X-scale text
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(14,16);
  display.println(F("Waiting for Data"));
  display.display(); //Display logo
  delay(500); 
  display.clearDisplay();

}

void loop()
{
  // Set up a "buffer" for characters that we'll send:
  static char sendbuffer[62];
  static int sendlength = 0;

  // read the state of the toggle button value:
  lastButtonState = toggleButtonState;     // save the last state
  toggleButtonState = digitalRead(togglePin); // read new state


    if(lastButtonState == HIGH && toggleButtonState == LOW) {
       if(toggleState == LOW) {
        toggleState = HIGH;
      }
      
      else {
      toggleState = LOW;
      }
     }


  // RECEIVING
  if (radio.receiveDone()) // Got one!
  {
    // Print out the information:
    Serial.print("received from node ");
    Serial.print(radio.SENDERID, DEC);
    Serial.print(", message [");

    // The actual message is contained in the DATA array,
    // and is DATALEN bytes in size:

    for (byte i = 0; i < radio.DATALEN; i++)
    Serial.print((char)radio.DATA[i]);

    // RSSI is the "Receive Signal Strength Indicator",
    // smaller numbers mean higher power.

    Serial.print("], RSSI ");
    Serial.println(radio.RSSI);

    // extract and store payload data
    myData = *(Payload*)radio.DATA;

    Serial.print("Humidity=");
    Serial.print(myData.h);
    Serial.println("%");
    Serial.print("Temp=");
    Serial.print(myData.t);
    Serial.println("C");
    Serial.print("DoorOpen=");
    Serial.println(myData.DoorOpen);
    Serial.print(F("ToggleState="));
    Serial.println(toggleState);
 
    // routine for converting temp/hum floats to char arrays
    char temp_buff[5];
    char hum_buff[5];
    char temp_disp_buff[11] = "";
    char hum_disp_buff[11] = "";

    // appending temp/hum to buffers
    dtostrf(myData.t,2,1,temp_buff);
    strcat(temp_disp_buff,temp_buff);
    dtostrf(myData.h,2,0,hum_buff);
    strcat(hum_disp_buff,hum_buff);

     if (myData.DoorOpen == HIGH) {

     display.clearDisplay();
     display.setTextSize(1);             // Normal 1:1 pixel scale
     display.setTextColor(SSD1306_WHITE);        // Draw white text
     display.setCursor(0,0);             // Start at top-left corner
     display.println(F("Temperature"));
    
     display.setTextSize(2);             // Draw 2X-scale text
     display.setTextColor(SSD1306_WHITE);
     display.setCursor(0,16);             // Start at top-left corner
     display.print(temp_disp_buff); display.print((char)247); display.println("C");
    
     display.setTextSize(1);             // Normal 1:1 pixel scale
     display.setTextColor(SSD1306_WHITE);        // Draw white text
     display.setCursor(80,0);             // Start at top-left corner
     display.println(F("Humidity"));
    
     display.setTextSize(2);             // Draw 2X-scale text
     display.setTextColor(SSD1306_WHITE);
     display.setCursor(80,16);             // Start at top-left corner
     display.print(hum_disp_buff); display.println("%");
     display.display();
     }
  
     if (myData.DoorOpen == LOW) {
      
      display.clearDisplay();
      display.setTextSize(2); // Draw 2X-scale text
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(14,12);
      display.println(F("Door Open !"));
      display.display();      // Show initial text
      delay(500);

      display.clearDisplay();
      display.setTextSize(2); // Draw 2X-scale text
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(14,12);
      display.println(F(""));
      display.display();      // Show initial text
      delay(250);
      
      if (toggleState == 0) {
      tone(buzzer, 2600);
      display.clearDisplay();
      display.setTextSize(2); // Draw 2X-scale text
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(14,12);
      display.println(F("Door Open"));
      display.display();      // Show initial text
      delay(100);
      
      noTone(buzzer);
      }

      }
      else {
      // turn buzzer off:
      noTone(buzzer);
      }
    }
 }

So you want to implement an heartbeat check.

  • Define a global unsigned long (or local static) variable to remember the last time you’ve received a message.

  • You update this variable with the value of millis() every time you get a message

  • in the loop - outside the message received code - you check if a timeout occurred

void loop() {
  static unsigned long lastHeartbeat;
  static const unsigned long heartbeatTimeout = 10000ul; // 10 seconds in ms

  if (messageReceived()) {
    lastHeartbeat = millis(); // remember it 
    ... // handle the message
  } else {
    if (millis() - lastHeartbeat > heartbeatTimeout) {
      // something is wrong 
    }
  }

}

Thanks mate, will give it a crack..

Works like a treat !!

Good have fun

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.