Go Down

Topic: Using interrupts with a Node MCU (Read 20740 times) previous topic - next topic

HenryPenton

Hi there,

I was using a NodeMCU a little while ago, but now that I've come back to it, any time I try to set up an interrupt in the arduino IDE I get the error "ISR not in IRAM".

Could anyone point me in the right direction of how to define/setup my ISRs?

Many thanks,
Henry

PaulS

Quote
Could anyone point me in the right direction of how to define/setup my ISRs?
Some way other than whatever mysterious way you are doing it now.

Read the stickies.

MechScientist

I experienced the same issue on previously working code after updating to version 2.5.1 of the ESP8266 library. I was able to get around it by reverting back to 2.5.0.

Don't know if it's a bug in the update, or something that shouldn't have been allowed all along. I suspect it's a bug in the update.


htaxil

I experienced the same issue on previously working code after updating to version 2.5.1 of the ESP8266 library. I was able to get around it by reverting back to 2.5.0.

Don't know if it's a bug in the update, or something that shouldn't have been allowed all along. I suspect it's a bug in the update.


I experienced the same issue and resolved the same way : downgrade to v2.5.0

wvmarle

#4
May 22, 2019, 07:28 am Last Edit: May 22, 2019, 07:32 am by wvmarle
Don't know if it's a bug in the update, or something that shouldn't have been allowed all along.
I've ran into the same issue... and it's actually something that we shouldn't have been allowed all along. A quick explanation here.

The proper way to do an ISR for ESP8266 is by placing it in the IRAM - instead of having it execute from Flash. The second option works most of the time but is not reliable, a few years ago I found that out the hard way as I had an ISR crash now and then. Adding the ICACHE_RAM_ATTR fixed this issue: it places the ISR in IRAM, and no more random crashes.

The new 2.5.2 core just enforces this more strictly.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

hitanjali

I was also facing the same issue. But following code example would solve your issue.

/* This code is for executing the interrupt in ESP8266.
*  The main purpose is to solve the ISR not in RAM isssue.
*  
* ISR Function : The interrupt pin [GPIO5 ] once changes state from HIGH to LOW
* ISR reads the value on GPIO4 and changes the state of the BUILTIN led based on the value read
*/


const byte pin5 = 5;
const byte pin4 = 4;



void ICACHE_RAM_ATTR ISRoutine ();

void setup () {
 Serial.begin(115200);
 pinMode(pin5,INPUT_PULLUP);
 pinMode(LED_BUILTIN,OUTPUT);
 attachInterrupt(digitalPinToInterrupt(pin5),ISRoutine,FALLING);
 pinMode(pin4,INPUT);
}

void loop () {

 // Repeatative code here

}

void ISRoutine () {
   int value;
   Serial.println("I am in ISR");
   value = digitalRead(pin4);
   Serial.print("Value read = ");
   Serial.println(value);
   digitalWrite(LED_BUILTIN,!value);
}

wvmarle

It's VERY bad practice to print from inside an ISR.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

SystemAdministrator

Can someone explain how to revert back to version 2.5.0 - in baby steps because I can't seem to get it right!
Please!!

I experienced the same issue on previously working code after updating to version 2.5.1 of the ESP8266 library. I was able to get around it by reverting back to 2.5.0.

Don't know if it's a bug in the update, or something that shouldn't have been allowed all along. I suspect it's a bug in the update.



wvmarle

You can do that easily in the boards manager. Just select the version you want to install.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

SystemAdministrator


SystemAdministrator

OMG Version 2.5.0 works like magic.. thank goodness for this thread - I was about to give up!

wvmarle

Reverting to 2.5.0 to fix the IRAM issue for an ISR is the wrong approach.

Fix your code! Not having your ISR in IRAM means you risk mysterious and unpredictable crashes!
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

hitanjali

It's VERY bad practice to print from inside an ISR.
Noted !

Thanks for the sharing.

asdonaire

I was also facing the same issue. But following code example would solve your issue.

/* This code is for executing the interrupt in ESP8266.
*  The main purpose is to solve the ISR not in RAM isssue.

* ISR Function : The interrupt pin [GPIO5 ] once changes state from HIGH to LOW
* ISR reads the value on GPIO4 and changes the state of the BUILTIN led based on the value read
*/


const byte pin5 = 5;
const byte pin4 = 4;



void ICACHE_RAM_ATTR ISRoutine ();

void setup () {
 Serial.begin(115200);
 pinMode(pin5,INPUT_PULLUP);
 pinMode(LED_BUILTIN,OUTPUT);
 attachInterrupt(digitalPinToInterrupt(pin5),ISRoutine,FALLING);
 pinMode(pin4,INPUT);
}

void loop () {

 // Repeatative code here

}

void ISRoutine () {
   int value;
   Serial.println("I am in ISR");
   value = digitalRead(pin4);
   Serial.print("Value read = ");
   Serial.println(value);
   digitalWrite(LED_BUILTIN,!value);
}


kcpn

I used this approach surgested by Hitanjali, and it made the trick for me.
I assume this is the right way to ensure ISR is placed in IRAM!?!
Comments are welcome.
Thanks

I was also facing the same issue. But following code example would solve your issue.

/* This code is for executing the interrupt in ESP8266.
*  The main purpose is to solve the ISR not in RAM isssue.
*  
* ISR Function : The interrupt pin [GPIO5 ] once changes state from HIGH to LOW
* ISR reads the value on GPIO4 and changes the state of the BUILTIN led based on the value read
*/


void ICACHE_RAM_ATTR ISRoutine ();

void setup () {
 Serial.begin(115200);
 pinMode(pin5,INPUT_PULLUP);
 pinMode(LED_BUILTIN,OUTPUT);
 attachInterrupt(digitalPinToInterrupt(pin5),ISRoutine,FALLING);
 pinMode(pin4,INPUT);
}

void loop () {

 // Repeatative code here

}

void ISRoutine () {
   int value;
   Serial.println("I am in ISR");
   value = digitalRead(pin4);
   Serial.print("Value read = ");
   Serial.println(value);
   digitalWrite(LED_BUILTIN,!value);
}

Go Up