Structures sent via NRF24L01 are returning the wrong values to the receiver

I'm developing a system in which I need to send two Structs via an NRF24L01 (Radio Module) from a transmitter to a receiver.
Struct Data has 23 Bytes of memory and VibrationPackage has 27 Bytes, so it would be possible to send them since the Maximum Payload of the NRF24L01 is 32 Bytes.
However, the structures are arriving at the receiver with the wrong values.

Image illustrating the output of the Receiver (RX) and Transmitter (Tx):

I have removed some parts of the code as they were too large to post in full, but if necessary I can edit the post.

Transmitter code:

#include <SoftwareSerial.h>
#include <Wire.h>
#include "FRAM.h"
#include <math.h>

#include <SPI.h>
#include "RF24.h"
#include "EmonLib.h"
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
#include "Adafruit_MCP9808.h"
#include <SoftwareSerial.h>
#include "LowPower.h"

#define DEBUG_LED 9

#define LED_ERROR_RADIO 3
#define LED_ERROR_SENSOR 2
#define LED_SUCCESS 1
#define LED_FAILURE 0

#define SENSOR_KEY "0000A"

RF24 radio(7, 8);

Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified();
Adafruit_MCP9808 tempsensor = Adafruit_MCP9808();

#include "MAX17048.h"

MAX17048 pwr_mgmt;

const byte radio_address[6] = "00006";

FRAM fram;

#define FRAM_I2C_ADDRESS 0x50

#define DATA_TRANSMISSION_PERIOD 60
#define TRANSMISSION_DATA_PACKAGE 5
#define SAMPLES 128

unsigned int sampling_period_us;
unsigned long data_sender_period;

int package_factor = 0;

uint32_t sizeInBytes = 0;

typedef struct{
  char type;  // 'D' para Data
  char key[6];
  float rms[3];
  float temperature;
}Data;
Data data;
typedef struct{
  char type;  // 'P' para VibrationPackage
  char key[6];
  float dataPackage[TRANSMISSION_DATA_PACKAGE];
}VibrationPackage;
VibrationPackage vibrationPackage;
typedef struct {
  float x;
  float y;
  float z;
} Vibration;

void radioSetup() {
  if (!radio.begin()) {
    Serial.println(F("[ERROR] Radio hardware is not responding..."));
    blinkLed(LED_ERROR_RADIO);
    while (1) {}
  }

  radio.setPALevel(RF24_PA_MAX);    // Definir o nível de potência como máximo
  radio.setDataRate(RF24_250KBPS);  // Definir a taxa de dados como 250 kbps
  radio.setChannel(76);             // Definir o canal de comunicação para evitar interferências (escolha um valor entre 0 e 125)
  radio.setRetries(15, 15);         // Definir o número de retransmissões e o atraso entre as tentativas
  radio.setCRCLength(RF24_CRC_16);  // Ativar CRC de 16 bits
  radio.openWritingPipe(radio_address);
  radio.stopListening();
  Serial.println("Radio set on transmitter mode...");
}

void setup() {
  Wire.begin();
  Serial.begin(115200);

  int rv = fram.begin(FRAM_I2C_ADDRESS);
  if (rv != 0) {
    Serial.print("INIT ERROR: ");
    Serial.println(rv);
  }

  radioSetup();

//....
}

//....

unsigned long readMicroseconds;
uint16_t address = 0;

void printDataPackage(Data data) {
  Serial.println("Data:");
  Serial.print("Size: ");
  Serial.print(sizeof(data));  // Imprime o tamanho da struct em bytes
  Serial.println(" Bytes");
  Serial.print("Type: ");
  Serial.println(data.type);
  Serial.print("Key: ");
  Serial.println(data.key);
  Serial.print("RMS: ");
  for (int i = 0; i < 3; i++) {
    Serial.print(data.rms[i]);
    Serial.print(" ");
  }
  Serial.println();
  Serial.print("Temperature: ");
  Serial.println(data.temperature);
}

void printVibrationPackage(VibrationPackage vp) {
  Serial.println("VibrationPackage:");
  Serial.print("Size: ");
  Serial.print(sizeof(vp));  // Imprime o tamanho da struct em bytes
  Serial.println(" Bytes");
  Serial.print("Type: ");
  Serial.println(vp.type);
  Serial.print("Key: ");
  Serial.println(vp.key);
  Serial.print("Data Package: ");
  for (int i = 0; i < TRANSMISSION_DATA_PACKAGE; i++) {
    Serial.print(vp.dataPackage[i]);
    Serial.print(" ");
  }
  Serial.println();
}

