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 19:11:54 +07:00
|
|
|
/**
|
|
|
|
|
* Hooks up the electrical solver to the main simulator store:
|
|
|
|
|
* - subscribe to components, wires, pin changes
|
|
|
|
|
* - on change, build the input and request a solve
|
|
|
|
|
* - inject node voltages back into ADC channels
|
|
|
|
|
*
|
|
|
|
|
* Called once at app startup (typically from EditorPage or main.tsx).
|
|
|
|
|
* Returns an `unsubscribe()` for cleanup.
|
|
|
|
|
*/
|
2026-04-18 05:27:18 +07:00
|
|
|
import { useSimulatorStore, getBoardSimulator, getBoardPinManager } from '../../store/useSimulatorStore';
|
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 19:11:54 +07:00
|
|
|
import { useElectricalStore } from '../../store/useElectricalStore';
|
|
|
|
|
import { buildInputFromStore } from './storeAdapter';
|
2026-04-18 05:27:18 +07:00
|
|
|
import { setAdcVoltage } from '../parts/partUtils';
|
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 19:11:54 +07:00
|
|
|
import type { PinSourceState } from './types';
|
|
|
|
|
import type { BoardKind } from '../../types/board';
|
2026-04-18 05:27:18 +07:00
|
|
|
import { BOARD_PIN_GROUPS } from './boardPinGroups';
|
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 19:11:54 +07:00
|
|
|
|
|
|
|
|
// Which Arduino-style pin name maps to which ADC channel, per board.
|
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-16 08:59:22 +07:00
|
|
|
// Used to inject SPICE-solved voltages back into the MCU's ADC peripheral.
|
|
|
|
|
function adcRange(prefix: string, start: number, count: number) {
|
|
|
|
|
return Array.from({ length: count }, (_, i) => ({
|
|
|
|
|
pinName: `${prefix}${start + i}`,
|
|
|
|
|
channel: i,
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ADC_6CH = adcRange('A', 0, 6); // A0..A5
|
|
|
|
|
const ADC_8CH = adcRange('A', 0, 8); // A0..A7
|
|
|
|
|
const ADC_16CH = adcRange('A', 0, 16); // A0..A15
|
|
|
|
|
|
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 19:11:54 +07:00
|
|
|
const ADC_PIN_MAP: Partial<Record<BoardKind, Array<{ pinName: string; channel: number }>>> = {
|
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-16 08:59:22 +07:00
|
|
|
// AVR boards
|
|
|
|
|
'arduino-uno': ADC_6CH,
|
|
|
|
|
'arduino-nano': ADC_8CH,
|
|
|
|
|
'arduino-mega': ADC_16CH,
|
|
|
|
|
'attiny85': adcRange('A', 0, 4), // A0..A3 (PB2-PB5)
|
|
|
|
|
|
|
|
|
|
// RP2040 boards — 4 ADC channels (GP26-GP29)
|
|
|
|
|
'raspberry-pi-pico': [
|
|
|
|
|
{ pinName: 'GP26', channel: 0 }, { pinName: 'GP27', channel: 1 },
|
|
|
|
|
{ pinName: 'GP28', channel: 2 }, { pinName: 'GP29', channel: 3 },
|
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 19:11:54 +07:00
|
|
|
],
|
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-16 08:59:22 +07:00
|
|
|
'pi-pico-w': [
|
|
|
|
|
{ pinName: 'GP26', channel: 0 }, { pinName: 'GP27', channel: 1 },
|
|
|
|
|
{ pinName: 'GP28', channel: 2 }, { pinName: 'GP29', channel: 3 },
|
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 19:11:54 +07:00
|
|
|
],
|
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-16 08:59:22 +07:00
|
|
|
|
|
|
|
|
// ESP32 variants — most GPIOs can be ADC but the common ones are:
|
|
|
|
|
// ADC1: GPIO 32-39 (channels 0-7), ADC2: GPIO 0,2,4,12-15,25-27
|
|
|
|
|
// Simplified to the 8 most-used pins (GPIO 32-39 = ADC1)
|
|
|
|
|
'esp32': adcRange('GPIO', 32, 8),
|
|
|
|
|
'esp32-devkit-c-v4': adcRange('GPIO', 32, 8),
|
|
|
|
|
'esp32-cam': adcRange('GPIO', 32, 8),
|
|
|
|
|
'wemos-lolin32-lite': adcRange('GPIO', 32, 8),
|
|
|
|
|
|
|
|
|
|
// ESP32-S3 — ADC1 channels on GPIO 1-10, ADC2 on GPIO 11-20
|
|
|
|
|
'esp32-s3': adcRange('GPIO', 1, 10),
|
|
|
|
|
'xiao-esp32-s3': adcRange('GPIO', 1, 10),
|
|
|
|
|
'arduino-nano-esp32': adcRange('A', 0, 8),
|
|
|
|
|
|
|
|
|
|
// ESP32-C3 — ADC1 channels on GPIO 0-4, ADC2 on GPIO 5
|
|
|
|
|
'esp32-c3': adcRange('GPIO', 0, 6),
|
|
|
|
|
'xiao-esp32-c3': adcRange('GPIO', 0, 6),
|
|
|
|
|
'aitewinrobot-esp32c3-supermini': adcRange('GPIO', 0, 6),
|
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 19:11:54 +07:00
|
|
|
};
|
|
|
|
|
|
2026-04-18 05:27:18 +07:00
|
|
|
/**
|
|
|
|
|
* Convert an ADC pin name + channel to the GPIO pin number that
|
|
|
|
|
* `setAdcVoltage()` (partUtils) expects, per board family.
|
|
|
|
|
*
|
|
|
|
|
* AVR: A0→14, A1→15, ... (analog pins start at 14)
|
|
|
|
|
* RP2040: GP26→26, GP27→27, ... (GPIO number directly)
|
|
|
|
|
* ESP32: GPIO32→32, ... or A0→channel-dependent (GPIO number)
|
|
|
|
|
*/
|
|
|
|
|
function avrPinFromName(_name: string, channel: number): number { return 14 + channel; }
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
|
|
function gpioPinFromName(name: string, _channel: number): number {
|
|
|
|
|
const m = name.match(/(\d+)$/);
|
|
|
|
|
return m ? parseInt(m[1], 10) : -1;
|
|
|
|
|
}
|
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 19:11:54 +07:00
|
|
|
|
2026-04-18 05:27:18 +07:00
|
|
|
const ADC_PIN_TO_GPIO: Partial<Record<BoardKind, (pinName: string, channel: number) => number>> = {
|
|
|
|
|
'arduino-uno': avrPinFromName,
|
|
|
|
|
'arduino-nano': avrPinFromName,
|
|
|
|
|
'arduino-mega': avrPinFromName,
|
|
|
|
|
'attiny85': avrPinFromName,
|
|
|
|
|
|
|
|
|
|
'raspberry-pi-pico': gpioPinFromName,
|
|
|
|
|
'pi-pico-w': gpioPinFromName,
|
|
|
|
|
|
|
|
|
|
'esp32': gpioPinFromName,
|
|
|
|
|
'esp32-devkit-c-v4': gpioPinFromName,
|
|
|
|
|
'esp32-cam': gpioPinFromName,
|
|
|
|
|
'wemos-lolin32-lite': gpioPinFromName,
|
|
|
|
|
'esp32-s3': gpioPinFromName,
|
|
|
|
|
'xiao-esp32-s3': gpioPinFromName,
|
|
|
|
|
'arduino-nano-esp32': avrPinFromName, // uses A0-A7 naming
|
|
|
|
|
'esp32-c3': gpioPinFromName,
|
|
|
|
|
'xiao-esp32-c3': gpioPinFromName,
|
|
|
|
|
'aitewinrobot-esp32c3-supermini': gpioPinFromName,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Convert a board pin name (e.g. "9", "A0", "GP26", "GPIO32") to the
|
|
|
|
|
* Arduino-style pin number that PinManager uses internally.
|
|
|
|
|
* Returns -1 if the name doesn't map to a GPIO pin.
|
|
|
|
|
*/
|
|
|
|
|
function pinNameToArduinoPin(pinName: string, boardKind: BoardKind): number {
|
|
|
|
|
const group = BOARD_PIN_GROUPS[boardKind] ?? BOARD_PIN_GROUPS.default;
|
|
|
|
|
// Skip power/ground pins — they're handled as canonical nets
|
|
|
|
|
if (group.gnd.includes(pinName) || group.vcc_pins.includes(pinName)) return -1;
|
|
|
|
|
|
|
|
|
|
// RP2040: "GP26" → 26
|
|
|
|
|
if (pinName.startsWith('GP')) {
|
|
|
|
|
const n = parseInt(pinName.slice(2), 10);
|
|
|
|
|
return Number.isFinite(n) ? n : -1;
|
|
|
|
|
}
|
|
|
|
|
// ESP32: "GPIO32" → 32
|
|
|
|
|
if (pinName.startsWith('GPIO')) {
|
|
|
|
|
const n = parseInt(pinName.slice(4), 10);
|
|
|
|
|
return Number.isFinite(n) ? n : -1;
|
|
|
|
|
}
|
|
|
|
|
// AVR analog: "A0" → 14, "A1" → 15, ...
|
|
|
|
|
if (/^A\d+$/.test(pinName)) {
|
|
|
|
|
return 14 + parseInt(pinName.slice(1), 10);
|
|
|
|
|
}
|
|
|
|
|
// Bare numeric: "9" → 9, "13" → 13
|
|
|
|
|
if (/^\d+$/.test(pinName)) {
|
|
|
|
|
return parseInt(pinName, 10);
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Collect MCU output pin states from PinManager for pins that participate
|
|
|
|
|
* in the circuit (i.e., are referenced by wires).
|
|
|
|
|
*/
|
|
|
|
|
function collectPinStates(
|
|
|
|
|
boardId: string,
|
|
|
|
|
boardKind: BoardKind,
|
|
|
|
|
wires: Array<{ start: { componentId: string; pinName: string }; end: { componentId: string; pinName: string } }>,
|
|
|
|
|
): Record<string, PinSourceState> {
|
|
|
|
|
const pm = getBoardPinManager(boardId);
|
|
|
|
|
if (!pm) return {};
|
|
|
|
|
const group = BOARD_PIN_GROUPS[boardKind] ?? BOARD_PIN_GROUPS.default;
|
|
|
|
|
const vcc = group.vcc;
|
|
|
|
|
|
|
|
|
|
const result: Record<string, PinSourceState> = {};
|
|
|
|
|
// Gather all pin names wired to this board
|
|
|
|
|
const pinNames = new Set<string>();
|
|
|
|
|
for (const w of wires) {
|
|
|
|
|
if (w.start.componentId === boardId) pinNames.add(w.start.pinName);
|
|
|
|
|
if (w.end.componentId === boardId) pinNames.add(w.end.pinName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const pinName of pinNames) {
|
|
|
|
|
const arduinoPin = pinNameToArduinoPin(pinName, boardKind);
|
|
|
|
|
if (arduinoPin < 0) continue;
|
|
|
|
|
const pwmDuty = pm.getPwmValue(arduinoPin);
|
|
|
|
|
if (pwmDuty > 0) {
|
|
|
|
|
result[pinName] = { type: 'pwm', duty: pwmDuty };
|
|
|
|
|
} else if (pm.getPinState(arduinoPin)) {
|
|
|
|
|
result[pinName] = { type: 'digital', v: vcc };
|
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 19:11:54 +07:00
|
|
|
}
|
2026-04-18 05:27:18 +07:00
|
|
|
// If pin is LOW or unknown, don't add — treated as input/floating by SPICE
|
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 19:11:54 +07:00
|
|
|
}
|
2026-04-18 05:27:18 +07:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function wireElectricalSolver(): () => void {
|
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 19:11:54 +07:00
|
|
|
|
2026-04-21 02:38:31 +07:00
|
|
|
// Cache the last solve input JSON to skip redundant solves.
|
|
|
|
|
// This is critical: without it, the periodic timer floods the scheduler
|
|
|
|
|
// with identical requests, delaying the result that carries updated
|
|
|
|
|
// pin states (e.g. PWM) until after the simulation stops.
|
|
|
|
|
let lastInputJson = '';
|
|
|
|
|
|
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 19:11:54 +07:00
|
|
|
function maybeSolve() {
|
|
|
|
|
const storeState = useSimulatorStore.getState();
|
|
|
|
|
const snap = {
|
|
|
|
|
components: storeState.components,
|
|
|
|
|
wires: storeState.wires,
|
|
|
|
|
boards: storeState.boards.map((b) => ({
|
|
|
|
|
id: b.id,
|
|
|
|
|
boardKind: b.boardKind,
|
2026-04-18 05:27:18 +07:00
|
|
|
pinStates: collectPinStates(b.id, b.boardKind, storeState.wires),
|
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 19:11:54 +07:00
|
|
|
})),
|
|
|
|
|
};
|
|
|
|
|
const input = buildInputFromStore(snap);
|
2026-04-21 02:38:31 +07:00
|
|
|
|
|
|
|
|
// Deduplicate: skip if the input hasn't changed since the last solve.
|
|
|
|
|
const inputJson = JSON.stringify(input);
|
|
|
|
|
if (inputJson === lastInputJson) return;
|
|
|
|
|
lastInputJson = inputJson;
|
|
|
|
|
|
2026-04-18 05:27:18 +07:00
|
|
|
// pinNetMap is now built inside buildNetlist() from the same UF and
|
|
|
|
|
// returned via CircuitScheduler → ElectricalSolveResult → store.
|
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 19:11:54 +07:00
|
|
|
useElectricalStore.getState().triggerSolve(input);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function injectVoltagesIntoADC() {
|
2026-04-18 05:27:18 +07:00
|
|
|
const { nodeVoltages, pinNetMap } = useElectricalStore.getState();
|
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 19:11:54 +07:00
|
|
|
const { boards } = useSimulatorStore.getState();
|
|
|
|
|
for (const board of boards) {
|
2026-04-18 05:27:18 +07:00
|
|
|
const adcPins = ADC_PIN_MAP[board.boardKind];
|
|
|
|
|
if (!adcPins) continue;
|
|
|
|
|
const sim = getBoardSimulator(board.id);
|
|
|
|
|
if (!sim) continue;
|
|
|
|
|
const vMax = board.boardKind.startsWith('esp32') ? 3.3 : 5.0;
|
|
|
|
|
for (const { pinName, channel } of adcPins) {
|
|
|
|
|
const netName = pinNetMap.get(`${board.id}:${pinName}`);
|
|
|
|
|
if (!netName) continue;
|
|
|
|
|
const v = nodeVoltages[netName];
|
|
|
|
|
if (v == null) continue;
|
|
|
|
|
const clamped = Math.max(0, Math.min(vMax, v));
|
|
|
|
|
const gpioPin = ADC_PIN_TO_GPIO[board.boardKind]?.(pinName, channel);
|
|
|
|
|
if (gpioPin != null) setAdcVoltage(sim, gpioPin, clamped);
|
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 19:11:54 +07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-21 02:38:31 +07:00
|
|
|
// Re-solve on components / wires changes.
|
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 19:11:54 +07:00
|
|
|
const unsubSim = useSimulatorStore.subscribe((state, prev) => {
|
|
|
|
|
if (state.components !== prev.components || state.wires !== prev.wires) {
|
|
|
|
|
maybeSolve();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// On every solve result, re-inject ADC voltages.
|
|
|
|
|
const unsubResult = useElectricalStore.subscribe((state, prev) => {
|
|
|
|
|
if (state.nodeVoltages !== prev.nodeVoltages) {
|
|
|
|
|
injectVoltagesIntoADC();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2026-04-18 05:27:18 +07:00
|
|
|
// Re-inject whenever boards change (e.g. loadHex recreates AVRADC).
|
|
|
|
|
// loadHex() creates a fresh AVRADC *before* updating the store, so by the
|
|
|
|
|
// time this fires the new ADC already exists and needs the SPICE values.
|
|
|
|
|
const unsubBoards = useSimulatorStore.subscribe((state, prev) => {
|
|
|
|
|
if (state.boards !== prev.boards) {
|
|
|
|
|
const { nodeVoltages } = useElectricalStore.getState();
|
|
|
|
|
if (Object.keys(nodeVoltages).length > 0) {
|
|
|
|
|
injectVoltagesIntoADC();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Periodic re-solve while any board is running, so SPICE picks up
|
|
|
|
|
// MCU pin-state changes (e.g. analogWrite → PWM → voltage source).
|
|
|
|
|
let solveInterval: ReturnType<typeof setInterval> | null = null;
|
|
|
|
|
const SOLVE_INTERVAL_MS = 200;
|
|
|
|
|
|
|
|
|
|
function updateSolveTimer() {
|
|
|
|
|
const anyRunning = useSimulatorStore.getState().boards.some((b) => b.running);
|
2026-04-21 02:38:31 +07:00
|
|
|
if (anyRunning) {
|
2026-04-18 05:27:18 +07:00
|
|
|
if (!solveInterval) {
|
|
|
|
|
solveInterval = setInterval(maybeSolve, SOLVE_INTERVAL_MS);
|
|
|
|
|
}
|
|
|
|
|
} else if (solveInterval) {
|
|
|
|
|
clearInterval(solveInterval);
|
|
|
|
|
solveInterval = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const unsubRunning = useSimulatorStore.subscribe((state, prev) => {
|
|
|
|
|
const wasRunning = prev.boards.some((b) => b.running);
|
|
|
|
|
const nowRunning = state.boards.some((b) => b.running);
|
|
|
|
|
if (wasRunning !== nowRunning) updateSolveTimer();
|
|
|
|
|
});
|
|
|
|
|
|
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 19:11:54 +07:00
|
|
|
return () => {
|
|
|
|
|
unsubSim();
|
|
|
|
|
unsubResult();
|
2026-04-18 05:27:18 +07:00
|
|
|
unsubBoards();
|
|
|
|
|
unsubRunning();
|
|
|
|
|
if (solveInterval) clearInterval(solveInterval);
|
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 19:11:54 +07:00
|
|
|
};
|
|
|
|
|
}
|