Hello.
I previously posted here but I just found out the solution is wrong, so once again I need your help investigating this issue
Note that the project has moved to using a pair of raspberry pis (3B and 4) but I'm still posting here because:
- code part is portable and relevant to any arduino mcu
- previous post needs an update
- the RF24 community seems most active in this forum
Here are the details:
- I'm using RF24 from the official repo
- The library examples seem to work correctly, along with the program I was writing in the previous post
- Both pi's are running the same code
- The correct packet is handed over to the radio, wrong bit data is received. It is kind of consistent though
- Radio model is NRF24L01+PA+LNA with the 5V adapter board. Hardware side should be totally sorted for inconsistencies
Peeking into sent/received data bits

Interestingly, if roles are swapped:

The first 17 bytes look identical through multiple tries, while the last ones seem random.
But all bits are off
I uploaded my code and will be walking through it
Settings.h (982 Bytes)
radiohandler.h (1.1 KB)
radiohandler.cpp (4.0 KB)
packetshandler.h (1.5 KB)
packetshandler.cpp (3.7 KB)
tuntaphandler.h (654 Bytes)
tuntaphandler.cpp (5.0 KB)
main.cpp (1.3 KB)
CMakeLists.txt (2.5 KB)
Settings holds the radio settings, the issue are present with any combination I've tried
radiohandler is the radio-program interface class.
Holds the RF24 object and makes sure it is properly working.
How?
- Checks if radio is connected in the loop function, if not, resets it
- When resetting the radio all settings are used and then printed
Receiver pretty settings
Transmitter pretty settings
This class holds the write and read functions and the radiopacket struct:
Note: write and writeFast produces same output
radiopacket* radiohandler::send(radiopacket *rp) {
std::cout << "Packet OUT: " << radioprintchararray((uint8_t*)rp,32);
if (radio->writeFast(&rp, 32)) {
// Not sure what to do with this yet
}
if(radio->txStandBy()){
cout << "Successful\n";
return read();
}else{
cout << "Failed\n";
return nullptr;
}
}
// Checks if radio is connected and returns nullptr if nothing is read
radiopacket* radiohandler::read() {
if (!radio->isChipConnected()) {
resetRadio();
}
// Note: this->data is instanced in the class constructor (data = new radiopacket;), is always reused and never deleted
if (radio->available()) {
radio->read(this->data, 32);
std::cout << "Packet IN: " << radioprintchararray((uint8_t*)data,32);
return data;
}
return nullptr;
}
packetshandler is the class handling the packets to be sent and recomposes the ones received.
Handles the radiopacket queue, then in the loop function hands them over in order to the radiohandler class and deletes the radiopackets after they're sent.
Also reads for incoming radiopackets and recomposes them to a larger message, which then is sent to the system through the c->writeback line
Everything is run from a third class tuntaphandler called from main (handles TUN/TAP I/O)
void tuntaphandler::TunnelThread() {
this->running_ = true;
std::thread t([&] {
uint8_t buffer[mtu + (mtu / 2)];
while (this->running_) {
/* Note that "buffer" should be at least the MTU size of the interface, eg 1500 bytes */
int nread = read(tunnel_fd_, buffer, sizeof(buffer));
if (nread < 0) {
perror("Reading from interface");
close(tunnel_fd_);
exit(1);
}
/* Do whatever with the data */
printf("Read %d bytes from device %s\n", nread, "arocc");
// Commented this out for testing the custom packet shown in the pictures
//pth.handlepacket(nread, buffer);
//write(tunnel_fd_, buffer, nread);
}
});
t.detach();
while (running_) {
// pth refers to the packethandler instance
pth.loop();
}
}
void tuntaphandler::writeback(int size, uint8_t *data) {
int n = write(tunnel_fd_, data, size);
if (n != size) {
cout << "Data written is not the same as sent\n";
}
}
I also attached my CMakeLists.txt for error checking
Thank you

