Arduino NRF24L01 to UART

Board arduino uno.
On arduino uno RX pin is always taking some data from somewhere. And redirecting it to other device over TX pin. At same time I want to send the received data over RX to other arduino wirelessly over NRF24L01. But when I use only UART RX TX there is nor problem. When I use only NRF24L01 there is no problem. But when use both of them at same time each data stream slowing observable.

At the end of this topic Robin states he can doing this. Robin can you help me :slight_smile: ?

My UART code is that

#include <string.h>
#include <SPI.h>
#include "printf.h"
#include "RF24.h"
#define IBUS_BUFFSIZE 32    // Max iBus packet size (2 byte header, 14 channels x 2 bytes, 2 byte checksum)
#define IBUS_MAXCHANNELS 10 // My TX only has 10 channels, no point in polling the rest

static uint8_t ibusIndex = 0;
static uint8_t ibus[IBUS_BUFFSIZE] = {0};
static uint16_t rcValue[IBUS_MAXCHANNELS];

static boolean rxFrameDone;

void setup() 
{
  Serial.begin(115200); 
  Serial.println("setup done!");
}

void loop() 
{
  readRx();
}

void readRx()
{
  rxFrameDone = false;
  
  if (Serial.available())
  {
    uint8_t val = Serial.read();
    // Look for 0x2040 as start of packet
    if (ibusIndex == 0 && val != 0x20)
    {
      ibusIndex = 0;
      return;
    }
    if (ibusIndex == 1 && val != 0x40) 
    {
      ibusIndex = 0;
      return;
    }

    if (ibusIndex == IBUS_BUFFSIZE)
    {
      ibusIndex = 0;
      int high=3;
      int low=2;
      for(int i=0;i<IBUS_MAXCHANNELS; i++)
      {
        //left shift away the first 8 bits of the first byte and add the whole value of the previous one
        rcValue[i] = (ibus[high] << 8) + ibus[low];
        Serial.print(rcValue[i]);
        Serial.print("     ");
        high += 2;
        low += 2;
      }
      Serial.println();
      rxFrameDone = true;
      return;
    }
    else
    {
      ibus[ibusIndex] = val;
      ibusIndex++;
    }
  }
}

I want to sen each byte to ground over NRF24L01. I tried to add by using a lot of way but anyone worked so I'm sharing the original code whic should be change.
Code source:

In summary:
I'm takin IBUS packet from receiver. And sending them to flight controller. This is okay. Now I want to send IBUS packet at same time to other arduino over NRF24L01.
My first post sorry for any fault. Have a nice day.

I see no try to send or receive anything with the NRF.

If the iBus packets are all 32 bytes or fewer,
you could just send them as a single packet.

First of all thanks for your reply. Yes you are right there is not spi part in this code. This is only IBUS handler. I'm trying to integrate SPI to this. But due to there is no notable try I mentioned original code directly.

My main purpose is that.I There is a drone.And while flying with transmitter I want to sent used IBUS packets during flight to ground station. And after next part of the project I'm planning to use this saved IBUS packets to perform same flight autonomously.

Actually my main problem is that
When I only read from Arduino UNO RX(connected to receiver) and write it to TX(connected to flight controller) flight controller reacting to commands properly. Because I'm setting Serial baud rate 115200. My receiver baud rate is also 115200. And Flight controller baud rate is 115200 too. So everything can communicating without problem.

But when I want to send IBUS packets to ground station(NRF) from arduino(NRF) at same time ie:

uint8_t val = Serial.read();//Read from receiver(Arduino RX)
Serial.write(val);//Sent to flight controller(Arduino TX)
const char text[] = "H";//H only for example. I will send val variable to ground 
      radio.stopListening();
      radio.write(&text, sizeof(text),0,1);//Sent to ground over NRF.
      radio.startListening();
      ibusIndex++;

While doing this,spi send part taking too much time for flight controller so transmit rate to flight controller over arduino TX not enough. And drone note reacting to commands unlike first situation(Read from rx and write it to tx). So I guess I should find true usage of spi write process. To decrease latency. I'm looking tmrh20 library functions. There is different writing functions like startFastWrite, fastWrite etc. I'm still trying them. If you can explain writing process with more detail it could be very well. Or should I look for interrupt parts ? Thanks. I hope I was able to explain clearly. Hava a nice day.

What strange type of write/library is a 4 parameter version?

Do you receive via the NRF?

Sorry I was tried startFastWrite() function from library. There should have been 3 parameters. By the way with this way:

ibus[ibusIndex] = val;
      Serial.write(val);
      const char text[] = "H";
      //radio.stopListening();
      radio.startFastWrite(&text, sizeof(text),0,1);
      //radio.startListening();

Setup part:

{
  radio.begin();
  radio.setPALevel(RF24_PA_LOW);  // RF24_PA_MAX is default.
  radio.openWritingPipe(address[0]);     // always uses pipe 0
  radio.setDataRate(RF24_2MBPS);
  radio.stopListening();
  Serial.begin(115200); 
  Serial.println("setup done!");
}

Flight controller started to reacting to commands. But It doesn't seem as safe
and reliable connection.There is no retries no ack etc.
As I understand SPI is faster than uart. While I' using only SPI I can using 2MBPS speed. So I tought that I can use SPI and UART in turn like 1 spi send - 1 uart send-1spi send-1 uart send... with reliable methods. You think is it possible ? Or not due to latency problem in my case.

Whandall thank you so much now I tried to send and receive 32 byte (1 packet) at same time as you said in your first reply and it worked very well. Even with normal write function without disabled ack. Actually I was performing this with raspberry too. Ant there I was sending and receiving one byte at a time. So I focused on it and trying only 1 byte sending/receiving for a few day :smiley: . I want to try some other thing before close the topic. I hope it really worked as I think :slight_smile: I will share final results. Thanks again.

You were sending and receiving 32 bytes all the time,
because you did not enable dynamic payloads and left the default set to 32 bytes fixed.

I would use acks and retries all the time.
Without acks you don't have a clue whether your packet made it.
The ack can also be used to pass some data back within the same transaction,
so that can be handy too.

So arduino first writing coming bytes to buffer until 32 byte complete and send all of them at same time ? I looked for payload size topic and I thought different. Because I was sending the received byte to ground after each serial read process. At this point you are right sending payload size is 32 byte but only first byte was including my data rest of it filling with zero automatically as I understand from library explanation . So I guess by running sending process after a packet created fully(An IBUS packet is 32 byte) I saved the lost time as I mentioned. If there is a different situation could you please give some details or referances about payload size? But if my guess is right I have another question: If as I said I was sending "1 byte received packet + 31 byte zeros" is there a difference between sending zero or 1 byte data? Both of them using sources equally?Not only for NRF, for general situations sending zero data keep the system busy? By the way system working now I'm trying a few different process,after that I hope I will share the results for other people. Thanks again.

If you want to transfer serial data, a buffer would be useful, the closer you get to 32 byte data,
the less relative overhead you have.
Or, if you want to send a block of data, just send a packet containing the whole block in one packet.
There is no benefit from adding zeros to pad the packet, it just takes longer to transmit.

You can not send zero byte data IIRC.