Using RF24 with interrupts and replies

I am working on a recording barometer (and some other data). There will be a remote data collector and a display controller. Communication between the two is by RF24s.

The logic is this. The display controller sends a wake up signal to the data collector who replies with the current readings. To save power the display controller uses LowPower and SLEEP_FOREVER. The RF24 uses its interrupt to wake up the data collector, who then replies with the data.

This works with a weird anomaly: the reply is always 1 step behind the wake up.

The display sends: "wakeup n".
The collector replies with: "temp,dewpoint,barometer,solarpower,batterystate,wakeup n"
The display says that it received: "temp,dewpoint,barometer,solarpower,batterystate,wakeup n-1"

below is the code I am using.

Can anyone see what I am doing wrong?


```cpp
#include <Wire.h>

#include "LowPower.h"

#include <Adafruit_INA219.h>
#include <math.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(9, 10); // CE, CSN

Adafruit_INA219 ina219(0x040);

Adafruit_BME280 bme;

const byte address[][6] = {"00001", "00002"};
int count = 0;

void setup() {
  Serial.begin(57600);
  // put your setup code here, to run once:
  lcd.begin(20,4);
  lcd.init();
  lcd.backlight();
  lcd.home();
  lcd.clear();

  analogReference(INTERNAL);
  bme.begin(0x76);
  
  ina219.begin();  //
  ina219.setCalibration_16V_400mA();
  
  pinMode(2, INPUT);
  radio.begin();
  radio.setChannel(72); 
  radio.openReadingPipe(0, address[0]);
  radio.openWritingPipe(address[1]);
  radio.setPALevel(RF24_PA_MIN);
  radio.maskIRQ(1,1,0);    //mask all IRQ triggers except for receive (1 is mask, 0 is no mask)
  radio.startListening();
 
}

void loop() {
  // put your main code here, to run repeatedly:
  char text[32] = "";
  String reply;

   radio.startListening();
   lcd.noBacklight();
   attachInterrupt(0, interruptFunction, FALLING);
   LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
   detachInterrupt(0);
   lcd.backlight();
   
//   while(radio.available() & c < 8) 
    if(radio.available() ){
      lcd.clear();
      radio.read(&text, sizeof(text));
      lcd.print(text);
      reply = getData() + "#" + text;
      lcd.setCursor(0,1);
      lcd.print(reply);
      reply.toCharArray(text, reply.length()+5);
      radio.stopListening();
      radio.write(&text, 32 );
   }
   else lcd.print("*");
   count++;if(count == 80) {count = 0;lcd.clear();lcd.setCursor(0,0);}
   delay(2000);


}

void interruptFunction() {}

String getData(){
  float tempC, rh, dewpointC, t, pressure;
  int tempF, dewpointF, power, count;
  String readings = "";
  bool report;

  tempC = bme.readTemperature();
  tempF = int(32 + 1.8 * tempC);
  
  rh = bme.readHumidity();
  t = logf(rh/100) + ((17.625 * tempC) / (243.04 + tempC) );
  dewpointC = (243.04 * t) / 
              (17.625 - t); 
  dewpointF = int(32 + 1.8 * dewpointC);
  
  pressure = 1.07+(0.02953*bme.readPressure()) / 100.0F;
  
  power = int(ina219.getPower_mW());
  power = 150;
  readings = String(tempF) + "," 
           + String(dewpointF) + ","
           + String(pressure) + ","
           + String(power) + ","
           + 5123 ;//int(1 11.5 * analogRead(A0)  ); //battery state

//  readings.toCharArray(payload, 32);
  return readings;
}

`

#include <Wire.h>

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(9, 10); // CE, CSN

const byte address[][6] = {"00001", "00002"};
int count = 0;

void setup() {

Serial.begin(57600);

  lcd.begin(20,4);
  lcd.init();
  lcd.backlight();
  lcd.home();
  lcd.clear();

  radio.begin();
  radio.setChannel(72); 
  radio.openWritingPipe(address[0]);
  radio.openReadingPipe(0, address[1]);
  radio.setPALevel(RF24_PA_MIN, true);
  radio.stopListening();
}
 


void loop() {

  char text[32]; 
  String txt = "wakeup ";

  lcd.clear();
  txt = txt + String(count);
  txt.toCharArray(text, txt.length()+5);
  lcd.setCursor(0,0);
  lcd.print("sending ");lcd.print(count);
  radio.stopListening();
  radio.write(&text, 32);
  radio.startListening();
  
  delay(5);
  if(radio.available()){
    lcd.setCursor(0,1);
    radio.read(&text, 32);
    lcd.print(text);
    Serial.println(text);
   }
    count++;
  delay(5000);

}

Solved. I wasn't waiting long enough for the reply. I inserted the following before getting the data.

while( !radio.available() & c < 10){
delay(10);
c++;
}

1 Like

Sometimes just turning the other way for a short while and the solution comes. Good Job and thanks for letting us know.

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