Trouble sending a struct data type using the NRF24L01+

Hello,

I am trying to send a voltage and temperature from one Arduino to another. I found a helpful guide Here. I tried to alter the tx code to fit my need but I am getting an adress error and I am not sure why.

tx code:

#include <nRF24L01.h>
#include <SPI.h>
#include <RF24.h>
#include <RF24_config.h>
#include <Wire.h>
#include <Adafruit_MLX90614.h>

#define CE_PIN   9
#define CSN_PIN 10

float temperature_old = 0;
float voltage_old = 0;


RF24 transmit (2,3);                            //create RF24 object called transmit

byte address [5] = “00001”;                     //set address to 00001
int analogInput = A1;                            //set rain sensor to pin 4


//===== Voltage Sensor
int analogInput = A1;
float vout = 0.0;
float vin = 0.0;
float R1 = 30000; //  
float R2 = 7500; // 
float value = 0;



struct package
  {
    float temperature = 0;
    float voltage = 0
  };

typedef struct package Package;
Package data;

void setup() {
  pinMode(analogInput, INPUT);
  transmit.begin();
  transmit.openWritingPipe(address);            //open writing pipe to address 00001
  transmit.setPALevel(RF24_PA_MIN);             //set RF power output to minimum
  transmit.setDataRate(RF24_250KBPS);           //set data rate to 250kbps
  transmit.setChannel(100);                               //set frequency to channel 100
  transmit.stopListening();
               
            
  }

//********************Function****************************************************
float get_voltage()                          //get_rainfall function
{
// read the value at analog input
   value = analogRead(analogInput);
   vout = (value * 5.0) / 1024.0; // for 10 bit ADC on atmega328
   vin = vout / (R2/(R1+R2)); 
   data.voltage = vin;               
}

//*********************************************************************************

void loop() {
  get_voltage();
  data.temperature = mlx.readObjectTempC();
  
  
  if (data.voltage != rainfall_old)               //check variables for changes and transmit updated data
        {
          transmit.write(&data,sizeof(data));         //transmit the data
        }
        else if (data.temperature != temperature_old)
        {
          transmit.write(&data,sizeof(data));         //transmit the data
        }
   
  
  temperature_old = data.temperature;         //update temperature_old to new reading
  voltage_old = data.voltage;               //update rainfall_old to new reading
  
  delay(300);                                 //delay to prevent false rainfall readings

}

byte address [5] = "00001"; //set address to 00001

Why are you trying to put a 5 char text string into a char array with only 5 elements?

Sorry, NO, text strings are required to have a NULL byte (value=0) at the end. It takes 6 bytes to hold 5 text chars and terminator.

What is address used by or for? Addresses are usually numbers not text.

Have a look at the examples in this Simple nRF24L01+ Tutorial

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

Sending a struct will be exactly the same as sending an array.

Referring to Reply #1 ...

I don't know if this style of creating an address works byte address [5] = "00001"; or whether it might actually write a '\0' into the next memory space after the array. If it does, maybe it gets overwritten by the next line int analogInput = A1;.

In any case, the address is used as a byte array rather than a cstring so there is no need for a terminating '\0'

...R

So it's not an address and whoever decided they need a char array buffer doesn't seem to understand what variables are. If they did, they'd stuff the incoming bytes into variables directly.

byte address [5] = "00001"; // will write 6 bytes to RAM, 48 48 48 48 49 0. Lose the zero to analogInput that is a low value int (A1 is a pin) so now the string is 48 48 48 48 49 pin# 0

and the place that 'address' is used in the code I see.....

void setup() { pinMode(analogInput, INPUT); transmit.begin(); transmit.openWritingPipe(address); //open writing pipe to address 00001

So what is that variable doing again?

GoForSmoke: So what is that variable doing again?

Have you had a look at the examples in my tutorial?

The nRF24L01+ devices use 5 byte addresses to identify the recipient of a message. The address is a number, not text, but, of course, you can use characters to make up the number.

...R

Thank you Robin2, I used your simple tx and simple rx code and was able to transmit a float value.

As for the byte address[5] I am not sure. When I looked at other example code the said to make sure the address value matched from the transmitter and receiver. I believe that variable is needed for the library to set the "pipe" for the transceiver. I read that each transceiver can actually act as 6 transmitters/Receivers since it can handle 6 different pipes.

Jack125: As for the byte address[5] I am not sure.

The point being made by @GoForSmoke is how you put data into the array - not the array itself. Have you seen how it is done in my examples?

...R

@Robin2 yes I saw how you did it with letters. I tried to change your simple tx code so it can send a struct data type and got this. It works and sends but the receiver only gets “0.0”

Here is the code I altered.

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


#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[5] = {'R','x','A','A','A'}; // address for master to slave communication


RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

typedef struct {
 char dataToSend[10] = "Hello"; 
 int A = 47;
} data;

data payload;


unsigned long currentMillis; //Millis = Time that has passed since running code
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second


void setup() {

    Serial.begin(9600); //Ensure the baurd rate is the same in the reciever

    Serial.println("SimpleTx Starting");

    radio.begin(); //opening channel 
    radio.setDataRate( RF24_250KBPS ); //setting bandwidth to 250kBps
    radio.setRetries(3,5); // delay, count
    radio.openWritingPipe(slaveAddress); //setting the address for this pipe
}

//====================

void loop() {
    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
        send();
        prevMillis = millis();
    }
}

//====================

void send() {

    bool rslt;
    rslt = radio.write(&payload, sizeof(payload));
        // Always use sizeof() as it gives the size as the number of bytes.
        // For example if dataToSend was an int sizeof() would correctly return 2

    Serial.print("Data Sent ");
    if (rslt) {
        Serial.println("  Acknowledge received");   
    }
    else {
        Serial.println("  Tx failed");
    }
}

Jack125: Here is the code I altered.

You must post the programs for both Arduinos - sending and receiving.

...R