Hardware · Firmware · Reverse engineering
A smart switch brought back: from a burnt Tuya chip to an ESP32-C3
A smart wall switch with a dead WiFi chip comes back to life with an ESP32-C3 soldered onto its original board, custom firmware and restart diagnostics.
- Year
- 2026
- Status
- In use: controls a water pump
- Role
- Diagnosis, electronic adaptation and firmware
- Repository
- Repository coming soon
01 · Problem
The WiFi chip (BK7231, Tuya WA2 module) of a smart switch burnt out. The rest of the board —capacitive power supply, relay, touch button and LED— was fine, but the device was useless.
02 · Approach
I identified the function of each pad on the board and soldered an ESP32-C3 Super Mini in place of the module. The board LED runs at close to 5 V, so I drive it through an NPN transistor (MPS2222A) to protect the 3.3 V GPIOs. I wrote the firmware from scratch.
03 · Result
Firmware v1.4.0 with control from the button, web, MQTT / Home Assistant and bilingual WebSerial; captive portal, OTA and status LED effects. After a restart incident with the pump, I added a persistent restart-cause log and a safe boot that will not turn the pump back on after a brownout.
04 · Stack
- ESP32-C3
- C++ / Arduino
- PlatformIO
- MQTT
- Home Assistant
- ElegantOTA
- WebSerial
- NPN transistor
Wiring
| Wire | Board pad | ESP32-C3 | Function |
|---|---|---|---|
| Red | VBat / VCC | 3V3 | Power from the AMS1117 regulator |
| Black | GND | GND | Common ground |
| Brown | PWM0 | GPIO4 | Button (LOW = pressed) |
| Green | PWM4 | GPIO3 | Relay (HIGH = on) |
| Blue | PWM1 | via transistor | Status LED |
The LED pad sits at 4.4–4.8 V with ripple from the capacitive supply. The original chip sank that current; an ESP32-C3 GPIO cannot take it. The NPN acts as a switch: the ESP32 only drives the base through 1 kΩ, and since it switches fast at 5 kHz, the LED also works as a dimmer for breathing and fade effects.
The pump incident
On version 1.3.1 the switch rebooted by itself and sometimes the pump started without anyone turning it on. I measured before changing anything:
- WiFi signal: −83 to −92 dBm (−86 average) over 158 samples.
- Link: 7.5 % packet loss and 11 % of API requests unanswered.
- Code: on boot, the relay was restored to ON right before the biggest current peak (WiFi start-up), and no restart cause was ever stored.
Main hypothesis: the Tuya board’s supply —designed for a chip that draws less— cannot handle the peak, the voltage drops, the ESP32 reboots and switches the pump on again. But there was also a reboot with the relay off, so I did not call the root cause closed.
What changed in v1.4.0
- Persistent log of the last 8 restarts (cause, previous uptime, relay state and signal) available in WebSerial, the API and as Home Assistant sensors.
- Safe boot: after a brownout or two unexpected restarts in a row, the pump is not switched back on automatically.
- The relay is held through restarts the firmware itself decides.
- Commands go through a queue and are applied in the main loop (no cross-task race conditions).
- Any retained MQTT command is cleared to avoid “ghost” switch-ons.
Honest status: the problem is mitigated in software; the new log will confirm the root cause, which most likely calls for a hardware fix (a dedicated supply or better signal).