dparson55 / NRFLite

nRF24L01+ library with AVR 2 pin support, requiring very little code along with YouTube videos showing all available features.
MIT License
161 stars 26 forks source link

(NRF24L01+) ("NRFLite.h") (_radio.scanChannel(0)) it always show 0 #86

Closed gordon4liu closed 7 months ago

gordon4liu commented 7 months ago

Hi , My Antenna distance is 15cm between the tx module and rx module. I can receive meaasge form the tx module (channel=0) but the signal strength is always 0 (<-64dBm). Does it HW or SS issue??

==== Rx module == while (_radio.hasData()) {
uint8_t signalStrength = _radio.scanChannel(0); Serial.println(" RSSI= " + String(signalStrength));

dparson55 commented 7 months ago

I was not able to recreate the issue, maybe you are not transmitting on channel 0 when calling scanChannel. You might be confusing channel and radio id.

channel controls the frequency that the radio uses when transmitting and receiving data. When channel = 0 the radio uses a frequency of 2400MHz, when channel = 1 the radio uses 2401MHz. As detailed in NRFLite.h, any channel between 0 and 125 can be used, so any frequency between 2400 and 2525MHz.

radio_id controls the address used for data packets and can be any number between 0 and 255. The address is one of the fields inside a data packet and allows radios that are listening on the same channel to identify packets that are meant for receiption. If a radio receives a data packet, it looks at the address inside the packet and if it does not match the address assigned to the radio, the packet is ignored.

This code scans channel 0 (2400MHz) to see how noisy it is:

#include "SPI.h"
#include "NRFLite.h"

const static uint8_t RADIO_ID = 0;
const static uint8_t PIN_RADIO_CE = 9;
const static uint8_t PIN_RADIO_CSN = 10;

NRFLite _radio;

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

    // Setup the radio. It will default to channel 100 but this will be changed by scanChannel in the loop.
    _radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN);
}

void loop()
{
    // Scan channel 0 for noise and print out the results.
    Serial.println(_radio.scanChannel(0));
}

Initially scanChannel reports 0-2 as shown in the serial monitor and serial plotter, which is not very noisy.

image

This code creates a lot of noise on channel 0 (2400MHz):

#include "SPI.h"
#include "NRFLite.h"

const static uint8_t RADIO_ID = 1;
const static uint8_t PIN_RADIO_CE = 9;
const static uint8_t PIN_RADIO_CSN = 10;

NRFLite _radio;

void setup()
{
  // Setup the radio to use channel 0.
  _radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN, NRFLite::BITRATE2MBPS, 0);
}

void loop()
{
  // Send the number 77, which is 1 byte in length. The data packet will be addressed to radio id 99.
  // It is not necessary for radio 99 to exist since the purpose of this code is to flood channel 0 with signals.
  _radio.send(99, 77, 1);
}

When the above code is run, scanChannel returns a value between 23 and 33. I have the radios about 0.5m from each other and they are in line of sight.

image

As mentioned in the Basic_TX example, NRFLite assigns the radios to use channel 100 by default (2500MHz), so you need to change it to 0 if that is the channel you would like to use. You can use the ChannelScanner example to find the channel that has the least amount of noise in your environment and below is a subset of mine for an example (channels 14-38 are really noisy so I would not want to use them for projects).

10:21:32.568 -> Use a channel without existing signals.
10:21:32.568 -> Each X indicates a signal was received.
10:21:32.568 -> 
10:21:32.670 -> Channel   0  X
10:21:32.773 -> Channel   1  X
10:21:32.887 -> Channel   2  
10:21:33.017 -> Channel   3  X
10:21:33.102 -> Channel   4  X
10:21:33.231 -> Channel   5  XX
10:21:33.350 -> Channel   6  X
10:21:33.422 -> Channel   7  X
10:21:33.551 -> Channel   8  X
10:21:33.685 -> Channel   9  
10:21:33.801 -> Channel  10  
10:21:33.870 -> Channel  11  
10:21:33.999 -> Channel  12  
10:21:34.123 -> Channel  13  XXX
10:21:34.253 -> Channel  14  XXXXXXXXXXXXXXX
10:21:34.340 -> Channel  15  XXXXXXXXXXXXXX
10:21:34.471 -> Channel  16  XXXXXXXXXXXXXXXXXXXXXX
10:21:34.588 -> Channel  17  XXXXXXXXXXXXXX
10:21:34.674 -> Channel  18  XXXXXXXXXXXXXXXX
10:21:34.804 -> Channel  19  XXXXXXXXXXXXXXXXXXXXX
10:21:34.922 -> Channel  20  XXXXXXXXXXXXXX
10:21:35.006 -> Channel  21  XXXXXXXXXXXXXXXX
10:21:35.124 -> Channel  22  XXXXXXXXXXXXXXX
10:21:35.254 -> Channel  23  XXXXXXXXXXXXXXX
10:21:35.343 -> Channel  24  XXXXXXXXXXXXXXX
10:21:35.459 -> Channel  25  XXXXXXXXXXXXXXXXXXXXX
10:21:35.574 -> Channel  26  XXXXXXXXXXXXXXXXXXXXXXXXXXX
10:21:35.695 -> Channel  27  XXXXXXXXXXXXXXXXXXXXXX
10:21:35.809 -> Channel  28  XXXXXXXXXXXXXXXXXXXXXXX
10:21:35.922 -> Channel  29  XXXXXXXXXXXXXXXXXXXXXXXXXXXX
10:21:36.042 -> Channel  30  XXXXXXXXXXXXXXXXXXXX
10:21:36.110 -> Channel  31  XXXXXX
10:21:36.229 -> Channel  32  XXXXXX
10:21:36.374 -> Channel  33  XXXXXXXXXXXXXXXXXXXXXXXXX
10:21:36.462 -> Channel  34  XXXXXXXXXXXXXXXXXXXXXXXX
10:21:36.574 -> Channel  35  XXXXX
10:21:36.696 -> Channel  36  XXXXX
10:21:36.812 -> Channel  37  XXXXXX
10:21:36.928 -> Channel  38  XXXXXXXXXXX
10:21:37.041 -> Channel  39  
10:21:37.160 -> Channel  40  X

Just to be clear, scanChannel does not return the RSSI because the nRF24L01 chip does not have the ability to measure that, the nRF24L01 chip can only report a 1 if it sees a signal on a channel and 0 if it does not. The datasheet indicates that it will be able to detect a signal if the strength is stronger than -64 dBm for 170 microseconds. Using this information, as detailed in NRFLite.h, scanChannel asks the radio if it sees a signal on a channel a given number of times and by default, it takes 255 measurements. If it sees a signal 10 times, a 10 is returned, if it does not see any signals, a 0 is returned. You can see internally what NRFLite is doing here, it assigns the nRF24L01 to the specified channel, puts it into RX mode and waits 400 microseconds for a signal to be detected, turns off RX mode and increments a counter if a signal was detected, then repeats the process up to the specified measurementCount. So if scanChannel returns a 0 it means it checked 255 times, waiting 400 microseconds for a signal each time, and over all those checks the nRF24L01 never detected a signal.

gordon4liu commented 7 months ago

Hi dparson55, Your're right, The radio.scanChannel function is only for the noise sniffer. It can't be use for the communication quality check. Anyway, thanks for your responses.