logo elektroda
logo elektroda
X
logo elektroda

NodeMCU V1 reset using interrupts after Arduino IDE 1.8.12 update

globalinfo 1017 17
Best answers

How can I stop a NodeMCU V1 from resetting when an interrupt routine is used with WiFi after updating to Arduino IDE 1.8.12?

The reset is caused by the interrupt handler not being placed in IRAM, so you need to mark the ISR function(s) with the IRAM attribute and move the interrupt code there [#18600043] The original poster confirmed that adding two lines for this fixed the problem [#18600112] If you also share variables between the ISR and the main program, declare them as atomic because they can be accessed both from the interrupt and from ESP8266 background WiFi tasks [#18600813]
Generated by the language model.
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • #1 18599487
    globalinfo
    Level 13  
    Posts: 430
    Help: 1
    Rate: 29
    Hello,
    I have a problem using interrupts and WiFi on a NodeMcu V1 module.
    The worst part is that everything worked for a year.
    Now I have updated the Arduino IDE to version 1.8.12 and after uploading the code to the module, it resets.
    After deleting the line and with the interrupt code, the chip does not reset.
    Please give me a hint on how to deal with this.

    Below is an excerpt from the code which, when inserted, causes a reset.
    Code: C / C++
    Log in, to see the code
    .
    Here the error message.
    Quote:
    Here is the error message.
    User exception (panic/abort/assert)
    Abort called

    >>>stack>>

    ctx: cont
    sp: 3ffffef0 end: 3fffffc0 offset: 0000
    3ffffef0: feefeffe feefeffe feefeffe 00000100
    3fffff00: 000000fe 00000000 00000000 00000000
    3fffff10: 00000000 00000000 00000000 00ff0000
    3fffff20: 5ffffe00 5ffffe00 3ffef394 00000000
    3fffff30: 00000002 00000000 3ffee4c8 40203f1a
    3fffff40: 4010046a 51eefae7 ffffff00 40203f30
    3fffff50: 401055b9 00000001 3ffee4c8 40204431
    3fffff60: 00000000 3ffee6b4 00000002 40204624
    3fffff70: 00000004 00000000 00000064 3ffee540
    3fffff80: 3fffdad0 00000000 3ffee4c8 402044e0
    3fffff90: 3fffdad0 00000000 3ffee4c8 40201240
    3fffffa0: feefeffe feefeffe 3ffee500 40203b70
    3fffffb0: feefeffe feefeffe 3ffe84f0 40100d75
    <<<stack<<<
    .
  • ADVERTISEMENT
  • #2 18599559
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #3 18599623
    globalinfo
    Level 13  
    Posts: 430
    Help: 1
    Rate: 29
    drobok wrote:
    And when you give empty count_production and count_use it restarts too ? I would look there for the problem.


    These are function references, how am I supposed to count pulses if I don't execute the function.

    Below is the code for these functions.
    Code: C / C++
    Log in, to see the code
    .
  • ADVERTISEMENT
  • #4 18599885
    Anonymous
    Level 1  
  • #5 18599978
    globalinfo
    Level 13  
    Posts: 430
    Help: 1
    Rate: 29
    drobok wrote:
    A place where you use production_Wh and consumption_Wh ? This is not a problem with the interrupt itself. You need to pre-bug it when it specifically resets for you. If I were you, I would compare the resulting asm of one version with the other and start looking where the differences are.
    .

    The program resets when it hasn't executed the whole void setup() .
    I've added some checks and it does a reset between spr3 and spr4, so this is an interrupt issue.
    Below is the code with the checks added and the error message.
    Code: C / C++
    Log in, to see the code
    .
    Quote:
    .
    spr1
    Connecting to ComNet_2EX........................
    Connected - IP: 192.168.100.120 RSSI: -75 dBm

    spr2
    spr3
    ISR not in IRAM!

    User exception (panic/abort/assert)
    Abort called

    >>>stack>>

    ctx: cont
    sp: 3ffffef0 end: 3fffffc0 offset: 0000
    3ffffef0: 3ffe86cb ffffffb5 3ffee4d8 4020408a
    3fffff00: 000000fe 00000000 00000000 00000000
    3fffff10: 00000000 00000000 00000000 00ff0000
    3fffff20: 5ffffe00 5ffffe00 000a0d0a 00000000
    3fffff30: 00000002 00000000 3ffee4d8 40203f9a
    3fffff40: 4010046a 9bcfb0b8 3ffee400 40203fb0
    3fffff50: 401055b9 009baf90 3ffee4d8 402044b1
    3fffff60: 00000000 3ffee5ac 00002710 3ffee550
    3fffff70: 00000000 3ffee5ac 00002710 3ffee550
    3fffff80: 00000000 00002710 3ffee4d8 40204560
    3fffff90: 00000000 00002710 3ffee4d8 402012a1
    3fffffa0: 3fffdad0 00000000 3ffee510 40203bf0
    3fffffb0: feefeffe feefeffe 3ffe84f0 40100d75
    <<<stack<<<

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

    load 0x4010f000, len 1392, room 16
    tail 0
    chksum 0xd0
    csum 0xd0
    v3d128e5c
    ~ld

    .
  • #7 18600112
    globalinfo
    Level 13  
    Posts: 430
    Help: 1
    Rate: 29
    I added 2 lines and everything works.
    Thank you for your guidance.

    Code: C / C++
    Log in, to see the code
    .
  • #8 18600211
    Anonymous
    Level 1  
  • #9 18600722
    globalinfo
    Level 13  
    Posts: 430
    Help: 1
    Rate: 29
    khoam wrote:
    Variables production_Wh and use_Wh should be declared as atomic, if you use them in interrupts and the main program.
    .
    I have so declared
    Code: C / C++
    Log in, to see the code
    .
    Please give me a hint as to what this means
    Quote:
    declared as atomic
    .
  • #10 18600813
    Anonymous
    Level 1  
  • #11 18602349
    globalinfo
    Level 13  
    Posts: 430
    Help: 1
    Rate: 29
    It cannot compile for me after inserting these codes.
    Quote:

    collect2.exe: error: ld returned 1 exit status

    exit status 1
    Compilation error for the NodeMCU 1.0 board (ESP-12E Module).
    .
  • #12 18602362
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #13 18602395
    globalinfo
    Level 13  
    Posts: 430
    Help: 1
    Rate: 29
    I have cropped the paths because it is not possible to paste whole access paths.
    Quote:
    .
    /ld.exe: sketch\ Countermoj7042020.ino.cpp.o:( .iram.text.Countermoj7042020.ino.72.1+0x4): undefined reference to `__atomic_fetch_add_4'

    Licznikmoj7042020.ino.cpp.o: in function `count_use()':
    bits/atomic_base.h:614: undefined reference to `__atomic_fetch_add_4'.
    xtensa-lx106-elf/bin/ld.exe: sketch_countmoj7042020.ino.cpp.o: in function `count_productions()':

    atomic_base.h:614: undefined reference to `__atomic_fetch_add_4'.

    collect2.exe: error: ld returned 1 exit status

    exit status 1
    Compilation error for NodeMCU 1.0 board (ESP-12E Module).
    .
  • #14 18602410
    Anonymous
    Level 1  
  • #15 18602414
    globalinfo
    Level 13  
    Posts: 430
    Help: 1
    Rate: 29
    khoam wrote:
    What does the code for the count_use() and count_production() functions look like at the moment?

    Code: C / C++
    Log in, to see the code
    .
  • #16 18602432
    Anonymous
    Level 1  
  • #17 18602476
    globalinfo
    Level 13  
    Posts: 430
    Help: 1
    Rate: 29
    Yes and they still can't compile.
  • #18 18603608
    Anonymous
    Level 1  

Topic summary

✨ The discussion revolves around issues faced by a user with a NodeMCU V1 module after updating the Arduino IDE to version 1.8.12. The user reports that the module resets when using interrupts for pulse counting, specifically when the interrupt functions are included in the code. Various responses suggest checking the interrupt handler functions, ensuring they are placed in IRAM, and declaring shared variables as atomic to prevent race conditions. The user successfully resolves the issue by adding the ICACHE_RAM_ATTR attribute to the interrupt functions. Additional advice includes modifying the increment operations within the interrupt handlers to ensure proper compilation and functionality.
Generated by the language model.

FAQ

TL;DR: If your NodeMCU V1 started hard‑resetting after IDE 1.8.12, a 2‑line ICACHE_RAM_ATTR fix stops the "ISR not in IRAM!" panic—"Interrupt handler functions should have an attribute added to place them in IRAM." [Elektroda, szelus, post #18600043]

Why it matters: This FAQ helps ESP8266/NodeMCU users fix attachInterrupt resets and handle safe counter updates with WiFi enabled.

Quick Facts

Why is my NodeMCU V1 resetting right after attachInterrupt with WiFi on ESP8266?

Because the ISR is not in IRAM. After WiFi connects, enabling the interrupt causes “ISR not in IRAM!” and a panic reset before setup() finishes. The user verified this by printing checkpoints and seeing the crash right after attachInterrupt. [Elektroda, globalinfo, post #18599978]

How do I fix “ISR not in IRAM!” on ESP8266?

Place your ISR in IRAM using ICACHE_RAM_ATTR on both the prototype and the definition. Then attach the interrupt after pinMode. How‑To: 1) Add void ICACHE_RAM_ATTR isr(); 2) Define void ICACHE_RAM_ATTR isr(){...} 3) Call attachInterrupt(pin, isr, mode); The author reported that adding two lines solved it. [Elektroda, globalinfo, post #18600112]

Do ESP8266 ISRs really need to live in IRAM?

Yes. As one expert put it, “Interrupt handler functions should have an attribute added to place them in IRAM.” Without this, the core aborts with the panic you see. This requirement applies when using attachInterrupt on ESP8266. [Elektroda, szelus, post #18600043]

Where exactly does the crash happen in setup()?

It occurs immediately after calling attachInterrupt on the first input. The user inserted 10‑second delays between Serial markers (“spr3” to “spr4”) and saw the reset right there with “ISR not in IRAM!” in the log. [Elektroda, globalinfo, post #18599978]

Should counters updated in ISRs be atomic on ESP8266?

Yes. Declare shared counters as std::atomic<unsigned long> and include <atomic>. Atomic access prevents torn reads and maintains memory ordering between the ISR, the main loop, and WiFi background tasks. “Atomic type objects allow basic operations to be performed in an indivisible way.” [Elektroda, khoam, post #18600813]

I hit “undefined reference to __atomic_fetch_add_4” when building. What does that indicate?

It is a link‑time failure observed when using atomic increments on the ESP8266 toolchain. The error appears when the code uses atomic fetch‑add semantics, which the provided libraries did not resolve in that build. The posted log shows the exact message and halted link step. [Elektroda, globalinfo, post #18602395]

What’s the workaround for the atomic increment issue on ESP8266?

Inside the ISR, replace counter++ with counter = counter + 1; and keep ICACHE_RAM_ATTR on the ISR. This avoids the problematic increment form and compiles on the ESP8266 HAL. “It should compile and work.” [Elektroda, khoam, post #18603608]

Is testing with empty ISRs useful to isolate the fault?

Yes. Temporarily use empty handlers for the attached interrupts to confirm whether the fault lies in the ISR or elsewhere. If resets stop, the issue is inside the handler or its attributes, not in attachInterrupt itself. [Elektroda, Anonymous, post #18599559]

Do WiFi background tasks affect interrupt safety on ESP8266?

Yes. ESP8266 runs WiFi tasks concurrently. Shared variables touched by ISRs and other threads should be atomic, or guarded appropriately. This avoids race conditions when both the main loop and ISR update or read counters while WiFi is active. [Elektroda, khoam, post #18600813]

Which interrupt mode and pin configuration should I use for pulse inputs?

Use INPUT_PULLUP on the pin and trigger on FALLING edge for clean pulse counting from sensors or energy meters. This pairing matches typical open‑collector or dry‑contact pulse outputs and was used in the working code. [Elektroda, globalinfo, post #18599487]

How can I quickly locate where setup() fails?

Use a simple trace technique. 1) Insert Serial.println markers around suspect lines. 2) Add 10,000 ms delays to make logs readable. 3) Enable one feature at a time, like attachInterrupt, to see when it crashes. [Elektroda, globalinfo, post #18599978]

Will the ICACHE_RAM_ATTR fix apply to NodeMCU 1.0 (ESP-12E) boards?

Yes. The original reporter used a NodeMCU 1.0 (ESP‑12E). Adding ICACHE_RAM_ATTR on the ISRs resolved the resets immediately after the Arduino IDE update. They confirmed, “I added 2 lines and everything works.” [Elektroda, globalinfo, post #18600112]

Do I need to include the atomic header when using std::atomic on Arduino?

Yes. Always #include <atomic> before declaring std::atomic<unsigned long> variables. Without the header, types and operations may not compile or behave correctly across translation units in your sketch. This was explicitly noted alongside the atomic guidance. [Elektroda, khoam, post #18600813]
Generated by the language model.
ADVERTISEMENT