[SOLVED] Communication issues with nRF24L01

EDIT: solution on post #30 and following

Hi !

I'm looking for some help here regarding a wered issue I'm facing with RF modules and Mirf lib.

I'm trying to light ON and OFF some LED modules, but depending the code I use the message is sometimes not received (or sent I don't know).

I use:

Arduino Pro Micro ATMega 32U4 5V 16Mhz
NRF24L01+ 2.4GHz RF Wireless Transceiver + Socket Adapter plate Board

Mirf nRF24L01 library for RF interface
Arduino IDE 1.8.8

The following code is working, the LED modules are receiving well the 1000 requests (tried several times) :

void test() {

 for (int i = 0; i < 1000; i++) { 
 sendToBtn(1, "cmd22");
 delay(300);
 sendToBtn(2, "cmd22");
 delay(300);
 sendToBtn(3, "cmd22");
 delay(300);
 sendToBtn(4, "cmd22");
 delay(300);
 sendToBtn(5, "cmd22");
 delay(300);
 sendToBtn(6, "cmd22");
 delay(300);
 sendToBtn(7, "cmd22");
 delay(300);
 }

}

These codes aren't working, some requests aren't received by LED modules ( ~20% are lost):

void test2() {

 int num = 0;

 byte buto[] = { 7,5,1,6,7,1,5,7,1,7,5,6,5,7,1,6,1,5,1,5,7,6,7,1,5,6,7,6,5,1,6,7,5,7,6,5 };

 for (int i = 0; i < sizeof(buto); i++) {
 sendToBtn(buto[i], "cmd22");
 delay(300);
 }

}
void randomBlinkBtn() {

 int turns = btnCount * 10;

 int rnd = 0;

 int last = 0;

 for (int i = 1; i<turns; i++) {
 
 rnd = getRandomButton(last);

 last = rnd;
 
 sendToBtn(rnd,"cmd22");
 
 delay(300);

 }
 sendToBtn(getRandomButton(last), "cmd11");
}

My sent code :

void sendToBtn(int butID, char* data) {

 Mirf.setTADDR(btnNames[butID]);

 delay(50);

 Mirf.send((uint8_t*) data);

 unsigned long time = millis();
 while (Mirf.isSending()) ;
 }
}

I don't think it's a hardware issues as some code is working well.

I've placed 30uF cap on RF modules but that doesn't help.

Mirf config:

Mirf.cePin = A1;
Mirf.csnPin = A0;

Mirf.spi = &MirfHardwareSpi;
Mirf.init();

Mirf.setRADDR((byte *) "btn00"); // Configure transmitting address.
Mirf.payload = 7;
Mirf.channel = 90;
 
 Mirf.configRegister(RF_SETUP, 0x0E);  //2Mbps

Mirf.configRegister(SETUP_RETR, 0x0F);  //Up to 15 retries

Mirf.configRegister(EN_RXADDR, 0x3F);  //Activate all channels

Mirf.configRegister(EN_AA, 0x3F);

Mirf.config();

Control module :

LED Module :

Does anyone already face the same issue ?

Thanks in advance for any advice regarding this strange issue I'm unable to fix.

Regards

I am not familiar with the Mirf library.

If you are not wedded to it then have a look at this Simple nRF24L01+ Tutorial.

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

The examples are as simple as I could make them and they have worked for other Forum members. If you get stuck it will be easier to help with code that I am familiar with. Start by getting the first example to work

...R

Hi Robin,

Thanks for the link, I'll read it carefully.

What's strange is that part of my code is working 100% (1000 requests sent without any issue) and some other part 80% (3 requests not received out of 20...).

I spent a day to try many code style and tricks without been able to put the finger on the issue.

Regards

Hi Robin,

I've recoded all my RF24 part and I'm now able to coomunicate between Tx & Rx, the only issue is that I'm not able to read the dataReceived.

Serials outputs :

On Tx side : send : CMD13����

On Rx side : order received : "weird chars"

Any idea what's wrong ?

my code (simplified) on Tx side :

char INVERSE_LED[5] = "CMD13";

const byte buttonAddress[2][5] = { {'B','T','N','0','0'},{ 'B','T','N','0','1' }};

loop () {
 sendToBtn(1, INVERSE_LED);
}

void sendToBtn(int butID, char dataToSend[]) {

 Serial.print("send BTN");
 Serial.print(butID);
 Serial.print(" : ");
 Serial.println(dataToSend);

 bool rslt;

 radio.stopListening();
 
 radio.openWritingPipe(buttonAddress[butID]);

 rslt = radio.write(&dataToSend, sizeof(dataToSend));

 radio.startListening();

 if (rslt) {
 if (radio.isAckPayloadAvailable()) {
 radio.read(&ackData, sizeof(ackData));
 newData = true;
 }
 else {
 Serial.println("  Acknowledge but no data ");
 }
 }
 else {
 Serial.println("  Tx failed");
 }
}

On Rx side :

loop() {
char dataReceived[5];

if(radio.available())
 {
 radio.read(&dataReceived, sizeof(dataReceived));
 }

 // Output result
 Serial.print("order received : ");
 Serial.println(dataReceived);
}

If you are using code with the TMRh20 library I will try to help - but you need to post the two complete programs.

Did you get my examples working?

If you are using the Mirf library you will need to wait for someone who is familiar with it to come along.

...R

HI !

I use TMRh20 library now, I've totally removed Mirf.

Tx code:

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

#define CE_PIN A1
#define CSN_PIN A0

#define IR_1 0xC101E57B

//Button Orders
char BLINK_LED[5] = "CMD10";
char TURN_ON_LED[5] = "CMD11";
char TURN_OFF_LED[5] = "CMD12";
char INVERSE_LED[] = "CMD13";

//Setup IR
IRrecv irrecv(9);
decode_results IRvalues;

long previousMillis = 0;

long interval = 1000;           

//RF24
const byte thisMasterAddress[5] = { 'S','R','V','0','0' };
const byte buttonAddress[2][5] = { {'B','T','N','0','0'},{ 'B','T','N','0','1' } };

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

char dataReceived[5]; // this must match dataToSend in the TX
char txNum = '0';
int ackData[2] = { -1, -1 }; // to hold the two values coming from the slave
bool newData = false;

void setup() {

//Setting up the Serial USB comm port
Serial.begin(115200);

// Setting up the IR receiver
irrecv.enableIRIn(); 

//Setting up the RF24
radio.begin();
radio.setDataRate(RF24_250KBPS);
radio.openReadingPipe(1, thisMasterAddress);
radio.enableAckPayload();
radio.setRetries(3, 5); // delay, count
radio.startListening();

}

void loop() {

//Handle IR orders
IRorders();

}

void IRorders() {
if (irrecv.decode(&IRvalues)) {
if (IRvalues.value == IR_1) { //1
sendToBtn(1, INVERSE_LED);
}
irrecv.resume();
}
}

void sendToBtn(int butID, char dataToSend[]) {

Serial.print("send BTN");
Serial.print(butID);
Serial.print(" : ");
Serial.println(dataToSend);

bool rslt;

radio.stopListening();

radio.openWritingPipe(buttonAddress[butID]);

rslt = radio.write(&dataToSend, sizeof(dataToSend));

radio.startListening();

if (rslt) {
if (radio.isAckPayloadAvailable()) {
radio.read(&ackData, sizeof(ackData));
newData = true;
}
else {
Serial.println("  Acknowledge but no data ");
}
}
else {
Serial.println("  Tx failed");
}
}

Rx code:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <ctype.h>
#include <avr/sleep.h>
#include <avr/power.h>

