Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP8266 crashing when used with nRF24L01 #244

Closed
kcfresher opened this issue Apr 13, 2016 · 15 comments
Closed

ESP8266 crashing when used with nRF24L01 #244

kcfresher opened this issue Apr 13, 2016 · 15 comments
Labels

Comments

@kcfresher
Copy link

Hi,
I connected ESP8266 to nRF24L01 as below.
nRF24L01 ESP
CE(3) GPIO4
CSN(4) GPIO15
SCK(5) GPIO14
MOSI(6) GPIO13
MISO(7) GPIO12
I tried the below sample program. ESP8266 gets crashed at the below line.

/*********
  Rui Santos
  Complete project details at http://randomnerdtutorials.com  
*********/

#include <ESP8266WiFi.h>
/*
* Getting Started example sketch for nRF24L01+ radios
* This is a very basic example of how to send data from one node to another
* Updated: Dec 2014 by TMRh20
*/

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

/****************** User Config ***************************/
/***      Set this radio as radio number 0 or 1         ***/
bool radioNumber = 1;

/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8
CE  PIN 9
SCN PIN 10*/
RF24 radio(15,4);
/**********************************************************/

byte addresses[][6] = {"1Node","2Node"};

// Used to control whether this node is sending or receiving
bool role = 0;

void setup() {
  Serial.begin(115200);
  Serial.println(F("RF24/examples/GettingStarted"));
   delay(5000);
  Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
   delay(5000);
  radio.begin();

  // Set the PA Level low to prevent power supply related issues since this is a
 // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
  radio.setPALevel(RF24_PA_LOW);

  // Open a writing and reading pipe on each radio, with opposite addresses
  if(radioNumber){
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  }

  // Start the radio listening for data
  radio.startListening();
}

void loop() {


/****************** Ping Out Role ***************************/  
if (role == 1)  {

    radio.stopListening();                                    // First, stop listening so we can talk.


    Serial.println(F("Now sending"));

    unsigned long start_time = micros();                             // Take the time, and send it.  This will block until complete
     if (!radio.write( &start_time, sizeof(unsigned long) )){
       Serial.println(F("failed"));
     }

    radio.startListening();                                    // Now, continue listening

    unsigned long started_waiting_at = micros();               // Set up a timeout period, get the current microseconds
    boolean timeout = false;                                   // Set up a variable to indicate if a response was received or not

    while ( ! radio.available() ){                             // While nothing is received
      if (micros() - started_waiting_at > 200000 ){            // If waited longer than 200ms, indicate timeout and exit while loop
          timeout = true;
          break;
      }      
    }

    if ( timeout ){                                             // Describe the results
        Serial.println(F("Failed, response timed out."));
    }else{
        unsigned long got_time;                                 // Grab the response, compare, and send to debugging spew
        radio.read( &got_time, sizeof(unsigned long) );
        unsigned long end_time = micros();

        // Spew it
        Serial.print(F("Sent "));
        Serial.print(start_time);
        Serial.print(F(", Got response "));
        Serial.print(got_time);
        Serial.print(F(", Round-trip delay "));
        Serial.print(end_time-start_time);
        Serial.println(F(" microseconds"));
    }

    // Try again 1s later
    delay(1000);
  }



/****************** Pong Back Role ***************************/

  if ( role == 0 )
  {
      Serial.println(F("loop1 "));
    unsigned long got_time;
    Serial.println(F("loop2 "));
    if( radio.available()){
                 Serial.println(F("loop3 "));                                                    // Variable for the received timestamp
      while (radio.available()) {                                   // While there is data ready
         Serial.println(F("loop4 "));
        radio.read( &got_time, sizeof(unsigned long) );             // Get the payload
      }

      radio.stopListening();                                        // First, stop listening so we can talk   
      radio.write( &got_time, sizeof(unsigned long) );              // Send the final one back.      
      radio.startListening();                                       // Now, resume listening so we catch the next packets.     
      Serial.print(F("Sent response "));
      Serial.println(got_time);  
   }
 }




/****************** Change Roles via Serial Commands ***************************/

  if ( Serial.available() )
  {
    char c = toupper(Serial.read());
    if ( c == 'T' && role == 0 ){      
      Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
      role = 1;                  // Become the primary transmitter (ping out)

   }else
    if ( c == 'R' && role == 1 ){
      Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));      
       role = 0;                // Become the primary receiver (pong back)
       radio.startListening();

    }
  }


} // `Loop`

