Sending a byte via nrf24l01 and then passing it along via wire serial connection

Alright so what I am trying to do should be really straightforward. I have three chips, an attiny84 (chip 1) and two arduino nanos (chips 2 and 3). Chip 1 is connected to an nrf radio, which sends a byte to chip 2 which is also connected to an nrf radio. Chip 2 then passes that byte along to chip 3 via a wired serial connection. That is all.

Sending a byte from chip 1 to chip 2 via nrf works no problem. Sending an arbitrary byte via serial from chip 2 to chip 3 also works no problem.

However, when I try to receive a byte via nrf in chip 2 and then send that specific byte to chip 3, it works only about 1/2 to 1/3 of the time.

Here is a video to show more specifically what I am talking about.

Code for chip 1 left out because of post length limit, but basically it is just sending a byte via nrf.

Code for chip 2, receiving byte via nrf24l01 and passing along via wired serial

#include <Wire.h>
#include "RF24.h"
RF24 radio(9,10);

bool radioNumber      = 0;
byte addresses[][6]   = {"1Node","2Node"};
boolean timeToUpdate  = false;

byte b;

struct dataStruct2{
  float value1 = 1;
  float value2 = 2;
  float value3 = 3;
  float value4 = 4;
  float value5 = 5;
} ackData;

void setup() {

  
  Serial.begin(9600);
  radio.begin();
  bool result = radio.isChipConnected();
  radio.setPALevel(RF24_PA_MIN);
  radio.setAutoAck(1);
  radio.enableAckPayload();                     // Allow optional ack payloads
  radio.setRetries(5, 15);
  radio.setChannel(108);  

  if(radioNumber){
     radio.openWritingPipe(addresses[1]);        // Both radios listen on the same pipes by default, but opposite addresses
     radio.openReadingPipe(1,addresses[0]);      // Open a reading pipe on address 0, pipe 1
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
    radio.openReadingPipe(2,addresses[2]);
  }

  ackData.value1 = 1;
  ackData.value2 = 2;
  ackData.value3 = 3;
  ackData.value4 = 4;
  ackData.value5 = 5;
  radio.startListening();                       // Start listening 

}


void loop() {
  if( radio.available()){
      while (radio.available()) {
        radio.read( &b, sizeof(b) );
      }
      radio.writeAckPayload(1,&ackData, sizeof(ackData));
      timeToUpdate = true;
  }
  if(timeToUpdate) { update(); }
}


void update() { 
  Serial.println(b);
  timeToUpdate = false;
}

Code for chip 3, receiving and printing byte via serial

byte b;

void setup() { 
  Serial.begin(9600); 
}

void loop() {
  if(Serial.available() > 0) {
    b = Serial.read();
    Serial.println(b);
  }
}

You have to write the ack-payload before a packet can be acked with that data.

And your "Sending a byte" does not describe ack-payload in any way.

      while (radio.available()) {
        radio.read( &b, sizeof(b) );
      }

Eat away all packets (that expect an ack-payload) and only process the last seems not very sensible to me.

  Serial.println(b);

sends three bytes

    b = Serial.read();

reads one byte.

Have a look at 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.

The examples are as simple as I could make them and they have worked for other Forum members. If you get stuck it will be easier to help with code that I am familiar with. Start by getting the first example to work

I you get the wireless part working correctly then the serial part should be straightforward.

It would also be a good idea to write a short program that just sends serial data without the complications of the nRF24s. When both parts work separately you can join them together.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

The technique in the 3rd example will be the most reliable. It is what I use for my Arduino to Arduino communication.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

…R

Whandall: You have to write the ack-payload before a packet can be acked with that data.

And your "Sending a byte" does not describe ack-payload in any way.

      while (radio.available()) {
        radio.read( &b, sizeof(b) );
      }

Eat away all packets (that expect an ack-payload) and only process the last seems not very sensible to me.

Not sure what exactly you mean here. This chip is not receiving at ack-payload, just sending one back to the other chip. Anyway, I have never had issues with the nrf communication between two chips, it is only when i involve the third chip that I am trying to relay the information to over a wired serial connection. If I just print out the data from the receiving nrf chip, it is always correct.

Whandall:   Serial.println(b);

sends three bytes

    b = Serial.read();

reads one byte.

Also not sure what you mean here, but it sounds like this could be my issue. Why would serial.println(b) send three bytes/how is that even possible if b is only 1 byte? Note that I only have serial.println(b) in there for the example part where I am showing that the data arrives at chip 2 correctly, when i go to send that data to chip three I change that line to Serial.write(b) (which works when b is hardcoded) or Serial.write(dataByte) (which doesn't work, dataBate is the byte read in via nrf).

Robin2:
I you get the wireless part working correctly then the serial part should be straightforward.

It would also be a good idea to write a short program that just sends serial data without the complications of the nRF24s. When both parts work separately you can join them together.

This is why this is so frustrating!!! I have had the nrfs talking to each other for months, doing all kinds of different things, and they always work, no problem. I am also able to send data between two chips via wired connection, also no problem.

It is ONLY when I send a byte from chip 1 to chip 2 via nrf and then try to pass that SPECIFIC byte to chip 3 with serial.write() that it only works about half the time.

If I receive the data at chip 2 via nrf and then pass some arbitrary data over serial to chip 3, like:

byte b = 55;
Serial.write(b);

That works. There is just something strange happening when I want to pass along the same byte that was read in via nrf over serial.

The video in my original post will more effectively explain, it is hard to type out what is happening using only text.

steveemling: Not sure what exactly you mean here.

You don't know the difference between while and if?

byte b = 123;
Serial.println(b);

This will put out even 5 characters namely 0x31 0x32 0x33 0x0A 0x0D ('1', '2', '3', LF, CR);

If you want to transmit a single char with the value of 123 use

Serial.write(b);

steveemling: This is why this is so frustrating!!! I have had the nrfs talking to each other for months, doing all kinds of different things, and they always work, no problem. I am also able to send data between two chips via wired connection, also no problem.

That is not true.

The very first packet from node 1 did never get the expected ack-payload, you just did not notice the flaw in your program.

Whandall: You don't know the difference between while and if?

byte b = 123;
Serial.println(b);

This will put out even 5 characters namely 0x31 0x32 0x33 0x0A 0x0D ('1', '2', '3', LF, CR);

If you want to transmit a single char with the value of 123 use

Serial.write(b);

I do Serial.write(b). In the code in the post, it is serial.println(b), but that is just to show that it makes it to chip 2. Serial.write(b) does not work to send the byte to chip 3 when it is the same byte received from the nrf. It is hard to understand from just text, but if you watch the video it makes more sense.

Whandall: You don't know the difference between while and if

I think you know that is not what I meant, why go out of your way to say stuff like this?

The code you presented here only uses println(b); I can and will not debug unknown code.

Good luck with your project.

Whandall: The code you presented here only uses println(b); I can and will not debug unknown code.

Good luck with your project.

Well thank you for hijacking the thread with seemingly intentionally unhelpful derogatory comments

I pointed out some errors in the code you presented and tried to help you, sorry that that seems to bother you.

I will not repeat that error.