#define BUTTON_PIN 2 //Set the button pin nr
#define LED_PIN 3 //Set LED pin nr
#define RF_POWER_PIN 4 //RF module power pin
#define CE_PIN A1
#define CSN_PIN A0



char ANSWER[5] = "ANS00";

//RF24
const byte buttonAddress[11][5] = { { 'B','T','N','0','0' },{ 'B','T','N','0','1' }};
const byte masterAddress[5] = { 'S','R','V','0','0' };
int thisButtonAddress;

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[5];

int ackData[2] = { -1, -1 };
bool newData = false;

volatile int ledState = LOW; 


long previousMillis = 0;        
long lastActionMillis = 0;

void setup() {

	pinMode(RF_POWER_PIN, OUTPUT); 
	digitalWrite(RF_POWER_PIN, HIGH);

	Serial.begin(115200);

	setButtonNr();
	Serial.print("BTN");
	Serial.println(thisButtonAddress);
	Serial.print("Version: ");
	Serial.println(version);

	setupRF24();

	pinMode(LED_PIN, OUTPUT);

}


void loop() {

if (radio.available()) 	{
		radio.read(&dataReceived, sizeof(dataReceived));
	Serial.print("Button order received: ");	  
	Serial.println(dataReceived);
	}

}


void setupRF24() {
	radio.begin();
	radio.setDataRate(RF24_250KBPS);
	radio.openReadingPipe(1, buttonAddress[thisButtonAddress]);
	radio.enableAckPayload();
	radio.setRetries(3, 5); // delay, count
	radio.startListening();
	radio.openWritingPipe(masterAddress);
}
}

Thanks for your help.

I can't get your code to work, I've error :

Error linking for board SparkFun Pro Micro w/ ATmega32U4 (5V, 16 MHz)

Build failed for project 'Server'
wiring_digital.c: In function pinMode.constprop

wiring_digital.c:59: internal compiler error Segmentation fault
Please submit a full bug report
with preprocessed source if appropriate
gcc.gnu.org\bugs.html> for instructions

lto-wrapper.exe*: fatal error: C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-gcc returned 1 exit status
compilation terminated

ld.exe: error: lto-wrapper failed

collect2.exe*: error: ld returned 1 exit status

After many retries it compiles, Tx seems to send data, but nothing received on Rx side.

Alkerion:
I can't get your code to work, I've error :

[...]

After many retries it compiles, Tx seems to send data, but nothing received on Rx side.

Let's get this working before you embark on anything more complicated.

Post the code that YOU have uploaded to your Arduinos - are they both Pro-Micros? - and also post a photo of a drawing showing how you have everything connected.

How are you powering the nRF24s - a 3.3v output from a ProMicro may be be adequate.

Have you tried the connection test program in my Tutorial ?

...R

HI !

Your program doesn't compile well, I don't know why but I need to try several times in order to get it to work.

Yes I use pro micro.

RF powered from an Output from the pro mivro 5V -> 3.3V with an adapter.

Here is the dialog with the RF module.

If the numbers are mostly 0x00 or 0xff it means that the Arduino is not
communicating with the nRF24

STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0xe7e7e7e7e7 0xc2c2c2c2c2
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xe7e7e7e7e7
RX_PW_P0-6 = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x03
RF_CH = 0x4c
RF_SETUP = 0x07
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX

AND NOW WITH ADDRESS AAAxR 0x41 41 41 78 52 ON P1
and 250KBPS data rate

STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0xe7e7e7e7e7 0x31304e5442
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xe7e7e7e7e7
RX_PW_P0-6 = 0x00 0x20 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x03
RF_CH = 0x4c
RF_SETUP = 0x27
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 250KBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX

Tx:

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

#define CE_PIN A1
#define CSN_PIN A0


//RF24
const byte thisMasterAddress[5] = { 'S','R','V','0','0' };


RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

bool newData = false;

char dataToSend[] = "Message 0";
char txNum = '0';
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000;
const byte slaveAddress[5] = { 'B','T','N','0','1' };

