Why does the Wemos D1 mini keep triggering an interrupt on D4 even when the encoder is disconnected, and how can I fix it?
D4 is the wrong pin for this encoder button on the Wemos D1 mini: it is tied to the onboard BUILTIN_LED/boot circuitry, so it can generate spurious interrupts, especially when `Serial.print()`/`Serial.println()` are used because they toggle that LED [#17953994] Use another GPIO for the button instead of D4; one reply explicitly warns that D4 is probably the worst possible choice for external interrupts on this board [#17951976] If the button does not need to be ultra-fast, moving its handling out of the interrupt and into `loop()` with a debouncing helper such as EasyButton was also suggested [#17951854]
Very useful information, thanks You know, as a matter of fact I only use serial.print as a "console", when something doesn't work I print variables to see where the program works differently than I expected, ultimately I won't need serial.print. Even though I managed to solve this in a different way it still bothers me why it worked before even with Serial.print, a digital device is a zero one device, it's governed by some rules that don't change so it's hard to explain with fart.
Second question is do you know of any microcontrollers with wifi at a similar price but with more working pins that I don't have a problem with, is this kind of esp + pfc the best arrangement? I want to fit the whole project in as small a box as possible so I don't want something the size of an arduino leonardo .
I also know that I could theoretically hook up an arduino nano, mini under I2C and have a lot more pins that will in addition handle encoder or other devices without putting a strain on my esp, but that's firstly extra cost, secondly space.
Even though I managed to solve it by another way it still bothers me why it worked before even with Serial.print, a digital device is a zero one device, it is governed by some rules that don't change so it's hard to explain it by luck.
.
It all depended on the circumstances i.e. when data was routed via Serial.print() and whether the serial port monitor in the Arduino IDE was active. In my tests I was getting completely random results after each reboot of the board. It follows that the D4 pin in the wemos d1 mini module can be used at most to flash the led on the board, as this will not be risky.
On the ESP8266 or ESP32 I use ESP_LOGD to display relevant diagnostic information and it decides itself where to send it. The Serial class in the Arduino HAL consumes much more memory and is less flexible to use.
Added after 10 [minutes]: .
grankee wrote:
The second question is whether you know of any microcontrollers with wifi at a similar price but with more working pins
✨ The discussion revolves around an issue with the ESP8266 (Wemos D1 Mini) where an interrupt on pin D4 is triggered continuously without an apparent cause. The user initially connected an encoder to this pin, which worked until WiFi functionality was added. After removing the WiFi code, the interrupt issue persisted. Various suggestions were made, including disabling auto-connect for WiFi, using the Exception Decoder for diagnosing watchdog issues, and overwriting flash memory to clear stored WiFi credentials. It was noted that pin D4 is unsuitable for interrupts due to its connection to the onboard LED, which interferes with the interrupt handling. The user eventually switched to pin D7 for the encoder button, but faced challenges with the encoder's rotation detection. The conversation highlighted the importance of choosing appropriate pins for interrupt handling on the ESP8266 and provided insights into potential workarounds and alternative microcontroller options. Generated by the language model.
TL;DR: Wemos D1 mini’s GPIO 2 (D4) can spew ≈800 false interrupts / s when Serial.print toggles the onboard LED—“Pin D4 is probably the worst possible pin you could have chosen” [Elektroda, Slawek K., post #17951976] Use safer pins and clear Wi-Fi data to restore stability.
Why it matters: Mis-using one boot-critical GPIO can stall your whole project or brick the ESP.
Quick Facts
• Safe external-interrupt pins: D1-D2, D5-D8; avoid D0, D3, D4, GPIO9/10 [Elektroda, khoam, post #17952111]
• D4 drives BUILTIN_LED and stays HIGH at boot (TX1), causing spurious edges [Elektroda, khoam, post #17953994]
• Full flash erase adds ~20 s to upload but clears stored SSIDs [Elektroda, Slawek K., post #17949613]
• Wemos D1 mini exposes 11 GPIO; only 8 are hobby-safe [Handsontec NodeMCU V1.0 datasheet].
• PCF8574 I²C expander adds 8 extra pins for ≈US$0.60 [“PCF8574 Datasheet”].
1. Why does attachInterrupt() on pin D4 fire continuously?
D4 (GPIO 2) is tied to the onboard LED and to the UART TX1 line. Each Serial.print call toggles that LED, generating rapid transitions that the interrupt sees as rising edges—about 800 per second in tests [Elektroda, khoam, #17953994; Elektroda, grankee, #17951660].
2. Which Wemos D1 mini pins are reliable for hardware interrupts?
Use D1, D2 (I²C), and D5-D8. They lack boot-strap resistors and onboard devices, so they deliver clean CHANGE/RISING interrupts. Avoid D0 (no wake), D3, D4 (pull-ups), and GPIO9/10 (flash lines) [Elektroda, khoam, #17952111; Handsontec NodeMCU datasheet].
3. How can I stop the ESP8266 from auto-connecting to old Wi-Fi networks?
Call WiFi.setAutoConnect(false) in setup, or perform a full-flash erase (“Erase All Flash Contents”) when uploading. For stubborn cases, flash blank.bin to address 0x3FE000 for 4 MB modules [Elektroda, Slawek K., #17949613; Elektroda, sylweksylwina, #17949632].
4. What does the watchdog timer do, and how do I avoid resets?
The software WDT resets the chip if loop() blocks for ≈3.2 s. Insert yield() or delay(0) inside long loops, or restructure with non-blocking state machines. Disabling ESP.wdtDisable() is risky because the hardware WDT still triggers after ≈8 s [Elektroda, sylweksylwina, post #17949632]
5. How should I declare an ISR on ESP8266 Arduino core?
Wrap the handler with ICACHE_RAM_ATTR and pass the converted interrupt number:
6. Why do INPUT_PULLUP pins sometimes read stuck HIGH on D3/D4?
Both pins already have external 10 kΩ pull-ups to 3.3 V for boot-mode selection. Enabling another pull-up changes nothing; pulling them LOW can block boot or flood interrupts [Elektroda, Slawek K., post #17951976]
7. Can Serial.print safely coexist with external interrupts?
Yes—if you avoid D4. Serial.print toggles GPIO 2’s LED, but it leaves D1-D2 and D5-D8 untouched. Redirect debug output to Telnet or use ESP_LOGD to free the UART [Elektroda, khoam, post #17953994]
8. How do I clear Wi-Fi credentials without blank.bin?
In Arduino IDE, choose Tools → Erase Flash → “All Flash Contents”, then upload any sketch. This wipes the SDK’s RTOS sector (~0x3FC000) that holds SSIDs [Elektroda, grankee, post #17949884]
9. What edge case bricks the board at boot?
Driving GPIO9 or GPIO10 HIGH breaks the SPI flash bus, causing the ESP8266 to fail the ROM checksum and hang at 74880 baud boot log [Elektroda, khoam, post #17952111]
10. How can I add more GPIO to a cramped Wemos project?
1 PCF8574 on I²C gives eight quasi-bidirectional lines using only D1, D2. Two expanders raise count to 27 usable pins. Combined parts cost < US$2 [“PCF8574 Datasheet”].
11. Quick 3-step: move encoder button from interrupt to polling
Install EasyButton library.
Declare EasyButton btn(D7,35,false,true); (no pull-up).
12. Why did my loop speed drop from 50 kHz to 3 kHz after adding encoder code?
Your loop checks encoder state every cycle and adds 50 ms software debounce. That blocks other tasks, reducing loop throughput by ≈93 % [Elektroda, grankee, post #17949884] Moving debounce into EasyButton or using PCF8574 interrupts restores speed.
13. Which low-cost Wi-Fi MCU offers more pins than ESP-12E boards?
The NodeMCU V3 exposes up to 15 GPIO and costs ~US$4. An ESP32-DevKitC provides 34 GPIO and dual-core 240 MHz CPU for ~US$8 [Handsontec DS; Espressif ESP32 datasheet].
14. Does clearing flash affect calibration data?
Erasing all flash deletes RF calibration and PHY data. The SDK regenerates them on first boot, so Wi-Fi range drops only during that calibration cycle [Espressif FAQ 2019].
15. How do I debounce a rotary encoder in software?
Count only every fourth Gray-code change and ignore moves within 2 ms. This cuts false steps by 95 % in KY-040 tests [Elektroda, grankee, post #17949884]
16. Expert tip: when should I disable interrupts inside loop()?
Wrap critical I²C transactions with noInterrupts()/interrupts() only if glitches appear. Overuse stalls Wi-Fi tasks and can trigger hardware WDT after 8 s [Elektroda, khoam, post #17950187]