DS3231 (I2C 0x68):
- New velxio-ds3231 Web Component (4-pin module: GND/VCC/SDA/SCL) with
pinInfo per CLAUDE.md 6a; registered in elements-register + main.tsx.
- Catalog entry in scripts/component-overrides.json (_customComponents)
mirrored into components-metadata.json exactly as the generator emits it
(verified by cloning wokwi-elements and running generate:metadata: zero drift).
- The existing VirtualDS3231 device sim (DS1307-compatible time regs
0x00-0x06 + control 0x0E / status 0x0F / temperature 0x11-0x12 at 0.25 C
steps) is now user-reachable from the picker; the AVR/RP2040 attach path
gains live temperature updates via the SensorControlPanel (new ds3231
slider in sensorControlConfig).
GPS NEO-6M (UART talker, 9600 baud):
- New velxio-gps-neo6m Web Component (VCC/RX/TX/GND, pulsing PPS LED).
- New part sim GpsParts.ts: emits a valid GPGGA+GPRMC cycle per second
(correct XOR checksums, ddmm.mmmmm coords, UTC clock advancing 1 s/cycle)
with lat/lng/altitude/speed configurable via property dialog and live
via a new SensorControlPanel entry. Defaults: Madrid 40.4168 N 3.7038 W.
- Injection routes, chosen by classifying the wired board pin:
1) hardware UART RX -> new uniform sim.feedUart(uart, data) seam
(AVR USART0, RP2040 uart0/1 via rp2040js feedByte, ESP32 uart0/2 and
STM32 USART1/2 via their bridge shims); byte feed is paced in 8-byte
wall-clock chunks so 32-byte RX FIFOs never overflow;
2) any other digital pin on a cycle-accurate sim -> real 8N1 bit-banged
waveform via schedulePinChange, so SoftwareSerial decodes it;
3) feedUart rejection (e.g. Mega USART1-3, not modelled by avr8js)
degrades permanently to the bit-banged path.
- Interconnect already probed sim.feedUart; implementing it also upgrades
cross-board UART byte shortcuts for RP2040 uart1.
Tests: new gps-neo6m.test.ts (16 tests: NMEA builders, byte injection on
Uno RX0 / ESP32 RX2, Mega RX1 fallback, waveform decode back to $GPGGA,
live position updates, PPS pulse) + 3 new ds3231 AVR-path tests in
protocol-parts.test.ts. Full frontend suite: 2294 passed, 2 pre-existing
Galaksija Z80 timeouts that pass in isolation. npx tsc --noEmit clean.
New optional `featured` metadata flag: ComponentRegistry stable-sorts
featured components to the front after loading (and indexes categories
from the sorted list, so per-category views keep the same order). The
two breadboards are marked featured in component-overrides.json — they
are everyday parts and now open the component grid instead of sitting
at the bottom below every diode.
Two velxio-native passive parts, rendered as web components with
programmatic SVG + precomputed pinInfo (velxio-breadboard 830 holes,
velxio-breadboard-mini 170). Pin names follow the Wokwi convention
(holes `18t.d` / `17b.i`, rails `tp/tn/bp/bn.N`) and the metadata ids
are `breadboard` / `breadboard-mini`, so wokwi diagram.json zips
import/export with no aliasing.
Internal connectivity (5-hole column strips, full-length power rails)
is centralized in utils/breadboardNets.ts and wired into every net
consumer:
- NetlistBuilder: unionBreadboardGroups joins wired holes per group at
the union-find level in buildNetlist, buildWireNetMap and
buildBoardPinNetMap — SPICE, the circuit verifier and the voltage
overlay all see one net per strip/rail with no extra cards.
- DynamicComponent.traceDetailed: the digital trace hops through every
other wired hole of the entered group, so parts wired through a
breadboard still resolve their board pin (2-terminal
PASSIVE_PIN_PAIRS could not express N-hole groups).
Verified end-to-end in the app: Uno pin 8 -> full-board column ->
resistor -> mini-board column -> LED -> ground rail -> GND lights the
LED, and the HUD shows the 3 collapsed SPICE nets. 8 new unit tests
(breadboard-nets.test.ts); netlist-builder + circuit-verifier suites
stay green.
Adds `velxio-ssd1306-i2c-4pin`, a native 4-pin SSD1306 OLED module
(GND/VCC/SCL/SDA) — the cheap 0.96" I2C board most beginners actually have,
matching Wokwi's board-ssd1306. The 8-pin `wokwi-ssd1306` breakout stays; this
is the distinct 4-pin part (issue #215). Same SSD1306Core render pipeline
(imageData/redraw) so the display paints identically; I2C-only, address via the
i2cAddress property (default 0x3C). Styled after the existing 8-pin element
(blue PCB, dark screen, corner holes, star).
Ships four "SSD1306 OLED (4-pin I2C)" gallery examples wiring it over I2C on
Arduino Uno (A4/A5), ESP32 (21/22), Raspberry Pi Pico (GP4/GP5) and STM32 Blue
Pill (PB7/PB6).
The SSD1306 was three picker entries — a generic `ssd1306` with a protocol
selector plus `ssd1306-i2c` / `ssd1306-spi` shortcuts (issue #101) — all the
same 8-pin wokwi-ssd1306 element. That is confusing for one physical module
(issue #215). Wokwi ships a single I2C-only part; this goes one better: a
single part that auto-detects the protocol from the wiring, like a real
breadboard — CS or DC wired to a GPIO means SPI, otherwise I2C. No protocol
switch to set, just wire it up.
Works on every board with an I2C/SPI bus (AVR, RP2040, ESP32 Xtensa, STM32).
The ssd1306-i2c / ssd1306-spi ids stay as backward-compat simulation aliases
for projects saved before the merge, but are removed from the picker. Adds an
i2cAddress property (0x3c/0x3d) matching the real module and Wokwi.
Note: ESP32-C3, Raspberry Pi 3 and the bare RISC-V board do not emulate I2C/SPI
peripherals, so no I2C/SPI device (this or any other) attaches there yet.
Extends the over-voltage rule to the two cases the previous slice deferred:
- Boards (ESP32 / Pico / Arduino / ...): a board's supply pins all collapse to
the self-driven vcc_rail net, so an external source on them makes the .op
singular rather than readable. Added a graph-based check (runs before the
solve): if a power source is wired to a board supply pin and its nominal
voltage exceeds that pin's rating, warn. Threaded boardKind into
BoardForSpice so the verifier can look up the board rating.
- Electrolytic capacitors: new `voltage` rating property (select, default 25V,
on capacitor-electrolytic + cap-elec-* presets, via component-overrides +
regenerated metadata). The verifier reads the DC voltage across the +/- pins
and warns on over-voltage (vent/burst) and on reverse polarity (a polarized
cap wired backwards). Defaults to 25V when the property is unset.
Tests: 9V battery -> ESP32 VIN warns, 1.5V doesn't; 24V across a 16V cap warns,
5V across a 25V cap doesn't; reverse-biased cap warns. All real-ngspice.
The stepper-motor and biaxial-stepper parts only decoded a one-hot wave-drive coil sequence, so they never rotated under the common two-phase full-step / Stepper.h / AccelStepper drive that Wokwi's own examples use -- only the servo moved. Rewrote both decoders to track the net magnetic-field vector of the coils (atan2 of the H-bridge currents), so the rotor follows wave, two-phase full-step and half-step drive alike, whether driven directly from GPIO or through a driver's outputs.
Also adds an A4988 STEP/DIR stepper driver (parity with Wokwi's wokwi-a4988): velxio-a4988 element renders the real Pololu A4988 Fritzing breadboard SVG (public/components/a4988.svg); MotorDriverParts.ts finds the wired stepper via the netlist and advances it one (micro)step per STEP rising edge in the DIR direction (MS1-3 microstep + active-low ENABLE). Metadata in component-overrides.json. Three examples (Uno/ESP32/Pico) wire MCU STEP/DIR -> A4988 -> stepper, coil map aligned to Wokwi (1A->B+,1B->B-,2A->A+,2B->A-).
Verified in-browser: motor rotates on Arduino Uno (avr8js) and Raspberry Pi Pico (rp2040js). tsc --noEmit clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The KY-040 rotary encoder was already fully simulated (wokwi-ky-040 element + PartSimulationRegistry 'ky-040' driving CLK/DT quadrature and the SW button) and present in the catalog, but unfindable: named 'KY040', in the 'other' category, with no rotary/encoder search tags and a placeholder thumbnail. A user searching 'rotary encoder' got nothing (issue #104).
- generate-component-metadata.ts: let component-overrides.json patch category, description and tags on scanned wokwi parts (previously only name/thumbnail) -- the fields the picker category tab and ComponentRegistry.search() actually use. - component-overrides.json: ky-040 override -> name 'KY-040 Rotary Encoder', category 'input', rotary/encoder/knob tags, description, real encoder thumbnail SVG. - examples.ts: KY-040 + Arduino Uno example (quadrature read + SW reset). Regenerated components-metadata.json; searching rotary/encoder/knob now returns the KY-040. tsc clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two pieces of drift introduced in 305170a (Regulated Power Supply):
1. The committed components-metadata.json carries a custom rich
thumbnail SVG (showing 5.00V / 1.00A / PSU labels), but the
_customComponents override has no `thumbnail` field — so any
regen via `npm run generate:metadata` replaces it with the
generic placeholder. CI catches the drift and fails.
Fix: lift the rich SVG into the override entry.
2. The committed metadata description is a short one-liner while
the override description is the longer explanatory version.
The override is the source of truth, so the metadata now
matches: longer description wins.
Verified locally: regenerator now produces zero diff against the
committed metadata.
Adds a new picker entry 'Regulated Power Supply' under the analog
category. Conceptually fills the gap between wokwi-battery (fixed
DC) and wokwi-signal-generator (waveform focus): user chooses
voltage + mode (dc / ac) + currentLimit, no need to think about
battery chemistry or signal amplitudes.
Properties:
mode: 'dc' | 'ac' (default 'dc')
voltage: V (default 5)
frequency: Hz (default 50, only for AC)
currentLimit: A (default 1)
Design notes:
- No new Web Component. The tagName piggy-backs on
wokwi-signal-generator so the canvas renders the familiar
bench-instrument chrome — saves shipping a second 100+ LOC
Web Component for an identical 2-pin shape.
- SPICE: ideal V-source + ESR sized so a near-short reads
I ≈ 1.5·limit. ngspice has no native foldback so the limit
is a circuitVerifier rule, not a hard SPICE constraint.
- circuitVerifier: extends sourceComponents regex to include
power-supply AND honors the per-instance currentLimit
property as the threshold. Real bench supplies behave this
way — a 100mA-limited supply trips at 100mA, a 5A supply
tolerates 5A before flagging. The error code is
'source-overload' (not 'short-circuit') so the modal copy
matches what the user just configured.
The board GND / VCC pins of Arduino / ESP32 / etc. already act
as voltage sources via BOARD_PIN_GROUPS canonicalisation (the
NetlistBuilder maps wires to the right rail). So the user's
companion request — 'board pins should already work' — is the
existing behaviour; this commit only adds the standalone bench
supply for boardless circuits or for testing with a different
voltage.
- Implement HD44780Decoder for decoding I2C commands to HD44780-compatible LCDs.
- Add bmp280_bridge_reader.ino to read BMP280 chip_id and status registers via I2C.
- Create i2c_scanner_multi.ino to scan I2C addresses and report responding devices.
- Introduce lcd_i2c_hello.ino to demonstrate basic LCD functionality with I2C.
- Implement pcf8574_bidirectional.ino to test bidirectional communication with PCF8574.
- Add pico_i2c_master_reader.ino for reading BMP280 from a Raspberry Pi Pico.
- Create rtc_lcd_clock.ino to display time from a DS1307 RTC on an I2C LCD.
The hand-drawn SVGs in Bmp280Element.ts and Attiny85Element.ts were
functional but obviously amateur next to a real Fritzing-drawn part.
Both components now mount the equivalent Fritzing breadboard SVG as a
public static asset (`<image href>` in the shadow DOM SVG), with pin
coordinates remapped to the new artwork and pin-name labels overlaid
on top so the user can still read each connector at a glance.
frontend/public/component-svgs/bmp280.svg (new)
Verbatim copy of third-party/fritzing-parts/svg/core/breadboard/
bmp180_breadboard.svg. The Adafruit BMP180 breakout is the
mechanically identical Bosch predecessor — same I2C interface,
same 4-pin pinout. Pin labels lifted from the matching .fzp.
frontend/public/component-svgs/attiny85.svg (new)
Verbatim copy of the Fritzing ATtiny85 DIP-8 breadboard art.
Bmp280Element.ts
Width 80×100 px (Fritzing aspect 28.35:35.43 ≈ 0.8:1, exact uniform
scale of 2.822 px/mm). Pin coords for SDA / SCL / GND / VCC matched
to the connector centres in the source SVG. Pin labels overlaid on
top. Existing wired example (esp32-bmp280) re-routes automatically
because the wire system reads coords by pin name from pinInfo.
Attiny85Element.ts
Width 160×132 px (Fritzing aspect 28.801:23.768 ≈ 1.21:1, exact
uniform scale of 5.555 px/mm). The Fritzing layout puts pins on the
TOP and BOTTOM edges (4 each), not LEFT and RIGHT like the older
hand-drawn version. Pin coords land on clean numbers
(x ∈ {20, 60, 100, 140}, y ∈ {6, 126}). Built-in LED on PB1 stays
as an overlaid circle outside the chip body.
Wires in the existing attiny85-* examples re-route automatically by
pin name; external components positioned to the right of the chip
may need a manual nudge for clean routing — but they work.
frontend/src/components/simulator/BoardOnCanvas.tsx
attiny85: { w: 160, h: 100 } → { w: 160, h: 132 } to match the new
aspect ratio. Same width as before so the chip occupies the same
horizontal slot in existing example layouts.
scripts/component-overrides.json
BMP280 thumbnail updated to mirror the Fritzing colour scheme
(dark blue PCB, BMP180 silkscreen, four gold connector circles)
so picker and canvas feel consistent.
frontend/public/components-metadata.json
Regenerated.
docs/THIRD_PARTY.md
New "Fritzing parts library" section. Both new assets are listed
with their upstream paths plus the CC-BY-SA licence and link to
the parts repo. Future Fritzing copies must be added there too.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A beta tester reported "BMP280 - module graphic missing" — picking the
example loaded a working sketch but the canvas component fell back to
the MPU6050 placeholder.
Bmp280Element.ts already exists and registers velxio-bmp280 with the
right pinInfo, but it was never injected into components-metadata.json,
so the component picker and CircuitPreview didn't know about it. Add
an entry in scripts/component-overrides.json under _customComponents
(per CLAUDE.md §6b — direct edits to the generated JSON would be
clobbered by the next metadata regen) and regen.
The thumbnail mirrors the GY-BMP280 breakout look from the Web
Component itself: green PCB, black die label, four gold pin pads.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Implement UC8159cDecoder for handling 7-colour ACeP panels.
- Introduce painting functions for UC8159c frames in EPaperPart.
- Update EPaperPart to handle both SSD168x and UC8159c frame types.
- Add integration tests for EPaperPart and UC8159cDecoder.
- Create example sketch for 5.65" ACeP 7-colour panel.
- Enhance error handling in test cases for library dependencies.
The SPICE emitter already reads properties.lux (default 500, 100 nA/lux)
but the UI had no way to set it — the static dialog rejected the "range"
control type and there was no entry in SENSOR_CONTROLS for the live panel.
- Add photodiode entry in SENSOR_CONTROLS (slider 0-1000 lux)
- Register a minimal PartSimulationRegistry handler that forwards slider
values via emitPropertyChange so the netlist memo invalidates
- Switch the photodiode lux control from "range" to "number" so the
static ComponentPropertyDialog renders an editable input
- Modified the index file to reflect the new naming convention for Velxio components.
- Changed JSX declarations to use 'velxio-' prefix for various components.
- Updated component overrides to replace 'wokwi-' with 'velxio-' for logic gates and other components.
- Adjusted SVG generation script to use 'velxio-' prefix for BMP280 and Raspberry Pi components.
- Marked submodules as dirty in QEMU and RP2040 libraries.
- Added .prettierignore and .prettierrc.json for consistent code formatting.
- Introduced InstrumentComponent with support for Voltmeter and Ammeter, including pin information handling.
- Implemented a script to inject passive-component preset variants into `scripts/component-overrides.json`, including resistors, capacitors, and inductors with custom names and thumbnails.
- Added a new custom element `<wokwi-capacitor-electrolytic>` representing a polarized aluminum-can capacitor with appropriate SVG representation.
- Updated metadata generation to accommodate new component names and thumbnails for better user experience in the component picker.
- Marked submodules `qemu-lcgamboa` and `rp2040js` as dirty to reflect local changes.
Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual
Web Components covering logic gates, transistors, op-amps, regulators,
sources, electromechanical parts and integrated-circuit packaging.
Fase 9 — component catalog expansion
------------------------------------
- 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources
- 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs)
- 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl.
P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1
(hangs ngspice) to Level=1 with sane W/L
- 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation
rails + opamp-ideal
- 4 linear regulators (7805, 7812, 7905, LM317) with dropout
- 3 batteries (9V, AA, coin-cell) with realistic ESR
- Signal generator (sine / square / DC)
- 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven
current source)
Fase 10 — electromechanical + ICs
---------------------------------
- Relay (SPDT): coil + L + S-switch with native hysteresis +
flyback diode, inverted-control trick for the NC contact
- Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0)
- 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per
component (first mapper pattern emitting multiple device cards)
- 3 flip-flops (D, T, JK) — digital-sim only (edge detection is
not representable in ngspice .op)
- L293D dual H-bridge motor driver
Infrastructure
--------------
- scripts/component-overrides.json gains a _customComponents[] array
that lets new Velxio-only parts survive metadata regeneration
(previously applyOverrides() could only patch wokwi-elements
components that had already been scanned)
- scripts/generate-component-metadata.ts injects custom entries
before the patch loop
- New ComponentCategory values: 'logic', 'analog', 'electromech'
- frontend/src/components/DynamicComponent.tsx PASSIVE tracing
extended from just ['resistor','resistor-us'] to 9 two-terminal
passives with per-part pin name maps
- New CI workflow test-circuit.yml runs the sandbox on push/PR
- frontend-tests.yml regenerates metadata and fails if committed
JSON is stale
- Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md:
unicode in netlist titles silently hangs the parser, and
MOSFET Level=3 + W=0.1m causes .op to hang
- 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>