dparson55 / NRFLite

nRF24L01+ library with AVR 2 pin support, requiring very little code along with YouTube videos showing all available features. It can be installed via the Arduino IDE Library Manager
MIT License
155 stars 25 forks source link

Transmission problem #34

Closed heavyeste closed 4 years ago

heavyeste commented 4 years ago

Hello guys, I'm trying this library with 2 RF24 modules but i having some problem.

The program is very simple: TX send every second a packet with all data included PIN nr. 4 status (1 or 0)

My problem

Randomly the system loses packets. If i try with a second TX, the system loses some times packet from TX1 e some times packet from TX2. I can't understand the reason. The RX and TX are really close (1 meter). If I try to move the TX in another room the situation doesn't change.

The problem is the library? the devices (RF24)? the arduinos? the wires? Please give me support!

My configuration

Transmitter: Arduino Nano

/*

Demonstrates simple RX and TX operation.
Any of the Basic_TX examples can be used as a transmitter.
Please read through 'NRFLite.h' for a description of all the methods available in the library.

Radio    Arduino
CE    -> 9
CSN   -> 10 (Hardware SPI SS)
MOSI  -> 11 (Hardware SPI MOSI)
MISO  -> 12 (Hardware SPI MISO)
SCK   -> 13 (Hardware SPI SCK)
IRQ   -> No connection
VCC   -> No more than 3.6 volts
GND   -> GND

*/

#include <SPI.h>
#include <NRFLite.h>

const static uint8_t RADIO_ID = 0;       // Our radio's id.  The transmitter will send to this id.
const static uint8_t PIN_RADIO_CE = 9;
const static uint8_t PIN_RADIO_CSN = 10;

struct RadioPacket // Any packet up to 32 bytes can be sent.
{
    uint8_t FromRadioId;
    uint32_t OnTimeMillis;
    uint32_t FailedTxCount;
    uint32_t Data;
};

NRFLite _radio;
RadioPacket _radioData;

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

    // By default, 'init' configures the radio to use a 2MBPS bitrate on channel 100 (channels 0-125 are valid).
    // Both the RX and TX radios must have the same bitrate and channel to communicate with each other.
    // You can run the 'ChannelScanner' example to help select the best channel for your environment.
    // You can assign a different bitrate and channel as shown below.
    //   _radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN, NRFLite::BITRATE2MBPS, 100) // THE DEFAULT
    //   _radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN, NRFLite::BITRATE1MBPS, 75)
    //   _radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN, NRFLite::BITRATE250KBPS, 0)
    Serial.println("Setup...");
    if (!_radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN, NRFLite::BITRATE2MBPS, 50))
    {
        Serial.println("Cannot communicate with radio");
        while (1); // Wait here forever.
    }
    Serial.println("Setup done!");
}

void loop()
{
    while (_radio.hasData())
    {
        _radio.readData(&_radioData); // Note how '&' must be placed in front of the variable name.

        String msg = "Radio ";
        msg += _radioData.FromRadioId;
        msg += ", Data: ";
        msg += _radioData.Data;
        msg += ", ";
        msg += _radioData.OnTimeMillis;
        msg += " ms, ";
        msg += _radioData.FailedTxCount;
        msg += " Failed TX";

        Serial.println(msg);
    }
}

Receiver: Arduino Uno

/*
Demonstrates simple TX operation with an ATtiny85.  Note in this example the same pin is used for CE and CSN.
This slows the communication between the microcontroller and radio, but it frees up one pin.
Any of the Basic_RX examples can be used as a receiver.
Radio    Arduino
CE    -> 9
CSN   -> 10 (Hardware SPI SS)
MOSI  -> 11 (Hardware SPI MOSI)
MISO  -> 12 (Hardware SPI MISO)
SCK   -> 13 (Hardware SPI SCK)
IRQ   -> No connection
VCC   -> No more than 3.6 volts
GND   -> GND
*/

#include <NRFLite.h>

const static uint8_t RADIO_ID = 100;
const static uint8_t DESTINATION_RADIO_ID = 0;
const static uint8_t PIN_RADIO_CE = 9;
const static uint8_t PIN_RADIO_CSN = 10;
const static uint8_t PIN_INPUT = 4;

struct RadioPacket
{
    uint8_t FromRadioId;
    uint32_t OnTimeMillis;
    uint32_t FailedTxCount;
    uint32_t Data;
};
uint32_t val = 0;
NRFLite _radio;
RadioPacket _radioData;

void setup()
{
  Serial.begin(115200);
    if (!_radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN, NRFLite::BITRATE2MBPS, 50))
    {
      Serial.println("Cannot communicate with radio.");
        while (1); // Cannot communicate with radio.
    }
  Serial.println("Init radio done!");
    _radioData.FromRadioId = RADIO_ID;

    pinMode(PIN_INPUT, INPUT);
}

void loop()
{
    _radioData.OnTimeMillis = millis();
    val = digitalRead(PIN_INPUT);
    _radioData.Data = val;

    if (!_radio.send(DESTINATION_RADIO_ID, &_radioData, sizeof(_radioData)))
    {
       _radioData.FailedTxCount++;
      Serial.print("Error sending: FailedTxCount => ");
      Serial.println(_radioData.FailedTxCount++);

    }

    delay(1000);
}
dparson55 commented 4 years ago

Here are a couple of ideas to try:

  1. Add a 0.1uF capacitor between VCC and GND pins on the nRF24L01 modules.
  2. Run the ChannelScanner example to see which channel has the least amount of noise...maybe the one you are using (50) is noisy.
heavyeste commented 4 years ago

Hello, thank for the response! I try with capacitor but the situation doesn't change!

I notice that if I move the sensor, it start to have problem to send data! So the problem could be the wires?

Now i'm trying with another receiver (long range RF24) with ESP8266. In 24h it fail 2 tx per second but the data is receive correctly (I log the data in sql database throw http call to my web server).

The channel 50 is free. Infact the channel scanner found busy channel only between 10 and 16.

In your opinion.. could I try to use a PCB veroboard with rigid cables and tin soldering?

thank you very much! Esteban

dparson55 commented 4 years ago

It's not necessary to get radio modules to work with rigid cables and soldering. They can work ok without that as shown in many videos online. So I cannot say if your wires are an issue. You can test the connectivity of your wires with a multimeter if you are worried about them, measure the resistance of the wires and such.

Some long range RF24 modules do not support the auto-acknowledgement hardware of the nRF24L01+ chip. I actually had someone send me a long range module for troubleshooting and it simply did not work at a hardware level. So if you are using long range modules, you may need to send NO_ACK packets so auto-acknowledgement is not used. There is a different library (search for RadioHead) and it implements software-based acknowledgements. This library may be better suited for your needs. Good luck!