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.
This commit is contained in:
parent
6ccc090f0c
commit
a1137f1929
|
|
@ -16,6 +16,8 @@
|
|||
* - PWM duty cycle tracking (for servos, RGB LEDs, buzzers)
|
||||
*/
|
||||
|
||||
import { requestElectricalResolve } from './spice/electricalResolveHook';
|
||||
|
||||
export type PinState = boolean;
|
||||
export type PinChangeCallback = (pin: number, state: PinState) => void;
|
||||
export type AnalogCallback = (pin: number, voltage: number) => void;
|
||||
|
|
@ -155,6 +157,16 @@ export class PinManager {
|
|||
if (callbacks) {
|
||||
callbacks.forEach((cb) => cb(pin, state));
|
||||
}
|
||||
// An MCU output edge changes the circuit: request a SPICE re-solve so the
|
||||
// analog parts on this net (LED brightness, etc.) update. WS-backed boards
|
||||
// (ESP32 / STM32 / Raspberry Pi) reach the electrical sim ONLY through here
|
||||
// — previously they never triggered a re-solve, so a resistor-less LED
|
||||
// stayed at its first solved brightness until unrelated activity (e.g.
|
||||
// serial output) forced a solve. AVR / RP2040 already resolve at their own
|
||||
// toggle sites. Gated to 'mcu' so the solver's own input feedback
|
||||
// (triggerPinChange with the default 'external' source) can't create a
|
||||
// solve loop; the hook coalesces overlapping ticks so per-edge is cheap.
|
||||
if (source === 'mcu') requestElectricalResolve();
|
||||
}
|
||||
|
||||
/** Pins the MCU has actively driven this session. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue