Problem with two NRF24

Hi,

I have a weird problem with my NRF24 modules. I want to build custom control for my drone where I will have something like "ground station": joystick will be connected to PC where Node.js script will handle inputs and pass it to the Arduino transmitter. Then the TX side will transmit and wait for acknowledge payload from the drone receiver for flight data.

On one side I have Arduino Uno with NRF24L01+ (with ext. antenna) as the main transmitter and on the other side, I have Arduino pro micro with small NRF24 module as a receiver. Basically what I'm doing is that I'm sending data from TX to RX and from the RX side I'm sending back payload as a acknowledge data.

An NRF module on Uno (TX) is powered from Arduino connected directly with PC and for Pro Micro (RX) and NRF module on it I'm using standard 9V battery. Both NRF modules are using an adapter with a voltage stabilizer.

And everything worked like a charm, until last night when I started to get a lot of mysterious issues. First, it started with periodic printing ack payload (on TX side I always print ACK from RX as connection status, and "TX Failed" if ACK is not received), where on almost perfect intervals I got 1 ACK package and then 9 "Tx Failed" errors (rate of sending a signal is 10 times per second).

After little checking cables, pins, resetting both Arduinos, plugging in the RX side with USB instead of standalone power, I managed to get connection back between modules, and rates of the signal was 10/10 (10 commands sent, 10 ack payloads received).

Then, I wanted to play around with different radio settings. Radio instance on arduinos is created with 250Kbps bandwidth, default PA, without setting channels. And I wanted to play a little with bandwith and PA level. I set on both arduinos rate of 1Mbps and PA level to HIGH/MAX and then my nightmare started. I couldn't create a connection between NRF modules. I reverted code changes and the same happened. Bandwidth was returned to 250Kbps, default PA level, removed setChannel method call...I just couldn't make it to work like it worked before. There is only one scenario when I can get ack payload on TX side, and that is in the moment when I power on my RX side with battery. And after that, I get only "Tx Failed" errors...

I'm not sure where I'm wrong, but how can something that worked and after a little playing around with code and reverting everything back, the same code, the same setup, no longer work?

Wireless problems can be very difficult to debug. There is no obvious way to know whether the problem is with the Rx or the Tx.

Loose connections, inadequate 3.3v current and interference are obvious candidates.

Have you a spare Arduino with an nRF24 and nothing else attached which can stand-in as a substitute for the drone for test purposes?

...R
Simple nRF24L01+ Tutorial

Unfortunately, I do not have a spare Arduino. I will try to borrow one from a friend, but that is really my last possibility before throwing everything in the trash and ordering brand new components :slight_smile: And I’m thinking to drop this idea completely because if Arduino and those NRF modules are that much reliable, my drone can crash without a reason.

I attached my code for Drone and ground station, but I really don’t think that code is an issue. Also, I checked batteries, the voltage dropped out a little from 9.10V to 8.80V. Can this be an issue?

MyGroundStation.ino

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

const uint64_t droneAddress = 0xE8E8F0F0E1LL;

RF24 radio(7,8); // CE, CSN for Arduino UNO

struct ControlData {
  byte throttle;
  byte yaw;
  byte pitch;
  byte roll;
  byte AUX1;
  byte AUX2;
  byte AUX3;
};

ControlData controls;

struct FlightData {
  float lat;
  float lon;
  int16_t heading;
  int16_t pitch;
  int16_t roll;
  int32_t alt;
  byte flags;
};

FlightData flightData;

bool flightDataReceived = false;
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 50; // send data 10 times in second
byte buf[200];

void setup()
{
  Serial.begin(115200);

  radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_2MBPS);
  radio.enableAckPayload();
  radio.setRetries(5,5); // delay, count
  radio.openWritingPipe(droneAddress);

  setupDefaultControlValues();
}

void setupDefaultControlValues() {
  controls.throttle = 127;
  controls.yaw = 127;
  controls.pitch = 127;
  controls.roll = 127;
  controls.AUX1 = 0;
  controls.AUX2 = 0;
  controls.AUX3 = 0;
}

void loop() {
  currentMillis = millis();

  if (currentMillis - prevMillis >= txIntervalMillis) {
    sendControlSignal();
  }

  showFlightData();
}

void sendControlSignal() {
  bool isSignalSent;

  isSignalSent = radio.write(&controls, sizeof(controls));

  if (isSignalSent) {
    if (radio.isAckPayloadAvailable()) {
      radio.read(&flightData, sizeof(FlightData));
      flightDataReceived = true;
    } else {
      Serial.println("Acknowledge but no data ");
    }
  } else {
    Serial.println("Tx failed");
  }

  updateControlValues(); // temporary function until we implement joystick controls
  
  prevMillis = millis();
}

void updateControlValues() {
  if (Serial.available() >= 4) {
    controls.throttle = Serial.read();
    controls.pitch = Serial.read();
    controls.roll = Serial.read();
    controls.yaw = Serial.read();
  }
  controls.AUX1 = 0;
  controls.AUX2 = 0;
  controls.AUX3 = 0;
}

