Commit Graph

125 Commits

Author SHA1 Message Date
David Montero Crespo 0d5a1d5838 feat(motors): fix stepper rotation + add A4988 driver (real Fritzing SVG)
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>
2026-05-31 16:28:34 -03:00
David Montero Crespo 310271bdb2 feat(components): make KY-040 rotary encoder discoverable + add example (#104)
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>
2026-05-31 14:30:59 -03:00
David Montero Crespo 6813891f91 feat(boards): add 6 STM32 boards (F4 Discovery, Olimex H405, Netduino 2/+2, Pill variants)
Adds stm32-f4-discovery, stm32-olimex-h405, stm32-netduino-plus2, stm32-netduino2, stm32-blackpill-f401 and stm32-bluepill-f103cb, mapped to existing qemu-lcgamboa machines (netduinoplus2, olimex-stm32-h405, netduino2, stm32vldiscovery). A generic inline board renderer (no SVG) draws the Discovery/Olimex/Netduino boards from a header pin layout; the Pill variants reuse the Blue/Black Pill SVGs. Per-board onboard-LED pin and polarity via STM32_LED. One blink+serial example per board.

tsc --noEmit clean; all new FQBN pnum variants present in STM32 core 2.12.0; worker smoke tests pass for the new machines.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 03:19:26 -03:00
David Montero Crespo ca8dcedcc7 feat: STM32 (Blue Pill / Black Pill) QEMU emulation + Pro board gating
STM32 emulation (open-core, runs via libqemu-arm in the backend worker):
- backend: stm32_lib_manager + stm32_worker (GPIO, USART, I2C/SPI device models
  reusing the ESP32 slaves, live sensor updates), arduino_cli STM32 branch,
  start_stm32 simulation route.
- frontend: Stm32Bridge + Stm32BluePill(/BlackPill) web components (Wokwi SVGs),
  board kinds, Interconnect/boardPinMapping/boardProtocols wiring, example
  projects (blink, serial, I2C BMP280/MPU6050/DS1307/SSD1306/weather, 7-seg,
  RGB, button, switch, stepper, cross-board interconnect).
- Raspberry Pi 4/5 board elements + thumbnails.

Pro board gating (generic OSS->Pro seam; entitlement logic lives in the overlay):
- lib/proBoardGate.ts: isProBoardKind (STM32 + every QEMU Raspberry Pi),
  installBoardGateImpl/boardGateDecision, triggerProUpgradePrompt.
- PRO badge on those boards in the component picker; gate at the picker add +
  the run backstop (startBoard).
- backend/app/services/board_access.py: server-side enforcement seam for the
  simulation WebSocket; STM32/Pi unavailable -> Pro-framed message.
- desktop: generic QemuDownloadPrompt + Stm32QemuPrompt (download-behind-license,
  mirrors the ESP32 prompt).
- .gitignore: never ship libqemu-* binaries in the public image.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 19:06:14 -03:00
David Montero b09c8339ac fix(examples): use hardware I2C (not SoftI2C) in smart-ui-eyes
OSError: [Errno 19] ENODEV at ssd1306.SSD1306_I2C(...) on
100d-esp32-oled-smart-ui-eyes-animation-time-and-weather-micropython.

MicroPython SoftI2C bit-bangs GPIO directly. Velxio's ESP32 QEMU
bridge listens on the emulated I2C peripheral (registers slaves like
0x3C wokwi-ssd1306 against it) and doesn't decode bit-banged GPIO
toggles as I2C frames, so the OLED never sees any writes and
i2c.writeto() returns ENODEV on first use.

machine.I2C(0, ...) routes through the hardware I2C peripheral that
QEMU emulates, the registered slave receives the bytes, the OLED
panel updates. Same code path the other working SSD1306 MicroPython
examples on this repo already use.

API surface is identical to SoftI2C — only the constructor differs —
so the rest of the user sketch needs zero changes.
2026-05-23 18:06:42 +02:00
David Montero 0d43c5f892 fix: relax -Werror for user sketches + un-nest /* */ in robot-desktop-eyes
Two related fixes for the ESP32 Arduino-compat compile path:

(a) backend/app/services/esp-idf-template/main/CMakeLists.txt:
    Demote -Werror=comment / =parentheses / =sign-compare / =narrowing
    / =write-strings / =missing-field-initializers / =reorder back to
    plain warnings. ESP-IDF's project defaults are stricter than what
    Arduino/arduino-cli users expect, so common Arduino idioms (nested
    /* */, missing field initializers in struct literals, etc.) were
    failing builds that compile fine in the Arduino IDE. -Wall stays
    on; we just stop the abort.

(b) examples-robot-desktop.ts (robot-desktop-eyes example):
    Replace the nested /* xTaskCreatePinnedToCore( ... /* Task function. */
    ... */ block with `#if 0 / #endif` so the inner block comments
    don't terminate the outer one. Even with -Wno-error=comment the
    real-syntax-level issue (the first inner `*/` closes the outer
    comment, leaving the rest of the lines as bare code) would still
    bite, so this needs an actual code fix.
2026-05-23 16:19:56 +02:00
David Montero 1a6e2a23a7 fix(examples): auto-install libs for robot-desktop-eyes
Sketch fails to compile out of the box with
  fatal error: ESP32Servo.h: No such file or directory
because the ESP32Servo / U8g2 / DHT / Adafruit Unified Sensor libs
aren't part of arduino-esp32 and weren't declared on the example.

loadExample.ts already iterates `example.libraries` and runs
arduino-cli lib install for any missing entry before the user
touches Compile. Adding the four real deps the sketch needs gets
the example compiling cleanly on a fresh container without any
manual Library Manager dance.
2026-05-23 08:49:26 +02:00
David Montero 2dea3f0448 fix(examples): correct SSD1306 + big-sound-sensor pin names
robot-desktop-eyes and the day-30/100-days OLED example wired the
SSD1306 OLED with SDA/SCL/VCC, but the wokwi-ssd1306 element
exposes pinInfo as DATA/CLK/VIN/GND. The mismatched names couldn't
resolve, so all three wire endpoints fell back to (0,0) of the
component and visually attached to the corner instead of the pins.

Same class of bug on the wokwi-big-sound-sensor in
robot-desktop-eyes: the element has AOUT/DOUT (no plain OUT). The
sketch uses digitalRead(SOUND_PIN), so route to DOUT.

The COMPONENT_PIN_ALIASES map in wokwiZip.ts only normalises on
.zip import — static examples have to use the real pinInfo names.
2026-05-23 08:23:15 +02:00
David Montero 5bd541e56f fix(examples): add OLED + buttons circuit to ESP32 smart-ui-eyes example
The 100d-esp32-oled-smart-ui-eyes-animation-time-and-weather-micropython
example had components: [] and wires: [] — the MicroPython code wired
an SSD1306 OLED on I2C (GPIO 21/22) plus two buttons (GPIO 14, 27) but
the circuit had nothing on the canvas, so users saw a bare ESP32 board
and the simulation was missing every peripheral the code drives.

Adds:
- wokwi-ssd1306 on I2C (3V3 / GND / SDA=21 / SCL=22)
- two wokwi-pushbuttons wired HIGH-when-pressed (3V3 → 1.l, 2.l → GPIO
  14 / 27) to match the `if pin.value(): pressed` check in main.py
2026-05-23 08:16:13 +02:00
davidmonterocrespo24 28826e928e feat(examples): import robot_desktop — ESP32 animated-eyes face
Pulls https://github.com/davidmonterocrespo24/robot_desktop into the
examples gallery as a real-world ESP32 + sensors project. Cozmo-style
desktop robot: SSD1306 OLED face that blinks, looks around, and shows
emotions; DHT11 weather mode triggered after 10 min idle; PIR wakeup
from sleep; LDR-driven sleep when the room goes dark; sound-triggered
reactions; and two eyebrow servos.

Ships as 34 separate files (one .ino + 33 headers / source) rather
than the usual single-sketch flatten. The face engine
(Eye / EyeTransition / EyeVariation / FaceBehavior / FaceExpression
/ FaceEmotions / BlinkAssistant / LookAssistant / …) splits
responsibility across enough classes that flattening would obscure
the design. Velxio's multi-file `files: [{ name, content }]`
mechanism handles this cleanly — the editor mounts the .ino as the
active sketch and the rest sit in the same workspace.

Pre-placed components match the original board's pin map verbatim
from Common.h:

  - SSD1306 OLED on I²C (SDA=21, SCL=22 — ESP32 default)
  - DHT11 on GPIO 15
  - PIR motion on GPIO 4
  - Big sound sensor on GPIO 2
  - Photoresistor on GPIO 34 (ADC1)
  - Right eyebrow servo on GPIO 12
  - Left eyebrow servo on GPIO 13

Arduino libraries (U8g2lib, DHT, ESP32Servo, Adafruit_Sensor) are
auto-installed by velxio's Library Manager on the first compile.

Category 'displays', difficulty 'advanced', tags cover both the
sensor list and the project's identity (cozmo / robot / animation /
eyes) so the gallery search surfaces it from multiple angles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 00:29:25 -03:00
David Montero Crespo 603b791daa feat(attiny85+customchip): full ATtiny85 ADC/Timer0 + custom-chip pipeline fixes
ATtiny85 (AVRSimulator + collectPinStates + connectAnalogInputsToMcu + SimulatorCanvas + Attiny85Element + examples):
- Add attiny85AdcConfig with correct register addresses (ADMUX=0x27,
  ADCSRA=0x26, ADCSRB=0x23, ADCL=0x24, ADCH=0x25, DIDR0=0x34, adcInterrupt=0x08).
  Without this, analogRead() polled the wrong address forever and the
  firmware hung on first ADC read.