Output:-
loop1
loop2
loop3
loop4
loop4
loop4
loop4
loop4
loop4
loop4
loop4
loop4

Soft WDT reset

ctx: cont
sp: 3ffef9b0 end: 3ffefc00 offset: 01b0

stack>>>
3ffefb60: 0000001c 3ffefbc0 3ffeea9c 40202444
3ffefb70: 00000008 3ffeead0 3ffeea9c 4020266e
3ffefb80: 3ffefbc3 000000c4 3ffeead0 40202490
3ffefb90: 00000000 00000005 3ffeebac 3ffeea98
3ffefba0: 3ffe844c 3ffeea9c 3ffeea9c 402028d9
3ffefbb0: 0000001d 3ffeea9c 3ffeebac 40201d7c
3ffefbc0: 00000000 3ffe836e 3ffeea9c 40202a54
3ffefbd0: 3ffe8368 3ffe836e 3ffeea9c 3ffeebd8
3ffefbe0: 3fffdad0 00000000 3ffeebd0 40203134
3ffefbf0: feefeffe feefeffe 3ffeebe0 40100718
<<<stack<<<

ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1264, room 16
tail 0
chksum 0x0f
csum 0x0f
~ld

Please let me know where I'm doing mistake.

@Avamander
Copy link
Member

Using latest version of everything? IDE, the software on the ESP, the
libraries are all new, including the board configs?

@TMRh20
Copy link
Member

TMRh20 commented Apr 13, 2016

RF24 radio(4,15);

@kcfresher
Copy link
Author

I used the latest tag V.1.1.6. for RF24 and took the latest esp8266 arduino. We interchanged Pin 4 and 15 to see if connections were reversed. Tht's why in code, probably they were defined in reverse. For incorrect CE,CSE pin connections, control does not get inside radio.available().

@kcfresher
Copy link
Author

I downloaded master RF24 and checked wiring. There was some soldering issue for CE pin which I rectified.
Now I'm able run on ESP8266 (Receiver) and arduino (Transmitter). I used the Getting_Started example. But ESP side, i'm not getting any response. But If I restart Arduino I get the below response on ESP.
I'm getting the below output.
ESP:-
(only if I restart Arduino. It prints the below three lines. After that no ouput. But Arduino keeps sending)
Sent response 1073644400
Sent response 1073644400
Sent response 1073644400

ARDUINO SIDE:-
Now sending
Sent 122389760, Got response 0, Round-trip delay 116644 microseconds
Now sending
Sent 123508764, Got response 0, Round-trip delay 18640 microseconds
Now sending
Sent 124529728, Got response 0, Round-trip delay 18308 microseconds
Now sending
Sent 125550348, Got response 0, Round-trip delay 18424 microseconds

@TMRh20
Copy link
Member

TMRh20 commented Apr 15, 2016

I've been using & testing with a recent git version of the Arduino core with some nodemcu v0.9 and either Arduino 1.6.7 or a recent build other than 1.6.8

@kcfresher
Copy link
Author

Thank you all for the help! We were able to resolve the issue.
one of nRF module was defect one. And the second one, we connected nRF to SPI2 in arduino leonardo board. I think code works with SPI1. So, we connected to nRF to SPI1

@360art
Copy link

360art commented Oct 2, 2017

Unfortunately I have the same problem.
My config:

Library versions:
IDE Arduino 1.8.5
ESP8266 Arduino: 2.3.0
NRF24: 1.3.0

Transmitter: Arduino Uno
Code:

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

#define CE 9
#define CSN 10

RF24 transmitter(CE, CSN);

const uint64_t address = 0xB00B1E5000LL;