void showFlightData() {
  if (flightDataReceived) {
    Serial.print("Lat: ");
    Serial.print(flightData.lat);
    Serial.print(", Lon: ");
    Serial.print(flightData.lon);
    Serial.print(", Heading: ");
    Serial.print(flightData.heading);
    Serial.print(", Pitch: ");
    Serial.print(flightData.pitch);
    Serial.print(", Roll: ");
    Serial.print(flightData.roll);
    Serial.print(", Alt: ");
    Serial.print(flightData.alt);
    Serial.print(", Flags: ");
    Serial.print(flightData.flags);
    Serial.println();
    flightDataReceived = false;
  }
}

MyDrone.ino

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

const uint64_t groundStationAddress = 0xE8E8F0F0E1LL;

RF24 radio(8,10); // CE, CSN for Arduino Pro Micro

struct ControlData {
  byte throttle;
  byte pitch;
  byte roll;
  byte yaw;
  byte AUX1;
  byte AUX2;
  byte AUX3;
};

ControlData controls;

struct FlightData {
  float lat;
  float lon;
  int16_t heading;
  int16_t pitch;
  int16_t roll;
  int32_t alt;
  byte flags;
};

FlightData flightData;

bool controlsReceived = false;

void setup()
{
  Serial.begin(115200);
  
  Serial.println("Drone Comm booting...");
  
  radio.begin();
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_2MBPS);
  radio.openReadingPipe(1, groundStationAddress);
  radio.enableAckPayload();
  radio.startListening();
  
  Serial.println("Drone Comm started...");
  
  sendInitialFlightData();
}

void sendInitialFlightData() {
  flightData.lat = 11;
  flightData.lon = 12;
  flightData.heading = 13;
  flightData.pitch = 14;
  flightData.roll = 15;
  flightData.alt = 16;
  flightData.flags = 17;

  radio.writeAckPayload(1, &flightData, sizeof(flightData));
}

void loop() {
  getControls();
  showControls();
}

void getControls() {
  if (radio.available()) {
      radio.read(&controls, sizeof(controls));
      sendFlightData();
      controlsReceived = true;
  }
}

void sendFlightData() {
  if (flightData.lat < 20) {
    flightData.lat++;
  } else {
    flightData.lat = 11;
  }

  flightData.lon = 12;
  flightData.heading = 13;
  flightData.pitch = 14;
  flightData.roll = 15;
  flightData.alt = 16;
  flightData.flags = 17;

  radio.writeAckPayload(1, &flightData, sizeof(flightData)); // load the payload for the next time
}

void showControls() {
  if (controlsReceived) {
    Serial.print("Throttle: ");
    Serial.print(controls.throttle);
    Serial.print(", Pitch: ");
    Serial.print(controls.pitch);
    Serial.print(", Roll: ");
    Serial.print(controls.roll);
    Serial.print(", Yaw: ");
    Serial.print(controls.yaw);
    Serial.print(", AUX1: ");
    Serial.print(controls.AUX1);
    Serial.print(", AUX2: ");
    Serial.print(controls.AUX2);
    Serial.print(", AUX3: ");
    Serial.print(controls.AUX3);
    Serial.println();
    controlsReceived = false;
  }
}

MyGroundStation.ino (2.58 KB)

There is no reason to suppose that an Arduino with an nRF24 will be unreliable if it is constructed and programmed properly.

And I see no justification for throwing anything in the trash based on the information you have posted here.

I would not expect that small drop in battery voltage to matter, but it is the voltage and current available to the nRF24 that really matters.

Wireless problems can be very difficult to debug. My strong advice is to get very simple wireless communication working on its own before you start adding any other features to the program.

Please include short programs in your Post so we don't have to download them. See How to use the forum

...R

Oh, I just said that I will throw it away because I lost all my nerves. I'm coming from the software world (I'm a software engineer) where debugging is much easier than in the hardware world :slight_smile:

Right now, everything works as expected even with 2Mbps rate and PA level on MAX. What I found is that antenna on the RFN24L01+ module is like extra sensitive and everything works only if the antenna is a little more than 90 degrees turned from the base of the module. So I think that antenna is my main problem.

I tested first with some examples from that NRF24 thread, and when somehow started to works, I replaced with my code and magically all is fine :slight_smile: Even without batteries, only power from Arduino connected with a USB cable.

Do you have a piece of advice on how to replace this plastic antenna with something that I can build in my house?

Btw, sorry for attaching my code, I didn't want to bother visitors with a scrolling, I edited my post.

And one more question: I would like to share on this forum the whole project with Node.js code, wiring, plans, and so on, so can I use this topic or should I create a new one? I will have a lot of questions and I don't want to spam with new threads

v0idmp3:
Do you have a piece of advice on how to replace this plastic antenna with something that I can build in my house?

Sorry, no. I have no experience with the high-power nRF24s.

2.4Ghz wireless is not something simple so I would not be surprised if a DIY antenna did not work very well. Google may be able to find some info for you.

...R