Skip to content

Troubleshooting

Common failure modes, what causes them, and how to recover. For hardware-level diagnostics see the Hardware section.


Boot Issues

Symptom: No serial output at boot

  • Check baud rate — 230 400, 8N1. Not 115 200.
  • USB-C cable — must be data-capable (not power-only).
  • Try a different USB port — some hubs flake.
  • Verify USB power jumper if you removed the battery jumper.

Symptom: Boot loops (repeated === SYSTEM STARTUP ===)

Most common causes:

Cause Indicator Fix
FATAL: ... ps_malloc failed Boot log shows the failed allocation PSRAM is missing or mis-detected. Verify the WROOM-1 part has the -N16R8 suffix (16 MB flash, 8 MB PSRAM). Rebuild with PSRAMMode=enabled
Watchdog reboot during setup Guru Meditation Error or rst:0xc reset reason A specific setup step is hanging. Comment out subsystems one at a time to bisect — start with initializeHardware()
Brownout rst:0xf (BROWNOUT_RST) Power supply can't deliver enough current during boot. Add bulk capacitance at the input
Stuck on Cannot continue without filesystem LittleFS mount failed A previous flash corrupted the user data partition. Power-cycle once more; if it persists, perform a factory reset via GPIO45 LOW boot

Symptom: Booted but no WiFi network appears

  • First boot detection — the firmware enters CONFIG mode automatically on first boot. The AP should be at ALTERNATOR_WIFI / alternator123.
  • GPIO46 stuck low — also forces AP mode. Check the boot serial log; "GPIO46 LOW: OPERATIONAL AP MODE" means the pin is being held low.
  • GPIO45 stuck low — forces CONFIG mode regardless of saved credentials. Check for "GPIO45 LOW: FORCED CONFIGURATION MODE" in the boot log.
  • WiFi hardware fault — rare. Look for "WiFi connection failed" repeats in the serial log.

Forced recovery (any state)

Trick Effect
Hold GPIO45 LOW at boot Forces CONFIG mode with default AP credentials. Alternator disabled
Hold GPIO46 LOW at boot Forces AP mode with custom credentials. Full alternator operation
Hold GPIO41 LOW at boot Boots from factory partition (recovers from a bad OTA image)

Each pin has its own dedicated solder pad / pin header on the board — see the schematic for the exact location.


WiFi / Dashboard Issues

Symptom: Dashboard won't load

  • Wrong URL — Client mode uses http://alternator.local. AP mode uses http://192.168.4.1. Use HTTP, not HTTPS.
  • mDNS not resolving — some networks block mDNS. Try the IP directly: in client mode, find the IP from your router's connected-devices list.
  • Browser cache — hard-reload (Cmd-Shift-R / Ctrl-F5) once. The dashboard is a single static file, so cache issues are rare but possible.
  • Capacitor app — see JavaScript Logic → Reconnect Logic.

Symptom: Dashboard loads but values don't update

  • Connection indicator (top right) — should be green. Yellow = reconnecting. Red = SSE stream lost. Manual reconnect button forces a retry.
  • CSV schema mismatch — open the browser console (F12). A warning like [CSV1] schema mismatch: ESP32=34, UI=33 means the firmware and dashboard versions are out of sync. Re-flash both web files (flashFactory or flashOTA) and firmware together.
  • 5+ minutes of disconnects, then auto-retry stops — Reconnect cap hit (MAX_SSE_RECONNECTS = 10). Press the manual reconnect button.

Symptom: Settings save fails

  • Password unlocked? — most forms require the password. Enter it in the header.
  • Password forgotten — boot with GPIO45 LOW to enter CONFIG mode with default password reset, or perform factory reset via the dashboard.

Charging Issues

Symptom: Field never engages (duty stays at 0)

  • Ignition not detected — verify wiring to the ignition input (GPIO1, optocoupler). The dashboard shows IGN status in the header.
  • OnOff toggle off — the master alternator-enable toggle in the header.
  • BMS gate — if bmsLogic == 1, the BMS input (GPIO42) must be in the active state. Check bmsLogicLevelOff polarity setting.
  • In Idle stage (UseFloat=0 post-absorption) — by design. Will rebulk on voltage sag or discharge current.
  • In Lockout — a recent safety event triggered the cooldown (FIELD_COLLAPSE_DELAY, default 30 s). Wait it out; the dashboard shows remaining seconds.
  • In Limp HomeLimpHome == 1 is set. Console will show "LIMP HOME MODE" every 30 s.
  • RPM < MinRPMForField — engine not running, or RPM sensor not reading. Check Channel 2 raw voltage on the dashboard.
  • Weather mode disabled chargingcurrentWeatherMode == 1 means the forecast says solar is sufficient. Disable in Settings → Weather to override.

Symptom: Field engages but voltage doesn't reach bulk

  • uTargetAmps capped by RPM table — at low RPM the cap table is low by design. Increase the cap-table entry for your operating RPM if your alternator can sustain it.
  • Thermal deratethermalPenaltyAmps > 0. The temperature loop is reducing current to protect the alternator. Look at AlternatorTemperatureF and projectedTempF.
  • MaxTableValue ceiling — sanity cap on the cap table. Increase only if you understand the consequences.

