The slide-switch SPICE model only wired pin 1 <-> pin 2 (an SPST), ignoring
pin 3. The part is really an SPDT whose common wiper (pin 2) selects pin 1 at
value=0 or pin 3 at value=1, so a switch wired GND-1 / signal-2 / VCC-3 (the
natural Wokwi hookup) could never pull its signal high. Fixes the reported
ESP32-C3 case (issue #247) where only the green LED lit and the switch never
toggled the red one.
Second cause on that board: the ESP32-C3-DevKitM-1 exposes its supply as
3V3.1/3V3.2 and 5V.1/5V.2 (there is no bare 3V3/5V pin). VCC_PIN_RE has no
numeric-suffix branch on purpose (a dual-supply pin such as L293D VCC2 must
not collapse onto the shared logic rail), so those numbered pins floated at
0 V and the switch's HIGH side was dead. List them in boardPinGroups for
esp32-c3 / esp32-s3 / esp32-cam.
- componentToSpice: SPDT emission (both throws, complementary 0.01/1e9 R).
- digitalGateEngine: both driveSwitch paths (all-digital + mixed) made SPDT to
match, so the pure-digital paint and the ngspice solve agree.
- examples-digital / examples-circuits: rewire every slide-switch so the rail
feeds pin 3 and pin 1 is the value=0 throw, preserving value=ON=HIGH.
- spice-slide-switch-spdt-repro test reproduces issue #247 at the netlist level.
The pushbutton was modelled as a switch between only 1.l and 2.l; the
other two legs (1.r, 2.r) connected to nothing. Wiring GND/GPIO to those
legs silently produced a dead button, and the failure was invisible.
Model it like hardware: 1.l is internally shorted to 1.r and 2.l to 2.r,
and pressing bridges terminal 1 to terminal 2. Wiring to any leg now
works, and putting GPIO and GND on the same terminal is a dead short,
exactly as on a real tactile switch. Back-compat A/B variant preserved.
The NTC breakout's SPICE topology was inverted relative to the example
sketch's decode formula (rNtc = R_PULL * v / (5 - v)), which assumes a 10k
pull-up from VCC to OUT and the NTC from OUT to GND. The mapper had the NTC
on top (VCC->OUT) and the pull-down on the bottom, so the recovered
temperature ran backwards: dragging the slider to 100C made the sketch
print -25C. Swap the two resistors so V_OUT = 5 * Rntc / (Rntc + Rpull),
matching the sketch and the hand-built reference netlist in
spice-avr-mixed.test.ts (T=0 -> ADC 789, T=25 -> 511, T=50 -> 270).
Also replace the SensorParts linear approximation (2.5 - (t-25)*0.02) with
the same beta-model divider so the non-SPICE ADC injection decodes back to
the slider value, and drop the dead onInput path that treated the element's
value as a raw ADC count.
Reset now restores interactive sensors (temperature/lux/gas sliders) to
their configured defaults: resetBoard re-dispatches each sensor's default
into the running sim and bumps sensorResetNonce so the open
SensorControlPanel remounts and the slider snaps back. Previously a restart
left the NTC frozen at the last dragged temperature.
Updated the examples netlist snapshot for the swapped NTC cards.
The Pico W WiFi showcase examples are a paid-overlay feature now (the WiFi
engine moved to the overlay). Read them through a build-time `@pro` seam so the
SSR prerender + gallery + sitemap include them when built with the overlay, and
OSS gets an empty stub.
- data/examples.ts: import { proExamples } from '@pro/data/proExamples' (static,
build-time) instead of the local examples-picow-wifi.ts; delete that file.
- src/__pro_stub__/data/proExamples.ts: OSS no-op (empty list) for the @pro alias.
- vitest.config.ts: mirror the @pro alias (stub by default / overlay when
VITE_PRO_BUILD) so tests loading examples.ts resolve it.
- scripts/generate-sitemap.mjs: also parse <PRO_OVERLAY_PATH>/data/proExamples.ts
when building with the overlay (the script reads example IDs from source text,
so it can't follow the alias).
- Tests: drop the picow-wifi import/usage from the 5 OSS example tests (they
validate the OSS set now); prune the 4 obsolete picow netlist snapshots. The
overlay's proExamples get their own coverage in pro/.../__tests__/.
The stored snapshot predated the relay-LED netlist emission (current-sense
V-source + LED diode model), so examples-netlist-snapshot failed on a clean
checkout regardless of any source change. Regenerate it to match the current
NetlistBuilder output. Unblocks the deploy test gate.
A board example proving digital and analog coexist in ONE circuit: the Arduino
drives two logic levels, a physical AND gate combines them, and the AND output
switches an NPN 2N2222 transistor that drives the "motor" LED. Verified live: it
compiles, the MCU drives the AND gate (5 V), the transistor conducts and the LED
lights — MCU -> logic gate -> transistor -> load works across the digital and
ngspice motors together.
Known limitation (sim-mixedmode step 2, pending): the ngspice side does not
re-solve on every MCU pin edge, so a fast (1 Hz) blink does not track in real
time — the analog output changes on a slower cadence. User-driven / slow changes
track fine. Snapshot updated for the new example.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The AND Gate Alarm needed BOTH inputs HIGH at once, but it used momentary
pushbuttons buffered through an Arduino — with one mouse you can only hold one
button at a time, so the AND never fired and the alarm could never be
demonstrated.
Rebuilt it as a board-less digital circuit: two SLIDE switches (they latch) feed
a real AND gate that drives the alarm LED. Slide both switches ON and they stay,
so the alarm arms. No MCU / compilation — it runs on the digital gate engine.
Verified live: the LED lights only on 11 (00/01/10 -> off, 11 -> on).
Snapshot updated: the new board-less and-gate-alarm netlist, plus the digital
bucket count label (38 -> 39) from the earlier ripple-counter example.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Snapshot was written when the example had components: [] and wires:
[]. Now that 5bd541e populated the circuit (OLED + 2 buttons) and
2dea3f0 renamed the OLED pins to match wokwi-ssd1306's real
pinInfo, the netlist contains the button pull-down resistors and
floating-net autopulls. Regenerated with `vitest run -u`.
Three failures introduced by 603b791 (which added
MAPPERS['photoresistor-sensor'] = MAPPERS['photoresistor'] so the
metadata-id 'photoresistor-sensor' resolves to a SPICE mapper):
- component-to-spice.test.ts "every mapped metadataId has a test fixture"
flagged photoresistor-sensor as missing. Added a fixture entry that
mirrors the photoresistor one — the part is electrically identical.
- examples-netlist-snapshot.test.ts > photoresistor-light and
> nano-sensor-station snapshots now contain R_ldr_ldr + R_ldr_pull
cards (correct LDR + 10k pull) instead of the previous
R_autopull_n0 100M stub. This is the intended behaviour change:
before the alias the LDR was unmapped and the netlist autopulled the
net to ground with a 100M dummy; after the alias the SPICE deck
carries the real divider topology. Regenerated only these two
snapshot entries (vitest -u on the single file).
No production code changes.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two follow-ups to the realistic-simulator sprint:
1. component-to-spice.test.ts requires every mapped metadataId in
componentToSpice.ts to have a corresponding MINIMAL_FIXTURES entry
so the catalog-completeness assertion passes. Adds the power-supply
fixture (2 pins, default DC 5V/1A topology).
2. examples-netlist-snapshot.test.ts snapshot for mega-multi-led now
includes the new 8x 220Ω series resistors and the matching
autopull nodes. Net IDs shift from n0..n7 -> n9..n16 because the
resistor adds an intermediate node per LED. Verified the diff is
correct (every added R_r* card is a series resistor between the
board pin and the LED anode) before applying.
Snapshots the full SPICE netlist for every example across all six
data/examples-*.ts modules (168 examples total):
analog: 30, digital: 38, 100-days: 49, epaper: 7,
picow-wifi: 4, circuits: 40.
Pipeline: example → exampleToBuildNetlistInput → buildNetlist →
strip leading timestamp comment → toMatchSnapshot. Uses the
production helper (same one loadExample.ts uses) so any future
change to the brand-prefix rule / board filter / analysis picker
appears in the snapshot diff automatically.
To regenerate after a legitimate model change:
npx vitest run -u src/__tests__/examples-netlist-snapshot.test.ts
The PR diff of the snapshot file becomes the evidence of which
circuits change in response. Reviewer can scan the diff to confirm
the change is intended.
168 new sub-tests bring total to 1640 passing (was 1472).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>