-
Notifications
You must be signed in to change notification settings - Fork 638
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
Fast spin of rotary encoder reboots firmware #1447
Comments
Attempting to isolate the problem by selectively commenting-out sequences has isolated the issue to be caused by the call "wsSend(_lightWebSocketOnSend)" in "void lightUpdate(bool save, bool forward, bool group_forward)" which is called from "void _encoderLoop()". Apparently the WEB _SUPPORT has reentrancy or timing issues that surface when there are rapid callbacks from the rotary encoder motion. For additional testing isolation a semiphore was added to _encoderLoop so that a callback is ignored if still busy servicing the prior callback. This did not improve behavior with resets still occurring. This seems to point to cpu use or timing issues associated with WiFi management. The presence or absence of MQTT_SUPPORT had no effect so this may provide some clue into likely culprit in WEB_SUPPORT. |
One additional test was to put the call "wsSend(_lightWebSocketOnSend)" inside the "if (save)" near the end of "void lightUpdate(bool save, bool forward, bool group_forward)" to reduce the frequency of the call to what is expected to be five seconds. This did not improve behavior so it seems timing by itself is not the total explanation. |
Espurna records the crash info, which can be retrieved by using Also, check if this helps: https://github.com/PaulStoffregen/Encoder/pull/15/files#diff-5c2d4a7e2bc119e539f0ad9df5ae59a6R192 |
Probably the solution would be to slightly defer the websocket update to avoid rapid requests. |
My thought as well and that is why I tried the websocket update in the same "save" conditional block as used for reducing flash write cycles. The issue still occurred. I do not know how frequent the "save" condition occurs vs. encoder update, but would think it would be on the order of seconds rather than milliseconds. I have built with conditional that bypasses websocket update if the reason for it started with encoder. Solves the reboot problem, but some functionality lost. |
Can you check the exception number though? Encoder generates interrupts -> system is busy handling them. Hence the error when wifi stack tries to do the job and Encoder handler disables every interrupt (noInterrupts() etc.) For the change you described - you placed it inside ticker callback function here? espurna/code/espurna/light.ino Line 472 in eb249dd
edit: github treating + as list :/ |
Reinstalled firmware that produces undesired behavior. Two attempts made to create failure mode. First one able to capture crash info, but unclear if it was a reset or if it was just a loss of the socket. The crash info was gathered after a new socket connection was made via browser. Second attempt resulted in an actual hard crash and not able to bring it back to life with a power cycle. I do not have ability to reflash with serial connection at this time. Debug while knob is spun until debug no longer updates the browser window ... ---8<------- [952137] [MAIN] ESPURNA 1.13.4-dev [952140] [MAIN] CPU chip ID: 0xC5F2DD Debug info after new browser page requested ...[007636] [WEBSOCKET] #1 connected, ip: 192.168.0.173, url: /ws ---8<------- [176138] [MAIN] ESPURNA 1.13.4-dev [176142] [MAIN] CPU chip ID: 0xC5F2DD
|
I reviewed the suggestion for "fix esp8266 crash on interrupt routines" and really do not understand what the effect of the code change is, but my understanding is the Espurna polls rather than uses interrupts for the encoder as its encoder configuration has "espurnaRegisterLoop(_encoderLoop);" |
Encoder library uses interrupts. Loop here only reads the last state. BTW the PR mentioned earlier may be incomplete, as I see isr0, isr1 etc. funcs are still in flash looking at resulting .elf. Slightly changed library here, with all relevant things marked using ICACHE_RAM_ATTR. Line 83 in 2cd80ca
- Encoder
+ https://github.com/mcspr/Encoder#esp8266/isr-in-ram I have not tested further than "it builds" |
I replaced the Encoder line in espurna/code/platformio.ini with https://github.com/mcspr/Encoder#esp8266/isr-in-ram and tried to build without success. The reference line "C:/Users/Dell/Downloads/espurna-dev/code/espurna/encoder.ino:11:0:" is the #include <Encoder.h> Compiling .pioenvs\magichome-led-controller-20\liba26\Embedis_ID408\Embedis.cpp.o In file included from C:/Users/Dell/Downloads/espurna-dev/code/espurna/encoder.ino:11:0: |
Oops. Updated for 2.3.0 |
Success with build but system behavior has not changed with reboot during knob spins. Reboot is assumed because switches are setup to set LED output to OFF on power up and the LED turns off when knob spins. Off state is confirmed when browser connection reestablished the status shows OFF. 1st test spinning knob until debug windows stops updating[049310] [WEBSOCKET] #1 connected, ip: 192.168.0.17, url: /ws New browser session established crash and info reports[061390] [WEBSOCKET] #1 connected, ip: 192.168.0.17, url: /ws [140820] [MAIN] ESPURNA 1.13.4-dev [140823] [MAIN] CPU chip ID: 0xC5F2DD 2nd test spinning knob back and forth until debug windows stops updating[178780] [ENCODER] Delta: -2 New browser session established crash report[104547] [WEBSOCKET] #1 connected, ip: 192.168.0.17, url: /ws 3rd test crash report[043083] [WEBSOCKET] #1 connected, ip: 192.168.0.17, url: /ws |
Thanks! At least now it is consistent in resets. I got PEC16-4220F-S0024 encoder to test this Instead of triggering on first read >0, I've replaced the handler to trigger on some predefined delta value accumulated from multiple reads in a row i.e. having "minimal step" before triggering any action. TODO related to this:
|
Thank you. It's hard. Thank you for sharing and waiting for the last perfect. |
@xoseperez to summarize
The general idea right now is to just import encoder library here as a sensor, allowing both the use for lights and general delta values reading. Functional interrupts are kind-of a hack (and sometimes break on the same caching problem), attachInteruptArg api is not present :/ I think it is also possible to do dispatching a bit different by reading gpio registers to "know" which pin triggered the change, and use a single function instead of isrN: |
Bug description
A slow detent-by-detent motion of rotary encoder results in expected level change behavior with limits at 0 and 255. Fast spin of the rotary encoder results in a reboot of Espurna firmware.
Related issue is that a single detent motion results in four updates of the LIGHT_STEP. For example if LIGHT_STEP is defined as 8, then a single detent motion from level 100 will be reflect in the Browser STATUS tab of 108, 116, 124 and then finally 132. Expected is a single update to 108 with a single detent motion.
Steps to reproduce
Steps to reproduce the behavior.
Build magichome-20 configuration with the following added
#define ENCODER_SUPPORT 1
#define ENCODER1_PIN1 1
#define ENCODER1_PIN2 3
#define ENCODER1_BUTTON_PIN 0 // active low by default, with software pullup
#define ENCODER1_CHANNEL1 0 // please note this value is 0-based (LIGHT_CH1 above)
#define ENCODER1_CHANNEL2 1 // please note this value is 0-based (LIGHT_CH2 above)
// Light Dimmer
#define LIGHT_STEP 8
Wires connected to controller RX, TX, 3.3V pads for rotary encoder CLK / DT / +.
Single detent move of encoder to produce expected result. Spin encoder and reboot occurs. This is reflected as the LED strip turning off, the browser page not reflecting OFF state of the LED and sometimes the WiFi SSID disconnects and then reconnects.
Expected behavior
No reboot with fast spin of encoder.
Screenshots
Device information
platformio run
Processing magichome-led-controller-20 (framework: arduino; platform: espressif8266@1.5.0; board: esp01_1m)
Verbose mode can be enabled via
-v, --verbose
optionCONFIGURATION: https://docs.platformio.org/page/boards/espressif8266/esp01_1m.html
PLATFORM: Espressif 8266 > Espressif Generic ESP8266 ESP-01 1M
HARDWARE: ESP8266 80MHz 80KB RAM (1MB Flash)
Converting espurna.ino
Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF MODES: FINDER(chain) COMPATIBILITY(soft)
Collected 54 compatible libraries
Scanning dependencies...
If you cannot get this info from the device, please answer this questions:
Tools used
Additional context
The text was updated successfully, but these errors were encountered: