ESP32 & analog: the world is more than on and off
420-302-VA · WEEK 8 · FALL 2026

Utility · use it before asking for help

Troubleshoot by layer

A new board brings a new failure ladder, and its first two rungs are new in kind: before any code can be wrong, the laptop must see the board, and the board must hold the right firmware. Climb in order; the lower layers are faster to check and more often guilty on day one.

Find the layer that failed

Four layers in order: A, connection, the laptop sees a serial port; B, firmware, MicroPython answers on the REPL; C, code, the MicroPython program is right; D, circuit, the divider and LED wiring are right AConnectioncable, driver, port BFirmwareflash, REPL answers CCodethe MicroPython program Ddivider, LED, pinsCircuit
Work left to right. No port is A. A port but no >>> (or no machine module) is B. Python errors and wrong logic are C, where Week 4's traceback skills and Week 5's traces apply verbatim, MicroPython's messages read the same way. Readings or LEDs that defy working code are D, and the wiring checks from Week 4 carry over with new pin numbers.

Symptom table

SymptomLayerMost likely causeWhat to do
Board's power LED lights, but no serial port ever appearsAA power-only USB cable, the single most common Week 8 fault; else the USB bridge driver (CP210x or CH340, per your board) is missingSwap for a known data cable first; then install the matching bridge driver and replug
Thonny: "Unable to connect" or garbage characters in the ShellA/BWrong port selected, or another program (a second Thonny window, a serial monitor) is holding the portPick the right port in the interpreter settings; close other serial programs; press EN to reset; replug as a last resort
Firmware install fails or stalls mid-flashBThe chip did not enter download mode, or a flaky cable/hub drops the streamHold BOOT while the connection starts, release after flashing begins; use a direct USB port; retry, flashing is safely repeatable
>>> appears but import machine fails with ImportErrorBThonny's interpreter is set to local Python 3, so the prompt is your laptop, not the boardTools → Options → Interpreter → MicroPython (ESP32); the banner should name MicroPython
Readings pinned near the top long before the light is brightCAttenuation never set: the bare converter saturates around 1 Vadc.atten(ADC.ATTN_11DB) right after constructing the ADC, every script
Readings stuck at one extreme and ignoring the flashlight entirelyDThe GPIO34 jumper is on the wrong breadboard node (not the midpoint), a divider leg is unseated, or the LDR is openPower off; re-trace supply → LDR → node → 10 kΩ → ground; confirm the jumper shares the midpoint row; reseat parts
Readings jitter by tens of counts at steady light–Normal converter and supply noise, not a faultAverage per the analog page; keep divider wires short; worry only if jitter is hundreds of counts
PWM LED looks off at "half": duty_u16(512)CA 10-bit duty() value fed to the 16-bit API: 512/65535 is under 1%Half is 32768 on duty_u16; convert via value/65535
External LED never lights at any dutyDWeek 4's classics at a new address: LED reversed, resistor or jumper unseated, or the wrong GPIO rowPower off; long leg toward GPIO25's resistor; re-trace the loop; test the LED at full-on with a plain Pin(25, Pin.OUT).on()
main.py runs forever and the Shell seems dead–Expected: the autostart loop owns the board until interruptedCtrl+C in the Shell to interrupt; rename or delete main.py on the device to stop autostarting
Blink works in Thonny, nothing on a chargerCThe script was run from the editor, never saved to the device as main.pyFile → Save as → MicroPython device, name it main.py, power-cycle to prove it
ValueError: invalid pin or a pin that will not do what the code asksC/DA pin outside the chip's capability for that job, most often an input-only pin asked to outputSee the pin traps; move to a capable pin and re-run

The pin traps

Two families of ESP32 pins deserve standing suspicion, and both traps are avoided by this week's assignments of record (GPIO2 onboard LED, GPIO25 output, GPIO34 ADC):

  • Input-only pins, GPIO 34 to 39. They have no output driver and no internal pull-ups: ideal ADC homes, dead ends for LEDs and PWM. Asking one to output fails loudly or, worse, silently; if an "output" mysteriously does nothing, check its number against this range first.
  • Strapping pins, notably GPIO 0, 2, 12 and 15. The chip reads them at reset to decide how to boot, so external circuits pulling them can stop the board starting or flashing. The onboard LED's GPIO2 is handled by the board's own design; your breadboard circuits this term simply stay off the strapping set, and the quick reference is the authority when in doubt.

Before you ask for help

  • Which layer (A to D) you reached, and the check that ruled out each one before it.
  • For A: the cable's provenance (known-data or unknown), your OS, and whether any serial port appears anywhere.
  • For B: what the Shell shows verbatim, banner or error, and whether a reflash was attempted with BOOT held.
  • For C: the exact bottom line of the traceback and the script, committed; MicroPython tracebacks read bottom-up like Week 4's.
  • For D: the circuit traced out loud against the divider figure or the LED loop, power off, and what a full-on plain-Pin test showed.