ATtiny85 (AVRSimulator + collectPinStates + connectAnalogInputsToMcu + SimulatorCanvas + Attiny85Element + examples): - Add attiny85AdcConfig with correct register addresses (ADMUX=0x27, ADCSRA=0x26, ADCSRB=0x23, ADCL=0x24, ADCH=0x25, DIDR0=0x34, adcInterrupt=0x08). Without this, analogRead() polled the wrong address forever and the firmware hung on first ADC read. - Add attiny85Timer0Config + instantiate AVRTimer so OVF fires at the ATTinyCore-expected ~1.024 ms cadence. delay() advance is still blocked on avr8js TIFR auto-clear semantics (separate upstream issue, see ATTINY85_TIMER0_UPSTREAM_ISSUE.md in velxio-prod test plan). - Map ATtiny85 ADC channels to PB-style pin names (PB5/PB2/PB4/PB3 -> 0..3) in connectAnalogInputsToMcu so SPICE node voltages reach the right ADC channel. - Recognise /^PB\d+$/ in collectPinStates.pinNameToArduinoPin so wires named "PB1" emit v_attiny85_pb1 V-source and the LED responds to MCU writes. Previously every PB-wire returned -1 and SPICE saw no source. - SimulatorCanvas: subscribe pin 1 (PB1) for the built-in LED on the attiny85 board kind (Digispark convention), instead of falling through to the pin-13 default. - Attiny85Element: remove the hand-drawn "yellow LED" circle that was floating above the chip. The bare DIP-8 has no on-board LED; examples wire a real wokwi-led + resistor instead. - examples.ts: add a real wokwi-led + 220 Ohm wokwi-resistor + wires to attiny85-blink, and add missing series resistors to attiny85-button-led and attiny85-ntc-sensor. attiny85-pwm-fade was already correct. Custom-chip pipeline (CustomChipPart + simulatorBridges): - Add a requestAnimationFrame loop that calls instance.tickTimers() every frame in CustomChipPart. Chips that register vx_timer_create (e.g. an i8080 stepping its core, or a sensor publishing samples) had timers added to the queue but nothing fired them; tickTimers was dead code. - Gate the ESP32 backend path with detectSimulatorKind(sim)==='esp32'. The previous `typeof sim.registerSensor === 'function'` check matched AVR and RP2040 simulators too (they expose registerSensor for I2C sensor proxies), routing client-side chips to a non-existent ESP32 worker on those boards. - Replace direct simulator.usart.writeByte calls in avrUartTx with a JS-level FIFO + setTimeout(1ms) drainer. avr8js writeByte drops bytes under burst load (a chip emitting print_string lost ~99% of bytes via non-immediate, or kept only the last byte via immediate). The drainer attempts one non-immediate write per tick and retries on RXC busy / RXEN off. Added a guard for ATtiny85 (no USART -> would queue forever). End-to-end verified: i8080-banner-streamer now prints the boot banner followed by "uptime ticks: 0xNN" lines stepping every ~50 ms, executing real Intel 8080 instructions inside the WASM chip. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| public | ||
| scripts | ||
| src | ||
| .env.production | ||
| .gitignore | ||
| .prettierignore | ||
| .prettierrc.json | ||
| Dockerfile | ||
| README.md | ||
| eslint.config.js | ||
| esp32 plan.md | ||
| index.html | ||
| nginx.conf | ||
| package.json | ||
| tsconfig.app.json | ||
| tsconfig.json | ||
| tsconfig.node.json | ||
| vite.config.ts | ||
| vitest.config.ts | ||
README.md
Arduino Emulator - Frontend
React + TypeScript + Vite frontend for the Arduino emulator with visual simulator and code editor.
Features
- Monaco Code Editor - Full VSCode-like Arduino code editing experience
- Dynamic Component System - 48+ wokwi-elements components with search and categories
- Visual Simulator Canvas - Interactive drag-and-drop circuit builder
- Component Property Dialog - Single-click component interaction (rotate, delete, view pins)
- Segment-Based Wire Editing - Drag wire segments perpendicular to orientation (like Wokwi)
- Real AVR8 Emulation - Actual ATmega328p emulation using avr8js
- Pin Management - Automatic pin mapping and state synchronization
- Grid Snapping - 20px grid alignment for clean circuit layouts
Tech Stack
- React 18 - UI framework
- TypeScript - Static typing
- Vite 5 - Build tool and dev server
- Monaco Editor - Code editor (VSCode engine)
- Zustand - State management
- Axios - HTTP client for backend API
- avr8js - AVR8 CPU emulator (npm package)
- @wokwi/elements - Electronic web components (npm package)
Development
Prerequisites
- Node.js 18+
- Backend running at http://localhost:8001
Install Dependencies
npm install
Run Development Server
npm run dev
The app will be available at http://localhost:5173
Build for Production
npm run build
Output will be in the dist/ directory.
Lint
npm run lint
Project Structure
frontend/
├── src/
│ ├── components/
│ │ ├── velxio-components/ # React wrappers for wokwi-elements + Velxio-original parts
│ │ ├── editor/ # Monaco Editor components
│ │ │ ├── CodeEditor.tsx
│ │ │ └── EditorToolbar.tsx
│ │ └── simulator/ # Simulation canvas components
│ │ ├── SimulatorCanvas.tsx
│ │ ├── WireLayer.tsx
│ │ ├── WireRenderer.tsx
│ │ ├── PinOverlay.tsx
│ │ ├── ComponentPropertyDialog.tsx
│ │ ├── ComponentPickerModal.tsx
│ │ └── ComponentPalette.tsx
│ ├── simulation/
│ │ ├── AVRSimulator.ts # AVR8 CPU wrapper
│ │ └── PinManager.ts # Pin mapping and callbacks
│ ├── store/
│ │ ├── useEditorStore.ts # Code editor state
│ │ └── useSimulatorStore.ts # Simulation state
│ ├── services/
│ │ ├── api.ts # Backend API client
│ │ └── ComponentRegistry.ts # Component metadata
│ ├── types/ # TypeScript definitions
│ ├── utils/
│ │ ├── hexParser.ts # Intel HEX parser
│ │ ├── wirePathGenerator.ts # Wire SVG path generation
│ │ └── wireSegments.ts # Segment-based wire editing
│ ├── App.tsx # Main app component
│ └── main.tsx # Entry point
├── public/ # Static assets
├── vite.config.ts # Vite configuration
└── package.json
Key Architecture Patterns
State Management (Zustand)
Two main stores:
- useEditorStore - Code content, theme, compilation state
- useSimulatorStore - Simulation running state, components, wires, compiled hex
Wokwi Libraries
@wokwi/elements, avr8js and rp2040js are regular npm dependencies resolved
from node_modules like any other package — no local clones required.
AVR Simulation Loop
- Runs at ~60 FPS using
requestAnimationFrame - Executes ~267,000 CPU cycles per frame (16MHz / 60fps)
- Port listeners fire when GPIO registers change
- PinManager routes pin states to component callbacks
Component System
Components are Web Components from wokwi-elements:
- React wrappers in
velxio-components/ - Dynamic loading via ComponentRegistry
- Pin info extracted from component metadata
- State updates via refs and callbacks
Wire Editing System
Segment-based editing (like Wokwi):
- Wires consist of orthogonal segments (horizontal/vertical)
- Drag segments perpendicular to orientation:
- Horizontal segments: move up/down (ns-resize)
- Vertical segments: move left/right (ew-resize)
- Local preview state during drag (requestAnimationFrame)
- Store update only on mouse up with grid snapping (20px)
Performance Optimizations
requestAnimationFramefor smooth wire dragging- Local state for real-time previews
- Memoized path generation and segment computation
- Store updates batched at interaction completion
API Integration
Backend endpoints (http://localhost:8001):
POST /api/compile- Compile Arduino code to .hexGET /api/compile/status/{task_id}- Check compilation statusGET /api/compile/download/{filename}- Download compiled .hex
See backend documentation for API details.
Component Development
Adding a New Component Type
-
Check if wokwi-elements has the component:
ls ../third-party/wokwi-elements/src/ -
Create React wrapper in
src/components/velxio-components/:import React, { useRef, useEffect } from 'react'; export const WokwiMyComponent: React.FC<Props> = ({ ... }) => { const elementRef = useRef<any>(null); useEffect(() => { if (elementRef.current) { elementRef.current.setAttribute('prop', value); } }, [value]); return <wokwi-my-component ref={elementRef} />; }; -
Add to ComponentRegistry metadata
-
Use in SimulatorCanvas or make available in ComponentPalette
Troubleshooting
Monaco Editor Not Loading
- Check if
monaco-editoris installed - Verify Vite worker configuration in vite.config.ts
Components Not Rendering
- Ensure wokwi-elements is built:
cd ../third-party/wokwi-elements && npm run build - Check browser console for Web Component registration errors
- Verify Vite alias paths in vite.config.ts
Wire Editing Performance Issues
- Ensure
requestAnimationFrameis being used - Check that store updates only happen on mouse up, not during drag
- Verify no unnecessary re-renders with React DevTools
Pin Alignment Issues
- Pin coordinates from wokwi-elements are in CSS pixels
- Do NOT multiply by MM_TO_PX conversion factor
- Verify component position + pin offset calculation
Compilation Fails
- Check backend is running at http://localhost:8001
- Verify arduino-cli is installed and
arduino:avrcore is available - Check CORS configuration in backend