Slow and weird response from NRF transceivers.

I’ve hooked up a pair of Arduino Unos with NRF 24l01 transceivers and seem to have got them roughly communicating with one another but the response between the two is a little slow and on top of that, the sketch I have used isn’t responding as I thought it would.

My sketch takes a keyboard input from processing into one arduino and allows you to turn an LED on the receiver Uno on and off; however not only is the response slow (it takes a half second to turn on) the led also flashes instead of staying on.

I want to use these for radio control cars in future and so the latency is a problem i want to deal with before implementing that and would appreciate a look at my code to see what’s up.

First the processing code

import processing.serial.*;
//window if required could output battery, altitude speed etc
Serial port;

void setup(){
  size(100,100);
  
  port = new Serial(this, "COM4", 9600);
  port.bufferUntil('\n');
}

void draw(){
  if(keyPressed == true){
    if (key == 'a'){
      port.write("Y");
    }
  }
   else{
      port.write("Z");
   }
  
}

Next the transmitter code

//transmitter
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>

int msg [1];

RF24 radio (9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;

void setup(void){
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(pipe);
}
  

void loop(void){
  if ( Serial.available() > 0) {
  char ch = Serial.read(); // read in a character from the serial port and assign to ch
    
    switch(ch) { // switch based on the value of ch 
       case 'Y': 
           msg[0] = 111;
           radio.write(msg, 1);
        break;
        
       case 'Z': 
           msg[0] = 999;
           radio.write(msg, 1);
        break;
        }
    }
}

And here’s the receiver code

//reciever
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>

#include <SPI.h>

int msg [1];
int led = 6;

RF24 radio (9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;


void setup(void){
  Serial.begin(9600);
  pinMode(led, OUTPUT);
  radio.begin();
  radio.openReadingPipe(1,pipe);
  radio.startListening();
}

void loop(void){
  if (radio.available()){
    bool done = false;
    
    while(!done){
      done = radio.read(msg, 1);
      Serial.println(msg[0]);
       
      if (msg[0] == 111){
        digitalWrite(led, HIGH);
      }
      else{
        digitalWrite(led, LOW);
      }   
    }
  }

}

Apart from the above problems the code works fine so you’re welcome to try it for yourselves.
Cheers in advance for any suggestions

void draw(){
  if(keyPressed == true){
    if (key == 'a'){
      port.write("Y");
    }
  }
   else{
      port.write("Z");
   }
  
}

Piss-poor indenting aside, sending one value when the a is pressed and another value when no key is pressed makes no sense. Processing will be sending a steady stream of Zs.

           radio.write(msg, 1);
        break;
        
       case 'Z': 
           msg[0] = 999;
           radio.write(msg, 1);

An int is NOT one byte. 999 won't fit in a byte, so you are throwing away half of your data.

int msg [1];

A one element array is stupid.

It sounds like the delay is caused by filling up the buffers with useless not pressed messages and then when a pressed message comes along, it takes it's place in the queue and only some time later is it processed.

Okay I seem to have dealt with the weird response with the LED flashing but the response is still about a half second behind the button push.

First off the processing sketch now only fires three signals over serial (three to make sure the data is sent) when a button is pushed or released so this should take care of the backlog of data.

import processing.serial.*;
//window if required could output battery, altitude speed etc
boolean latch = false; 
Serial port;

void setup(){
  size(100,100);
  
  port = new Serial(this, "COM4", 9600);
  port.bufferUntil('\n');
}

void draw(){
}

void keyPressed(){
  if(key =='a'){
    if(latch == false){
      port.write("Y");
      port.write("Y");
      port.write("Y");
      latch = true;
    }
  }
}

void keyReleased() {
  if (key == 'a'){
    port.write("Z");
    port.write("Z");
    port.write("Z");
    latch = false;
  }
}

The transmitter code now sends two sets of data that are within a byte I hope.

//transmitter
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>

int msg [1];


RF24 radio (9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;

void setup(void){
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(pipe);
}
  

void loop(void){
  if ( Serial.available() > 0) {
  char ch = Serial.read(); // read in a character from the serial port and assign to ch
    
    switch(ch) { // switch based on the value of ch 
       case 'Y': 
           msg[0] = 111;
           radio.write(msg, 1);
       break;
        
       case 'Z': 
           msg[0] = 222;
           radio.write(msg, 1);
       break;
        
       default:
       break;
        }
    }
}

And the receiver code waits to receive an off signal for turning the led off rather than requiring constant updates to keep the led on.

//reciever
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>

#include <SPI.h>

int msg [1];
int led = 6;

RF24 radio (9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;


void setup(void){
  Serial.begin(9600);
  pinMode(led, OUTPUT);
  radio.begin();
  radio.openReadingPipe(1,pipe);
  radio.startListening();
}

void loop(void){
  if (radio.available()){
    bool done = false;
    
    while(!done){
      done = radio.read(msg, 1);

       
      if (msg[0] == 111){
        digitalWrite(led, HIGH);
      }
      if(msg[0] == 222){
        digitalWrite(led, LOW);
      }
    }
  }

}

Hope that’s some improvement however the lag is still there, regarding the 1 length array I’m not sure what radio.write is willing to accept as a data type, the notes on the github site claim something along the line of “const voids” which has me sort of lost so for the time being I’m using this as it works.

It’s improving but still slow, are there any other obvious things that would be causing this sketch to lag so much?

int msg [1];

You still have this stupid one element array. Why?

           radio.write(msg, 1);

You are still sending one byte of a two byte variable. Why?

Why isn't msg a scalar variable of type byte?

I used that as the original Sketch that I modified came with this and it's the only way that seems to work so I've stuck with it. I tried inputting bytes and int8_t values into radio.Write but it always came up with an error message about converting byte types to const_voids whenever I tried this .

On top of that I think it's likely I will need to send multiple information at a time if building a radio control car (e.g. throttle amount, direction as well as steering angle and direction) so I will one way or another need to send information from one NRF to another in the form of an array to contain all that information separately.

so I will one way or another need to send information from one NRF to another in the form of an array to contain all that information separately.

I'll respectively disagree with that. You need to send data when you need to send it. Waiting until throttle input is needed to send direction control is silly.

Of course, then you'll need to send two bytes, anyway, to define the type of input and the value. So, it doesn't make a lot of sense to NOT learn how to do that from the beginning.

As for the int vs. byte decision that is biting you in the ass now, I'm still waiting for an explanation of that.

Okay I modified the Sketch and I’m using int8_t for the message array and using values of both 111 and 222 which should both be small enough to fit in a byte i think unless there’s some weird way you have to enter data for int8_t and it is being interpreted wrong.

However the same half second delay is still there and it is definitely at radio.Write, I’ve added an LED to the transmitter arduino that turns on and then off just before and just after radio.Write and it lights up in accordance with the delay (IE the keyboard button is pushed, the transmitter led lights up for a half second and then turns off, at which point the receiver led turns on).

here’s the transmitter

//transmitter
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>

int led = 5;

uint8_t data[2] ; //buffer to store received data
const uint8_t buffer_size = sizeof(data);

RF24 radio (9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;

void setup(void){
  Serial.begin(9600);
  pinMode (led, OUTPUT);
  radio.begin();
  radio.openWritingPipe(pipe);
}
  

void loop(void){
  if ( Serial.available() > 0) {
  char ch = Serial.read(); // read in a character from the serial port and assign to ch
    
    switch(ch) { // switch based on the value of ch 
       case 'Y':
           data[0] = 111;
           digitalWrite(led, HIGH);
           radio.write(data, buffer_size);
           digitalWrite(led, LOW);
       break;
        
       case 'Z': 
           data[0] = 222;
           radio.write(data, buffer_size);
       break;
        
       default:
       break;
        } 
    }
}

and here’s the receiver

//reciever
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>

#include <SPI.h>

uint8_t data[2] ; //buffer to store received data
const uint8_t buffer_size = sizeof(data);

int led = 6;


RF24 radio (9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;


void setup(void){
  Serial.begin(9600);
  pinMode(led, OUTPUT);
  radio.begin();
  radio.openReadingPipe(1,pipe);
  radio.startListening();
}

void loop(void){
  if (radio.available()){
    bool done = false;
    
    while(!done){
      // read the "msg" array for "msgSize" ie the number of bits in the array
      done = radio.read(data, buffer_size);
      
      if (data[0] == 111){
        digitalWrite(led, HIGH);
      }
      if(data[0] == 222){
        digitalWrite(led, LOW);
      }
    }
  }
}

I’m starting to think that this has something more to do with mixing the RF24 library and processing as whenever I use just a simple bush button to determine whether the signal is being sent or not it works absolutely fine, instantaneous reaction from the receiver but when doing it by processing this weird half second delay shows up.

Here’s the code for a push button version that works perfectly well.

//transmitter
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>

int led = 5;
int button = 3;

uint8_t data[2] ; //buffer to store received data
const uint8_t buffer_size = sizeof(data);

RF24 radio (9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;

void setup(void){
  Serial.begin(9600);
  pinMode (button, INPUT);
  pinMode (led, OUTPUT);
  radio.begin();
  radio.openWritingPipe(pipe);
}
  

void loop(void){

  int ch = digitalRead(button);
    
        if (ch == HIGH){
           data[0] = 111;
           digitalWrite(led, HIGH);
           radio.write(data, buffer_size);
        }
        else{
           digitalWrite(led, LOW);
           data[0] = 222;
           radio.write(data, buffer_size);
        } 
    }