nRF24L01 stops transmitting after a while

You said

So I tought, if it's possible to for exaple ready every 10th packet (what I mean is that print that in serial monitor, not just ignore some packets) and and the same time for example feed the servo with informations from the pakets? Or I missunderstood your quoth

Or maybe i send too much information (size not speed)?

Where is the updated code?

haven't implemented it yet,now im trying with baud rate delay etc. I somehow made it last longer but now, well messages are a bit weird.
angleX: 1, angleY: -76, angleZ: 0 Latitude: 0.00000000, Longitude: 0.00000000, Altitue: 0.0, Speed: 0.00 angleX: 1, angleY: -76, angleZ: 0 Latitude: 0.00000000, Longitude: 0.00000000, Altiue0.bpeed: 0.00 angleX: 1, angleY: -76, angleZ: 0 Latitude: 0.00000000, Longitude: 0.00000000, Alide'r�peed: 0.00 angleX: 1, angleY: -76, angleZ: 0 Latitude: 0.00000000, Longitude: 0.00000000, Altitue: .0, Speed: 0.00 angleX: 1, angleY: -76, angleZ: 0 Latitude: 0.00000000, Longitude: 0.00000000, Alite .0, Speed: 0.00 angleX: 1, angleY: -76, angleZ: 0 Latitude: 0.00000000, Longitude: 0.00000000, Altitue:��bSeed: 0.00

can it be because of no delay(); ? it started after I removed it. I know its kinda off topic. Also its in serial monitor of the transmiter.

Update: after i added delay it stopped printing artefacts. But still, it's lasting like 2 times the time before. Also resoldered the ground and vcc because I saw rotation of ground cable affected the amount of messages printed.

If you insist in using delay, I'm not into wasting my time.

There is a list of changes that should improve the performance,
you could add "don't print each packet" as a means to reduce the chance of blocking on Serial.

I do not insist in using delay, I even find it better when theres not delay at all, however it started to print "artefacts". Also I've discovered it's transmiter fault because if I reset transmiter only, receiver will print messages as normal.

There is no use in talking about symptoms of a program that has to be changed.

Change it, then we can talk about symptoms, and we will have more information,
counters for success fail and retry, a moderated packet stream,
and less output generated than Serial can handle.

Okay i did some tests. I tried sending every second paket, It did not work out. I also tried sending every third paket, it lasted less than every second paket. So less flow in pakets doesn't mean lasting longer. I was thinking it might be the data rate which was 250 kbps. I turned it up, but it turned out to be automatic so I just had bigger flow. It did not impact the time it was working. turning off dynamic payloads only affected it by small additional amount of time. My dad told me to delete part of code for example gyro and test it. I did as he told me, I deleted the gyro part and now it has been working for nearly an hour. I'm thinking about changing the library for MPU6050.

transmiter:

#include <nRF24L01.h>
#include <RF24.h>
#include <TinyGPS++.h>

RF24 radio(9, 10); // Utwórz obiekt RF24 i zdefiniuj piny CE i CSN
const byte address[6] = "00001"; // Adres do komunikacji (musi być taki sam w odbiorniku)

TinyGPSPlus gps;

struct SensorData {
  uint8_t packetNum;
  double latitude;
  double longitude;
  double altitude;
  double speed;

};

SensorData sensorData;

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

  radio.begin(); // Inicjalizuj moduł nRF24L01
  radio.openWritingPipe(address); // Ustaw adres nadawczy
  radio.setPALevel(RF24_PA_LOW); // Ustaw moc nadajnika na niską
  radio.setDataRate(RF24_250KBPS); // Ustaw szybkość transmisji danych na 250 kbps
  radio.enableDynamicPayloads(); // Włącz dynamiczne pakiety
}


void loop() {


  // Odczytaj dane z GPS
  while (Serial.available() > 0) {
    if (gps.encode(Serial.read())) {
      if (gps.location.isUpdated()) {
        sensorData.latitude = gps.location.lat();
        sensorData.longitude = gps.location.lng();
        sensorData.altitude = gps.altitude.meters();
        sensorData.speed = gps.speed.kmph();
      }
    }
  }

  // Zwiększ numer pakietu
  static uint8_t packetNum = 0;
  sensorData.packetNum = packetNum;

  // Wysyłaj dane
  radio.write(&sensorData, sizeof(sensorData));

  // Wyświetl dane na Serial Monitorze
  Serial.print("Latitude: ");
  Serial.print(sensorData.latitude, 8);
  Serial.print(", Longitude: ");
  Serial.print(sensorData.longitude, 8);
  Serial.print(", Altitude: ");
  Serial.print(sensorData.altitude);
  Serial.print(", Speed: ");
  Serial.println(sensorData.speed);

  // Zwiększ numer pakietu
  packetNum++;


}

receiver:

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

RF24 radio(9, 10);
const byte address[6] = "00001";

struct SensorData {
  uint8_t packetNum;
  double latitude;
  double longitude;
  double altitude;
  double speed;
};

SensorData sensorData;

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

  radio.begin();
  radio.openReadingPipe(1, address);
  radio.setPALevel(RF24_PA_LOW);
  radio.setDataRate(RF24_250KBPS);
  radio.enableDynamicPayloads();
  radio.startListening();
}

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

    // Display the received data on the Serial Monitor
    Serial.print("PacketNum: ");
    Serial.print(sensorData.packetNum);
    Serial.print(", Latitude: ");
    Serial.print(sensorData.latitude, 8);
    Serial.print(", Longitude: ");
    Serial.print(sensorData.longitude, 8);
    Serial.print(", Altitude: ");
    Serial.print(sensorData.altitude);
    Serial.print(", Speed: ");
    Serial.println(sensorData.speed);
  }
}


