nRF24L01 robot joystick problem

Hi.I have a robot with nRF24L01 and a joystick and I have a problem with these 2 codes:

For transmitter: //I use arduino UNO...

/*
  nRF24L01+ Joystick Transmitter
  nrf24l01-joy-xmit-car.ino
  nRF24L01+ Transmitter with Joystick for Robot Car
  Use with Joystick Receiver for Robot Car
  DroneBot Workshop 2018
  https://dronebotworkshop.com
*/

// Include RadioHead ReliableDatagram & NRF24 Libraries
#include <RHReliableDatagram.h>
#include <RH_NRF24.h>

// Include dependant SPI Library 
#include <SPI.h>

// Define Joystick Connections
#define joyVert    A0 
#define joyHorz    A1

// Define Joystick Values - Start at 512 (middle position)
int joyposVert = 512;
int joyposHorz = 512;

// Define addresses for radio channels
#define CLIENT_ADDRESS 1   
#define SERVER_ADDRESS 2

// Create an instance of the radio driver
RH_NRF24 RadioDriver;

// Sets the radio driver to NRF24 and the client address to 1
RHReliableDatagram RadioManager(RadioDriver, CLIENT_ADDRESS);

// Declare unsigned 8-bit motorcontrol array
// 2 Bytes for motor speeds plus 1 byte for direction control
uint8_t motorcontrol[3]; 

// Define the Message Buffer
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];

void setup()
{
  // Setup Serial Monitor
  Serial.begin(9600);
 
  // Initialize RadioManager with defaults - 2.402 GHz (channel 2), 2Mbps, 0dBm
  if (!RadioManager.init())
    Serial.println("init failed");
  
  // Set initial motor direction as forward
  motorcontrol[2] = 0;

}

void loop()
{
  // Print to Serial Monitor
  Serial.println("Reading motorcontrol values ");
  
  // Read the Joystick X and Y positions
  joyposVert = analogRead(joyVert); 
  joyposHorz = analogRead(joyHorz);

  // Determine if this is a forward or backward motion
  // Do this by reading the Verticle Value
  // Apply results to MotorSpeed and to Direction

  if (joyposVert < 460)
  {
    // This is Backward
    // Set Motors backward
    motorcontrol[2] = 1;

    //Determine Motor Speeds
    // As we are going backwards we need to reverse readings
    motorcontrol[0] = map(joyposVert, 460, 0, 0, 255);
    motorcontrol[1] = map(joyposVert, 460, 0, 0, 255);

  }
  else if (joyposVert > 564)
  {
    // This is Forward
    // Set Motors forward
    motorcontrol[2] = 0;

    //Determine Motor Speeds
    motorcontrol[0] = map(joyposVert, 564, 1023, 0, 255);
    motorcontrol[1] = map(joyposVert, 564, 1023, 0, 255); 

  }
  else
  {
    // This is Stopped
    motorcontrol[0] = 0;
    motorcontrol[1] = 0;
    motorcontrol[2] = 0; 

  }
  
  // Now do the steering
  // The Horizontal position will "weigh" the motor speed
  // Values for each motor

  if (joyposHorz < 460)
  {
    // Move Left
    // As we are going left we need to reverse readings
    // Map the number to a value of 255 maximum
    joyposHorz = map(joyposHorz, 460, 0, 0, 255);

    motorcontrol[0] = motorcontrol[0] - joyposHorz;
    motorcontrol[1] = motorcontrol[1] + joyposHorz;

    // Don't exceed range of 0-255 for motor speeds
    if (motorcontrol[0] < 0)motorcontrol[0] = 0;
    if (motorcontrol[1] > 255)motorcontrol[1] = 255;

  }
  else if (joyposHorz > 564)
  {
    // Move Right
    // Map the number to a value of 255 maximum
    joyposHorz = map(joyposHorz, 564, 1023, 0, 255);
  
    motorcontrol[0] = motorcontrol[0] + joyposHorz;
    motorcontrol[1] = motorcontrol[1] - joyposHorz;

    // Don't exceed range of 0-255 for motor speeds
    if (motorcontrol[0] > 255)motorcontrol[0] = 255;
    if (motorcontrol[1] < 0)motorcontrol[1] = 0;      

  }

  // Adjust to prevent "buzzing" at very low speed
  if (motorcontrol[0] < 8)motorcontrol[0] = 0;
  if (motorcontrol[1] < 8)motorcontrol[1] = 0;

  //Display the Motor Control values in the serial monitor.
  Serial.print("Motor A: ");
  Serial.print(motorcontrol[0]);
  Serial.print(" - Motor B: ");
  Serial.print(motorcontrol[1]);
  Serial.print(" - Direction: ");
  Serial.println(motorcontrol[2]);
  
  //Send a message containing Motor Control data to manager_server
  if (RadioManager.sendtoWait(motorcontrol, sizeof(motorcontrol), SERVER_ADDRESS))
  {
    // Now wait for a reply from the server
    uint8_t len = sizeof(buf);
    uint8_t from;
    if (RadioManager.recvfromAckTimeout(buf, &len, 2000, &from))
    {
      Serial.print("got reply from : 0x");
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);
    }
    else
    {
      Serial.println("No reply, is nrf24_reliable_datagram_server running?");
    }
  }
  else
    Serial.println("sendtoWait failed");

  delay(100);  // Wait a bit before next transmission
}

