Struggling to get RC project using nRF24L01 with servos & LED's working

Hi

I am relatively new to Arduino but have already done a number of projects to learn the basics. Over the last month or so I have been trying to create a project using the NRF24L01.

The project is simply taking a lego model car and making it radio control with forward/reverse and steering (servo controlled), reverse buzzer, door opener (servo controlled) front and left and right indicator lights (LED's).

The transmitter consists of:

Nano
nRF24L01 and nRF24L01 adaptor
Voltage Regulator
9V battery
Potentiometer (controls car door)
Joystick (forward/reverse/steering and reverse buzzer)
3 x slide switches (front lights, indicator left lights and indicator right lights)

The receiver consists of:

Nano
nRF24L01 and nRF24L01 adaptor
Voltage Regulator
9V battery
3 servos - forward/reverse, steering, door opener
2 x front light LED's, 2 x left indicator LED's, 2 x right indicator LED's
Reverse buzzer

I have studied many nRF24L01 examples, researched the forum for similar projects and tried writing many sketches, but unfortunately I can't get it working.

Below is a copy of my latest transmit and receive codes that do absolutely nothing. They compile and upload but that's where the action ends. It seems like there is no communication between the transmitter and receiver.

I've tried to simplify it as much as possible, ie no flashing indicators etc (just on or off) until the base code works.

Any help and assistance getting this code working would be very much appreciated. Thanks very much.

/*
  Gerald’s Radio Control Code:
  Transmitter – This code will transmit 6 channels with data as follows:

  NRF24 Pins
  GND -> GND
  Vcc -> 3.3V
  CE -> D9
  CSN -> D10
  CLK -> D13
  MOSI -> D11
  MISO -> D12

  Tx/Rx matching pins
  Throttle A0 to D2
  Steering A1 to D3
  Door Open A2 to D8
  Reverse Buzzer A0 to D4
  Front Lights D2 to D5
  Indicator Left D3 to D6
  Indicator Right D4 to D7
*/

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

struct datapacket {
  byte throttle;
  byte steering;
  byte door;
  byte revbuzzer;
  byte frontlts;
  byte indileft;
  byte indiright;
} State;

RF24 radio(9, 10);    //CE=9, CSN=10

const uint64_t pipe = 0xE8E8F0F0E1LL;

byte frontltsPin = 2;
byte indileftPin = 3;
byte indirightPin = 4;


void setup(void) {
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.openWritingPipe(pipe);
}


void loop(void) {
  State.throttle = map(analogRead(A0), 0, 1023, 0, 255);
  State.steering = map(analogRead(A1), 0, 1023, 0, 255);
  State.door = map(analogRead(A2), 0, 1023, 0, 255);
  State.frontlts = digitalRead(frontltsPin);
  State.indileft = digitalRead(indileftPin);
  State.indiright = digitalRead(indirightPin);

  radio.write(&State, sizeof(State));

}



/*
  Gerald’s Radio Control Code:
  Receiver – This code will receive 6 channels with data as follows:

  NRF24 Pins
  GND -> GND
  Vcc -> 3.3V
  CE -> D9
  CSN -> D10
  CLK -> D13
  MOSI -> D11
  MISO -> D12

  TX/RX Pins
  Throttle A0 to D2
  Steering A1 to D3
  Door Open A2 to D8
  Reverse Buzzer A0 to D4
  Front Lights D2 to D5
  Indicator Left D3 to D6
  Indicator Right D4 to D7
*/

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>

struct datapacket {
  byte throttle;
  byte steering;
  byte door;
  byte revbuzzer;
  byte frontlts;
  byte indileft;
  byte indiright;
} State;

RF24 radio(9, 10);    //CE=9, CSN=10

const uint64_t pipe = 0xE8E8F0F0E1LL;

Servo throttleservo;
Servo steeringservo;
Servo doorservo;

byte revbuzzerPin = 4;
byte frontltsPin = 5;
byte indileftPin = 6;
byte indirightPin = 7;

int throttleValue = 1500;
int steeringValue = 0;
int doorValue = 0;
int revbuzzerValue = 0;
int frontltsValue = 0;
int indileftValue = 0;
int indirightValue = 0;


void setup(void) {
  throttleservo.attach(2);
  steeringservo.attach(3);
  doorservo.attach(8);

  pinMode(revbuzzerPin, OUTPUT);
  pinMode(frontltsPin, OUTPUT);
  pinMode(indileftPin, OUTPUT);
  pinMode(indirightPin, OUTPUT);
  radio.begin();
  radio.openReadingPipe(1, pipe);
  radio.setDataRate(RF24_250KBPS);
  radio.startListening();

  Serial.begin(9600);

}


void loop(void) {
  if (radio.available()) {
    radio.read(&State, sizeof(State));

    int throttleValue = map(State.throttle, 0, 255, 1000, 2000);
    int steeringValue = map(State.steering, 0, 255, 1000, 2000);
    int doorValue = map(State.door, 0, 255, 1000, 2000);
    int frontltsValue = map(State.frontlts, 0, 1, 0, 1);
    int indileftValue = map(State.indileft, 0, 1, 0, 1);
    int indirightValue = map(State.indiright, 0, 1, 0, 1);

    //Create the signals
    throttleservo.writeMicroseconds(throttleValue);
    steeringservo.writeMicroseconds(steeringValue);
    doorservo.writeMicroseconds(doorValue);

    Serial.println(State.throttle);   //This is here to check if any value is being received!

    if (throttleValue < 1400)
    {
      digitalWrite(revbuzzerPin, HIGH);
    }
    else
    {
      digitalWrite(revbuzzerPin, LOW);
    }

    if (frontltsValue == 1)
    {
      digitalWrite(frontltsPin, HIGH);
    }
    else
    {
      digitalWrite(frontltsPin, LOW);
    }

    if (indileftValue == 1)
    {
      digitalWrite(indileftPin, HIGH);
    }
    else
    {
      digitalWrite(indileftPin, LOW);
    }

    if (indirightValue == 1)
    {
      digitalWrite(indirightPin, HIGH);
    }
    else
    {
      digitalWrite(indirightPin, LOW);
    }

  }
}

//end

Is this a PP3 battery by any chance ?

If so, then it cannot supply enough current for the Arduino and RF24 to run for long before its voltage will be too low for the boards to operate

Can you measure the battery voltage with the system powered up ?

Hi UKHeliBob

Thanks, yes, they are 9V PP3 batteries. Following your suggestion I've just tried with 240V power adaptors (both tx and rx), unfortunately still nothing. I also checked on the serial monitor and there seems to be no signal being transmitted at all.

Both brand new batteries out of the packet, still showing 9.4V.

On the Tx you set the data rate

  radio.setDataRate(RF24_250KBPS);

but on the Rx you don't. I don't know what the default data rate is but try setting it to the same explicit rate at both ends

Hi

I've added the data rate into the Rx code but still no luck.

This works for me. All I did was to add

  radio.setDataRate(RF24_250KBPS);

to your receiver code and change the Serial baud rate to suit me

  radio.setDataRate(RF24_250KBPS);

and

/*
  Gerald’s Radio Control Code:
  Receiver – This code will receive 6 channels with data as follows:

  NRF24 Pins
  GND -> GND
  Vcc -> 3.3V
  CE -> D9
  CSN -> D10
  CLK -> D13
  MOSI -> D11
  MISO -> D12

  TX/RX Pins
  Throttle A0 to D2
  Steering A1 to D3
  Door Open A2 to D8
  Reverse Buzzer A0 to D4
  Front Lights D2 to D5
  Indicator Left D3 to D6
  Indicator Right D4 to D7
*/

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>

struct datapacket
{
  byte throttle;
  byte steering;
  byte door;
  byte revbuzzer;
  byte frontlts;
  byte indileft;
  byte indiright;
} State;

RF24 radio(9, 10);    //CE=9, CSN=10

const uint64_t pipe = 0xE8E8F0F0E1LL;

Servo throttleservo;
Servo steeringservo;
Servo doorservo;

byte revbuzzerPin = 4;
byte frontltsPin = 5;
byte indileftPin = 6;
byte indirightPin = 7;

int throttleValue = 1500;
int steeringValue = 0;
int doorValue = 0;
int revbuzzerValue = 0;
int frontltsValue = 0;
int indileftValue = 0;
int indirightValue = 0;


void setup(void)
{
  throttleservo.attach(2);
  steeringservo.attach(3);
  doorservo.attach(8);
  pinMode(revbuzzerPin, OUTPUT);
  pinMode(frontltsPin, OUTPUT);
  pinMode(indileftPin, OUTPUT);
  pinMode(indirightPin, OUTPUT);
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.openReadingPipe(1, pipe);
  radio.setDataRate(RF24_250KBPS);
  radio.startListening();
  Serial.begin(115200);
}


void loop(void)
{
  if (radio.available())
  {
    radio.read(&State, sizeof(State));
    int throttleValue = map(State.throttle, 0, 255, 1000, 2000);
    int steeringValue = map(State.steering, 0, 255, 1000, 2000);
    int doorValue = map(State.door, 0, 255, 1000, 2000);
    int frontltsValue = map(State.frontlts, 0, 1, 0, 1);
    int indileftValue = map(State.indileft, 0, 1, 0, 1);
    int indirightValue = map(State.indiright, 0, 1, 0, 1);
    //Create the signals
    throttleservo.writeMicroseconds(throttleValue);
    steeringservo.writeMicroseconds(steeringValue);
    doorservo.writeMicroseconds(doorValue);
    Serial.println(State.throttle);   //This is here to check if any value is being received!
    if (throttleValue < 1400)
    {
      digitalWrite(revbuzzerPin, HIGH);
    }
    else
    {
      digitalWrite(revbuzzerPin, LOW);
    }
    if (frontltsValue == 1)
    {
      digitalWrite(frontltsPin, HIGH);
    }
    else
    {
      digitalWrite(frontltsPin, LOW);
    }
    if (indileftValue == 1)
    {
      digitalWrite(indileftPin, HIGH);
    }
    else
    {
      digitalWrite(indileftPin, LOW);
    }
    if (indirightValue == 1)
    {
      digitalWrite(indirightPin, HIGH);
    }
    else
    {
      digitalWrite(indirightPin, LOW);
    }
  }
}
//end

Thanks for that, much appreciated. I noticed you added the pipe number 1 as well.

The following line is in the code twice, should I remove the first instance? radio.setDataRate(RF24_250KBPS);

..and lastly does the rest of the Rx logic look correct to you?

Thanks very much for your help. It's 1am in the morning here so might call it a night but will test again tomorrow.

Cheers

The line

  radio.setDataRate(RF24_250KBPS);

only needs to be there once so delete the second occurrence and leave the one immediately after

  radio.begin();

If you mean the 1 here

radio.openReadingPipe(1, pipe);

then that was in your original code

As to the logic of your code, there is no need for map() here

    int frontltsValue = map(State.frontlts, 0, 1, 0, 1);
    int indileftValue = map(State.indileft, 0, 1, 0, 1);
    int indirightValue = map(State.indiright, 0, 1, 0, 1);

as it does nothing. You can simply set the variables to the values in the struct. In fact you could use the values in the struct directly later in the sketch but using individual variables may make the sketch easier to read

You need to be careful about the number of bytes in the radio data (the maximum is 32 bytes) but you could send the raw values in a struct rather than using map() to convert the values at both ends

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.