Commit Graph

65 Commits

Author SHA1 Message Date
davidmonterocrespo24 c476084e00 feat(sim): Phase 2 — upgrade BJT/diode models to LTSpice Gummel-Poon (SPICE3F5)
Replaces the truncated 4-5 param NPN/PNP/D models in componentToSpice.ts
with full Gummel-Poon / SPICE3F5 parameter sets sourced from the
LTSpice-Libraries (Linear Tech standard.bjt and standard.dio). Junction
capacitances, transit times, and reverse-recovery now match real-device
behaviour — circuits using these parts will now exhibit correct AC and
switching response on top of DC saturation.

Parts upgraded:
  BJT NPN: 2N2222, BC547, 2N3055
  BJT PNP: 2N3906, BC557
  Diode:   1N4148 (silicon switching), 1N5817, 1N5819 (Schottky)

MOSFET (Level=1) and 1N4007/zener kept as-is - they need separate
VDMOS migration validated against the MOSFET PWM regression test.

Phase 2.0 of the mixed-mode simulator project. See
velxio-prod/project/sim-mixedmode/phase-02-device-models.md.

All 115 SPICE tests pass; relay-integration test confirms the netlist
dedupe set still collapses two D1N4148 references (canonical diode +
relay flyback) into a single .model line.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 16:57:36 +02:00
davidmonterocrespo24 27c59664cd feat(sim): Phase 1b skeleton — SPICE-resolved PinResolver + active-path detection
Adds the architecture pieces for mixed-mode coupling without yet
driving the SPICE engine.  Components on a path that crosses an active
device (BJT, MOSFET, op-amp, diode, regulator, LED, relay) now route
through a new SPICE-resolved PinResolver variant; everything else
keeps the digital fast-path from Phase 0.

What ships:

  - simulation/PinResolver.ts
    * `isActiveDevice(metadataId)` predicate + `ACTIVE_DEVICE_PREFIXES`
      list (BJTs, MOSFETs, op-amps, diodes, regulators, LED, relay).
    * `DetailedPinTrace` / `DetailedPinTracer` types — the trace
      function now reports whether it crossed an active device, on
      top of the Arduino pin number.
    * `createSpiceResolvedPinResolver()` — new factory; reads voltages
      from a `SpiceVoltageSource` and threshold-converts to HIGH/LOW
      with hysteresis (thresholdHigh != thresholdLow → Schmitt-like).

  - simulation/spice/MixedModeScheduler.ts (new)
    * Singleton orchestrator that holds the NgSpiceInteractive engine
      and the SpiceVoltageSource subscription registry.
    * `start()` / `stop()` / `dispose()` lifecycle.
    * `subscribe()` + `getCurrentVoltage()` implement SpiceVoltageSource.
    * `onMcuPinChange()` placeholder for the alter+tran event loop.
    * Skeleton: subscribers register but never receive events yet.
      Phase 1b continued will wire NgSpiceInteractive into the loop.

  - components/DynamicComponent.tsx
    * Trace function extended with `traceDetailed()` that tracks
      whether the BFS crossed an active component.
    * PinResolver factory branches: active-path → SPICE-resolved (uses
      the scheduler), digital-only → existing default impl.  Default
      threshold = vcc/2 with no hysteresis; Phase 3 will replace with
      per-logic-family Vil/Vih.

Phase 0 LED behavior intact (digital path).  Phase 1b SPICE-resolved
path falls back to FLOATING until Phase 1b continued wires the engine.

Tests:
  - pin-resolver-phase1b.test.ts (new) — 8/8 passing.
    Covers isActiveDevice for every BJT/MOSFET/op-amp/diode/regulator
    metadata id; SPICE-resolved resolver state reporting, threshold
    conversion, hysteresis dead-band, unsubscribe.
  - pin-resolver.test.ts (Phase 0) — 8/8 still passing (no regression).
  - tsc --noEmit on the new files: clean.

No deploy in this commit — staged for end-of-session rebuild + push
per user preference.
2026-05-15 16:38:30 +02:00
davidmonterocrespo24 d41be4f48b feat(sim/spice): vendor ngspice+XSpice WASM and add NgSpiceInteractive client (Phase 1a)
Phase 1a of the mixed-mode simulator project.  Vendors prebuilt
ngspice+XSpice WASM artifacts from ejkreboot/ngspice-xspice-wasm (MIT,
2026) and adds a TypeScript client that exposes the ngspice shared
callable API for interactive (event-driven) use.

What's vendored at frontend/public/wasm/ngspice-interactive/ (~27 MB):

  - ngspice-lib.wasm  (24 MB) — ngspice 33 + XSpice, MAIN_MODULE
  - ngspice-lib.js   (2.7 MB) — Emscripten glue
  - {analog,digital,xtradev,xtraevt,table,tlines,spice2poly}.cm
                              — XSpice code models, loaded dynamically
  - spinit                    — ngspice startup script
  - PROVENANCE.md             — sources + license info

Note on the cost: 27 MB is a one-way commit to git history, but the
existing eecircuit-engine dependency already ships 39 MB in node_modules
(not tracked, re-downloaded per build). Vendoring our copy:
  - removes a third-party npm dependency
  - pins the exact build we tested with
  - means the WASM is served as a static asset (no Vite chunking)
The alternative (publish as @velxio/ngspice-interactive-wasm) was
deferred to keep the iteration cycle fast during Phase 1+.

New TypeScript client at frontend/src/simulation/spice/wasm/:

  - NgSpiceInteractive.ts        — Promise-based client class with
                                    init / loadNetlist / command /
                                    alter / readVec / reset / dispose
  - ngspice-interactive-worker.js — vendored from ejkreboot's worker
                                    and extended with 'loadNetlist',
                                    'command', 'readVec' message types
                                    plus per-command stdout/stderr
                                    capture