This is the code that im using right now for an hour, I know it does enable dynamic payloads. Diffrence between old struct size and the one im using now is 6 bytes. Also, the artefacts are only visible on the transmiter (chinese uno), I guess its just some problem with processing the data on worse processor.

dynamicPayloads is useful, but here it worsens you problem slightly,
because you still send on each loop, unmoderateted.
The lower data rate could extend your range.
You still do not care for the transmit results.
You still have no data regarding success, fail or retries.
You still have no data regarding the last successful reception.

double is identical to float on AVRs,
so using double will be problematic if one of your nodes is a 32 bit processor,
and just silly if you don't.

You switched both nodes to RF24_PA_LOW,
maybe switch only the high power module could work better.

This is still true, which is rather disappointing.

It is still true because the transmiter will receive data regard movement of the servos onboard. So I do understand your disapointment that I'm so unproffesional.

I do not understand what you are talking about.

The characters arrive so slow

  if (Serial.available()) {

would do the job, look cleaner and has less chance to block.
I would also note, whether there was a new fix,
which could also be a flag in the transmit packet.

Why don't you use the packetNumber inside the transmit structure directly?

Well, first im trying to make it so "drone" sends data about it location and rotation. However at the end my plans are that receiver and transmiter will act as transceiver. Because one needs to send it's location and other has to send for example how should flaps act on wing (servo). So I would have to disable something and then enable it again. However I did put radio.stopListening(); in transmiter for now :slight_smile:

If you want to use bidirectional communication, I would suggest using AckPayload,
with the controller as sender and the drone as listener.

So this moves to an XY problem, your sketches are only struggle with the basics,
like packets are quite fast and 9600 baud is awfully slow?

That is disappointing.

I do not understand why are you disappointed, im not trying to solve problem Y. I'm trying to solve problem X right now. I want to understand why it stops working and fix it. The plan i told you is far away from being started.

#include <nRF24L01.h>
#include <RF24.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

TinyGPSPlus gps;

RF24 radio(9, 10);
const byte address[6] = "00001";

SoftwareSerial gpsSerial(2, 3);

struct SensorData {
  uint8_t packetNum;
  double latitude;
  double longitude;
  double altitude;
  double speed;
};

SensorData sensorData;

unsigned long lastPacketTime = 0;
unsigned long totalPacketTime = 0;
unsigned long packetCount = 0;
unsigned long failedPackets = 0;
unsigned long retries = 0;
unsigned long successes = 0;

void setup() {
  Serial.begin(115200);
  gpsSerial.begin(9600);
  
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_LOW);
  radio.setDataRate(RF24_250KBPS);
  radio.enableDynamicPayloads();
  radio.stopListening();

  // Ustaw liczbę prób ponownych na 15
  radio.setRetries(15, 15);
}

void loop() {
  // Odczytaj dane z GPS
  while (gpsSerial.available() > 0) {
    if (gps.encode(gpsSerial.read())) {
      sensorData.latitude = gps.location.lat();
      sensorData.longitude = gps.location.lng();
      sensorData.altitude = gps.altitude.meters();
      sensorData.speed = gps.speed.kmph();
    }
  }

  // Zwiększ numer pakietu
  static uint8_t packetNum = 0;
  sensorData.packetNum = packetNum;

  // Wysyłaj dane
  if (radio.write(&sensorData, sizeof(sensorData))) {
    successes++;

    // Oblicz czas pomiędzy pakietami
    if (packetNum > 0) {
      unsigned long currentPacketTime = millis() - lastPacketTime;
      totalPacketTime += currentPacketTime;
      packetCount++;
    }

    retries += 15;  // Użyj wartości ustawionej wcześniej
  }
  else {
    failedPackets++;
  }

  lastPacketTime = millis();

  // Wyświetl dane na Serial Monitorze
  Serial.print("Latitude: ");
  Serial.print(sensorData.latitude, 8);
  Serial.print(", Longitude: ");
  Serial.print(sensorData.longitude, 8);
  Serial.print(", Altitude: ");
  Serial.print(sensorData.altitude);
  Serial.print(", Speed: ");
  Serial.println(sensorData.speed);

  // Wyświetl statystyki
  Serial.print("Failed Packets: ");
  Serial.println(failedPackets);
  Serial.print("Retries: ");
  Serial.println(retries);
  Serial.print("Successful Packets: ");
  Serial.println(successes);
  Serial.print("Average Packet Time: ");
  Serial.print(totalPacketTime / packetCount);
  Serial.println(" ms");

  // Zwiększ numer pakietu
  packetNum++;
}

Okay the test lasted for 10 minutes. successful 34314 pakets, Retries 51410, failed 0 average time between pakets is 16ms. Are these results even possible? It seems weird theres 0 failed, and also it's weird how much retries there are.

Nonsense.

To measure the time a packet takes, get micros before and after the write.

Why 15, 15 ?

You still do not restrict the amount of packets in a meaningful way.

But that is not the problem you have to solve, because that involves bidirectional traffic.

Good luck with solving the X problem,
maybe I'm more interested when you start solving your real problem.

To learn handling the NRF's work through some tutorials,
the documentation of the chip and the library.

Long time no see :slight_smile:
I figured out what's wrong and it turned out to be very common problem. It's just that Mpu6050 freezes because of I2C problem . When its unplugged everything work's just fine. Thanks for all the help. :+1:

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