WeMos D1 mini - attachInterrupt causing Reset

This is my first time using WeMos D1 mini… I used interrupts with Arduino uno and worked fine but,
sssuming this code (it’s just a short example…)

#define PinSensorePIR D7


void setup() {
    Serial.begin(115200);
    Serial.println("Setup");
    Serial.println("pinMode");
    pinMode(PinSensorePIR, INPUT_PULLUP); 
    Serial.println("attachinterrupt");
    attachInterrupt(digitalPinToInterrupt(PinSensorePIR), PIRStateChanged, CHANGE);
    Serial.println("End Setup");
}

void loop() {
  Serial.println("Loop");
}

void PIRStateChanged(void) {
  Serial.print("PIRStateChanged");
}

I get this error (and WeMos reset repeat) in the serial monitor!

Setup
pinMode
attachinterrupt
ISR not in IRAM!

Abort called

>>>stack>>>

ctx: cont
sp: 3ffffdb0 end: 3fffffc0 offset: 01b0
3fffff60:  3ffe86bf 00ffffff 0103a8c0 40201a45  
3fffff70:  3ffe85c1 3ffee3b0 3ffee3e0 3ffee448  
3fffff80:  3ffe84e0 3ffee3b0 3ffee3e0 40100452  
3fffff90:  3ffe84e0 3ffee3b0 3ffee3e0 402011cc  
3fffffa0:  3fffdad0 00000000 3ffee418 402020a0  
3fffffb0:  feefeffe feefeffe 3ffe8510 40100745  
<<<stack<<<

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

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v8b899c12
~ld

what should I do to resolve the problem?
thanks in advance for help

Don’t print from the ISR - Serial requires interrupts and they are disabled whilst executing your ISR

Get a global flag volatile bool isrTriggered = false; and set it to true in the ISR

void PIRStateChanged(void) {
  isrTriggered = true;
}

and check the flag in the loop.

void loop() {
  if (isrTriggered) {
    Serial.println("bingo");
    isrTriggered = false;
  }
}

in boards manager, make sure you have a version 2.5.0 of esp 8266

that will solve your issue

https://arduino-esp8266.readthedocs.io/en/latest/reference.html?highlight=attachinterrupt#digital-io

ISRs need to have ICACHE_RAM_ATTR before the function definition.

1 Like

Juraj:
Reference — ESP8266 Arduino Core 3.0.1-8-g40876dc6 documentation

.
This solved the problem!!!
Thank you very much!!!

You still should get rid of the print in the ISR though

Also as there is actually not a lot left in IRAM, it’s always worth thinking twice at what you add there. Does your PIR requires an interrupt or can you just check it from time to time in the loop?

You still should get rid of the print in the ISR though

That was just a short example I wrote for debugging purpose.
The real procedure just increments a counter! :wink:

About "requiring an interrupt" I asked this question myself many times... :LOL:
I'm pretty new to electronics (I'm a computer programmer) and I assumed that the less "useless" code I run into loop function, the better will be the response expecially if the loop not only check the sensors (they are two) but also have to check wifi state, send "alive pings" to server and some other stuffs. Considering I have to debounce the signals coming from the other sensor etc., I suppose that avoid to run code when it's not needed is the best solution. I always have the fear that I'm not running an intel i7 under the table... it's just a weMos :smiley:

sure - but checking the status of 2 pins takes only a few micro-seconds → that won’t kill your performance even if it’s just a WeMos (compared to wifi latency and other operations)

I’m sure you check in the main loop() the value of your counter → so you do execute a test anyway each time you run the loop.

J-M-L:
sure - but checking the status of 2 pins takes only a few micro-seconds --> that won't kill your performance even if it's just a WeMos (compared to wifi latency and other operations)

I'm sure you check in the main loop() the value of your counter --> so you do execute a test anyway each time you run the loop.

with Arduino style network libraries it is hard to have a 'realtime' loop. it is much simpler to use the interrupt for a sensor which send a short pulse

J-M-L:
I'm sure you check in the main loop() the value of your counter --> so you do execute a test anyway each time you run the loop.

Getting deeper into the logic I'm using, I need to debounce multiple "ticks" of the sensor to avoid false positive (not the PIR sensor, but a window damper sensor) but I start the "test procedure" only if the FIRST tick happens. that's why I preferred to use the interrupt, because I avoid to execute millis counting, testing differences, 5 millis intervals for debounce, etc. I do that only if really necessary!

Of course there are multiple ways to solve a problem depending the personal point of view and mine could be not the best one. Maybe it's unnecessary to use the interrupts but I came into this path after I valued many possible solutions. Maybe in the future I realize there is a better one for some reason and I'll change it

OK - whatever rocks your boat and get you what you need is cool :slight_smile:

indeed multiple ways to do something. I tend to avoid ISR as much as I can as they usually bring complexity with things changing behind your back that you need to worry about and create protected sections etc.

Juraj:
with Arduino style network libraries it is hard to have a 'realtime' loop. it is much simpler to use the interrupt for a sensor which send a short pulse

Yes - my point was for this case as a PIR usually gets activated and stays ON for a while (seconds or minutes) --> hence the question around the need for using interrupts esp. as the handling of the detection would still happen in the loop anyway given it only triggers a counter. Short pulses you might miss are indeed a different story.

but I'm fine with all approaches, was just my personal view.

J-M-L:
Yes - my point was for this case as a PIR usually gets activated and stays ON for a while (seconds or minutes)

Absolutely RIGHT! In fact when I realized that the timeout in the PIR sensor is so long (too long!!!) I switched for the loop check for it.
Consider it's my really first time with a Arduino style project and while i discover things (and tricks) i change things on the way.
Every suggestion is well accepted since they create experience! :wink:

Maschiaccio72:
Absolutely RIGHT! In fact when I realized that the timeout in the PIR sensor is so long (too long!!!) I switched for the loop check for it.

most PIR have 2 small potentiometers - one that let you set the sensitivity for a trigger, and one that lets you set the duration of the activation once an event is detected. turn it to the minimum and you'll get a few seconds (usually ~5s - which is still long in some cases)