void setup()
{
	Serial.begin(115200);
	printf_begin();
	Serial.println("****** Nadajnik ******");
	transmitter.begin();
	transmitter.setAutoAck(1);
	transmitter.enableAckPayload();
	transmitter.setRetries(5, 15);
	transmitter.openWritingPipe(address);
	transmitter.stopListening();
	transmitter.printDetails();

}

void loop()
{
	int numberToSend = 9;
	Serial.println("Sending packet...");
	if (!transmitter.write("BW", sizeof("BW"))) {
		Serial.println("Sending FAILED.");
	}
	else 
	{
		Serial.println("Packet sent!");
	}

	delay(1000);
  /* add main program code here */

}

Receiver ESP8266 NodeMCU V3

Wiring:
CSN D8 (15)
CE D2 (4)
MOSI D7 (13)
SCK D5 (14)
MISO D6 (12)

#include <ESP8266WiFi.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <SPI.h>
//#include "printf.h"

#define CE 4
#define CSN 15

RF24 receiver(CE, CSN);
char buffer[10];

const uint64_t address = 0xB00B1E5000LL;

void setup()
{
	Serial.begin(115200);
	//printf_begin();
	Serial.println("****** Odbiornik ******");
	receiver.begin();
	receiver.setAutoAck(1);
	receiver.enableAckPayload();
	receiver.setRetries(5, 15);
	receiver.openReadingPipe(1, address);
	receiver.startListening();
	//receiver.printDetails();

}

void loop()
{
	while (receiver.available()) {
		uint8_t payloadSize = receiver.getPayloadSize();
		receiver.read(&buffer, receiver.getPayloadSize());
		Serial.print("Received data:");
		Serial.println(buffer);
	}
}

Output log from Receiver:

⸮****** Nadajnik ******
Received data:BW
Received data:BW

//*** A LOT OF RECEIVED DATA ***

Received data:BW
Received data:BW
Received data:BW

Soft WDT reset

ctx: cont 
sp: 3ffef230 end: 3ffef480 offset: 01b0

>>>stack>>>
3ffef3e0:  40106afc 3ffee34c 3ffee31c 40201e60  
3ffef3f0:  40106afc 00000001 3ffe85bd 40203000  
3ffef400:  00000000 00000001 3ffee311 3ffee454  
3ffef410:  3ffee428 00000002 3ffee428 40202ab9  
3ffef420:  3ffe85bc 3ffee310 3ffee428 40202ab9  
3ffef430:  3ffee310 3ffee31c 3ffee428 40202ae4  
3ffef440:  3ffee428 3ffee310 3ffee428 40202b08  
3ffef450:  00000000 3ffee310 3ffee31c 40201c97  
3ffef460:  3fffdad0 00000000 3ffee44c 40202d80  
3ffef470:  feefeffe feefeffe 3ffee460 40100718  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v09f0c112
~ld
⸮****** Nadajnik ******
Received data:BW
Received data:BW
Received data:BW
Received data:BW
Received data:BW
....
//Next reset...

@ipatalas
Copy link

I'm also getting random Soft WDTs on my NodeMCU.

Wiring is as follows:
image

CS -> D1
CE -> D2

The code is GettingStarted example from the library itself. Altered parts here:

bool radioNumber = 0;

/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */
RF24 radio(D2, D1);
/**********************************************************/

byte addresses[][6] = {"1Node","2Node"};

// Used to control whether this node is sending or receiving
bool role = 0;

