Commit Graph

22 Commits

Author SHA1 Message Date
David Montero Crespo 701042fa22 fix(perf): un-freeze the editor during fast-toggling simulations (ESP32 clock)
Running a multiplexed 4-digit 7-segment clock on ESP32/QEMU froze the
browser for minutes after Run — evaluate probes waited 40-90 s, and before
the first fixes the sim WebSocket eventually died (code 1006) with the page
never recovering. CPU-profiled on staging; four compounding per-GPIO-edge
costs, in profile order:

updateComponentState minted a new components array per edge
------------------------------------------------------------
The store setter rebuilt `components` (and one properties object) on EVERY
edge even when the state didn't change. The breadboard is direct-wired to
13 board pins, so segment toggles produced thousands of store sets per
second; every subscriber re-rendered each time, and the canvas subscription
effect (deps: [components, ...]) re-subscribed all pin listeners in a loop.
Now a no-op guard returns prevState unchanged, and breadboards are treated
as self-managed (they have no visual on/off state to echo).

CompilationConsole re-rendered every log line per editor render
----------------------------------------------------------------
The post-compile console holds hundreds of lines; each render called
Date.toLocaleTimeString per line (~0.2 ms each — it builds a fresh Intl
formatter every call). Profile: 162 s of self time in LogLine over a 337 s
window, in ~150 ms tasks. LogLine is now memoized (entries are immutable),
timestamps go through one shared Intl.DateTimeFormat, and the console
itself is React.memo'd against parent re-renders.

Per-edge full SPICE re-solves
------------------------------
PinManager requested a FULL netlist rebuild+solve on every 'mcu' edge.
Now only the edge that newly classifies a pin as MCU-output triggers the
rebuild (that's what emits the pin's V-source); steady-state updates flow
through connectMcuEdgesToService's per-pin coalesced alterSource path.
The start.ts resolve hook is trailing-throttled (33 ms) for the other
per-edge callers (RP2040, custom chips), the service's pending-edge queue
drains on a 33 ms gap timer instead of replaying back-to-back, and new
edges arriving inside the gap queue instead of soloing a solve.
STM32 / Pi reverse pin-name mappings added to connectMcuEdgesToService so
those boards keep fine-grained updates now that the full-tick storm is
gone (PA0/PC13-style and GPIO-style names never matched before).

wokwi-7segment re-rendered per segment write
---------------------------------------------
element.values now flushes at most every 8 ms per display (trailing write
guaranteed), instead of re-rendering the 32-shape SVG per edge.

Also: CLN (colon) pin support for 7-segment clock faces — wired CLN now
drives colon/colonValue in both the attachEvents path and the QEMU
onPinStateChange path; it was silently ignored, so clock colons never lit.

Verified on staging with the failing project: main-thread probes drop from
40-90 s waits (324 long tasks, 52.6 s blocked in 150 s) to 5-11 ms
(2 long tasks, 179 ms), display shows 12:00 with the colon blinking at
1 Hz from the first seconds after Run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 01:15:59 +02:00
David Montero a1137f1929 fix(sim): re-solve SPICE on ESP32/STM32/Pi output pin edges
WebSocket-backed boards (ESP32, STM32, Raspberry Pi) reach the electrical
simulation only through PinManager.triggerPinChange, which updated the pin
state + notified listeners but never requested an electrical re-solve. AVR
and RP2040 already resolve at their own toggle sites. As a result an analog
part on an MCU-driven net (e.g. a resistor-less LED whose brightness comes
from the SPICE solve) stayed at its first solved value until unrelated
activity (such as serial output) forced a solve — so an ESP32 blink with no
Serial in loop() left the LED stuck on.

Request an electrical re-solve after an 'mcu'-sourced pin edge, in one place
(triggerPinChange), covering all WS boards. Gated to source==='mcu' so the
solver's own input feedback (triggerPinChange with the default 'external'
source) can't loop; requestElectricalResolve coalesces overlapping ticks so
a per-edge call is cheap.
2026-07-02 22:33:46 +02:00
David Montero 48099c0bda feat(avr): drive inputs from real circuit, modeling the internal pull-up
Re-do the AVR spice-driven digital inputs (reverted in c11c195) the right way so
INPUT_PULLUP buttons keep working. PinManager.updatePort now detects the AVR
internal pull-up (input DDR bit + PORT bit high) and sets the pin pull, so the
netlist stamps the 45k pull-up and an INPUT_PULLUP input reads HIGH at idle.
connectDigitalInputsToMcu drives a pin from the solve only when its net is
source-backed by a RAIL or a COMPONENT card (button switch, divider, cross-board
output) — NOT by the internal pull alone — so INPUT_PULLUP pins wired to
event-driven parts with no SPICE model (rotary encoder, keypad) are left to the
part layer and never clobbered. AVR only; RP2040/STM32 stay on the part-seed
until their pulls are modeled.
2026-06-26 20:18:41 +02:00
David Montero df9e06c99a feat(esp32): emulate internal pull-up/pull-down for GPIO inputs
INPUT_PULLUP / INPUT_PULLDOWN had no effect in simulation: the ESP32's
internal pull resistors live inside QEMU and were invisible to the SPICE
solver, so an input wired to a button-to-GND floated to 0 V and read LOW
even at idle. The canonical active-low button never worked.

Read the pull config straight out of the running guest: the IO_MUX
register (FUN_PU bit 8 / FUN_PD bit 7) is already exposed read-only via
qemu_picsimlab_get_internals(3), so no QEMU rebuild is needed. The worker
scans it on the 100 ms poll thread and emits gpio_pull; the bridge feeds
it to PinManager; the netlist stamps a weak 45k resistor to the rail so
idle inputs read the correct level. 45k matches the real internal pull
and is weak enough that any external driver/pull dominates.

Verified with ngspice: idle ~3.3 V (HIGH), pressed ~0 V (LOW).
2026-06-24 03:32:30 +02:00
ciegovolador 9b86c816c1 fix(sim): keep PwmCallback 2-arg compatible via arity dispatch
Revert the earlier approach of widening the existing PWM-callback assertions to
accept the new timeMs arg — that masked a contract change rather than fixing it.
Instead, updatePwm now hands the optional timeMs only to listeners that declare
a 3rd parameter (cb.length >= 3) — i.e. the buzzer, which needs the precise
onset time. Plain (pin, dutyCycle) listeners, and the existing
toHaveBeenCalledWith(pin, dutyCycle) tests, see an unchanged 2-arg call, so the
original PwmCallback contract is preserved.

Add a PinManager test locking the dispatch: a 2-param listener stays 2-arg; a
3-param listener receives timeMs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 03:29:44 -03:00
ciegovolador 06526c7922 fix(sim): sample-accurate buzzer audio — precise PWM detection + display-aligned scheduling
A PWM-driven buzzer (analogWrite / Timer tones) was chaotic and unusable as a
metronome. Causes, all on the PWM path:

1. PWM was polled once per animation frame AFTER the cycle loop, so short clicks
   that started and ended within one frame were merged or lost, and onsets were
   quantised to the frame.
2. The buzzer started the oscillator with `oscillator.start()` (no scheduled
   time) — frame-delivery jitter and per-onset oscillator churn.
3. The digital HIGH/LOW path also fired on the ~490Hz PWM carrier edges,
   injecting spurious onsets (OCR read as 0 → 20kHz squeaks).

Fix:
- AVRSimulator: poll PWM sub-frame (every 256 cycles) so no pulse is merged or
  lost; pass the precise simulated time through updatePwm.