POC test at __tests__/ngspice-interactive.test.ts (skipped in node env
because Worker isn't available; runs in a browser-mode test env):
  - voltage divider .op → reads v(mid) ≈ 2.5V
  - RC step → reads v(cap) time series, final ≈ 5V
  - alter Vsrc → second .tran → final ≈ 1V (proves alter+rerun works)

Known limitation deferred to Phase 1b: the vendored WASM is built
without pthreads (no -sUSE_PTHREADS=1), so ngspice's bg_run is
synchronous-blocking. True mixed-mode event injection requires a
pthread-enabled rebuild (with SharedArrayBuffer + cross-origin
isolation). For Phase 1a we use the workaround: chained short-tran
invocations with `alter` between them. The new architecture is built
to swap in a real bg_halt/bg_resume implementation later without
changing component handlers — see NgSpiceInteractive.ts docstring.

Tests passing:
  - pin-resolver (Phase 0): 8/8
  - ngspice-interactive: 3 skipped (need browser env)
  - tsc --noEmit on the new files: clean
2026-05-15 16:14:50 +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
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 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 993a25390c feat: add passive component presets and custom elements
- 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.
2026-04-21 15:21:03 -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 137f9ab0a0 Add tests for serial batching and spice rectifier functionality
- Implement `serial-batching.test.ts` to verify the behavior of `createSerialBatcher`, ensuring it coalesces multiple appends into a single flush, preserves byte order, and groups by board.
- Create `spice-rectifier-integration.test.ts` to test the end-to-end functionality of the Half-Wave Rectifier example, covering the entire simulation pipeline from input building to circuit solving.
- Add `spice-rectifier-live-repro.test.ts` to reproduce a live-app failure scenario, tracing through each layer of the simulation to identify potential failure points.
- Introduce `spice-signal-generator-tran.test.ts` to validate the behavior of the signal generator and ensure correct analysis type switching based on circuit components.
- Establish `serialBatcher.ts` to implement a batching mechanism for USART output, reducing the frequency of store updates and preventing React's maximum update depth error.
2026-04-20 23:56:42 -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 04d14a74b2 feat: always-on SPICE mode, full board ADC integration, LED brightness from current
Electrical simulation is now active by default (mode='spice' instead of
'off') — users no longer need to toggle the mode on manually. The engine
lazy-loads on first solve, so there is no startup cost penalty.

Changes:
- useElectricalStore: default mode = 'spice' when ELECTRICAL_SIM_ENABLED
- subscribeToStore: ADC_PIN_MAP expanded to all 18 board types (Uno, Nano,
  Mega with 16 ADC channels, ATtiny85, RP2040 GP26-29, ESP32/S3/C3 GPIO
  ADCs). Voltages from SPICE solutions now inject into MCU ADC peripherals
  for all boards.
- BasicParts LED: reads branchCurrents from useElectricalStore when SPICE
  is active. Brightness = clamp(|I_led| / 20mA, 0, 1) instead of boolean.
  Subscribes to store changes to update in real time.
- ElectricalOverlay: shows per-wire voltage labels (gold monospace on dark
  pill) using buildWireNetMap() which replicates the NetlistBuilder's
  Union-Find to map wireId -> netName -> nodeVoltage. Summary pill shows
  net count + solve time.
- NetlistBuilder: new export buildWireNetMap() for lightweight wire-to-net
  resolution without running ngspice.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 22:59:22 -03:00
David Montero Crespo 36543e2479 feat: expand SPICE component catalog (fases 9 + 10)
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>
2026-04-15 22:41:26 -03:00
davidmonterocrespo24 ed9911dcc3 feat: electrical simulation via ngspice-WASM (eecircuit-engine)
Adds full SPICE-accurate electrical simulation to Velxio, behind a lazy-
loaded ⚡ toolbar toggle. Arduino / ESP32 / RP2040 sketches now co-simulate
with real analog behaviour: correct voltages on wires, real I–V curves on
LEDs, working potentiometers, NTC thermistors read by analogRead(), PWM
driving RC filters, transistors, op-amps, diodes, MOSFETs, etc.

Engine: eecircuit-engine (ngspice compiled to WebAssembly). Main bundle
stays at 2.4 MB; the 20 MB SPICE chunk only loads when the user activates
electrical mode. Disabled at build time via VITE_ELECTRICAL_SIM=false.

Frontend additions:
- simulation/spice/: SpiceEngine wrapper + lazy entry, NetlistBuilder with
  UnionFind over wires, componentToSpice mapping (24 metadataIds incl.
  real part numbers: 2N2222, 2N3055, BC547, IRF540, 2N7000, 1N4148,
  1N4007, 1N4733, LEDs, NTC, op-amp ideal), CircuitScheduler with
  debounced coalescing, AVRSpiceBridge for quasi-static co-simulation.
- store/useElectricalStore: Zustand slice, feature-flag aware.
- components/analog-ui/: ⚡ toolbar toggle + SVG voltage overlay.
- components/components-instruments/: Voltmeter, Ammeter probes.
- 62 tests (spice-*, netlist-builder, component-to-spice, instruments).

Sandbox (test/test_circuit/): 47-test validation sandbox that proved
the approach (hand-rolled MNA baseline + ngspice pipeline) before
porting to the app. Kept as reference.

Docs: docs/wiki/circuit-emulation-*.md (13 engineering pages covering
architecture, solvers, components, AVR bridge, gotchas, performance,
integration plan, API reference, appendix) + electrical-simulation-
user-guide.md (end-user facing).

Reference plan: test/test_circuit/plan/phase_8_velxio_implementation.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 12:11:54 +00:00