void setup() {
  Serial.begin(115200);
  Serial.println(F("RF24/examples/GettingStarted"));
  Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
  
  radio.begin();
  /******* my changes here *******/ 
  radio.setDataRate(RF24_250KBPS);
  radio.setCRCLength(RF24_CRC_8);
  radio.setRetries(15, 15);
  radio.setAutoAck(true);
  /****** end of my changes ******/

  // Set the PA Level low to prevent power supply related issues since this is a
 // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
  radio.setPALevel(RF24_PA_MIN);

Nothing else was changed.

One NodeMCU is using radioNumber 0 and role 0 and the other 1,1 respectively.
Interestingly this problem is very indeterministic. I'm pretty sure it wasn't there yesterday (no changes since then). At least I was able to keep the application running for a minute or two without exceptions.
Today I was getting them almost every few seconds sometimes. Now it's like once every 15-20 seconds or so.

I was able to decode stack traces using https://github.com/me-no-dev/EspExceptionDecoder
Here are few of them:
image
image
image

Any clue what might be wrong or what else should I check?
It also happens when I turn off the 'receiving' box and leave only the 'sending' one.

@wmarkow
Copy link
Contributor

wmarkow commented Jan 12, 2018

@ipatalas, it may hang somewhere in the code when you have some hardware issues (related to SPI wiring to the chip). Some advice:

  • go to the RF24_config.h file in the RF24 library and uncomment #define FAILURE_HANDLING. If something is wrong with the wiring the variable radio.failureDetected will be set to 1. You can inspect it later.
  • in your setup() mathod disable the auto ack radio.setAutoAck(false); . It has been proven that some chips have issues with auto ack.
  • you may use the isChipConnected() method and inspect its result
  • you may have to long wires between nRF24 and your NodeMCU ESP8266 board
  • you can solder the capacitor directly on the nRF24 chip (directly on the power pins) so it will be closer to the main electronic components

@Avamander
Copy link
Member

Avamander commented Jan 12, 2018

@wmarkow

Seeing how these questions are really common, maybe building a help page about this isn't such a bad idea?

@ipatalas
Copy link

Thanks @wmarkow for your tips.
If the wiring was wrong I guess it wouldn't have worked at all. I double checked it anyway. I've got two exact pieces of NodeMCU + nRF24 and only one of them is suffering from those exceptions so I must have done something wrong there (not wiring though - connections are exactly the same).
The other one works flawlessly.
It might be long wires - each NodeMCU to nRF24 connection length is around 15 cm but I don't have shorter wires now.
I am gonna try moving capacitor closer to nRF24 module as well. It's now 10cm from it so it might be too far away.

@keratos
Copy link

keratos commented Mar 2, 2019

Hello,

I encounter the same problem, I think I found the problem. At the moment of the crash at radio.write there is a drop in voltage, the order of 175mV, during 1ms, seen at the oscilloscope.

The 3.3V regulator on the card does not seem powerful enough to hold in transmission.

I will test with an external regulator.

sds00024

@keratos
Copy link

keratos commented Mar 3, 2019

Hello everyone,

I just did a test by feeding with a regulator ASM1117 that I had in my drawers, and a chemical condo of 22 μf at the terminals GND and VDD of the NRF24L01.
When the NRF24l01 passes in transmission the esp8266 does not crash anymore and the receiver receives the frame well.
For information :

  • Arduino IDE Version 1.8.8
  • Version ESP8266 communitys: 2.5.0
    Hoping that it can help some.

@wmarkow
Copy link
Contributor

wmarkow commented Mar 3, 2019

@keratos, thanks for your input in this investigations. If I understood you correctly, here is what happend:

  • nRF24L01 connected to ESP8266 and it is powered up directly from ESP8266
  • the software wants to send some data by nRF24L01: write method is called
  • nRF24L01 chip wants to send the data, it powers up the transmitter and probably wants to take some current to send data
  • however the power source is not so efficient and there is an around 170mV of voltage drop for about 1ms
  • because of this voltage drop ESP8266 goes into reset

@keratos, you have written before:

The 3.3V regulator on the card does not seem powerful enough to hold in transmission.

What is your 3.3V regulator on the card? What kind of ESP8266 board do you use? Is it NodeMCU or something similar? So you had some issue when you connected the power of nRF24L01 to this voltage regulator, right? And everything was fine when RF24 was connected to some external voltage regulator (ASM1117 in your case). Of course the capacitor soldered on RF24 could also help.

@keratos
Copy link

keratos commented Mar 4, 2019

The controller on the ESP8266 board is also an ASM 1117.
I do not know if it's a NodeMCU, but LoLin wrote on it, I think it must be the brand.

Yes the problem is solved by connecting a 3.3V external power supply with the ASM 1117 controller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants