How to save (received) data into a struct using NRF24? [SOLVED]

Hello, I'm trying to send a struct containing floats from one Arduino UNO to another UNO using NRF24 modules. I based my program on nrf2401 with radiohead library problem (SOLVED) . My question is how can I save the received data into a struct (myDataRX) on the receiver Arduino? I don't quite understand what Serial.print(((room*)buf)->temp); is doing.

My transmitter code is as follows:

#include <SPI.h>
#include <RH_NRF24.h>

RH_NRF24 nrf24(8, 7);

struct room{
  float temp;
  float hum;
  float dew;
  float pres;
}; room myDataTX;

void setup() {
  Serial.begin(9600);
  while(!Serial){
    ;
  }
  
  if(!nrf24.init()){
    Serial.println("NRF24 init. failed");
  }
  if(!nrf24.setChannel(1)){
    Serial.println("setChannel failed");
  }
  if(!nrf24.setRF(RH_NRF24::DataRate1Mbps, RH_NRF24::TransmitPower0dBm)){
    Serial.println("setRF failed");
  }
}

void loop() {
  myDataTX.temp = 1.1;
  myDataTX.hum = 2.2;
  myDataTX.dew = 3.3;
  myDataTX.pres = 4.4;
  
  Serial.println("Sending to nrf24_server");

  nrf24.send((uint8_t*)&myDataTX, sizeof(myDataTX));
  nrf24.waitPacketSent();
  
  delay(400);
}

And my receiver code is as follows:

#include <SPI.h>
#include <RH_NRF24.h>

RH_NRF24 nrf24(8, 7);

struct room{
  float temp;
  float hum;
  float dew;
  float pres;
}; room myDataRX;

void setup() {
  Serial.begin(9600);
  while(!Serial){
    ;
  }
  
  if(!nrf24.init()){
    Serial.println("init failed");
  }
  if(!nrf24.setChannel(1)){
    Serial.println("setChannel failed");
  }
  if(!nrf24.setRF(RH_NRF24::DataRate1Mbps, RH_NRF24::TransmitPower0dBm)){
    Serial.println("setRF failed");
  }
}

void loop() {
  if(nrf24.available()){
    uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
    uint8_t len = sizeof(buf);
    
    if(nrf24.recv(buf, &len)){
      Serial.println("got request: ");
      Serial.print(((room*)buf)->temp);
      Serial.print(" ");
      Serial.print(((room*)buf)->hum);
      Serial.print(" ");
      Serial.print(((room*)buf)->dew);
      Serial.print(" ");
      Serial.println(((room*)buf)->pres);

      Serial.println("Now my data: ");
      Serial.print(myDataRX.temp);
      Serial.print(" ");
      Serial.print(myDataRX.hum);
      Serial.print(" ");
      Serial.print(myDataRX.dew);
      Serial.print(" ");
      Serial.println(myDataRX.pres);
    }
    else{
      Serial.println("recv failed");
    }
  }
}

The serial monitor results of the receiver code is:

got request: 
1.10 2.20 3.30 4.40
Now my data: 
0.00 0.00 0.00 0.00

So clearly the received data is not stored in the myDataRX struct, how can I accomplish this?

Maybe this fairly extensively commented RX and TX code is of use. Worked for me, RFM69, but the struct packing and extracting should be similar, as it's also using RadioHead library.

1 Like

I think it is type casting the byte buffer into the elements of the stuct. It is the reverse of casting the struct into bytes with
(byte*)(&myStruct, sizeof(myStruct))

I'm not directly familiar with the nrf24 and the library, but you probably don't need to use a buffer, and can receive directly into the struct

if(nrf24.available()){
    if(nrf24.recv(&myDataRX,sizeof(myDataRX))){
      Serial.println("Now my data: ");
      Serial.print(myDataRX.temp);
      Serial.print(" ");
      Serial.print(myDataRX.hum);
      Serial.print(" ");
      Serial.print(myDataRX.dew);
      Serial.print(" ");
      Serial.println(myDataRX.pres);
    }

If for some reason that does not work and receiving into the buffer is required with the nrf library, you can receive into the buffer, and memcpy the buffer into the struct.

1 Like

Thank you to both @Lagom and @cattledog! I was able to bypass the buffer and directly insert the data into the desired struct.

Referring to the RFM69 code that was shared, the proper syntax is as follows:

if(nrf24.available()){
    uint8_t len = sizeof(myDataRX);
    if(nrf24.recv((uint8_t *)&myDataRX, &len)){
      Serial.println("Now my data: ");
      Serial.print(myDataRX.temp);
      Serial.print(" ");
      Serial.print(myDataRX.hum);
      Serial.print(" ");
      Serial.print(myDataRX.dew);
      Serial.print(" ");
      Serial.println(myDataRX.pres);
    }

The serial monitor confirms that the data is being inserted properly :smiley:

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