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.