- Add attiny85Timer0Config + instantiate AVRTimer so OVF fires at the
  ATTinyCore-expected ~1.024 ms cadence. delay() advance is still blocked
  on avr8js TIFR auto-clear semantics (separate upstream issue, see
  ATTINY85_TIMER0_UPSTREAM_ISSUE.md in velxio-prod test plan).
- Map ATtiny85 ADC channels to PB-style pin names (PB5/PB2/PB4/PB3 -> 0..3)
  in connectAnalogInputsToMcu so SPICE node voltages reach the right ADC
  channel.
- Recognise /^PB\d+$/ in collectPinStates.pinNameToArduinoPin so wires
  named "PB1" emit v_attiny85_pb1 V-source and the LED responds to MCU
  writes. Previously every PB-wire returned -1 and SPICE saw no source.
- SimulatorCanvas: subscribe pin 1 (PB1) for the built-in LED on the
  attiny85 board kind (Digispark convention), instead of falling through
  to the pin-13 default.
- Attiny85Element: remove the hand-drawn "yellow LED" circle that was
  floating above the chip. The bare DIP-8 has no on-board LED; examples
  wire a real wokwi-led + resistor instead.
- examples.ts: add a real wokwi-led + 220 Ohm wokwi-resistor + wires to
  attiny85-blink, and add missing series resistors to attiny85-button-led
  and attiny85-ntc-sensor. attiny85-pwm-fade was already correct.

Custom-chip pipeline (CustomChipPart + simulatorBridges):
- Add a requestAnimationFrame loop that calls instance.tickTimers() every
  frame in CustomChipPart. Chips that register vx_timer_create (e.g. an
  i8080 stepping its core, or a sensor publishing samples) had timers
  added to the queue but nothing fired them; tickTimers was dead code.
- Gate the ESP32 backend path with detectSimulatorKind(sim)==='esp32'.
  The previous `typeof sim.registerSensor === 'function'` check matched
  AVR and RP2040 simulators too (they expose registerSensor for I2C
  sensor proxies), routing client-side chips to a non-existent ESP32
  worker on those boards.
- Replace direct simulator.usart.writeByte calls in avrUartTx with a
  JS-level FIFO + setTimeout(1ms) drainer. avr8js writeByte drops bytes
  under burst load (a chip emitting print_string lost ~99% of bytes via
  non-immediate, or kept only the last byte via immediate). The drainer
  attempts one non-immediate write per tick and retries on RXC busy /
  RXEN off. Added a guard for ATtiny85 (no USART -> would queue forever).

End-to-end verified: i8080-banner-streamer now prints the boot banner
followed by "uptime ticks: 0xNN" lines stepping every ~50 ms, executing
real Intel 8080 instructions inside the WASM chip.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 18:10:08 -03:00
David Montero Crespo dd22bcfe50 fix(ui+spice+example): interactive wokwi components, NTC formula, photoresistor alias
Three independent fixes uncovered during a systematic example-by-example
audit (plan/full_test_plan/):

1. DynamicComponent.handleMouseDown was calling e.stopPropagation()
   unconditionally in the capture phase. That swallowed pointerdown
   BEFORE wokwi-potentiometer / pushbutton / slide-switch / joystick
   could see it, so the rotary knob would not rotate and buttons
   wouldn't press even with a real OS mouse. Now we skip the swallow
   when the click target is an inner wokwi-* element during a live
   simulation, letting the wokwi component own its own pointerdown
   while still allowing the canvas drag-to-rearrange flow on the
   wrapper / non-interactive surface.

2. examples.ts uno-ntc (and pico-ntc) sketch had the NTC divider
   formula inverted relative to both the SPICE mapper topology
   (VCC -> R_NTC -> A1 -> R_pull -> GND, the standard module wiring)
   and real wokwi-ntc-temperature-sensor modules. Moving the slider
   to 60 C made the firmware print -3.42 C. Flipped the formula to
   r = SERIES_R * (VCC - v) / v. Now slider 60 C -> Serial reports
   60.12 C and A1 voltmeter shows 4.00 V.

3. componentToSpice.ts photoresistor mapper was only registered under
   the bare key `photoresistor`, but example components use the
   metadataId `photoresistor-sensor`. Added an alias so the LDR +
   pull-down divider gets emitted for the real component instance.

All three reproduce visually in seconds; documented per-example in
plan/full_test_plan/examples/.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 15:10:42 -03:00
David Montero Crespo 0e2f0790db feat(chips): C-to-Z80 compile via SDCC + LED chaser example
Adds a third format to /api/compile-rom: `c` (C source compiled by SDCC
to Z80 bytes). Same chip-program flow as 8080/Z80 asm — write C in a
project file, click Compile, click Run.

Backend:
- backend/app/services/c_compile.py — async SDCC wrapper. Locates the
  sdcc binary on PATH (or via SDCC env var, or common Windows install
  paths) and shells out with target=mz80 + --code-loc 0x100 --data-loc
  0x8000. Parses the resulting Intel HEX into raw ROM bytes. Pure 8080
  is rejected with a clear error (SDCC has no 8080 backend; Z80 ROMs
  also run on the i8080-cpu chip if you avoid Z80-only ops).
- rom_compile.py: compile_rom is now async; the new c branch delegates
  to c_compile. compile_rom_endpoint awaits it.

Frontend:
- romCompileService: RomFormat gains 'c'; formatForFile maps .c/.cpp to
  'c'. isChipProgramFile intentionally still excludes .c — disambiguation
  happens at the EditorToolbar level.
- EditorToolbar: the chip-program path also fires when a custom-chip
  has programFile === activeFile.name (regardless of extension). That
  lets .c files route to /api/compile-rom (SDCC) when bound to a CPU
  chip, while .c files NOT bound to any chip continue to route to
  arduino-cli as before.

Docker:
- Dockerfile.standalone adds `sdcc` to the apt-get install list, so the
  prod image ships with SDCC out of the box.

