Variable values changed/altered over wireless link (NRF24LO1 + DUE + NANO)

Hello,

I am using an NRF24 transceiver to send data from an Arduino DUE to NAno (unidirectional).

The packet is formatted as a structure :

typedef struct{

  int16_t spd;  
  int32_t time_ms;
  float lon;
  float lat;
  int16_t alt;
  byte seq ; 
  
} BUFFER ; 
BUFFER data ;

The problem is that received data doesn't match sent data as in the picture below.

I am aware that variable types in DUE are different in size from NAno (especially INT & DOUBLE) so I used fixed size types (int32_t , int16_t ..) hoping it would solve the problem.

Also, when I run

sizeof(data)

On NANO, it returns the right size ( 2 x 16 + 32 + 32 x 2 + 8 ) / 8 = 17 bytes.
But on DUE it gives 20 bytes
When I run sizeof for each variable separately it gives the same expected result on both platforms) .

Here is the code on TX (DUE)

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

RF24 radio(7, 10); // CE, CSN
const byte address[6] = "00001";
typedef struct{

  int16_t spd;  
  int32_t time_ms;
  float lon;
  float lat;
  int16_t alt;
  byte seq ; 
  
} BUFFER ; 
BUFFER data ; 
void setup() {

  Serial.begin(9600);
  
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MAX);
  radio.stopListening();

  // Variables sent 
  data.spd = 600; 
  data.time_ms = 360;
  data.lon = 33.43   ; 
  data.lat =  -105.88;  
  data.alt = 7000;
  data.seq = 10;


  /*Serial.print("Size of latitude ");
  Serial.print((sizeof(data.lat)));
  //Serial.print("| Size of speed ");
  //Serial.print((sizeof(data.spd)));
  Serial.print("| Size of time ");
  Serial.print((sizeof(data.time_ms)));
  Serial.print("| Size of sequence ");
  Serial.print((sizeof(data.seq)));
  Serial.print("| Longitude ");
  Serial.print((sizeof(data.lon)));
  Serial.print("| altitude ");
  Serial.println((sizeof(data.alt)));*/
  
  Serial.print("| LAtitude ");
  Serial.println( data.lat, 3);
  Serial.print("| Longitude ");
  Serial.println(data.lon,3);

   
}

void loop() {
radio.write(&data, sizeof(data));
  Serial.print("Sending data | ");
  Serial.print(sizeof(data));
  Serial.println(" Bytes on DUE 32 bit | ");

  
  
 
  delay(1000);


}

The code for RX (Nano)

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";

typedef struct{

  int16_t spd;  
  int32_t time_ms;
  float lon;
  float lat;
  int16_t alt;
  byte seq ; 
  
} BUFFER ; 
BUFFER data ; 
 
 void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MAX);
  radio.startListening();

  

   
 }
void loop() {
  if (radio.available()) {
     radio.read(&data, sizeof(data));
     printdata ();

  }  
}

void printdata ()
{

  Serial.print("Received : ");
  Serial.print(sizeof(data));
  Serial.println(" bytes ");
  Serial.print("| spd = ");
  Serial.println(data.spd);
  Serial.print("| time_ms = ");
  Serial.println(data.time_ms);
  Serial.print("| data.lon = ");
  Serial.println(data.lon);
  Serial.print("| data.lat = ");
  Serial.println(data.lat);
  Serial.print("| data.alt = ");
  Serial.println(data.alt);
  Serial.print("| data.seq = ");
  Serial.println(data.seq);
    Serial.println("*******************************************************************************************");

  
 
}

Thank you in advance for any help / suggestion

you are probably having problems with the alignment of the data types within a struct when implementing for diffent target processors

Not sure if it works on DUE, but this works when i send data from uno to esp32:

struct __attribute__((__packed__)) dataStruct4 {
  int16_t tmp;
  int16_t hum;
  uint32_t counter;
  int16_t volt;
} myData_ht21d;

(only needed on esp32(due) side)

Best of luck!

I confirm that there is an alignement "issue" with structure types. All structures variables are aligned on 4 bytes, i.e. the compiler adds padding, e.g.:

typedef struct {

int16_t var0;
int32_t var1;

} Buffer_Type; is equivalent to :

typedef struct {

int16_t var0;
int16_t Padding;
int32_t var1;
} Buffer_Type;

Thank you for your replies.

So to fix the alignment issue all variables must be same type ?

Knowing that NRF is limited to 32 bytes/packet, I'll be able to send only 8 variables of int32_t / float ?

if I run the following code

typedef struct{
  int16_t spd;  
  int32_t time_ms;
  float lon;
  float lat;
  int16_t alt;
  byte seq ;
} BUFFER ;
BUFFER data ; 
void setup() {
  Serial.begin(115200);
  Serial.println(sizeof(data), DEC);
}

on a Uno I get 17 on a Due I get 20 (I assume the time_ms being on a 32 bit boundary)

changing the struct and using packed

typedef struct __attribute__((__packed__)){
  int16_t spd;  
  int16_t alt;
  int32_t time_ms;
  float lon;
  float lat;
  byte seq ;
} BUFFER ;

both the Uno and Due give me a sizeof() 17

I just tried this fix
It works

Thank you so much