For reciever: //I use arduino MEGA...

/*
  nRF24L01+ Joystick Receiver for Robot Car
  nrf24l01-joy-rcv-car.ino
  nRF24L01+ Receiver and L298N driver for Robot Car
  Use with Joystick Transmitter for Robot Car
  DroneBot Workshop 2018
  https://dronebotworkshop.com
*/

// Include RadioHead ReliableDatagram & NRF24 Libraries
#include <RHReliableDatagram.h>
#include <RH_NRF24.h>

// Include dependant SPI Library
#include <SPI.h>

// Define addresses for radio channels
#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Motor A Connections
int enA = 9;
int in1 = 14;
int in2 = 4;
//int enA = 2;
//int in1 = 32;
//int in2 = 28;

// Motor B Connections
int enB = 5;
int in3 = 7;
int in4 = 6;
//int enB = 3;
//int in3 = 49;
//int in4 = 47;

// Create an instance of the radio driver
RH_NRF24 RadioDriver;

// Sets the radio driver to NRF24 and the server address to 2
RHReliableDatagram RadioManager(RadioDriver, SERVER_ADDRESS);

// Define a message to return if values received
uint8_t ReturnMessage[] = "JoyStick Data Received";

// Define the Message Buffer
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];

void setup()
{
  // Setup Serial Monitor
  Serial.begin(9600);

  // Set all the motor control pins to outputs
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

  // Initialize RadioManager with defaults - 2.402 GHz (channel 2), 2Mbps, 0dBm
  if (!RadioManager.init())
    Serial.println("init failed");
}

void loop()
{
  if (RadioManager.available())
  {
    // Wait for a message addressed to us from the client
    uint8_t len = sizeof(buf);
    uint8_t from;
    if (RadioManager.recvfromAck(buf, &len, &from))

    {

      //Serial Print the values of joystick
      //Serial.print("got request from : 0x");
      //Serial.print(from, HEX);
      //Serial.print(": MotorA = ");
      //Serial.print(buf[0]);
      //Serial.print(" MotorB = ");
      //Serial.print(buf[1]);
      //Serial.print(" Dir = ");
      //Serial.println(buf[2]);

      // Set Motor Direction
      if (buf[2] == 1)
      {
        // Motors are backwards
        digitalWrite(in1, LOW);
        digitalWrite(in2, HIGH);
        digitalWrite(in3, LOW);
        digitalWrite(in4, HIGH);
      } else {
        // Motors are forwards
        digitalWrite(in1, HIGH);
        digitalWrite(in2, LOW);
        digitalWrite(in3, HIGH);
        digitalWrite(in4, LOW);
      }


      // Drive Motors
      analogWrite(enA, buf[1]);
      analogWrite(enB, buf[0]);

      // Send a reply back to the originator client, check for error
      if (!RadioManager.sendtoWait(ReturnMessage, sizeof(ReturnMessage), from))
        Serial.println("sendtoWait failed");
    }
  }
}