void setup() {

 delay(1500);


 //Setting up the Serial USB comm port
 Serial.begin(115200);
 Serial.print("Server version: ");
 Serial.println(version);



 //Setting up the RF24
 radio.begin();
 radio.setDataRate(RF24_250KBPS);
 radio.openWritingPipe(slaveAddress);
 radio.enableAckPayload();
 radio.setRetries(3, 5); // delay, count


 Serial.println("Reset OK");

}


void loop() {
 currentMillis = millis();
 if (currentMillis - prevMillis >= txIntervalMillis) {
 send();
 prevMillis = millis();
 }
}


void send() {
 Serial.print("Data Sent ");
 Serial.print(dataToSend);
 bool rslt;
 rslt = radio.write(&dataToSend, sizeof(dataToSend));
 // Always use sizeof() as it gives the size as the number of bytes.
 // For example if dataToSend was an int sizeof() would correctly return 2


 if (rslt) {
 Serial.println("  Acknowledge received");
 updateMessage();
 }
 else {
 Serial.println("  Tx failed");
 }
}

void updateMessage() {
 // so you can see that new data is being sent
 txNum += 1;
 if (txNum > '9') {
 txNum = '0';
 }
 dataToSend[8] = txNum;
}

Rx:

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

#include <printf.h>

#define CE_PIN A1
#define CSN_PIN A0

const byte thisSlaveAddress[5] = { 'B','T','N','0','1' };

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

//===========

void setup() {
 pinMode(4, OUTPUT);   
 digitalWrite(4, HIGH);   
 Serial.begin(9600);
 delay(1000);

 printf_begin();

 Serial.println("CheckConnection Starting");
 Serial.println();
 Serial.println("FIRST WITH THE DEFAULT ADDRESSES after power on");
 Serial.println("  Note that RF24 does NOT reset when Arduino resets - only when power is removed");
 Serial.println("  If the numbers are mostly 0x00 or 0xff it means that the Arduino is not");
 Serial.println("     communicating with the nRF24");
 Serial.println();
 radio.begin();
 radio.printDetails();
 Serial.println();
 Serial.println();
 Serial.println("AND NOW WITH ADDRESS AAAxR  0x41 41 41 78 52   ON P1");
 Serial.println(" and 250KBPS data rate");
 Serial.println();
 radio.openReadingPipe(1, thisSlaveAddress);
 radio.setDataRate(RF24_250KBPS);
 radio.printDetails();
 Serial.println();
 Serial.println();
 radio.startListening();
}

//=============

void loop() {
 if (radio.available()) {
 radio.read(&dataReceived, sizeof(dataReceived));
 Serial.print("Data received ");
 Serial.println(dataReceived);
 }
}

Tx is sending, but Rx doesn't receive anything...

Alkerion:
Tx is sending, but Rx doesn't receive anything...

You cannot know that the Tx is sending unless the Rx receives a message.

Get communication working with the first example in my Tutorial before you try anything else.

You say my programs are not compiling for you, but you have not posted the compiler error message.

You have not said how you are creating the 3.3v power - some of the adapters are not suitable. Try powering the nRF24 from a pair of AA alkaline cells (3v) with the battery GND connected to the Arduino GND.

Do you have a pair of Unos that you can use to get started? That will make life easier. Then, if there are subsequently problems with the Pro Micro you will know that they are specific to the Pro Micro and that will guide the diagnostics.

...R

Hi !

The compiler error is on Post #6.

Tx Serial :
send : CMD13
Acknowledge but no data

Rx Serial :
weird chars I can't display here

Which SPI.h lib do you use ?

What is supposed to be sent ? String ? char? char*?

Why [10] as there is only 9 chars?
char dataToSend[10] = "Message 0";

I'm unable for unknown reasons to get your code working.

I've no other Arduino boards at the moment, must order them if I want to test.

