Sending data struct from Arduino to Raspberry via NRF24L01

I removed that delay some time ago when I was testing so now payload size is set to size of data delay is gone and here is a screen screen (google drive)

it is clearly a problem with transmission/reception

print out the sizeof(temp) on both the Arduino and pi just in case some padding bytes are being addded

On arduino sizeof(temp) returns 5 bytes and on raspberry it returned 6 bytes.

clearlt the pi compiler is adding an extra byte to get to a 16bit bit boundry
try adding another byte to both, e.g.

typedef struct{
        uint8_t seq;
        uint8_t id;   // debug value
        uint16_t temperature;
        uint8_t spare;
        uint8_t crc;
}
temp;

Now they both return same value of 6 bytes. But still packages wise it is terrible I hope that is only because I'm in home and have one 2,4Ghz WiFi and one 5Ghz but I set NRF channel to 125 as close WiFi channel 14 because it is empty at my place and my 2,4Ghz WiFi is set to some low channel like 8 or so. So I don't think they interfere both devices are maybe 2 meters apart for now. Can this be caused by power supply? In many tutorials I have seen people hooking up 10nF ceramic capacitor and 1uF electrolytic capacitor between Vcc and GND I don't have any ceramic so I connected 10uF electrolytic capacitor but I don't see any difference with and without it

Screen (google drive)

if you run the programs several times do you get identical output?
could you switch off the local WiFi for a short time and see what effect it has?
post latest code

Latest code
Arduino

#include <SPI.h>
#include "RF24.h"
#include <Adafruit_MAX31865.h>

#define RREF      430.0
#define RNOMINAL  100.0

typedef struct{
  uint8_t seq;
  uint8_t id;
  uint16_t temperature;
  uint8_t spare;
  uint8_t crc;
}
temp;

temp data;

unsigned char checksum(unsigned char *data, uint8_t *crc) {
    unsigned char sum=0;
    while(data != crc) {
      sum+=*data;
      data++;
      }
    return sum;
    }

bool radioNumber = 0;
uint8_t i = 0;
Adafruit_MAX31865 thermo[1] = {Adafruit_MAX31865(10 )};
RF24 radio(7,8);

byte addresses[][6] = {"1Node","2Node"};
bool role = 0;

void setup() {
  Serial.begin(115200);
  Serial.print("temp sizeof:  ");
  Serial.println(sizeof(temp));
  thermo[0].begin(MAX31865_3WIRE);
  radio.begin();
  radio.setChannel(125);
  radio.setPALevel(RF24_PA_MIN);
  radio.powerUp();
  radio.setDataRate(RF24_1MBPS);
  radio.setPayloadSize(sizeof(data));
  if(radioNumber){
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  }
  radio.stopListening();
}

void loop() {
    if(i == 255){ i=0; }
    data.seq = i;
    data.id = 3;
    data.temperature = 5; //thermo[0].temperature(RNOMINAL, RREF);
    data.crc = checksum((unsigned char *)&data, &data.crc);    
    //Serial.println(sizeof(temp));
    
    Serial.print("seq:   ");
    Serial.print(data.seq);
    
    Serial.print("  temperature:   ");
    Serial.print(data.temperature);

    Serial.print("  crc:   ");
    Serial.println(data.crc);
    
    if (!radio.write( &data, sizeof(data) )){
        Serial.println(F("failed"));
     }
     delay(1000);
     i++;
}

Raspberry

#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>
#include <RF24/RF24.h>

using namespace std;

typedef struct{
        uint8_t seq;
        uint8_t id;   // debug value
        uint16_t temperature;
        uint8_t spare;
        uint8_t crc;
}
temp;

RF24 radio(22,0);
temp data;

bool radioNumber = 1;
const uint8_t pipes[][6] = {"1Node", "2Node"};

unsigned char checksum(unsigned char *data, unsigned char *crc){
        unsigned char sum = 0;
        while(data != crc){
                sum+=*data;
                data++;
        }
        return sum;
}


int main(int argc, char** argv)
{
    cout << sizeof(temp) << endl;
    radio.begin();
    radio.setChannel(125);
    radio.setPALevel(RF24_PA_MIN);
    radio.setDataRate(RF24_1MBPS);
    radio.setRetries(15, 15);
    radio.setPayloadSize(sizeof(data));
    //cout << sizeof(data) << endl;
    radio.printDetails();
    if (!radioNumber) {
        radio.openWritingPipe(pipes[0]);
        radio.openReadingPipe(1, pipes[1]);
    } else {
        radio.openWritingPipe(pipes[1]);
        radio.openReadingPipe(1, pipes[0]);
    }

    radio.startListening();
    while (1) {
            if (radio.available()) {
                while (radio.available()) {
                    radio.read(&data, sizeof(data));
                    if(checksum((unsigned char *)&data, &data.crc) == data.crc){
                            cout << "CRC OK  ";
                    } else{
                        cout << "CRC ZLE  ";
                    }
                    cout <<"seq " << (int)data.seq << " id: "<< (int)data.id<< " temperatura: " << data.temperature << " crc " << (int)data.crc << endl;
                }

            }


    } // forever loop

    return 0;
}

Running programs multiple times do not change output, but I guess at the moment of writing this post 7:40AM it is slightly better than it was yesterday afternoon, but now almost everyone asleep yet so network traffic is quite low. I could turn off local wifi both 2,4Ghz and 5Ghz or only 2,4G? I’m going to test it today’s afternoon.

when running several times is the output identical, i.e. same frames OK and same frames corrupt, or are the corruptions random ?
if you reduce the data rate does it improve communications?
try increasing the delay() on the Arduino - does it improve communications?

I'm sorry for not making it clear, corruptions are random, reducing data rate does not improve communications neither do increasing delay or changing output power to MAX.

certainly sounds like noise corrupting the frames
have you tried a 10uF capacitor across the NRF24L01 GND and Vcc?
also have look thru

if reception without errors is critical you can add handshaking

  1. the receiver sends an acknowledgement of correct reception (seq and CRC correct) or error.
  2. The transmitter resends a corrupt frame - it will also require a timeout in case a frame is lost completly - you need to check for duplicate frames in case an acknowledgement is lost.

Have you considered WiFi or Bluetooth as the Raspberry pi 3b has these built in. You can make the Raspberry pi a WiFi Access point and use TCP/IP client/server to transfer data.

I tried a couple of NRF24L01 devices today - they appear to be completly dead and I cannot remember if I ever used them - will have to order some more!

Yes I have that capacitor across Vcc and GND I mentioned it in some earlier posts, reception without errors isn't critical I think I can deal with it and only save valid frames. It is only temperaure of smoke so I will be satysfied with 1 or 2 frames per minute and this data will be displayed locally too so this isn't big problem just a minor inconvenience. Thank you for all your help and sorry I bothered you so long!

so long as you have sufficient results to meet the application requirements discarding invalid data should be no problem

  1. if the CRC indicates corrupt frame so discard it
  2. the seq number can be used to determine how may frames are discarded and/or lost

I guess I'm going to do that. Thank you again for so much help. And I'm going to assemble it tomorrow! Solved. Thanks again.

extended your code at add frame count, error count and sequence number check
Arduino transmitter

//  NRF24L10 transmitter

#include <SPI.h>
#include "RF24.h"
//#include <Adafruit_MAX31865.h>

#define RREF      430.0
#define RNOMINAL  100.0

typedef struct{
  uint8_t seq;
  uint8_t id;
  uint16_t temperature;
  uint8_t spare;
  uint8_t crc;
}
temp;

temp data;

unsigned char checksum(unsigned char *data, uint8_t *crc) {
    unsigned char sum=0;
    while(data != crc) {
      sum+=*data;
      data++;
      }
    return sum;
    }

bool radioNumber = 0;
uint8_t i = 0;
//Adafruit_MAX31865 thermo[1] = {Adafruit_MAX31865(10 )};
RF24 radio(7,8);

byte addresses[][6] = {"1Node","2Node"};
bool role = 0;

void setup() {
  Serial.begin(115200);
  Serial.print("temp sizeof:  ");
  Serial.println(sizeof(temp));
   // thermo[0].begin(MAX31865_3WIRE);
   radio.begin();
   if(radio.isChipConnected())Serial.println("Transmitter NF24 connected to SPI");
    else    Serial.println("NF24 is NOT connected to SPI");
    radio.setChannel(125);
    radio.setPALevel(RF24_PA_MIN);
    radio.powerUp(); 
    radio.setDataRate(RF24_1MBPS);
    if(radioNumber){
      radio.openWritingPipe(addresses[1]);
      radio.openReadingPipe(1,addresses[0]);
    }else{
      radio.openWritingPipe(addresses[0]);
      radio.openReadingPipe(1,addresses[1]);
    }
    radio.stopListening();
}

void loop() {
    static int errors=0, frames=0;
    if(i == 255){ i=0; }
     data.id = 3;
    data.temperature = 5; //thermo[0].temperature(RNOMINAL, RREF);
    data.crc = checksum((unsigned char *)&data, &data.crc);   
    Serial.print("Tx Frame: ");   Serial.print(++frames);
    Serial.print(" seq:   ");
    Serial.print(data.seq); 
    Serial.print("  temperature:   ");
    Serial.print(data.temperature);
    Serial.print("  crc:   ");
    Serial.print(data.crc); 
    if (!radio.write( &data, sizeof(data) ))
          { Serial.print(F(" Tx failed ")); Serial.println(++errors); }
     else { Serial.print(" Tx OK! - errorrs "); Serial.println(errors); }
     delay(1000);
   data.seq++;
}

and the Raspberry pi receiver

// Raspberry pi NF24 receiver

// RasPi SCK pin 23 goes to NRF24L10_pin SCK
// RasPi MISO pin 21 goes to NRF24L10_pin MI
// RasPi MOSI pin 19 goes to NRF24L10_pin MO
// RasPi CE0 pin 24 goes to NRF24L10_pin CSN
// RasPi GPIO22 pin 15 goes to NRF24L10_pin CE


#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>
#include "RF24/RF24.h"

using namespace std;

// data structure to transmit
typedef struct{
        uint8_t seq;          //frame sequence number
        uint8_t id;           // debug value
        uint16_t temperature; // data
        uint8_t spare;        // force to 16bit word boundary
        uint8_t crc;          // checksum or crc
}
temp;

RF24 radio(22,0);
temp data;

bool radioNumber = 1;
const uint8_t pipes[][6] = {"1Node", "2Node"};

// calculate 8 bit checksum of data[] - stop at element crc
unsigned char checksum(unsigned char *data, unsigned char *crc){
        unsigned char sum = 0;
        while(data != crc){
                sum+=*data;
                data++;
        }
        return sum;
}


int main(int argc, char** argv)
{
    static uint8_t seq_check=0;
    static int errors=0, frames=0;
    // initialise RF2, check if connected, print details
    radio.begin();
    if(radio.isChipConnected())cout << ("Receiver NF24 connected to SPI") << endl;
    else   cout << ("NF24 is NOT connected to SPI") << endl;
    radio.setChannel(125);
    radio.setPALevel(RF24_PA_MIN);
    radio.setDataRate(RF24_1MBPS);
    radio.setRetries(15, 15);
    radio.printDetails();
    if(!radio.isChipConnected()) return -1;  // failed to connect - stop
    if (!radioNumber) {
        radio.openWritingPipe(pipes[0]);
        radio.openReadingPipe(1, pipes[1]);
    } else {
        radio.openWritingPipe(pipes[1]);
        radio.openReadingPipe(1, pipes[0]);
    }
    // loop waiting for incomming frames
    radio.startListening();
    while (1) {
      if (radio.available()) {
        radio.read(&data, sizeof(data));
        cout << "Rx frame " <<++ frames << " crc: " << (int) data.crc;
        if(checksum((unsigned char *)&data, &data.crc) == data.crc)
                  cout << " CRC OK  ";
             else cout << "CRC ZLE  ";
        cout << " id: " << (int)data.id << " temperature: " << data.temperature 
                  << " seq " << (int) data.seq ;
      if(seq_check == data.seq) cout << " seq OK ";
      else { cout << " seq error! " << (int) seq_check; errors++; }
      cout << " - seq errors " << errors << endl;
      seq_check=++data.seq;
      }
   } // forever loop

    return 0;
}

ran for a few hours without problems

Arduino transmitter output

Transmitter NF24 connected to SPI
Tx Frame: 1 seq:   0  temperature:   5  crc:   8 Tx OK! - errorrs 0
Tx Frame: 2 seq:   1  temperature:   5  crc:   9 Tx OK! - errorrs 0
Tx Frame: 3 seq:   2  temperature:   5  crc:   10 Tx OK! - errorrs 0
Tx Frame: 4 seq:   3  temperature:   5  crc:   11 Tx OK! - errorrs 0
...
Tx Frame: 5118 seq:   253  temperature:   5  crc:   5 Tx OK! - errorrs 0
Tx Frame: 5119 seq:   254  temperature:   5  crc:   6 Tx OK! - errorrs 0
Tx Frame: 5120 seq:   255  temperature:   5  crc:   7 Tx OK! - errorrs 0
Tx Frame: 5121 seq:   0  temperature:   5  crc:   8 Tx OK! - errorrs 0
Tx Frame: 5122 seq:   1  temperature:   5  crc:   9 Tx OK! - errorrs 0
Tx Frame: 5123 seq:   2  temperature:   5  crc:   10 Tx OK! - errorrs 0
...
Tx Frame: 5139 seq:   18  temperature:   5  crc:   26 Tx OK! - errorrs 0
Tx Frame: 5140 seq:   19  temperature:   5  crc:   27 Tx OK! - errorrs 0
Tx Frame: 5141 seq:   20  temperature:   5  crc:   28 Tx OK! - errorrs 0
Tx Frame: 5142 seq:   21  temperature:   5  crc:   29 Tx OK! - errorrs 0
Tx Frame: 5143 seq:   22  temperature:   5  crc:   30 Tx failed 1
Tx Frame: 5144 seq:   23  temperature:   5  crc:   31 Tx failed 2
Tx Frame: 5145 seq:   24  temperature:   5  crc:   32 Tx failed 3
Tx Frame: 5146 seq:   25  temperature:   5  crc:   33 Tx failed 4

at seq number 5143 I switch off the receiver hence the errors

Raspberry pi output

Receiver NF24 connected to SPI
Rx frame 1 crc: 8 CRC OK   id: 3 temperature: 5 seq 0 seq OK  - seq errors 0
Rx frame 2 crc: 9 CRC OK   id: 3 temperature: 5 seq 1 seq OK  - seq errors 0
Rx frame 3 crc: 10 CRC OK   id: 3 temperature: 5 seq 2 seq OK  - seq errors 0
Rx frame 4 crc: 11 CRC OK   id: 3 temperature: 5 seq 3 seq OK  - seq errors 0
Rx frame 5 crc: 12 CRC OK   id: 3 temperature: 5 seq 4 seq OK  - seq errors 0
Rx frame 6 crc: 13 CRC OK   id: 3 temperature: 5 seq 5 seq OK  - seq errors 0
Rx frame 7 crc: 14 CRC OK   id: 3 temperature: 5 seq 6 seq OK  - seq errors 0
Rx frame 8 crc: 15 CRC OK   id: 3 temperature: 5 seq 7 seq OK  - seq errors 0
Rx frame 9 crc: 16 CRC OK   id: 3 temperature: 5 seq 8 seq OK  - seq errors 0
Rx frame 10 crc: 17 CRC OK   id: 3 temperature: 5 seq 9 seq OK  - seq errors 0
Rx frame 11 crc: 18 CRC OK   id: 3 temperature: 5 seq 10 seq OK  - seq errors 0
Rx frame 12 crc: 19 CRC OK   id: 3 temperature: 5 seq 11 seq OK  - seq errors 0
Rx frame 13 crc: 20 CRC OK   id: 3 temperature: 5 seq 12 seq OK  - seq errors 0
...
Rx frame 5116 crc: 3 CRC OK   id: 3 temperature: 5 seq 251 seq OK  - seq errors 0
Rx frame 5117 crc: 4 CRC OK   id: 3 temperature: 5 seq 252 seq OK  - seq errors 0
Rx frame 5118 crc: 5 CRC OK   id: 3 temperature: 5 seq 253 seq OK  - seq errors 0
Rx frame 5119 crc: 6 CRC OK   id: 3 temperature: 5 seq 254 seq OK  - seq errors 0
Rx frame 5120 crc: 7 CRC OK   id: 3 temperature: 5 seq 255 seq OK  - seq errors 0
Rx frame 5121 crc: 8 CRC OK   id: 3 temperature: 5 seq 0 seq OK  - seq errors 0
Rx frame 5122 crc: 9 CRC OK   id: 3 temperature: 5 seq 1 seq OK  - seq errors 0
Rx frame 5123 crc: 10 CRC OK   id: 3 temperature: 5 seq 2 seq OK  - seq errors 0

to test receiver sequence number check the transmitter can the stopped and started several times

I appear to have no problems untill I switch off corresponding transmitter or receiver to force faults

noted that if I went near the wires connection the Arduino and NF24 I immediatly get lots of errors
changing from 1MBPS to 250KBPS

    radio.setDataRate(RF24_250KBPS);

still gives the odd error but no where near the corruption at 1MBPS