But the robot do nothing or many times goes backward or do anything else without my commands...
Here is the link I followed(the wires is correct(as he said)

I am not familiar with the RadioHead library. The examples in this Simple nRF24L01+ Tutorial uses the TMRh20 RF4 library.

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 presume you are aware that the SPI pins are in a different place on the Mega compared to the Uno.

...R

    // Move Right
    // Map the number to a value of 255 maximum
    joyposHorz = map(joyposHorz, 564, 1023, 0, 255);
 
    motorcontrol[0] = motorcontrol[0] + joyposHorz;
    motorcontrol[1] = motorcontrol[1] - joyposHorz;

    // Don't exceed range of 0-255 for motor speeds
    if (motorcontrol[0] > 255)motorcontrol[0] = 255;
    if (motorcontrol[1] < 0)motorcontrol[1] = 0;

Since "motorcontrol" is of type "uint8_t" it cannot be below "0" or above "255" and the code above may cause an unintended "rollover" (eg. 255 + 1 = 0). Consider to change the code to something like:

void loop()
{
  int value;
  ...
  value = motorcontrol[0] + joyposHorz;
  if (value < 0) value = 0;
  else if (value > 255) value = 255;
  motorcontrol[0] = value;
  ...
}

Which will ensure that the rollover is avoided - this has to be done in multiple places, so I would create a function to do the job.

Hello guys...
I found 2 codes for reciever and transmitter (nRF24L01 modules) and the codes are working fine for the robot,but for only few seconds(5-15 seconds).I don't know if there is no enough range or anything else.
I read that the normal range is until 100 meters and the distance between my robot and joystick is 10 meters.
Do you recognize where the problem is ?

code for transmitter:

#include <nRF24L01.h>
#include <RF24.h>
#include<SPI.h>
int X_axis = A0;
int Y_axis = A1;
int Z_axis = 2;
int x = 0;
int y = 0;
int z = 0;
RF24 radio(7, 8);
const byte address[6] = "00001";
const char var1[32] = "up";
const char var2[32] = "down";
const char var3[32] = "left";
const char var4[32] = "right";
const char var5[32] = "ON";
const char var6[32] = "OFF";
boolean light = true;
int thresholdUP = 460;
int thresholdDOWN = 560;
int thresholdLEFT = 460;
int thresholdRIGHT = 560;
void setup()
{
  radio.begin();
  Serial.begin(9600);
  pinMode(X_axis, INPUT);
  pinMode(Y_axis, INPUT);
  pinMode(Z_axis, INPUT);
  digitalWrite(Z_axis, HIGH);
  radio.openWritingPipe(address);
  radio.setChannel(100);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MAX);
  radio.stopListening();
}
void loop()
{
  x = analogRead(X_axis);
  y = analogRead(Y_axis);
  z = digitalRead(Z_axis);
  if (y <= thresholdUP)
  {
    radio.write(&var1, sizeof(var1));
  }
  if (y >= thresholdDOWN)
  {
    radio.write(&var2, sizeof(var2));
  }
  if (x <= thresholdLEFT)
  {
    radio.write(&var3, sizeof(var3));
  }
  if (x >= thresholdRIGHT)
  {
    radio.write(&var4, sizeof(var4));
  }
  if (z == LOW)
  {
    if (light == true)
    {
      radio.write(&var5, sizeof(var5));
      light = false;
      delay(200);
    }
    else
    {
      radio.write(&var6, sizeof(var6));
      light = true;
      delay(200);
    }
  }
}

code for reciever:

#include <nRF24L01.h>
#include <RF24.h>
#include<SPI.h>
RF24 radio(7, 8);
const byte address[6] = "00001";
const char var1[32] = "up";
const char var2[32] = "down";
const char var3[32] = "left";
const char var4[32] = "right";
const char var5[32] = "ON";
const char var6[32] = "OFF";
char input[32] = "";
const int output1 = 13;
const int output2 = 12;
const int output3 = 6;
const int output4 = 9;
const int light = 5;
void setup()
{
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setChannel(100);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MAX);
  radio.startListening();
  pinMode(output1, OUTPUT);
  pinMode(output2, OUTPUT);
  pinMode(output3, OUTPUT);
  pinMode(output4, OUTPUT);
  pinMode(light, OUTPUT);
  digitalWrite(output1, LOW);
  digitalWrite(output2, LOW);
  digitalWrite(output3, LOW);
  digitalWrite(output4, LOW);
  digitalWrite(light, LOW);
}
void loop()
{
  if (!radio.available())
  {
    digitalWrite(output1, LOW);
    digitalWrite(output2, LOW);
    digitalWrite(output3, LOW);
    digitalWrite(output4, LOW);
  }
  radio.read(&input, sizeof(input));
  if ((strcmp(input, var1) == 0))
  {
    digitalWrite(output1, HIGH);
    digitalWrite(output2, LOW);
    digitalWrite(output3, HIGH);
    digitalWrite(output4, LOW);
    delay(10);
  }
  else if ((strcmp(input, var2) == 0))
  {
    digitalWrite(output1, LOW);
    digitalWrite(output2, HIGH);
    digitalWrite(output3, LOW);
    digitalWrite(output4, HIGH);
    delay(10);
  }
  else if ((strcmp(input, var3) == 0))
  {
    digitalWrite(output1, LOW);
    digitalWrite(output2, HIGH);
    digitalWrite(output3, HIGH);
    digitalWrite(output4, LOW);
    delay(10);
  }
  else if ((strcmp(input, var4) == 0))
  {
    digitalWrite(output1, HIGH);
    digitalWrite(output2, LOW);
    digitalWrite(output3, LOW);
    digitalWrite(output4, HIGH);
    delay(10);
  }
  else if ((strcmp(input, var5) == 0))
  {
    digitalWrite(light, HIGH);
  }
  else if ((strcmp(input, var6) == 0))
  {
    digitalWrite(light, LOW);
  }
}

I hope to help me ...

arduiNICK:
I found 2 codes for reciever and transmitter

Oh, boy.....

Each message is 32 bytes long and only a few bytes (6 at most) are actually used - this is inefficient and poorly coded. There is no error control / handling of failed transmissions in either end, one failed transmission and the device is broken.

How can I solve this problem??

Get studying, get coding :slight_smile:

EDIT: Btw, the assembly / wiring shown in your first link does not include a (stabilizing) capacitor for the radios - this may also be an issue.

What kind of capacitor can I use?(Farads)
The pinouts of capacitor is GND and 5V ?
How a capacitor increase the range?

Thanks...

arduiNICK:
What kind of capacitor can I use?(Farads)
The pinouts of capacitor is GND and 5V ?
How a capacitor increase the range?

22 uF and up, yes, it doesn't.

With the capacitor ,will I fix my problem?? Because my problem is that when I use the joystick ,robot move ,but for few minutes...

It won't make your problems worse.

I always use one with nRF24.

I will try it. If it is not gonna work ,what can I do?

Do you have any link about nRF24L01 joystock and robot??
Thanks!!!

The capacitor will ensure that the radio's always have stable power and that they do not fail due to a "brown out". If unstable power is your problem, then the capacitors may be a fix. Capacitors are not gonna fix the issues with the code, though.. Using maximum PA level may also be a problem if the distance between the trancievers is small.

arduiNICK:
Do you have any link about nRF24L01 joystock and robot??

Why are you so declined to write the code your self? You may actually learn something valueable from that process..

Any way,thank you!!! :slight_smile:

Hello.
I used 10uf 16V capacitors in nRF24L01 modules
I also used 22uf 16V ,but the signal of 2 modules is worse than without capacitors...

What can I do?? :frowning:

ANY HELP GUYS!!!

Have you tried the first example in the link in Reply #1 ?

...R

It works with 10uf... :slight_smile:
I didn't connect it directly to module....

Good to hear you have a solution.

...R