int current_package = 0;
void readAndSendFRAMData() {
  if (micros() > (readMicroseconds + data_sender_period)) {
    for (int i = 0 * current_package; i < TRANSMISSION_DATA_PACKAGE; i++) {
      address = i * sizeof(float);
      if (address >= sizeInBytes) {
        //Serial.println("End of FRAM");
        //break;
      }
      //float value = fram.readFloat(address);
      vibrationPackage.dataPackage[0] = 1.0f;
      vibrationPackage.dataPackage[3] = 2.0f;
      vibrationPackage.dataPackage[2] = 3.0f;
    }
    //send Struct
    strncpy(vibrationPackage.key, SENSOR_KEY, sizeof(vibrationPackage.key));

    vibrationPackage.type = 'P';

    radio.write(&vibrationPackage, sizeof(vibrationPackage));
    printVibrationPackage(vibrationPackage);
    Serial.println("Send package");
    readMicroseconds = micros();
    current_package++;
  }
}

void loop() {
  readAndSendFRAMData();

  if (current_package >= package_factor) {
    //Get new Package
    writeVibrationInformation();

    data.temperature = readTemperature();
    strncpy(data.key, SENSOR_KEY, sizeof(data.key));

    data.type = 'D';

    sendData(data);
    printDataPackage(data);

    current_package = 0;
  }
}

bool sendData(Data sendingData) {
  unsigned long start_timer = micros();
  bool report = radio.write(&sendingData, sizeof(sendingData));
  unsigned long end_timer = micros();

  if (report) {
    blinkLed(LED_SUCCESS);
  } else {
    blinkLed(LED_FAILURE);
  }
  return report;
}

Receiver code:

#include <SoftwareSerial.h>
#include "RF24.h"

RF24 radio(7, 8);  // Defina os pinos CE, CSN conforme necessário
const byte radio_address[6] = "00006";

struct Data {
  char type;  // 'D' para Data
  char key[6];
  float rms[3];
  float temperature;
};

struct VibrationPackage {
  char type;  // 'P' para VibrationPackage
  char key[6];
  float dataPackage[TRANSMISSION_DATA_PACKAGE];
};

void setup() {
  Serial.begin(115200);
  
  if (!radio.begin()) {
    Serial.println(F("[ERROR] Radio hardware is not responding..."));
    while (1) {}
  }

  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_250KBPS);
  radio.setChannel(76);
  radio.setCRCLength(RF24_CRC_16);
  radio.openReadingPipe(1, radio_address);
  radio.startListening();
}

void printDataPackage(Data data) {
  Serial.println("Data:");
  Serial.print("Size: ");
  Serial.print(sizeof(data));  // Tamanho da struct em bytes
  Serial.println(" Bytes");
  Serial.print("Type: ");
  Serial.println(data.type);
  Serial.print("Key: ");
  Serial.println(data.key);
  Serial.print("RMS: ");
  for (int i = 0; i < 3; i++) {
    Serial.print(data.rms[i]);
    Serial.print(" ");
  }
  Serial.println();
  Serial.print("Temperature: ");
  Serial.println(data.temperature);
}

void printVibrationPackage(VibrationPackage vp) {
  Serial.println("VibrationPackage:");
  Serial.print("Size: ");
  Serial.print(sizeof(vp));  // Tamanho da struct em bytes
  Serial.println(" Bytes");
  Serial.print("Type: ");
  Serial.println(vp.type);
  Serial.print("Key: ");
  Serial.println(vp.key);
  Serial.print("Data Package: ");
  for (int i = 0; i < TRANSMISSION_DATA_PACKAGE; i++) {
    Serial.print(vp.dataPackage[i]);
    Serial.print(" ");
  }
  Serial.println();
}

void loop() {
  uint8_t pipe;
  if (radio.available(&pipe)) {
    char type;
    radio.read(&type, sizeof(type));

    if (type == 'D') {
      Data data;
      radio.read(&data, sizeof(Data));
      printDataPackage(data);
    } else if (type == 'P') {
      VibrationPackage vp;
      radio.read(&vp, sizeof(VibrationPackage));
      printVibrationPackage(vp);
    }
  }
}

Structs have an initial "type" field, with which I can identify on the receiver which struct was received. What I find strange is that the correct functions are called when the structs arrive at the receiver, i.e. the type field is identified correctly.

Basically the Structs are being printed on the screen with the Default values and not with the values of the Structs sent in the Transmitter.

struct Data{
  char type;  // 'D' para Data
  char key[6];
  float rms[3];
  float temperature;
}data;

if you shorten sketch to minimal required i look further, because now it is not compileable.

It didn't work, I made the necessary changes and that was the answer:

should i answer to you with pictures too?

try packing structures on both ends..

good luck.. ~q

Are you sure you are not reading the data before all of the message has arrived? The serial connection is slow.

What do you think the size of "type" is?

you are reading a char to determine type then you read sizeof(Data) into &data

   char type;
    radio.read(&type, sizeof(type));

    if (type == 'D') {
      Data data;
      radio.read(&data, sizeof(Data));
      printDataPackage(data);
    }

when you have already read a char

possibly read a packet then check the first byte for 'D' etc,
if 'D' copy the packet into the structure, e.g.

      int length = radio.getPayloadSize(); 
      byte packet[32];
      radio.read(&packet, length);

      if (packet[0] == 'D') {
        memcpy(&data, &packet, sizeof(data));
        Serial.print(" bytes temperature:   ");
        Serial.println(data.temperature);
      }
    }
 

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