I'll try with the 3V ext batteries, but I'm pretty confident on hardware side as the RF is working pretty well with Mirf but one specific case.

OK, I'm progressing.

In my function I've this :

void sendToBtn(int butID, char dataToSend) {

bool rslt;

radio.stopListening();

radio.openWritingPipe(buttonAddress[butID]);

rslt = radio.write(&dataToSend, sizeof(dataToSend));

radio.startListening();

if (rslt) {
if (radio.isAckPayloadAvailable()) {
radio.read(&ackData, sizeof(ackData));
newData = true;
}
else {
Serial.println("  Acknowledge but no data ");
}
}
else {
Serial.println("  Tx failed");
}
}

I've declared an order (message) like this :

char INVERSE_LED[6] = {'C','M','D','1','3'};

If I call my function with: sendToBtn(1, INVERSE_LED);

I receive a corrupted message.

If I do the following change in my function the message is well received :

rslt = radio.write(&INVERSE_LED, sizeof(INVERSE_LED));

What's wrong ?

Alkerion:
The compiler error is on Post #6.

Post the code that produced that error - it is very unusual.

What version of the Arduino IDE are you using?

What PC operating system?

I have a ProMicro somewhere but it is a long time since I used it. IIRC you have to install stuff to allow the IDE to work with it - if so what have you installed?

I am using the normal SPI library.

Rather than asking a range of disjointed questions let's just focus on getting my example to work. It certainly works on my Leonardo which has a lot in common with a ProMicro.

...R

OK, I got it to work ! :slight_smile:

The problem was variable types I tried to send to radio.write();

If I use the variable passed to my function it is not working, I've had to use a global variable.

This write function is very strange

write(buf, len)

buf is Pointer to the data to be sent
len is the length of bytes to be sent

I don't understand why so complicated and why we can't just send a String, an Int or any other standard variable type.

If you have a solution to use function parameter instead of a global variable I'll appreciate.

The error is produced with your SimpleTx code, for unknown reason 1 out of 5 retries it compile and upload on arduino.
Even when uploaded the modules aren't talking to each other, I don't know why.

I've tried for hours to get your code to work without success.

I use Arduino 1.8.8 on W10 with Visual Studio 2015, all required lib installed.

Thanks for your help.

OK !

Now the modules are communicating and receiving the command with the new library, but....

I still have some transmissions not successful :frowning:

With this lib is easier to trace when it's going wrong with the acknowledge.

I sometimes get Tx failed message for unknown reasons, so cmd are sent but not received.

All the RF24 modules are powered with 2.8 to 2.9V, it's OK as Nordic specs report a 1.9 to 3.6V supply range.

nRF24L01+

Still strange to have only 2.8V as I use modules supposed to convert 5V to 3.3V.

MODULES

I've tried to power them with 9V but they burnt... quite strange too as AMS1117-3.3 is supposed to support up to 12V according to specs.

SPECS AMS1117-3.3

At the moment I still have no idea what's going wrong.

I thought it was a Mirf issue, but it's probably more and hardware issue at the end.

Bad quality RF24 modules ?

Any ideas ?

Thanks for help

I've ordered 5V modules, at least I will remove the 5V to 3.3V potential issue.

5V nRF24L01+ modules

I should not be the only one facing such issues with this modules

Are you sure the module in the link in Reply #17 works with a 5v power supply? I can't see any voltage regulator chip on the board. All the I/O pins on a 3.3v nRF24 are 5v tolerant - it is only the power pin that has a max of 3.6v.

...R

You're right, no regulator chip, but it's written 5V in the title and '5 v input tolerance level' & 'With regulated voltage regulator', and also 'Voltage supply: 5V' in details
So I expect them to work with 5V.

Perhaps the picture is not corresponding to the exact article.

Otherwise there is this model, but far too expensive:

Sparkfun

Do you have any other idea why I'm facing these issues ?

Regards