Symptom: Voltage overshoots target

  • Group 1/2/3 overvoltage supervisors not tuned — if the dashboard shows frequent fastOvClampCount increments and cv_I collapses, the CV loop is over-correcting. Run the CV Tuning test to find better VoltageKp / VoltageKi values.
  • Load dumpg_loadDumpCount incrementing means loads are switching off and the current spike is being caught. Working as intended.
  • System voltage class mismatch — verify BulkVoltage is in the right range for your battery (e.g. 14.4 V on a 12 V system, not 14.4 V on a 24 V system).

Symptom: Repeated lockouts

  • Sensor disagreementBatteryV (ADS) vs IBV (INA) differ by more than VoltageDisagreeThreshold for VoltageDisagreeTimeout. Check wiring, calibration, and noise on both inputs.
  • Voltage spikeAlternatorHardShutdownV exceeded. This is by design; it means the system saw a dangerous voltage. Look at the cv-log for what happened.
  • Temperature warning sustainedTempToUse > TemperatureLimitF + TempWarnExcess continuously for TempSustainedTimeout (default 2 min). Reduce alternator load, improve cooling, or raise TemperatureLimitF if your alternator is rated for higher.

Sensor Issues

Symptom: Temperature stale / 20 s cut

  • TempTask hung — Console will show "CRITICAL: TempTask hung up". Indicates Core 0 has stalled. Most often caused by I²C bus issues affecting other Core 0 work.
  • DS18B20 read failures — open Live Data → Stats, look at tempReadFailCount, tempCrcFailCount, tempCrcRecoveredCount. Climbing CRC failures = noisy bus, marginal pull-up, or corroded crimp.
  • Auto-disable — after enumeration failure, the task retries every 5 s. If the sensor was hot-unplugged, it stays disabled until reconnected.

Symptom: ADS1115 errors

  • adsI2CErrorCount climbing — bus contention or wiring fault. Inspect cabling.
  • adsSlowReadCount non-zeroI2C operation took > 5 ms. Indicates bus stall. Bench-test with a logic analyzer.
  • ADS1115Disconnected = 1 (auto) — 5 consecutive failures. Re-enabling requires reboot, or set to 0 via /get after fixing the wiring.

Symptom: INA228 errors

  • INA228 read failed in console — the I²C transaction threw an exception. Throttled to one per 10 s.
  • INADisconnected = 1 — manual disable (no auto-disable for INA228 right now). Voltage/current freeze at last value.

Symptom: IMU disabled

  • imuEnabled = false with "IMU disabled: N I2C errors in 60s" — 10+ I²C failures in any rolling minute. Check IMU wiring and I²C bus integrity. Bus speed is intentionally 800 kHz which is out of spec for the LSM6DSOX — if errors persist, drop to 400 kHz (Wire.setClock(400000) in initializeHardware()).

Crash / Reset Investigation

Reading the reset reason

The dashboard's Stats panel shows LastResetReason. Values:

Reason Meaning
POWERON_RESET Normal cold boot
SW_RESET Firmware called ESP.restart() (factory reset, scheduled maintenance, post-OTA)
INT_WDT, TASK_WDT Watchdog timeout — Core 1 hung
PANIC Crash — see coredump partition
BROWNOUT Supply voltage dipped below brownout threshold

Decoding a crash backtrace

When the device prints Guru Meditation Error followed by a backtrace, use the addr2line workflow from Configuration → Backtrace Decoding.


Cloud / OTA Issues

Symptom: Cloud upload says "queued" but never completes

  • WiFi RSSI — uploads gate on RSSI ≥ −76 dBm. Weak signal blocks uploads.
  • fieldOffSettled(10 s) gate — the field must be off for 70 s before uploads run. Cycling the engine on/off resets the timer.
  • Backoff active — after 5 consecutive failures, uploads suspend for 30 s. Console shows "Cloud sync paused, too many failures."

Symptom: OTA update fails

  • Signature verification fail — wrong bundle for this device, or the public key in firmware doesn't match the signing private key. Check OTA_PUBLIC_KEY in Xregulator.ino against the build pipeline.
  • Heap integrity fail — system is in a degraded state. Boot from factory partition (GPIO41 LOW) to clear, then retry.
  • Mid-download disconnect — automatic rollback. Factory partition keeps running.

Recovery from a bad OTA image

  1. Power off the regulator.
  2. Ground GPIO41.
  3. Power on. Boot log will show "We are in factory partition."
  4. Connect to the dashboard normally and clear the bad OTA from the Cloud → Firmware tab.

Last-Resort Recovery

Factory reset (preserves nothing)

  • Via dashboard — Settings → System → Factory Reset (requires password). Wipes all LittleFS settings, clears all NVS, restarts.
  • Via GPIO45 boot — enters CONFIG mode with default credentials so you can at least reach the device, but does NOT wipe settings. Use to recover from a lost password without losing data.

Re-flashing firmware over USB

If OTA is broken and GPIO41 boot doesn't help, fall back to USB-C:

  1. Connect USB-C.
  2. Hold GPIO0 LOW, press Reset, release GPIO0. The chip enters bootloader mode.
  3. Run flashFactory from the project shell.

Firmware re-flash never touches user settings — LittleFS and NVS partitions are preserved.


Getting more help

  • GitHub Issuesgithub.com/markliquid1/Regulator2026-public/issues for bug reports and feature requests.
  • Console output — the dashboard's Console tab is the live serial-equivalent log. Save it before reporting an issue.
  • Stats panel — Live Data → Stats shows error counters and runtime diagnostics. Include them in bug reports.