- PinManager: PwmCallback / updatePwm carry an optional timeMs (backward compat).
- Buzzer: one continuous oscillator gated by the gain node, each on/off scheduled
  on the AudioContext clock. The schedule predicts the next onset at a smoothed
  interval (de-jittering the simulator's bursty per-frame delivery) and holds a
  small bounded latency so the click stays aligned with the on-screen playhead
  (driven from the same clock) instead of drifting behind it. A `pwmActive` flag
  mutes the digital path once hardware PWM drives the pin.

Result: onset jitter for a firmware metronome drops from chaotic (σ ≈ 250ms,
dropped/extra beats, unbounded audio latency) to σ ≈ 15ms at ~30ms latency —
steady and aligned with the display. All 54 simulation-parts tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 22:46:21 -03:00
David Montero d64eebc200 fix(stop): reset CPU to PC=0 on Stop (real-life power-cycle semantics)
The previous fix preserved display state on Stop so Resume could pick
up the multiplexed frame seamlessly — but that's Pause semantics, not
Stop. On a real Arduino, hitting the physical Stop is cutting power:
the next Run must boot from setup(), not continue at the saved PC.

User report on https://velxio.dev/example/uno-7segment :
  > empieza a contar, le doy stop en el 6, le doy run y sigue desde 6

stopBoard now:
  - calls sim.reset() (was sim.stop()) — CPU back to PC=0
  - calls hardResetPinStates() (was the soft resetPinStates) — clears
    cached states AND notifies listeners so 7-seg / NeoPixel / LCD
    blank out instead of freezing on whatever was lit.

Reset and Stop are now the same cold-boot semantics; Reset still
additionally clears serial output + baud rate. The soft
resetPinStates() helper stays for internal SPICE-classification-only
paths that don't want listener fan-out.
2026-05-26 21:28:41 +02:00
David Montero b2474bf5d1 fix(stop): preserve display state on Stop, only blank on Reset
Reporter feedback after 7aca3db: pressing Stop on the uno-7segment
example turned the 7-segment off, and pressing Start again left
random segments lit / no number at all. The previous fix made
resetPinStates() notify every listener with (pin, false) on both
Stop and Reset, which was right for Reset (full reboot) but wrong
for Stop:

  - On Stop the AVR CPU is just paused. Internally it still has
    PORTD=0xFF (or whatever the last drive was).
  - resetPinStates blanked the pinStates cache + fan-out LOW
    notifications. Display turns off, fine.
  - On Start the CPU resumes from where it paused. avr8js's port
    listener fires only for bits that CHANGED relative to its OWN
    oldValue (which still holds the pre-stop value). If oldValue
    matches the live register, no pinChange event fires for that
    bit, and the display has no signal telling it to come back on.

Split the API into two methods:

  resetPinStates()    — soft cleanup, drops outputPins only. Used by
                        stopBoard. Cached pinStates and visual state
                        stay so the resume picks up where it left off.

  hardResetPinStates() — full cleanup, drops outputPins + pinStates
                        and fan-outs (pin, false) to listeners.
                        Used by resetBoard (CPU starts at PC=0,
                        firmware re-drives every pin from setup()).

Updated the test helper clearAllPinManagerState to call
hardResetPinStates between tests so the same-state short-circuit in
triggerPinChange doesn't suppress fresh events.

All 32 vitest tests pass (AVRSimulator, interconnect-routing,
dual-arduino-software-serial, pin-position-rotation).
2026-05-26 18:54:17 +02:00
David Montero 7aca3db51c fix(reset): clear display state + don't clobber Interconnect on Reset
Two paired bugs that surfaced on the Reset button.

(1) 7-segment / NeoPixel / LCD freeze on last pattern after Reset.
    resetPinStates() was wiping the pinStates cache + outputPins set
    silently — no listener notifications fired, so visual components
    that update on pinChange kept rendering whatever segments were
    lit at the instant the user pressed Reset. Now we snapshot every
    pin that was HIGH before clearing and fan out a synthetic
    (pin, false) to each registered listener. Stateful displays
    redraw cleanly to all-off; passive listeners (analog sensors,
    debounce-only buttons) ignore the synthetic LOW and recover on
    their next real write.

(2) Cross-board serial silently dies after pressing Reset. resetBoard
    was unconditionally reassigning:
        sim.onSerialData = (ch) => appendSerial(boardId, ch);
    immediately after sim.reset(). The comment said "re-wire after
    reset" but reset() does NOT clear that property — the new USART's
    onByteTransmit chains through `this.onSerialData` which IS the
    Interconnect wrapper. The reassignment destroyed that wrapper and
    sibling-board UART forwarding (Uno TX → Nano RX) stopped working
    until a full page reload. Same root pattern as the initSimulator
    bug fixed in 5480052 — Interconnect's __icSerialHookInstalled
    flag is on the live sim, so once the wrapper is blown away
    nothing reinstalls it. Removed the reassignment and left a NOTE
    so the next person doesn't reintroduce it.

Verified the AVRSimulator + dual-arduino-software-serial +
interconnect-routing test suites still pass (26 tests).
2026-05-26 17:30:44 +02:00
David Montero Crespo ca1bf00597
Merge pull request #193 from davidmonterocrespo24/esp32-cleanup-broadcast-pwm
refactor(esp32): retire ledc_update + broadcastPwm + channelGpioMemo
2026-05-18 23:23:05 -03:00
davidmonterocrespo24 ba59fd4b4a refactor(esp32): retire ledc_update + broadcastPwm + channelGpioMemo
The SignalRouter path has been in prod through Phase 2.5 / Phase 3.3
deploys without regressions, so the temporary fallback shipped in
commit 77bf897 can come out. Closes #101.

Backend (esp32_worker.py + esp32_lib_manager.py):
- Stop emitting `ledc_update` from the 0x5000 LEDC callback and from
  the polling thread. Only `ledc_duty` (channel + duty_pct) and the
  GPIO matrix routing events ship now.
- Drop the channel→gpio reverse-lookup that fed the legacy event.

Frontend:
- Delete `PinManager.broadcastPwm` and `PinManager.pwmListenerPinCount`.
- Delete `makeLedcUpdateHandler` + its `channelGpioMemo`.
- Delete `Esp32Bridge.onLedcUpdate` field + the `case 'ledc_update':`
  message handler + the `LedcUpdate` type.
- Strip `this.onLedcUpdate = null` from 14 test mocks.
- Rewrite the `does not call broadcastPwm` guard in
  esp32-multi-servo-gpio-matrix.test.ts to assert the method itself
  no longer exists on PinManager (stronger regression guard than the
  spy version, and doesn't need vi).
- Remove the `PinManager.broadcastPwm fallback` describe block from
  esp32-servo-pot.test.ts — every test in it exercised the deleted
  fallback path.

Docs (ESP32_EMULATION.md):
- Replace `ledc_update` rows in the events / implementation tables
  with the SignalRouter trio (`ledc_duty`, `gpio_routing`,
  `gpio_routing_clear`).
- Update the visual flow diagram + the "why this matters" paragraph
  to past-tense the broadcastPwm bug.

Tests: 1886 frontend tests pass (the previously-failing
board-kinds-coverage test that needed the new Pi Zero/1/2 kinds is
also green). Backend unit suite: 279 pass, the 11 espidf_real_paths
prereq failures are environment-dependent (need arduino-cli libs in
the local shell) and unrelated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 04:05:34 +02: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
davidmonterocrespo24 77bf8971ff fix(esp32): multi-servo blink — don't broadcast LEDC duty across consumers
User-reported bug (project 5218f9e3, solar-tracker with 2× ESP32
servos): when LDR values change the servos visibly oscillate between
two positions instead of moving smoothly.

Root cause in useSimulatorStore.makeLedcUpdateHandler. When the
backend emits a ledc_update with gpio=-1 (the per-channel gpio_out_sel
map isn't populated yet on the very first duty change after attach),
the handler called PinManager.broadcastPwm(duty). broadcastPwm fans
the same duty out to ALL registered PWM consumers — for a project
with two servos both subscribed in the 0.01-0.20 duty range, each
broadcast made BOTH servos mirror whichever channel was last
written. Result: servoPan→91° and servoTilt→87° alternating writes
would visibly snap both servos to 87°, then 91°, then 87°…

Two-part fix:

1. PinManager grows `pwmListenerPinCount()` — number of distinct
   pins with at least one PWM consumer registered.

2. makeLedcUpdateHandler now keeps a per-board memo of
   {ledc_channel → last-known-good-gpio}. On a gpio=-1 update:
     - if the channel has a remembered gpio, route there;
     - else, only broadcast when there's at most ONE consumer
       (single-LED / single-servo setups still work);
     - otherwise drop the update — the backend's GPIO out_sel poll
       repopulates the map within a few ms and the next ledc_update
       arrives with a real gpio.

The drop is correct because the same LEDC channel keeps emitting
duty changes every Servo.write() call (~33 Hz at 30 ms loop delay),
so missing one transient gpio=-1 frame is invisible.

Tests: 1853 pass. The existing esp32-servo-pot tests already cover
the gpio>=0 happy path; the new memo path is exercised indirectly
through that handler.
2026-05-17 04:22:11 +02:00
David Montero Crespo 8e769f8a4e feat(multi-board): add wire-aware cross-board interconnect router
Fixes the user-reported bug where two RPi Pico W boards wired GP0↔GP1
running SerialPassthrough don't communicate. Replaces the broken
broadcast-style cross-board logic in addBoard (only routed AVR↔Pi3B,
ignored wires entirely, no RP2040↔anything path) with a wire-aware
Interconnect singleton.

Architecture: digital pin transitions are the lowest-common-denominator
abstraction. Each simulator's hardware peripherals (UART/I2C/SPI) and
bit-banging libraries (SoftwareSerial, software I2C) decode the
transitions naturally — propagate the pin and the protocols come for
free. For cross-process boards (ESP32 backend QEMU, Pi3B QEMU) a
byte-level shortcut is additionally enabled on hardware-UART pin
pairs to handle high-baud links over WebSocket latency.

Implementation:
- New simulation/Interconnect.ts singleton subscribes to wire/board
  changes via the Zustand store. Handlers per tier: browser-sim →
  pinManager.onPinChange, ESP32 → Esp32Bridge.sendPinEvent, Pi3B →
  bridge.sendPinEvent. Re-entrancy guard via per-(board,pin) Set.
- New utils/boardProtocols.ts classifies pins (uart-tx, i2c-sda, etc.)
  per board kind, used as optimization hint for the byte shortcut.
- types/wire.ts: added signalType field, exports WireSignalType /
  WireColorMap (fixes a pre-existing TS import error in wireColors).
- Deleted the bridgeMap/simulatorMap broadcast forEach blocks in
  addBoard. Initial board + future boards register with Interconnect
  via setInterconnectRuntime + store subscription.
- PinManager.resetPinStates() helper for test isolation.

Tests (16 new files, 96 tests, all passing):
- Per-pair × per-protocol matrix: dual-arduino-digital,
  dual-pico-digital, arduino-pico-digital, triple-pico-digital-chain,
  dual-arduino-hw-uart, dual-arduino-software-serial,
  arduino-pico-mixed-uart, arduino-esp32-uart, dual-esp32-uart,
  pi3-pico-uart, arduino-pico-i2c, arduino-arduino-spi,
  interconnect-routing, dual-arduino-multi-protocol (UART+I2C+SPI+
  digital + concurrent), dual-pico-multi-protocol (UART0+UART1 alt+
  I2C0+I2C1+SPI0+digital + 3-Pico star topology)
- Updated dual-pico-serial-passthrough to assert correct behaviour
- Backend test/multi_board_esp32/test_dual_esp32_serial.py for two
  real QEMU instances (skip-graceful when lcgamboa lib absent)

Verified: 1107/1107 tests pass, zero regressions, vite build OK.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 19:47:40 -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 01f75cf313 feat: implement eager scan for LEDC GPIO mapping and add tests for race condition fix 2026-03-24 13:54:44 -03:00
David Montero Crespo dc5dfb8635 feat: enhance simulation accuracy and component interactions across various modules 2026-03-20 17:11:12 -03:00
David Montero Crespo 507fa0671c feat: enhance ESP32-C3 simulator with ROM stubs, timer group handling, and diagnostic logging 2026-03-17 16:46:44 -03:00
David Montero Crespo 1018609ed4 feat: add Arduino Mega support to simulator
- Introduced ArduinoMega component for rendering in the simulator.
- Updated SimulatorCanvas to handle Arduino Mega board type.
- Enhanced AVRSimulator to support ATmega2560 architecture, including PWM pin mapping and port management.
- Modified PinManager to accommodate Mega's non-linear pin mapping.
- Updated boardPinMapping utility to include Mega analog pins.
- Adjusted Wokwi import/export functionality to recognize and handle Arduino Mega.
- Updated useSimulatorStore to initialize AVRSimulator with the correct board variant.
2026-03-09 10:08:14 -03:00
David Montero Crespo 7944ce2de3 feat: add support for RP2040 board, including simulator and compilation enhancements 2026-03-04 19:28:33 -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 a8c4f143af feat: Implement Arduino Simulator with component management and simulation features
- Added SimulatorCanvas component for rendering the simulator interface.
- Integrated Wokwi components (Arduino, LED, Resistor, Pushbutton, Potentiometer) into the simulator.
- Created PinManager to handle pin state changes and notifications.
- Developed AVRSimulator class for emulating Arduino Uno functionality.
- Implemented hex file loading and compilation service.
- Added CSS styles for the simulator interface.
- Established Zustand stores for managing editor and simulator states.
- Created utility functions for parsing Intel HEX format.
- Set up Vite configuration for the frontend project.
- Added batch scripts for starting backend and frontend servers, and updating Wokwi libraries.
2026-03-03 00:20:49 -03:00