Example:
- /examples/z80-led-chaser-c — z80-cpu chip + chaser.c (a Larson
  scanner written in C with __at() MMIO definitions). Compiles cleanly
  with SDCC's --code-loc 0x100 default crt0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 00:31:10 -03:00
David Montero Crespo 96ef12b585 feat(chips): programmable Z80 chip + Larson scanner example
Adds the Zilog Z80 to the programmable-retro-CPU lineup. Same compile-rom
flow that landed for the 8080 in PR #189: write Z80 asm in a project
file, click Compile (backend assembles via in-tree two-pass asm-z80),
click Run, the chip emulator boots from the resulting ROM bytes.

Backend:
- backend/app/services/asmz80.py — two-pass Z80 assembler covering the
  practical demo subset: LD r,n / r,r' / rp,nn / (nn),A / A,(nn) +
  ALU r/n + INC/DEC + JP/JR/DJNZ/CALL/RET + PUSH/POP + IN/OUT +
  EX/EXX + LDIR/LDDR/IM/NEG + RLCA/RRCA/RLA/RRA + the simple
  ED-prefix variants. Not yet: CB-prefix bit ops, DD/FD index ops.
- rom_compile.py routes target=z80 through the new assembler.

Chip:
- frontend/src/components/customChips/examples/intel/z80-cpu.{c,chip.json}
  Generated by scripts/make-z80-cpu.py from the existing z80.c emulator
  (same clean-room implementation that passes ZEXDOC end-to-end). The
  external pin/bus protocol is replaced with internal RAM + ROM + MMIO
  for LED/BTN/UART. 35 KB WASM.

Example:
- /examples/z80-larson-scanner — Knight-Rider-style walking LED.
  Demonstrates JR/DJNZ/RLCA which the 8080 can't run.

Plus a small Z80 smoke-test asm under scripts/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 00:21:08 -03:00
David Montero Crespo bbf8cd0303 feat(chips): programmable retro CPU chips with external ROM
Adds a new way to use the retro CPU chips: write your program in a
project file (.s / .asm / .hex / .bin), click Compile, click Run, and
the same chip emulates whatever you wrote. Same chip + different ROMs =
mini PC, calculator, LED demo, Kill-the-Bit game, etc.

SDK:
- velxio-chip.h gets two new host imports:
    uint32_t vx_rom_size(void);
    void     vx_rom_read(uint32_t off, uint8_t* dst, uint32_t len);
  CPU-emulator chips call these in chip_setup to pull their program out
  of the host's romBytes property.

Frontend runtime:
- ChipRuntime accepts opts.romBytes (Uint8Array) and exposes the new
  imports, copying bytes into chip memory on vx_rom_read.
- CustomChipPart pulls component.properties.romBytes (base64) and passes
  it through.
- Component registry declares three new custom-chip properties:
  romBytes (base64), programFile (matching project filename), and
  programTarget (cpu name).

New programmable bundled chip:
- frontend/src/components/customChips/examples/intel/i8080-cpu.{c,chip.json}
  Same clean-room 8080 emulator as i8080-repl/i8080-counter, but ROM is
  loaded externally via vx_rom_*. Has 8 LEDs, 8 buttons, UART, 16 KB RAM,
  32 KB of external ROM.

Backend:
- New /api/compile-rom endpoint and rom_compile service that turns
  chip-program source into ROM bytes. 8080 ASM is assembled by the
  in-tree two-pass assembler (moved to backend/app/services/asm8080.py).
  Intel HEX records are parsed; raw .bin is passed through. Future targets
  (z80, 8086, 4004) are scaffolded but not wired yet.

EditorToolbar:
- Compile button detects when the active file is .s/.asm/.hex/.bin and
  routes to compile-rom instead of arduino-cli. The compiled bytes are
  injected into every custom-chip on the canvas whose programFile property
  matches the active filename (or is empty).

Example:
- /examples/i8080-killbits loads Dean McDaniel's 1975 Kill-the-Bit on
  the programmable i8080-cpu chip. killbits.s is shipped as a project
  file alongside sketch.ino; the user clicks Compile then Run and the
  LED walks across 8 outputs, buttons kill it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 23:38:18 -03:00
David Montero Crespo 81837eedb9 fix(spice+pipeline): LED visualization, INPUT_PULLUP, ESP32-C3, PWM fade, examples
End-to-end pipeline fixes uncovered while auditing the /examples gallery.
Each bug shipped past green unit + snapshot tests because none of those run
firmware + render LEDs. Added scripts/visual-led-test.mjs as a CDP-driven
visual harness that loads each example, runs the simulator, samples
`wokwi-led.brightness`, and asserts toggle / gradient / initial-off
invariants — exits non-zero on any regression.

Frontend simulator
- PinManager.updatePort: new optional ddrMask param. A pin is added to
  `outputPins` only if the DDR bit is set, so the PORTx write that
  enables INPUT_PULLUP (DDR=0, PORT=1) no longer falsely marks the pin
  as MCU output. AVRSimulator now reads DDRB/C/D (0x24/0x27/0x2A on
  Uno/Nano, 0x37 on ATtiny85, per-port table on Mega) and forwards it.
- AVRSimulator: pass DDR mask alongside every port-listener fire.
- BasicParts pushbutton{,-6mm}: seed pin HIGH in attachEvents so
  `digitalRead()` returns HIGH while idle. avr8js doesn't auto-simulate
  INPUT_PULLUP — without this the firmware reads LOW from boot and
  thinks the button is permanently pressed (the "LED is always on,
  pressing does nothing" UX bug).
- connectMcuEdgesToService: suppress synthetic digital edges on pins
  with active PWM, AND subscribe to onPwmChange to re-tick the netlist
  on duty changes. Fade-LED now produces a true gradient (6 distinct
  brightness levels across a fade cycle) instead of a binary 0/full
  toggle.
- CircuitSimulationService.handleMcuEdge: replace single-slot
  pendingMcuEdge with a per-pin Map. Multiple pins toggling during the
  same in-flight tick used to overwrite each other; now every pin's
  most-recent edge replays after the tick. Fixes Traffic-Light RED→
  YELLOW→GREEN sequencing.
- NetlistBuilder: new sanitizeSpiceId() helper replaces hyphens with
  underscores in V-source names. ngspice's interactive `alter` command
  treats `-` as an operator and silently no-ops on hyphenated source
  names, so mid-simulation MCU pin transitions stopped propagating
  after the first solve. MixedModeScheduler.onMcuPinChange and
  CircuitSimulationService self-heal use the same sanitizer so names
  stay consistent across emit/alter/lookup. Also added a regex-based
  fallback in step 2 so any board pin matching `GND.\d+` canonicalises
  to net "0" — ESP32-C3 dev kits expose up to 10 GND pins and the
  per-board `groundPinNames` list missed several, leaving wires
  floating instead of grounded.
- collectPinStates: emit V-sources only for pins in `outputPins`, not
  every wired board pin. Leaves INPUT pins (analog sensors on A0,
  pull-down dividers, etc.) free for the SPICE solver instead of being
  shorted to 0 V by an ideal MCU V-source.
- start.ts: extended __spiceDebug to also expose outputPinsByBoard +
  nodeVoltages + pinNetMapEntries for the visual harness.
- ESP32 / RP2040 / RISC-V / C3 simulators: pass `'mcu'` source flag to
  triggerPinChange / setPinState so the new outputPins tracking fires
  on those boards too (was AVR-only before).
- useSimulatorStore: stopBoard/resetBoard call pm.resetPinStates() so
  outputPins clears between runs; Esp32Bridge.onPinChange passes the
  `'mcu'` flag in all three places it's wired.
- types/board.ts: ATtiny85 FQBN `clock=internal16mhz` →
  `clock=16pll` (ATTinyCore 1.5.2 renamed the option).

Backend
- esp-idf-template/main/CMakeLists.txt: skip the
  `-DLED_BUILTIN=2` fallback for esp32c3 and esp32s3 targets. Both
  variants already define LED_BUILTIN in pins_arduino.h via a
  self-define macro (`#define LED_BUILTIN LED_BUILTIN` + `static const
  uint8_t LED_BUILTIN = ...;`). Pre-defining the symbol from the
  command line expanded the static-const declaration to
  `static const uint8_t 2 = ...;` — a syntax error that broke every
  ESP32-C3 / S3 build (`expected unqualified-id before numeric
  constant`).

Examples
- examples.ts: bulk-fix 72 wire endpoints that referenced
  `componentId: 'nano-rp2040'` / `'esp32-c3'` etc. (boards that don't
  exist on the canvas). Replaced with `'arduino-uno'` (the canvas
  board-id convention) and converted `D<n>` pin names to `GP<n>` for
  Pico-style boards. Affects pico-blink, pico-i2c-scanner,
  pico-i2c-rtc-read, pico-spi-loopback, c3-blink and others.

Tests
- scripts/visual-led-test.mjs: CDP-driven harness. Default suite covers
  Blink (single-pin), Button (idle-OFF invariant — catches the
  INPUT_PULLUP regression), Traffic-Light (multi-pin sequencing),
  Fade-LED (PWM gradient — ≥3 distinct levels), RGB-LED (≥3 PWM pins
  driven). Run via `npm --prefix frontend run test:visual` against a
  Chrome on `:9222` + vite on `:5174` + backend on `:8001`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 21:52:07 -03:00
David Montero Crespo 5c5336acc0
Merge pull request #187 from davidmonterocrespo24/feat/retro-intel-cpus
feat(chips): port retro Intel/Zilog CPUs as Velxio custom chips + 2 d…
2026-05-18 02:30:23 -03:00
David Montero Crespo b714c79e3d feat(chips): port retro Intel/Zilog CPUs as Velxio custom chips + 2 demos
Adds 17 chips from the test/test_intel clean-room research to the Custom
Chip gallery, all sourced from manufacturer datasheets and validated by
the existing 129-test vitest harness (CPUDIAG end-to-end for the 8080,
ZEXDOC for the Z80).

CPUs: 4004, 4040, 8080, 8086, Z80 (categoria retro-cpu)
Bus chips: rom-32k, ram-64k, rom-1m, latch-8282, 4001-rom, 4002-ram,
           8255-ppi, 8251-usart, 8259-pic, 8253-pit (retro-bus)

Two bundled "mini-computer" demos under retro-bundle that drop on the
canvas as a single chip and run real 8080 code out of an embedded ROM:

  * i8080-repl     8080 + RAM + ROM + UART, prints a banner and an
                   "uptime ticks: 0xNN" counter every ~50 ms via a real
                   DCR/JNZ busy-wait. Visible in Serial Monitor.

  * i8080-counter  8080 + RAM + ROM + 8 LED pins + 2 button pins.
                   Counts up in binary on BTN_INC, clears on BTN_RST.

Two example projects under /examples reuse these chips end-to-end:

  * /examples/i8080-banner-streamer
  * /examples/i8080-button-counter

The bundled chips inline a 328 / 34-byte 8080 ROM produced by a new
two-pass 8080 assembler in Python (scripts/asm8080.py) from the .s
sources in scripts/. Both ROMs are pre-assembled and committed under
scripts/*.txt so contributors can rebuild deterministically.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 02:27:53 -03:00
David Montero Crespo 3b527f3dce fix(examples): add missing 220Ω series resistors to LED examples
Five examples wired LEDs directly between a GPIO pin and GND with
no current-limiting resistor:

  - examples.ts: traffic-light (3 LEDs), button-led (1), fade-led (1),
    simon-says (4)
  - examples-circuits.ts: mega-multi-led (8 LEDs)

In real hardware these wire-ups blow the LED in seconds. In the
simulator, ngspice cannot converge on a forward-biased diode with
no series resistance so the branch current comes back as NaN; the
LED visual stays dark even though the user's code is driving the
pin HIGH every cycle.

Adds a 220Ω wokwi-resistor per LED (textbook value for 5 V supplies
and standard diodes) and rewires:
  arduino pin → r.1 / r.2 → led anode / led cathode → GND

The same upstream commit hardens the verifier (worst-case GPIO drive
in pre-flight) and the LED renderer (NaN guard) so this class of
mistake is now caught immediately and degrades gracefully when a
user creates their own broken circuit.
2026-05-18 00:00:45 -03:00
David Montero Crespo 844083657c fix(examples/pico-doom): wire ILI9341 power + MISO
The Pico Doom example loaded with the ILI9341 dangling on three
critical pins:

  - VCC  — unconnected (no 3V3 from the Pico)
  - GND  — unconnected (no return path)
  - MISO — unconnected

On real hardware the TFT wouldn't power on at all without VCC/GND.
Inside the velxio simulator the missing power isn't strictly fatal
(the simulator drives pixels off the SPI bus, not the rail), but it
makes the schematic incorrect and misleading for users who copy it
to a breadboard. MISO is electrically idle for write-only drivers,
but Adafruit_ILI9341 with the 3-arg constructor binds to hardware
SPI0, so MISO physically maps to GP16 — leaving it floating leaves
the SPI bus topology incomplete.

Wires added:

  Pico 3V3   → tft1.VCC   (red)
  Pico GND.5 → tft1.GND   (black) — closest GND pad to GP17/18/19
  Pico GP16  → tft1.MISO  (amber) — hardware SPI0 MISO

Updated the data-integrity test (examples-pico-doom.test.ts) to
include the three new pairs in the SPI/control/power expectation
map. 10/10 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 23:22:31 -03:00
davidmonterocrespo24 5742ed0146 feat(examples): Pico Doom — Wolf3D-style raycaster on RP2040 + ILI9341
A new entry in the games category for the Raspberry Pi Pico. Renders
a first-person 3D corridor à la Wolfenstein / early Doom using a
column-wise DDA raycaster — 160 rays per frame drawn straight to a
320×240 ILI9341 TFT via drawFastVLine, no framebuffer. 16×16 tile map
with 5 wall palettes (slate, blood, brown, toxic green, bronze door),
darkened on NS faces so corners read in 3D. Forward / back move,
two more buttons turn the player. 40-px HUD bar.

Why a demo, not the canonical id Software Doom: Graham Sanderson's
rp2040-doom port shoehorns DOOM1.WAD into 2 MB of flash with custom
compression and pushes video out over PIO-driven DVI / VGA — none of
that survives the rp2040js emulator (no PIO accuracy, no flash
mapping for huge assets). A raycaster reproduces the *visual* of
early Doom using only ~67 KB of flash and 9 KB of RAM, which the
emulator runs perfectly.

Pre-flight: arduino-cli compile against rp2040:rp2040:rpipico
already verified inside the Velxio backend container — 3 % flash,
3 % RAM. The Adafruit_GFX + Adafruit_ILI9341 libs the example
declares are already in the gallery's auto-install list.

Bundled:
  test/pico_doom_demo/arduino_sketch.ino — source of truth sketch
  test/pico_doom_demo/README.md          — what + why + pin map
  test/pico_doom_demo/compile_check.sh   — operator script that
    runs arduino-cli against the same FQBN the prod backend uses
  frontend/src/data/examples.ts          — gallery entry (boardType
    raspberry-pi-pico, category games, difficulty advanced, 5
    components, 14 wires)
  frontend/src/__tests__/examples-pico-doom.test.ts — 10 vitest
    assertions: example is registered exactly once, target board /
    category / difficulty match, libraries declared, all four
    pushbuttons present, every wire endpoint references a real
    component id, SPI pin mapping matches the sketch's #define
    block, every button has a GND wire, the renderFrame loop is
    still present in the embedded code.
2026-05-13 22:54:35 +02:00
David Montero Crespo a097601a73 Add HD44780Decoder and various I2C sketches
- 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.
2026-05-12 14:26:33 -03:00
davidmonterocrespo24 9d5d2e8a4a fix(docs): RISC-V emulation goes through QEMU, not a TypeScript browser core
The marketing copy and docs claimed ESP32-C3 / XIAO-C3 / SuperMini /
CH32V003 ran on a "browser-native RV32IMC core written in TypeScript",
but production runs through QEMU lcgamboa (libqemu-riscv32) with the
esp32c3-picsimlab machine — same backend pattern as Xtensa ESP32, just
a different libqemu binary. The TypeScript ISA layer
(RiscVCore.ts / Esp32C3Simulator.ts / RiscVSimulator.ts) is kept only
as Vitest unit-test infrastructure for RV32IMC instruction decoding;
it cannot handle the 150+ ROM functions ESP-IDF needs at boot and is
not wired into the production emulation path.

Files updated:

Marketing pages
- LandingPage: board-group label, FAQ answer, architecture description
  no longer claim "browser-native" or "no backend needed" for RISC-V.
- AboutPage: arch card retitled "RISC-V via QEMU", body explains the
  libqemu-riscv32 / lcgamboa backend.
- Velxio2Page: arch group engine label, multi-board feature item,
  competitive-comparison card all corrected.
- ArduinoEmulatorPage: two RISC-V cards corrected.
- ESP32SimulatorPage: ESP32-C3 cross-link card corrected.
- ESP32C3SimulatorPage: hero subtitle, trust strip, supported-boards
  intro, JSON-LD description corrected.
- ElectronicsSimulatorPage: install-needed FAQ corrected.
- examples.ts: c3-blink description and code-comment corrected.

SEO surfaces
- index.html: JSON-LD SoftwareApplication description, OS-fallback FAQ
  body, supported-boards <ul> bullets, feature list bullets corrected.
- seoRoutes.ts: /esp32-c3-simulator title + description corrected;
  homepage description corrected.

Docs page
- DocsPage RiscVEmulationSection: intro paragraph rewritten — RISC-V
  goes through QEMU lcgamboa with libqemu-riscv32 / esp32c3-picsimlab,
  TypeScript layer is Vitest-only.
- DocsPage Esp32EmulationSection callout: section now applies to all
  ESP32 family (Xtensa + RISC-V), pointer to RISC-V doc clarified.

README
- "Boards" table: production-engine column for ESP32-C3 family and
  CH32V003 changed from "RiscVCore.ts (browser)" to "QEMU lcgamboa
  (backend)".
- "ESP32-C3 / XIAO-C3 / SuperMini / CH32V003" subsection retitled
  "(RISC-V via QEMU)" — body explains libqemu-riscv32 backend and
  flags the TypeScript layer as Vitest-only.

The two remaining "browser-native" hits in the codebase
(Velxio25Page:176, index.html:348) are about ngspice-WASM SPICE
analog simulation, which genuinely is browser-native — left alone.

Build verified: npm run build:docker succeeds, 246 SEO pages prerender.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 21:56:29 +02:00
David Montero 78a834700b fix(examples): use esp32-devkit-c-v4 for ePaper examples (GPIO 16/17)
The 4 ESP32 ePaper examples (BW weather, BWR alert, UC8179 dashboard,
ACeP rainbow) wired GxEPD2 to GPIO 16 (RST) and GPIO 17 (DC), which is
the canonical pinout shown in every GxEPD2 example. But those pins are
not broken out on the DevKit V1 variant (PINS_ESP32) — they only exist
on DevKit-C-V4 (PINS_ESP32_DEVKIT_C_V4).

Result: the RST and DC wires fell back to (0,0) and rendered as a red
+ purple line shooting from the corner of the board. CLAUDE.md §6a
documents this exact symptom.

Switching boardType to 'esp32-devkit-c-v4' renders the variant whose
pinInfo includes 16 and 17. Also rename pinName 'GND' → 'GND.1' since
DevKit-C-V4 exposes three GND pins as GND.1/2/3 (not a plain 'GND').

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 06:37:20 +02:00
David Montero Crespo 9cd5061732 refactor: rename wokwi-libs/ → third-party/
The directory grew well beyond Wokwi-only contents: it now hosts
lcgamboa's QEMU fork (qemu-lcgamboa), Espressif's esp32-camera, the
ngspice WASM build, fritzing-parts, picowi, an alternative QEMU
(qemu-esp32), the 100_Days_100_IoT_Projects examples repo, and
Wokwi's own avr8js/rp2040js/wokwi-elements/wokwi-features/wokwi-boards.
"wokwi-libs" was misleading — half the contents have nothing to do
with Wokwi. "third-party/" is the standard convention for vendored
external dependencies.

Mechanical changes:

  Path rename:
    wokwi-libs/ → third-party/
    update-wokwi-libs.bat → update-third-party.bat
    docs/WOKWI_LIBS.md → docs/THIRD_PARTY.md

  Submodule reconfiguration:
    .gitmodules — 4 path= and section names updated
    .git/modules/wokwi-libs/ → .git/modules/third-party/
    each submodule's .git file rewired to ../../.git/modules/third-party/<name>

  Reference updates (~80 files): vite.config.ts aliases, Dockerfile
    COPY paths, GH Actions workflow steps, build_qemu_*.sh, all
    docs/* and test/*/autosearch/* entries that mention the path,
    package-lock.json file: dependencies, .gitignore patterns,
    sitemap.xml + index.html SEO blurbs, scripts/generate-component-*,
    .dockerignore, .idea/vcs.xml. Bulk replaced both `wokwi-libs/`
    (path) and bare `wokwi-libs` (textual mentions in docs/comments).

Verified:
  - npx tsc -b --noEmit produces no new errors related to these paths
  - vite.config.ts aliases now point at ../third-party/avr8js etc.
  - All 4 git submodules (avr8js, rp2040js, wokwi-elements,
    wokwi-features) are linked under third-party/ with their
    worktrees re-populated and config files referencing the new path
  - `grep -r wokwi-libs` returns zero hits outside node_modules,
    .vite, frontend/dist, third-party/ (upstream submodule contents),
    *.pyc caches, and *.dll.pre-camera rollback binaries

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 00:58:57 -03:00
David Montero Crespo d4d015c25d perf(spi): batch SPI bytes per WS message — ~50× faster TFT in emulator
User reported the ESP32-CAM + ILI9341 live preview at ~1 frame/min.
Profile: 80×60 preview pushes 9600 SPI bytes per drawRGBBitmap, and
each byte was emitting a full {type:'spi_event'} JSON message over
the worker→backend→WS→frontend pipeline. Per-byte overhead ~150-200µs
in Python (json.dumps + sys.stdout.write+flush dominates) plus
asyncio + WS dispatch. Net: 1.5-2 sec/frame minimum, much worse with
GIL contention.

Fix: buffer MOSI bytes in the worker and emit a single base64-encoded
`spi_batch` message when CS goes HIGH (transaction ended) or the
buffer crosses 4 KiB. ~9600 events/frame collapse to ~3 messages.

  backend/app/services/esp32_worker.py:_on_spi_event
    - Add _spi_byte_buf bytearray + threading.Lock
    - On op==0x00 (byte): append; flush early if buf >= 4096
    - On op==0x01 (CS change): flush buffer, then emit the CS event
      via the legacy spi_event channel (ePaper / custom chips that
      observe CS still get it).

  frontend/src/simulation/Esp32Bridge.ts
    - New 'spi_batch' message handler decodes b64 and replays each
      byte through the existing onSpiByte callback. Parts that
      subscribed via simulator.spi.onByte don't notice the protocol
      change. The 'spi_event' branch still handles CS changes plus
      legacy single-byte payloads for backwards compat.

Now that 38 KB/frame is cheap, restore preview to 160×120 + JPEG
quality 0.35 in the gallery example. Real measured speedup: ~50× on
the QVGA preview demo. Real hardware was never affected — it runs
SPI at 80 MHz and pushes the bitmap in ~4 ms either way.

PSRAM emulation is unrelated to this bottleneck and was left untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 00:25:06 -03:00
David Montero Crespo a20b10a252 perf(esp32-cam-lcd-preview): 4x faster preview by shrinking SPI traffic
User reported the live preview "looks slow" after the JPEG decode fix.
Diagnosis: each tft.drawRGBBitmap pushes width × height × 2 bytes over
SPI, and every byte takes a full QEMU → worker → backend (WS) → frontend
round-trip. At 160×120 that's 38 400 messages per frame; the bus
saturates at ~0.2 fps perceived.

Two changes shrink the per-frame SPI bandwidth:

1. Preview 160×120 → 80×60 (and JPG_SCALE_2X → JPG_SCALE_4X).
   38 400 bytes/frame → 9 600 bytes/frame. Already 4× faster.

2. Status bar redraw throttled to every 10th frame instead of every
   frame. The text writes (printf, fillRect, fillCircle) account for
   another ~1-2 KB of SPI traffic per loop iteration. Skipping 9 of
   every 10 redraws frees up a chunk more bandwidth without losing
   the headline numbers (fps, frame counter) — they just refresh
   once a second instead of 5x/sec.

Also dropped the trailing `delay(20)` — we don't need an artificial
throttle, the SPI bus is the throttle.

Real-hardware effect: zero. ESP32 SPI runs at 80 MHz; a full
160×120 bitmap pushes in ~4 ms either way.

Applied in two places:
- examples/esp32-cam-lcd-preview/esp32-cam-lcd-preview.ino
- frontend/src/data/examples.ts (in-app gallery copy)

Long-term plan: batch SPI bytes at the worker level (one WS message
per N bytes instead of per byte) — that's a deeper change in
qemu-lcgamboa + Esp32Bridge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 00:15:06 -03:00
David Montero Crespo 155b962c21 feat(gallery): add 2 ESP32-CAM examples to the in-app gallery
Adds two listed examples to the gallery (book icon → Examples) so
users can one-click load the new ESP32-CAM emulation:

1. ESP32-CAM: Webcam Demo (sensors / beginner)
   Minimal sketch — init OV2640, verify SCCB chip-id, loop on
   esp_camera_fb_get() printing frame metadata to Serial. Proves
   the emulation is alive without any external components.

2. ESP32-CAM + ILI9341 Live Preview (displays / intermediate)
   Full demo — decode JPEG with jpg2rgb565() (built-in to
   esp32-camera/conversions, header exposed by the Velxio compile
   template) and render the resulting RGB565 bitmap to a 320×240
   SPI TFT. Pre-wired diagram: ILI9341 connected via VSPI to GPIOs
   12-15 (the only block free after OV2640 takes over the rest of
   the AI-Thinker pins).

Type changes:
- ExampleProject.boardType union extended with 'esp32-cam'
- BOARD_TABS in ExamplesGallery.tsx gets a new "ESP32-CAM" tab
  (orange #d35400)

Both examples use boardFilter: 'esp32-cam' so they show under
the new tab and not the generic ESP32 one.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 22:21:19 -03:00
David Montero Crespo 2e4c470f75 feat: add support for UC8159c (ACeP 7-colour) display
- 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.
2026-04-30 00:27:40 -03:00
David Montero Crespo bcc7129aa3 feat: Add support for SSD168x ePaper panels
- Introduced EPaperPanels.ts to define configurations for various ePaper panels including dimensions, refresh rates, and controller details.
- Implemented SSD168xDecoder.ts to handle the decoding of SPI commands for the SSD168x family of ePaper displays.
- Created EPaperPart.ts to manage the simulation of ePaper panels, integrating with the existing simulator architecture and handling events.
- Added example sketches for 2.13", 2.9", 4.2", and 7.5" ePaper displays, demonstrating basic functionality and text rendering.
- Ensured compatibility with AVR, RP2040, and ESP32 platforms, with appropriate pin configurations for each.
2026-04-29 22:23:00 -03:00
David Montero Crespo 175b248108 feat(epaper): Add SVG layouts and emulation plan for ePaper panels
- Introduced SVG layout dimensions for Phase 1 (B/W mono) and Phase 2 (colour) ePaper panels, detailing active areas, bezels, and pin layouts.
- Developed a phased emulation plan outlining the architecture and deliverables for different panel types, including SSD168x and UC81xx.
- Created a canonical "Hello, World!" sketch for the 1.54" ePaper panel, ensuring compatibility across ESP32, Raspberry Pi Pico, and Arduino Uno.
- Implemented a pure Python SSD168x decoder to validate SPI command sets and framebuffers against specifications.
- Added tests for compiling the hello-world sketch across supported boards and for the SSD168x protocol to ensure correct framebuffer behavior.
2026-04-29 02:33:59 -03:00
David Montero Crespo 0a66c70512 feat(examples): update dual Pico example to demonstrate bidirectional digital handshake 2026-04-28 22:38:54 -03:00
David Montero Crespo 7f2014bef7 Add ESP32 chip demos and comprehensive tests for I2C, SPI, and UART interactions
- Implemented `esp32_spi_chip_demo.ino` to demonstrate SPI communication with a 74HC595 shift register.
- Created `esp32_uart_chip_demo.ino` for UART loopback testing with ROT13 transformation.
- Added Python tests for compiling chips and sketches, ensuring valid WASM output and successful compilation for various board families.
- Developed end-to-end tests for ESP32 with custom chips using I2C and SPI, validating synchronous communication through the backend.
- Introduced GPIO bridge tests to verify serial communication and GPIO state changes.
- Ensured all tests validate the expected behavior of the custom chips and their interaction with the ESP32 firmware.
2026-04-28 19:24:39 -03:00
David Montero Crespo 692af00258 style: update ESLint rules and clean up code formatting across multiple files 2026-04-21 17:14:27 -03:00
David Montero Crespo 53efc226a3 Merge branch 'master' into feature/electrical-simulation-ngspice
# Conflicts:
#	deploy/entrypoint.sh
#	frontend/src/components/examples/ExamplesGallery.tsx
2026-04-21 17:11:26 -03:00
David Montero Crespo 212ecd1bcb refactor: rename components and update prefixes to 'velxio-' for consistency
- 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.
2026-04-21 16:45:45 -03:00
David Montero Crespo a1d3179e1c Add SPICE behavior tests for analog examples and update example circuit definitions 2026-04-21 13:20:48 -03:00
David Montero Crespo eaf3fffd36 Refactor code structure for improved readability and maintainability 2026-04-21 12:59:59 -03:00
David Montero Crespo b152cb1919 Refactor property synchronization in simulation parts; introduce emitPropertyChange event
- Replaced syncStoreProperty function with emitPropertyChange to decouple parts from Zustand store.
- Updated relay component mapping to ensure proper handling of coil and contact states.
- Added new test cases for half-wave rectifier and relay-controlled LED to ensure correct functionality.
- Introduced InlineComponentSVGs for schematic-style icons of various components.
- Updated submodule references for qemu-lcgamboa, rp2040js, and wokwi-elements to indicate dirty state.
2026-04-21 10:56:20 -03:00
David Montero Crespo 9cc9cfebd6 Add end-to-end tests for ammeter, voltmeter, and capacitor charging behavior
- Implement `ammeter-waveform.test.ts` to validate AC readings from a sine wave source.
- Create `capacitor-charge-transient.test.ts` to test the charging response of an RC circuit driven by a microcontroller pin.
- Introduce `esp32-rectifier-integration.test.ts` for testing rectifier behavior using QEMU and ESP32.
- Add helper functions in `esp32RectifierE2E.ts` for the rectifier test harness.
- Develop `voltmeter-waveform.test.ts` to ensure correct AC and DC readings from a sine wave source.
- Implement unit tests for waveform statistics in `waveform-stats.test.ts` to validate RMS, mean, peak, and interpolation functions.
- Create `waveformStats.ts` to provide statistical functions for time-domain waveform analysis.
2026-04-21 02:17:30 -03:00
David Montero Crespo dcb8a92b79 feat: enhance electrical simulation and testing framework
- Decoupled electrical simulation from the simulator store, ensuring SPICE is always active for accurate circuit analysis.
- Removed feature flag for electrical simulation, simplifying the state management.
- Preloaded SPICE engine at app start to eliminate latency during the first solve.
- Added comprehensive tests for MOSFET PWM LED behavior and NPN transistor switch functionality, ensuring correct current flow and response to pin states.
- Implemented diagnostics for floating input nodes in RC low-pass filter circuits, addressing singular matrix issues in SPICE simulations.
- Introduced active semiconductor metadata registry for better component management and simulation fidelity.
- Updated Vite configuration to force re-bundling of local wokwi-elements after component additions.
2026-04-20 16:38:31 -03:00
David Montero Crespo 61c1ddfc22 feat: add capacitor and inductor components, update netlist builder to return pinNetMap 2026-04-17 19:27:18 -03:00
David Montero Crespo 00a15c6f76 feat: add 'circuits' category to ExampleProject interface
fix: increase timeout for compilation requests to 180 seconds

refactor: call recalculateAllWirePositions after loading examples

chore: update subproject commit for rp2040js to dirty state

chore: update subproject commit for wokwi-elements to dirty state
2026-04-16 08:39:47 -03:00
David Montero Crespo 635bc2a952 fix(examples): merge circuitExamples via array spread, not side-effect push
Previously examples.ts pushed to exampleProjects[] after declaration, which
some bundlers can treat as dead code under aggressive tree-shaking. This
also made HMR unreliable when examples-circuits.ts changed.

Now:
  const legacyExamples = [...]
  export const exampleProjects = [...legacyExamples, ...circuitExamples]

Single immutable export. Guaranteed to include all 150 examples at import
time. The gallery (ExamplesGallery.tsx) and SSR prerender (entry-server.tsx)
both pick up the new circuit examples automatically.

Also adds frontend/src/__tests__/examples-circuits.test.ts with 5 assertions
to catch future regressions (all circuit ids present, no duplicates, valid
required fields, expected categories covered).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 01:02:27 -03:00
David Montero Crespo df37fdf6a4 feat: add 40 circuit examples + matching SPICE tests
Adds frontend/src/data/examples-circuits.ts with 40 new examples organized
into 6 categories, each demonstrating a specific analog/digital/electromech
concept that the SPICE engine can simulate end-to-end:

PASSIVE / ANALOG (10):
  voltage-divider, rc-low-pass-filter, wheatstone-bridge,
  ntc-temperature, led-current-limiting, parallel-resistors,
  pot-adc-reader, photoresistor-light, multi-led-bar,
  capacitor-charge-curve

TRANSISTOR / SEMICONDUCTOR (8):
  npn-led-switch, pnp-high-side-switch, mosfet-pwm-led,
  diode-rectifier, zener-regulator, schottky-reverse-protection,
  bjt-common-emitter, darlington-high-current

OP-AMP (5):
  opamp-inverting, opamp-voltage-follower, opamp-comparator,
  opamp-difference, opamp-schmitt-trigger

LOGIC GATES (6):
  and-gate-alarm, xor-toggle-detector, nand-sr-latch,
  full-adder, binary-counter-leds, logic-probe

ELECTROMECHANICAL (4):
  relay-led-switch, optocoupler-signal,
  l293d-motor-control, l293d-speed-pwm

POWER / REGULATOR (3):
  power-supply-7805, lm317-adjustable-psu, battery-voltage-monitor

BOARD-SPECIFIC (4):
  esp32-dual-adc, mega-multi-led, nano-sensor-station,
  esp32-pwm-led-rgb (uses ESP32 LEDC peripheral)

The new examples are appended to exampleProjects[] in examples.ts so the
existing gallery and category filters pick them up automatically.

test/test_circuit/test/spice_examples.test.js validates each example's
analog topology in ngspice — 45 individual assertions covering all 40
examples (plus extra cases for NTC/Zener sweeps and L293D direction).

Sandbox tally: 164 -> 209 tests, 7.9s runtime, all green.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 00:52:51 -03:00
David Montero Crespo 09d048e20f feat: add ATtiny85 support with examples and simulation tests; update pin mapping and AVRSimulator logic 2026-04-15 02:46:33 -03:00
David Montero Crespo 2ba8020438 feat: Enhance ESPIDFCompiler library resolution logic; add support for dynamic library detection and patching in CMakeLists.txt
refactor: Update wiring examples for E32 OLED integration; correct pin mappings for VCC, GND, DATA, and CLK
test: Improve unit tests for ESPIDFCompiler; add scenarios for library resolution and CMake patching
chore: Mark subproject commits as dirty for wokwi-libs
2026-04-11 15:25:40 -03:00
David Montero Crespo 689f8e71db feat: Add I2C slave emulation for MPU-6050 and BMP280 sensors
- Implemented _MPU6050Slave and _BMP280Slave classes for I2C communication.
- Enhanced main function to register these sensors and handle I2C events.
- Updated sensor management to support MPU-6050, BMP280, DS1307, DS3231, SSD1306, and PCF8574.
- Added frontend examples for BMP280 weather station and SSD1306 OLED display.
- Modified Esp32Bridge to handle new I2C transaction events.
- Updated ProtocolParts to support ESP32 path for I2C devices.
- Enhanced useSimulatorStore to manage I2C transaction listeners.
2026-04-07 15:43:09 -03:00
David Montero Crespo 54f8f2782b feat: add ESP32 WiFi/BLE emulation with ESP-IDF compilation pipeline
Replace arduino-cli with ESP-IDF 4.4.7 for ESP32 compilation — Arduino-compiled
firmware crashes in QEMU (9-28 reboots) while ESP-IDF boots cleanly (0 reboots).
The new espidf_compiler translates Arduino WiFi/WebServer sketches to native
ESP-IDF C code, compiles with cmake+ninja, and merges into 4MB flash images.

Key changes:
- ESP-IDF compiler: translates WiFi.begin/WebServer to esp_wifi/esp_http_server
- ESP-IDF project template with QEMU-optimized sdkconfig (DIO, 40MHz, no WDT)
- WiFi status parser for ESP-IDF serial logs (wifi_status, ble_status events)
- IoT Gateway HTTP reverse proxy for ESP32 web servers
- WiFi/BLE auto-detection from sketch content + visual status icons
- Static IP 192.168.4.15 matching slirp DHCP first-client range
- Docker: new espidf-builder stage with ESP-IDF 4.4.7 toolchain
- 157 tests covering WiFi/BLE for both ESP32 (Xtensa) and ESP32-C3 (RISC-V)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 20:53:56 -03:00
David Montero Crespo c7eeab5891 feat: initialize arduino-cli config and install missing cores; mark subproject commits as dirty 2026-03-24 18:33:21 -03:00
David Montero Crespo d12a2ad7e4 feat: enhance ExamplesPage to auto-install required libraries; update example projects with library dependencies 2026-03-24 18:19:43 -03:00
David Montero Crespo dc335c666e feat: add WebSocket support for ESP32 simulation in nginx configuration; clean up example code by removing unused WDT functions 2026-03-24 17:02:23 -03:00
David Montero Crespo 09118fcdef feat: update .gitignore to include marketing directory; modify example texts to reflect Velxio branding; mark subproject commits as dirty 2026-03-24 16:47:19 -03:00
David Montero Crespo 083d8d69a8 feat: Add HC-SR04 sensor support and enhance DHT22 response timing in simulation 2026-03-22 18:39:09 -03:00
David Montero Crespo 6a55f58e46 feat: Implement generic sensor registration for ESP32 and RP2040
- Added board-agnostic sensor registration methods in RP2040Simulator.
- Enhanced ComplexParts to handle LEDC PWM duty updates for ESP32.
- Updated ProtocolParts to check if the simulator handles sensor protocols natively, delegating to backend if applicable.
- Introduced pre-registration of sensors in useSimulatorStore for ESP32 to prevent race conditions.
- Added tests for ESP32 DHT22 sensor registration flow, ensuring proper delegation and fallback mechanisms.
- Created tests for ESP32 Servo and Potentiometer interactions, verifying PWM subscriptions and ADC handling.
2026-03-22 18:03:17 -03:00
David Montero Crespo f5257009cd feat: implement DHT22 sensor support with attach, update, and detach functionality in ESP32 simulation 2026-03-22 15:17:44 -03:00
David Montero Crespo b900f960ad feat: update pin mappings and descriptions for Raspberry Pi Pico examples 2026-03-21 14:02:46 -03:00
David Montero Crespo d170b4f7ea Add generate_examples.py script and update subproject commits
- Introduced a new script `generate_examples.py` to catalog board and sensor combinations, generating TypeScript example stubs for the frontend.
- Updated subproject commit references for `qemu-lcgamboa`, `rp2040js`, and `wokwi-elements` to indicate they are in a dirty state.
2026-03-19 01:12:29 -03:00
David Montero Crespo 372e0f1d00 feat: update ESP32-C3 wiring and enhance ROM function emulation with detailed logging 2026-03-17 23:06:36 -03:00
David Montero Crespo c19a6cb848 feat: update PWM handling in SimulatorCanvas and enhance I2C Scanner example with SSD1306 OLED integration 2026-03-16 22:15:52 -03:00
David Montero Crespo d35ad2d2f7 Refactor code structure for improved readability and maintainability 2026-03-16 18:31:46 -03:00
David Montero Crespo 20ccd87d1b feat: enhance ESP32 emulation with GPIO mapping and ADC support 2026-03-16 13:11:59 -03:00
David Montero Crespo bc31ee76c1 feat: enhance oscilloscope and simulator functionality
- Added `onPinStateChange` method to `ChipParts` for handling pin state changes in 7-segment displays.
- Updated `useOscilloscopeStore` to allow independent monitoring of multiple boards by adding `boardId` to channels and modifying `addChannel` method.
- Modified `getOscilloscopeCallback` in `useSimulatorStore` to filter channels based on `boardId` and pin number.
- Adjusted component and board position calculations in `useSimulatorStore` to account for wrapper offsets.
- Updated submodule references for `qemu-lcgamboa`, `rp2040js`, and `wokwi-elements` to indicate dirty states.
2026-03-16 10:31:02 -03:00
David Montero Crespo 5311a01103 Refactor code structure for improved readability and maintainability 2026-03-15 23:15:38 -03:00
David Montero Crespo c69094e7d7 feat: Implement Virtual File System for Raspberry Pi 3 with context menu and upload functionality
- Add VirtualFileSystem component for managing files and directories.
- Integrate useVfsStore for state management of the virtual file system.
- Implement context menu for file operations: New File, New Folder, Rename, Delete.
- Add upload functionality to send files to Raspberry Pi.
- Create default file structure for new Raspberry Pi boards.
- Enhance editor with board-aware features and compile/run orchestration.
- Introduce CompileAllProgress component for tracking compilation status across boards.
- Redesign SerialMonitor to support multiple boards with tabbed interface.
- Establish Raspberry Pi specific workspace with terminal and file system integration.
2026-03-15 14:04:01 -03:00
David Montero Crespo b0b3a8763d V1 feat: Enhance ESP32 emulation support and logging
- Added detailed logging for GPIO changes, system events, and errors in simulation websocket.
- Improved ESP32 firmware handling by merging individual binaries into a single 4MB flash image.
- Updated ESP32 bridge to handle serial output and GPIO changes with appropriate logging.
- Introduced integration test for ESP32 emulation, covering compilation, WebSocket connection, and event handling.
- Enhanced examples to include ESP32 projects and updated the examples gallery to reflect new board types.
- Refactored simulator store to manage ESP32 bridge and simulator instances more effectively.
- Updated requirements to include esptool for ESP32 firmware management.
2026-03-14 16:57:22 -03:00
David Montero Crespo 41dfd20583 feat: Add Arduino Nano support to simulator and update related components 2026-03-07 23:14:33 -03:00
David Montero Crespo 4ba2ccb877 Refactor simulator store to unify serial data handling and add board pin mapping utility
- Simplified serial data handling in `useSimulatorStore` for both AVR and RP2040 simulators.
- Introduced `boardPinMapping.ts` to map wokwi-element pin names to simulator GPIO/pin numbers for Arduino Uno and Nano RP2040.
- Added `compilationLogger.ts` to parse compile results into structured log entries for better console output.
2026-03-05 21:07:03 -03:00
David Montero Crespo 5d175abdcf feat: add Serial Monitor component and integrate with AVR simulator
- Implemented SerialMonitor component to display serial output and allow user input.
- Enhanced AVRSimulator to handle USART communication and transmit serial data.
- Updated useSimulatorStore to manage serial output state and toggle visibility of the Serial Monitor.
- Added example Arduino sketches for serial communication, including Serial Echo and Serial LED Control.
- Introduced I2CBusManager to manage virtual I2C devices and integrated with AVRSimulator.
2026-03-05 06:56:14 -03:00
David Montero Crespo 13cf7be465 fix: update DynamicComponent to check if simulation is running before attaching events; enhance TFT display example with Adafruit libraries and improved UI elements 2026-03-05 02:09:30 -03:00
David Montero Crespo efd4c11e03 feat: add ILI9341 TFT display simulation and enhance component registry loading 2026-03-05 01:52:15 -03:00
David Montero Crespo 5ca8a82985 feat: Enhance PinManager with PWM and Analog support
- Added PWM duty cycle tracking and callback registration to PinManager.
- Introduced methods for handling analog voltage injection and callbacks.
- Updated updatePort method to notify digital pin listeners.
- Improved listener management with clearAllListeners method.

feat: Expand BasicParts with new components

- Registered new components: 6mm Pushbutton, Slide Switch, DIP Switch 8, LED Bar Graph, and 7-Segment Display.
- Implemented event handling for each component to interact with the AVR simulator.

feat: Introduce ComplexParts with advanced components

- Added RGB LED with PWM support for color mixing.
- Implemented Potentiometer and Slide Potentiometer for analog input.
- Created Photoresistor Sensor to simulate light levels.
- Developed Analog Joystick for two-axis control and button press.
- Added Servo motor simulation with pulse width modulation.
- Implemented Buzzer using Web Audio API for sound generation.
- Created LCD 1602 and 2004 simulations with command/data processing.
2026-03-04 18:27:14 -03:00
David Montero Crespo c2f07665b4 feat: add react-router-dom for routing and enhance wire rendering with automatic offsets 2026-03-04 18:03:54 -03:00
David Montero Crespo ef7e86bc1e feat: Enhance simulator with new components and event handling
- Updated components-metadata.json with new generation timestamp.
- Added event handling for button presses and releases in DynamicComponent.
- Improved ExamplesGallery with new styles for placeholders and previews.
- Introduced LCD 20x4 display example with corresponding code and wiring.
- Enhanced SimulatorCanvas to subscribe components to pin changes.
- Implemented PartSimulationRegistry for managing component simulation logic.
- Added basic and complex parts simulation including pushbuttons, LEDs, and LCDs.
- Created utility functions for capturing canvas previews and generating SVG previews for example projects.
2026-03-04 13:36:33 -03:00
David Montero Crespo b7e9bf64c4 feat: implement examples gallery and editor page with routing and example loading functionality 2026-03-03 22:25:52 -03:00