xoseperez / hlw8012

HLW8012 library for Arduino and ESP8266 using the Arduino Core for ESP8266.
GNU General Public License v3.0
125 stars 48 forks source link

ESP crash when using interrupts + webserver #1

Closed xoseperez closed 6 years ago

xoseperez commented 7 years ago

Originally reported by: Alexander Christian (Bitbucket: alexander_christian, GitHub: Unknown)


I'm using just the HLW8012 lib with my own sketch, which includes a webserver presenting the measurements... When using interrupts I face the following stacktrace when opening/loading the webpage:

#!arduino

0x40107314: interrupt_handler at ?? line ?
0x4010078f: ppProcessTxQ at ?? line ?
0x4020521e: HLW8012::cf1_interrupt() at ?? line ?
0x4010078f: ppProcessTxQ at ?? line ?
0x401072dc: interrupt_handler at ?? line ?
0x4020856c: hlw8012_cf1_interrupt() at ?? line ?
0x40107378: interrupt_handler at ?? line ?
0x40107362: interrupt_handler at ?? line ?
0x401048f9: ets_timer_disarm at ?? line ?
0x401072dc: interrupt_handler at ?? line ?
0x402101f0: pm_get_sleep_type at ?? line ?
0x40104e5e: spi_flash_read at ?? line ?
0x401077b4: pvPortZalloc at ?? line ?
0x4020fcb5: pm_set_sleep_time at ?? line ?
0x40210156: pm_get_sleep_type at ?? line ?
0x4021c7c8: tcpip_tcp_timer at /Users/igrokhotkov/espressif/arduino/tools/sdk/lwip/src/core/timers.c line 81
0x40210203: pm_get_sleep_type at ?? line ?
0x40212edd: ets_timer_handler_isr at ?? line ?
0x40212f22: ets_timer_handler_isr at ?? line ?

This also happens when no load is connected. So I guess it's not really load-related (like this very similar issue with very similar stack trace: https://bitbucket.org/xoseperez/espurna/issues/3/sonoff-pow-crash-with-high-wattage), but rather a kind of interrupt issue. Maybe in combination with the webserver?!

If I don't open/load/refresh the webpage, there's no crash.

If I switch to non-interrupt-mode, there is also no crash. But having precise measurement without interrupt (timeout >500ms, f.i. 5sec) will block the webserver :-( Even 500ms will give a bad user experience when loading the page.

Pls. help...

xoseperez commented 7 years ago

Changes included in version 1.0.1 of the library

xoseperez commented 7 years ago

Hi Sorry, been away for a while. Very useful information. Will update the library and my code. Thank you so much!

xoseperez commented 7 years ago

Original comment by Alexander Christian (Bitbucket: alexander_christian, GitHub: Unknown):


Still working fine. Webpage refreshes every 5sec and displays interrupt-measured values. Now running for ~45min... So I assume: Finally solved. Please consider putting the attribute to your lib and mention the use of the attribute in your documentation.

xoseperez commented 7 years ago

Original comment by Alexander Christian (Bitbucket: alexander_christian, GitHub: Unknown):


Issue solved for me.

Solution, according to https://github.com/esp8266/Arduino/issues/3337#issuecomment-307725009:

Put ICACHE_RAM_ATTR attribute to library's interrupt handler functions, as well as to interrupt-wrapper functions in sketch:

So, in HLW8012.cpp:

#!arduino

void ICACHE_RAM_ATTR  HLW8012::cf_interrupt() {
    unsigned long now = micros();
    _power_pulse_width = now - _last_cf_interrupt;
    _last_cf_interrupt = now;
}

void ICACHE_RAM_ATTR  HLW8012::cf1_interrupt() {

    unsigned long now = micros();
    unsigned long pulse_width;

    if ((now - _first_cf1_interrupt) > _pulse_timeout) {

        if (_last_cf1_interrupt == _first_cf1_interrupt) {
......

and in your sketch:

#!arduino

// redirect interrupt to HLW library
void ICACHE_RAM_ATTR  hlw8012_cf1_interrupt() {
  _hlw8012.cf1_interrupt();
}
void ICACHE_RAM_ATTR  hlw8012_cf_interrupt() {
  _hlw8012.cf_interrupt();
}

No crash since ~15min... Before it crashed within seconds...

xoseperez commented 7 years ago

Original comment by Alexander Christian (Bitbucket: alexander_christian, GitHub: Unknown):


looks like the ESP does not crash if I simply disable the "crashing" interrupt-handler:

#!arduino

  // attachInterrupt(GPIO_HLW8012_CF1, hlw8012_cf1_interrupt, CHANGE);
  attachInterrupt(GPIO_HLW8012_CF, hlw8012_cf_interrupt, CHANGE);

very weird... the only difference is then, that

Any ideas?

xoseperez commented 7 years ago

Original comment by Alexander Christian (Bitbucket: alexander_christian, GitHub: Unknown):


Also created an issue on esp8266 arduino core: https://github.com/esp8266/Arduino/issues/3337

xoseperez commented 7 years ago

Original comment by Alexander Christian (Bitbucket: alexander_christian, GitHub: Unknown):


Looks like it's esp8266 arduino core related?! --> https://github.com/esp8266/Arduino/issues/1020 But the suggested solution (disabling interrupts before actually handling interrupt code in HLW lib and enabling it again after) does not work/solve the problem.... Still facing crashes.