Actualiza la documentación de Wokwi Libraries para reflejar cambios en la descripción y uso de componentes, mejora la generación automática de metadata, y agrega detalles sobre la emulación AVR. Además, se actualiza el submódulo wokwi-elements y se crea un archivo de prueba de conectividad.

pull/10/head
David Montero Crespo 2026-03-04 18:41:49 -03:00
parent d81aa76260
commit 0187886dcf
2 changed files with 553 additions and 296 deletions

View File

@ -1,70 +1,90 @@
# Project Architecture - Arduino Emulator
# Project Architecture - OpenWokwi Arduino Emulator
## Overview
This project is a fully local Arduino emulator using official Wokwi repositories for maximum compatibility.
This project is a fully local Arduino emulator using official Wokwi repositories for maximum compatibility. It features real AVR8 CPU emulation, 48+ interactive electronic components, a comprehensive wire system, and a build-time component discovery pipeline.
```
┌─────────────────────────────────────────────────────────────┐
│ USER (Browser) │
│ http://localhost:5173 │
└──────────────────────────┬──────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────
USER (Browser)
http://localhost:5173
└──────────────────────────┬──────────────────────────────────────────
┌─────────────────────────────────────────────────────────────┐
│ FRONTEND (React + Vite) │
│ │
│ ┌────────────────┐ ┌──────────────────┐ ┌─────────────┐ │
│ │ Monaco Editor │ │ Zustand Store │ │ Simulator │ │
│ │ (Code Edit) │ │ (State Mgmt) │ │ Canvas │ │
│ └────────────────┘ └──────────────────┘ └─────────────┘ │
│ │ │ │ │
│ └───────────────────┴──────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Wokwi Components Integration │ │
│ │ (wokwi-elements + avr8js from local repos) │ │
│ └──────────────────────────────────────────────────────┘ │
└──────────────────────────┬──────────────────────────────────┘
│ HTTP (axios)
┌─────────────────────────────────────────────────────────────────────┐
│ FRONTEND (React 19 + Vite 7) │
│ │
│ ┌────────────────┐ ┌──────────────────┐ ┌───────────────────┐ │
│ │ Monaco Editor │ │ Zustand Stores │ │ SimulatorCanvas │ │
│ │ (Code Edit) │ │ (Editor+Sim) │ │ (Components+ │ │
│ │ C++ / Arduino │ │ │ │ Wires+Pins) │ │
│ └────────┬───────┘ └────────┬─────────┘ └────────┬──────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ AVRSimulator (avr8js) │ │
│ │ CPU 16MHz · Timer0/1/2 · USART · ADC · PORTB/C/D │ │
│ │ ~60fps · 267k cycles/frame · Speed 0.1x-10x │ │
│ └──────────────────────────────┬───────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ PinManager + PartSimulationRegistry │ │
│ │ Digital/PWM/Analog listeners · 16 registered parts │ │
│ │ LED · RGB · Button · Pot · LCD · Servo · Buzzer · etc. │ │
│ └──────────────────────────────┬───────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ 48+ wokwi-elements (Lit Web Components) │ │
│ │ DynamicComponent renderer · ComponentRegistry (metadata) │ │
│ │ ComponentPickerModal · Property dialog · Pin selector │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Wire System │ │
│ │ Orthogonal routing · Segment editing · 8 signal colors │ │
│ │ Overlap offset · Pin overlay · Grid snapping (20px) │ │
│ └──────────────────────────────────────────────────────────────┘ │
└──────────────────────────┬──────────────────────────────────────────┘
│ HTTP (Axios)
┌─────────────────────────────────────────────────────────────┐
│ BACKEND (FastAPI + Python) │
│ http://localhost:8000 │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ POST /api/compile │ │
│ │ - Receives Arduino code (.ino) │ │
│ │ - Compiles with arduino-cli │ │
│ │ - Returns .hex file │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Arduino CLI Service │ │
│ │ (Invokes arduino-cli as subprocess) │ │
│ └─────────────────────────────────────────────────────┘ │
└──────────────────────────┬──────────────────────────────────┘
┌──────────────────────┐
│ arduino-cli │
│ (Local system) │
└──────────────────────┘
┌─────────────────────────────────────────────────────────────────────
BACKEND (FastAPI + Python)
http://localhost:8001
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ POST /api/compile/ → Compile Arduino code to .hex │ │
│ │ GET /api/compile/boards → List available boards │ │
│ │ GET / → API info │ │
│ │ GET /health → Health check │ │
│ └──────────────────────────────┬──────────────────────────────┘ │
┌─────────────────────────────────────────────────────────────┐
│ ArduinoCLIService │
│ │ Auto-installs arduino:avr core │ │
│ │ Temp directory + subprocess.run via asyncio.to_thread │ │
│ └──────────────────────────────┬──────────────────────────────┘ │
└─────────────────────────────────┼──────────────────────────────────┘
┌──────────────────────┐
│ arduino-cli │
│ (Local system) │
└──────────────────────┘
```
## Data Flow: Compilation and Simulation
## Data Flow
### 1. Code Editing
```
User writes code
User writes Arduino code
Monaco Editor
Monaco Editor (C++, dark theme, autocomplete)
Zustand (useEditorStore)
Zustand useEditorStore
State: code
State: { code, theme, fontSize }
```
### 2. Compilation
@ -73,57 +93,83 @@ Click "Compile"
EditorToolbar.tsx → compileCode()
Axios POST → http://localhost:8000/api/compile
Axios POST → http://localhost:8001/api/compile/
Backend: ArduinoCLIService.compile()
arduino-cli compile --fqbn arduino:avr:uno
arduino-cli compile --fqbn arduino:avr:uno --output-dir build/
Generates .hex file in temp directory
Reads build/sketch.ino.hex → returns hex_content
Backend reads .hex and returns content
Frontend: useSimulatorStore.setCompiledHex(hex)
Frontend: useSimulatorStore.setCompiledHex()
Auto-calls loadHex() → CPU + peripherals created
```
### 3. Simulation (Currently simplified)
### 3. Simulation (Real AVR8 Emulation)
```
Click "Run"
useSimulatorStore.setRunning(true)
useSimulatorStore.startSimulation()
SimulatorCanvas: useEffect detects running=true
AVRSimulator.start()
setInterval every 1000ms
requestAnimationFrame loop @ ~60fps
updateComponentState('led-builtin', !state)
Each frame: Math.floor(267000 × speed) cycles
wokwi-led component updates visually
For each cycle:
├── avrInstruction(cpu) ← Execute AVR instruction
└── cpu.tick() ← Update peripherals/timers
Port writes → AVRIOPort listeners
PinManager.updatePort(portName, newValue, oldValue)
Per-pin callbacks fire for changed pins
PartSimulationRegistry.onPinStateChange()
wokwi web components update visually
Additionally per frame:
pollPwmRegisters() → reads OCR0A/B, OCR1AL/BL, OCR2A/B
PinManager.updatePwm(pin, dutyCycle)
```
### 4. Real Simulation (Coming with avr8js)
### 4. Input Components Flow
```
Compiled .hex file
User presses a pushbutton on canvas
AVRSimulator.loadHex(hex)
Web component fires 'button-press' event
hexParser → Uint16Array (program memory)
DynamicComponent catches event
CPU = new CPU(program)
PartSimulationRegistry.attachEvents() handler
Click "Run" → AVRSimulator.start()
AVRSimulator.setPinState(arduinoPin, LOW)
requestAnimationFrame loop
AVRIOPort.setPin(bitIndex) injects external pin state
CPU.tick() × 267,000 cycles/frame
CPU reads pin value in next instruction
```
### 5. Wire Creation Flow
```
Click pin on component A → startWireCreation(endpoint)
Writes to PORTB/PORTC/PORTD
Mouse move → updateWireInProgress(x, y)
Write hooks → PinManager.updatePort()
WireInProgressRenderer shows dashed green L-shape preview
PinManager notifies callbacks
Click pin on component B → finishWireCreation(endpoint)
Components update visual state
Wire created with midpoint control point
WireLayer renders orthogonal SVG path
Components subscribe to Arduino pins via wire lookup
```
## Key Components
@ -131,81 +177,215 @@ Components update visual state
### Frontend
#### 1. Stores (Zustand)
- **[useEditorStore.ts](frontend/src/store/useEditorStore.ts)**
- `code`: Current source code
- `theme`: Editor theme (dark/light)
- `setCode()`: Update code
- **[useSimulatorStore.ts](frontend/src/store/useSimulatorStore.ts)**
- `running`: Simulation state
- `compiledHex`: Compiled hex file
- `components`: List of electronic components
- `setCompiledHex()`: Save hex
- `updateComponentState()`: Update LED/component
**useEditorStore** — Code editor state
| Property | Type | Default |
|----------|------|---------|
| `code` | `string` | Blink example sketch |
| `theme` | `'vs-dark' \| 'light'` | `'vs-dark'` |
| `fontSize` | `number` | `14` |
#### 2. UI Components
- **[CodeEditor.tsx](frontend/src/components/editor/CodeEditor.tsx)**
- Monaco Editor wrapper
- C++ syntax highlighting
- Auto-completion
Methods: `setCode()`, `setTheme()`, `setFontSize()`
- **[EditorToolbar.tsx](frontend/src/components/editor/EditorToolbar.tsx)**
- Buttons: Compile, Run, Stop
- Compilation state handling
- Error/success messages
**useSimulatorStore** — Simulation + components + wires state
| Property | Type | Description |
|----------|------|-------------|
| `simulator` | `AVRSimulator \| null` | CPU emulator instance |
| `pinManager` | `PinManager` | Pin-to-component mapping |
| `running` | `boolean` | Simulation active |
| `compiledHex` | `string \| null` | Compiled hex content |
| `components` | `Component[]` | All electronic components |
| `wires` | `Wire[]` | All wire connections |
| `selectedWireId` | `string \| null` | Currently selected wire |
| `wireInProgress` | `WireInProgress \| null` | Wire being created |
- **[SimulatorCanvas.tsx](frontend/src/components/simulator/SimulatorCanvas.tsx)**
- Renders Arduino Uno
- Renders components (LEDs)
- Simulation loop
Methods (20+):
- **Simulation**: `initSimulator()`, `loadHex()`, `startSimulation()`, `stopSimulation()`, `resetSimulation()`, `setCompiledHex()`, `setRunning()`
- **Components**: `addComponent()`, `removeComponent()`, `updateComponent()`, `updateComponentState()`, `handleComponentEvent()`, `setComponents()`
- **Wires**: `addWire()`, `removeWire()`, `updateWire()`, `setSelectedWire()`, `setWires()`
- **Wire creation**: `startWireCreation()`, `updateWireInProgress()`, `finishWireCreation()`, `cancelWireCreation()`
- **Wire positions**: `updateWirePositions(componentId)`, `recalculateAllWirePositions()`
#### 3. Wokwi Component Wrappers
- **[LED.tsx](frontend/src/components/components-wokwi/LED.tsx)**
- React wrapper for `<wokwi-led>`
- Props: color, value, x, y
Notable behaviors:
- `removeComponent()` cascades: removes all connected wires
- `updateComponent()` auto-recalculates wire positions when x/y changes
- `setCompiledHex()` auto-calls `loadHex()`
- **[ArduinoUno.tsx](frontend/src/components/components-wokwi/ArduinoUno.tsx)**
- React wrapper for `<wokwi-arduino-uno>`
- Internal LED control (pin 13)
#### 2. Simulation Engine
- **[Resistor.tsx](frontend/src/components/components-wokwi/Resistor.tsx)**
- React wrapper for `<wokwi-resistor>`
- Props: value (ohms)
**AVRSimulator** — Real ATmega328p emulation
- **CPU**: 16MHz clock, 32KB program memory (16K words)
- **Timers**: Timer0 (`timer0Config`), Timer1 (`timer1Config`), Timer2 (`timer2Config`)
- **Serial**: USART (`usart0Config`) at 16MHz
- **ADC**: Analog-to-digital converter (`adcConfig`)
- **GPIO**: PORTB (pins 8-13), PORTC (A0-A5), PORTD (pins 0-7)
- **Simulation loop**: ~60fps via `requestAnimationFrame`, `267000 × speed` cycles/frame
- **Speed control**: 0.1x 10x multiplier
- **PWM polling**: Reads OCR0A/B, OCR1AL/BL, OCR2A/B each frame
- **API**: `loadHex()`, `start()`, `stop()`, `reset()`, `step()`, `setSpeed()`, `setPinState()`, `getADC()`
- **[Pushbutton.tsx](frontend/src/components/components-wokwi/Pushbutton.tsx)**
- React wrapper for `<wokwi-pushbutton>`
- Events: onPress, onRelease
**PinManager** — Pin state tracking and listener dispatch
- **Digital**: `onPinChange(pin, callback)`, `updatePort(portName, newValue, oldValue)`, `getPinState(pin)`
- **PWM**: `onPwmChange(pin, callback)`, `updatePwm(pin, dutyCycle)`, `getPwmValue(pin)`
- **Analog**: `onAnalogChange(pin, callback)`, `setAnalogVoltage(pin, voltage)`
- **Utility**: `getListenersCount()`, `clearAllListeners()`
**PartSimulationRegistry** — Plugin system for component behaviors
- Interface: `onPinStateChange(pinName, state, element)` for outputs, `attachEvents(element, simulator, pinHelper) → cleanup` for inputs
- **16 registered parts**:
| Part | Type | Key Behavior |
|------|------|--------------|
| `led` | Output | Pin A state → `element.value` |
| `rgb-led` | Output | Digital + PWM on R/G/B → `ledRed/Green/Blue` |
| `led-bar-graph` | Output | 10 LEDs (A1-A10) → `.values` array |
| `7segment` | Output | 8 segments (A-G + DP) → `.values` array |
| `pushbutton` | Input | Press/release → `setPinState(pin, LOW/HIGH)` |
| `pushbutton-6mm` | Input | Same as pushbutton |
| `slide-switch` | Input | Change event → pin state |
| `dip-switch-8` | Input | 8 independent switches |
| `potentiometer` | Input | Value (0-1023) → ADC voltage injection |
| `slide-potentiometer` | Input | Same via SIG/OUT pins |
| `photoresistor-sensor` | Input/Output | Default 2.5V on AO, monitors DO for LED |
| `analog-joystick` | Input | VRX/VRY (ADC) + SW (digital) |
| `servo` | Output | Polls OCR1A/ICR1 → angle 0-180° |
| `buzzer` | Output | Web Audio API, reads Timer2 registers |
| `lcd1602` | Output | Full HD44780 4-bit protocol (16×2) |
| `lcd2004` | Output | Full HD44780 4-bit protocol (20×4) |
#### 3. Component System
**ComponentRegistry** — Singleton from `/components-metadata.json`
- **48 components** across 8 categories
- Auto-generated at build time by `scripts/generate-component-metadata.ts` (TypeScript AST parser)
- Methods: `getAllComponents()`, `getByCategory()`, `getById()`, `search()`, `getCategories()`
| Category | Count | Components |
|----------|-------|------------|
| Boards | 4 | Arduino Uno, Mega, Nano, etc. |
| Sensors | 6 | DHT22, HC-SR04, PIR, photoresistor, etc. |
| Displays | 3 | LCD 1602, LCD 2004, 7-segment |
| Input | 5 | Buttons, switches, potentiometers, joystick |
| Output | 5 | LEDs, RGB LED, LED bar graph, buzzer |
| Motors | 2 | Servo, stepper |
| Passive | 4 | Resistor, capacitor, etc. |
| Other | 19 | Various components |
**DynamicComponent** — Generic web component renderer
- Creates DOM elements with `document.createElement(metadata.tagName)`
- Syncs React properties to web component properties
- Extracts `pinInfo` from web component DOM (100ms polling, 2s timeout)
- Integrates with PartSimulationRegistry for simulation events
- Resolves Arduino pin from wire connections
- Handles visual state: selection border, rotation, cursor, labels
**ComponentPickerModal** — Component search and selection UI
- Search bar with real-time filtering
- Category tabs from registry
- Live wokwi-element thumbnails (actual web components at reduced scale)
- Component count, pin count, description badges
#### 4. UI Components
**SimulatorCanvas** (~472 lines) — Main simulation canvas
- Arduino Uno board at fixed position
- Dynamic component rendering via DynamicComponent
- Component drag-and-drop with viewport→canvas coordinate conversion
- Click vs. drag detection (time <300ms, distance <5px threshold)
- Single-click: opens ComponentPropertyDialog
- Double-click: opens PinSelector
- Wire creation via pin clicks (crosshair cursor during creation)
- Wire auto-recalculation on component move (retries at 100/300/500ms)
- PinOverlay on all components (hidden during simulation)
- Keyboard shortcuts: Delete/Backspace (remove), Escape (cancel wire)
- PinManager subscriptions for output component state updates
- Status indicator: Running/Stopped + component count
- "+ Add Component" button → opens ComponentPickerModal
**WireRenderer** (~400 lines) — Interactive wire display and editing
- Orthogonal SVG path rendering
- 10px invisible hitbox for easy clicking
- Segment-based editing: hover highlights, drag perpendicular to orientation
- `requestAnimationFrame` smooth drag with local preview state
- Grid snapping (20px) applied on mouseUp
- Invalid wire styling (red dashed)
- Endpoint markers at start/end
**WireLayer** — SVG overlay with automatic offset calculation for overlapping wires
**WireInProgressRenderer** — Dashed green preview during wire creation (L-shaped routing)
**PinOverlay** — 12px cyan circles at each pin position; green on hover with scale animation
**ComponentPropertyDialog** — Shows pin roles, Arduino pin assignment, Rotate and Delete buttons
**PinSelector** — Modal for assigning D0-D13 and A0-A5 to component pins
**CodeEditor** — Monaco Editor wrapper (C++, dark theme, minimap, word wrap)
**EditorToolbar** — Compile/Run/Stop/Reset buttons with status messages
**ExamplesGallery** — Filterable card grid (category + difficulty filters)
#### 5. Wire Utilities
| Utility | Purpose |
|---------|---------|
| `wirePathGenerator.ts` | L-shape and multi-segment orthogonal SVG path generation |
| `wireSegments.ts` | Segment computation, hit testing (8px tolerance), drag updates |
| `wireColors.ts` | 8 signal-type colors + `determineSignalType()` |
| `wireOffsetCalculator.ts` | Parallel overlap detection (5px tolerance), symmetric offset (6px spacing) |
| `pinPositionCalculator.ts` | Pin coordinate conversion (element → canvas space), closest pin snap (20px) |
| `hexParser.ts` | Intel HEX parser with checksum verification |
| `captureCanvasPreview.ts` | SVG foreignObject preview image generation |
### Backend
#### 1. API Routes
- **[compile.py](backend/app/api/routes/compile.py)**
- `POST /api/compile`: Compile code
- `GET /api/compile/boards`: List boards
**FastAPI** app (port 8001) with CORS for ports 5173-5175
#### 2. Services
- **[arduino_cli.py](backend/app/services/arduino_cli.py)**
- `compile()`: Compile sketch with arduino-cli
- `list_boards()`: Get available boards
- Temporary directory management
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/` | GET | API info |
| `/health` | GET | Health check |
| `/api/compile/` | POST | Compile Arduino code → hex content |
| `/api/compile/boards` | GET | List available boards |
### Wokwi Libraries (Cloned Locally)
**ArduinoCLIService**:
- Auto-installs `arduino:avr` core if missing
- Creates temp sketch directory, runs `arduino-cli compile` via `asyncio.to_thread(subprocess.run)`
- Reads `build/sketch.ino.hex` output
- Board listing via `arduino-cli board listall`
#### 1. wokwi-elements
- **Location**: `wokwi-libs/wokwi-elements/`
- **Build**: `dist/esm/` and `dist/cjs/`
- **Components**: 50+ electronic elements
- **Technology**: Lit (Web Components)
### Pages & Routing
#### 2. avr8js
- **Location**: `wokwi-libs/avr8js/`
- **Build**: `dist/esm/` and `dist/cjs/`
- **Functionality**: Complete ATmega328p emulator
- **Supports**: CPU, Timers, USART, GPIO, ADC, etc.
| Route | Page | Layout |
|-------|------|--------|
| `/` | EditorPage | Header + split panels: Editor (left) + Simulator (right) |
| `/examples` | ExamplesPage | Examples gallery with "Back to Editor" link |
#### 3. rp2040js
- **Location**: `wokwi-libs/rp2040js/`
- **Future use**: Raspberry Pi Pico support
### Example Projects (8)
| ID | Title | Category | Difficulty |
|----|-------|----------|------------|
| `blink-led` | Blink LED | basics | beginner |
| `traffic-light` | Traffic Light | basics | beginner |
| `button-led` | Button Control | basics | beginner |
| `fade-led` | Fade LED | basics | beginner |
| `serial-hello` | Serial Hello World | communication | beginner |
| `rgb-led` | RGB LED Colors | basics | intermediate |
| `simon-says` | Simon Says Game | games | advanced |
| `lcd-hello` | LCD 20x4 Display | displays | intermediate |
Each example includes full Arduino sketch, component definitions, and wire connections.
### Wokwi Libraries (Local Clones)
| Library | Location | Purpose |
|---------|----------|---------|
| wokwi-elements | `wokwi-libs/wokwi-elements/` | 48+ Lit Web Components |
| avr8js | `wokwi-libs/avr8js/` | AVR8 ATmega328p emulator |
| rp2040js | `wokwi-libs/rp2040js/` | RP2040 emulator (future) |
| wokwi-features | `wokwi-libs/wokwi-features/` | Features documentation |
## Vite Integration
@ -217,99 +397,85 @@ resolve: {
'avr8js': path.resolve(__dirname, '../wokwi-libs/avr8js/dist/esm'),
'@wokwi/elements': path.resolve(__dirname, '../wokwi-libs/wokwi-elements/dist/esm'),
},
},
optimizeDeps: {
include: ['avr8js', '@wokwi/elements'],
}
```
This allows:
- Use local repos instead of npm
- Import from local repos as if they were npm packages
- Easy updates with `git pull`
- Modify source code if needed
- Modify source code if needed for debugging
## Technology Stack
### Frontend
| Technology | Version | Purpose |
|------------|---------|-----------|
|------------|---------|---------|
| React | 19.2 | UI framework |
| Vite | 7.3 | Build tool & dev server |
| TypeScript | 5.9 | Static typing |
| Monaco Editor | 4.7 | Code editor (VSCode) |
| Monaco Editor | 4.7 | Code editor (VS Code engine) |
| Zustand | 5.0 | State management |
| React Router | 7.13 | Client-side routing |
| Axios | 1.13 | HTTP client |
| wokwi-elements | 1.9.2 | Electronic components |
| avr8js | 0.21.0 | AVR8 emulator |
| wokwi-elements | local | 48+ electronic web components |
| avr8js | local | AVR8 CPU emulator |
### Backend
| Technology | Version | Purpose |
|------------|---------|-----------|
|------------|---------|---------|
| Python | 3.12+ | Runtime |
| FastAPI | 0.115 | Web framework |
| Uvicorn | 0.32 | ASGI server |
| SQLAlchemy | 2.0 | ORM (future) |
| aiosqlite | 0.20 | Async DB (future) |
### External Tools
| Tool | Purpose |
|------|---------|
| arduino-cli | Arduino compiler |
| arduino-cli | Arduino compiler (subprocess) |
| Git | Version control for Wokwi libs |
## Architecture Advantages
### ✅ Real Emulation
- True AVR8 CPU execution, not simulation mockups
- Same avr8js engine used by Wokwi.com
- Accurate timing with configurable speed
### ✅ Plugin-Based Component Behaviors
- PartSimulationRegistry decouples simulation logic from rendering
- Easy to add new component behaviors
- Supports both input (event-driven) and output (pin-state-driven) components
### ✅ Automatic Component Discovery
- Build-time TypeScript AST parser extracts metadata from wokwi-elements source
- No manual component registration needed
- New wokwi-elements components appear automatically after rebuild
### ✅ Separation of Concerns
- **Frontend**: UI, UX, visualization
- **Backend**: Compilation, business logic
- **Wokwi Libs**: Emulation and components (maintained by Wokwi)
- **Frontend**: UI, visualization, simulation engine
- **Backend**: Compilation via arduino-cli
- **Wokwi Libs**: Emulation and components (maintained by Wokwi community)
### ✅ Wokwi Compatibility
- Official repositories = same functionality
- Official repositories = same functionality as Wokwi.com
- Automatic updates with `git pull`
- New components available immediately
### ✅ Scalability
- Frontend can easily add more components
- Backend can add more endpoints (projects, sensors)
- Wokwi libs update independently
- New components available immediately after rebuild
### ✅ Local Development
- No internet required to work
- No internet required after initial setup
- Local compilation with arduino-cli
- Local database (SQLite)
- All simulation runs in the browser
## Upcoming Improvements
## Planned Improvements
### Phase 2: Real Emulation (avr8js)
```
[ ] Implement AVRSimulator.ts
[ ] Intel HEX file parser
[ ] PinManager with write hooks
[ ] Integrate CPU execution loop
[ ] Map Arduino pins to components
```
### Phase 3: More Components
```
[ ] Integrate more wokwi-elements
[ ] Buttons, potentiometers
[ ] Sensors (DHT22, HC-SR04)
[ ] Displays (LCD, 7-segment)
```
### Phase 4: Persistence
```
[ ] SQLite database
[ ] SQLAlchemy models
[ ] Project CRUD
[ ] Save circuits as JSON
```
### Phase 5: Advanced Features
```
[ ] Serial Monitor
[ ] Visual wiring (drag & drop)
[ ] Multiple boards (Mega, Nano, ESP32)
[ ] Export to Wokwi.com
```
- 📋 **Serial Monitor** — UI for USART output display
- 📋 **Project Persistence** — SQLite database for save/load
- 📋 **Undo/Redo** — Edit history for code and circuit changes
- 📋 **Multi-board Support** — Runtime board switching (Mega, Nano, ESP32)
- 📋 **Wire Validation** — Electrical validation and error highlighting
- 📋 **Export/Import** — Share projects as files
## References

View File

@ -1,29 +1,29 @@
# Wokwi Libraries Integration
Este proyecto utiliza los repositorios oficiales de Wokwi clonados localmente, lo que permite mantenerlos actualizados y compatibles con las últimas versiones.
Este proyecto utiliza los repositorios oficiales de Wokwi clonados localmente, lo que permite mantenerlos actualizados y compatibles con las últimas versiones. Los repositorios locales alimentan tanto la emulación AVR como el sistema dinámico de componentes con 48+ elementos electrónicos.
## Repositorios Clonados
### 📦 wokwi-elements
- **Ubicación**: `wokwi-libs/wokwi-elements/`
- **Descripción**: Web Components para elementos electrónicos (LEDs, resistencias, botones, etc.)
- **Descripción**: Web Components (Lit) para 48+ elementos electrónicos (LEDs, resistencias, botones, LCDs, sensores, etc.)
- **Repositorio**: https://github.com/wokwi/wokwi-elements
- **Licencia**: MIT
- **Versión actual**: 1.9.2
- **Uso actual**: Renderizado visual de todos los componentes en el canvas de simulación. Un script de generación de metadata (`scripts/generate-component-metadata.ts`) parsea el código fuente TypeScript para descubrir automáticamente todos los componentes, sus propiedades y pines.
### 🎮 avr8js
- **Ubicación**: `wokwi-libs/avr8js/`
- **Descripción**: Emulador de microcontroladores AVR8 (Arduino Uno, Mega, etc.) en JavaScript
- **Descripción**: Emulador completo de microcontroladores AVR8 (ATmega328p) en JavaScript
- **Repositorio**: https://github.com/wokwi/avr8js
- **Licencia**: MIT
- **Versión actual**: 0.21.0
- **Uso actual**: Emulación real del CPU a 16MHz, con Timer0/1/2, USART, ADC, y puertos GPIO (PORTB/C/D). Ejecuta ~267,000 ciclos por frame a ~60fps.
### 🚀 rp2040js
- **Ubicación**: `wokwi-libs/rp2040js/`
- **Descripción**: Emulador de Raspberry Pi Pico (RP2040) en JavaScript
- **Repositorio**: https://github.com/wokwi/rp2040js
- **Licencia**: MIT
- **Uso**: Futuro soporte para Raspberry Pi Pico
- **Uso**: Clonado para futuro soporte de Raspberry Pi Pico
### 📝 wokwi-features
- **Ubicación**: `wokwi-libs/wokwi-features/`
@ -34,7 +34,7 @@ Este proyecto utiliza los repositorios oficiales de Wokwi clonados localmente, l
### Frontend (Vite)
El archivo [vite.config.ts](frontend/vite.config.ts) está configurado para usar los repositorios locales:
El archivo `frontend/vite.config.ts` está configurado para usar los repositorios locales mediante aliases:
```typescript
resolve: {
@ -42,10 +42,13 @@ resolve: {
'avr8js': path.resolve(__dirname, '../wokwi-libs/avr8js/dist/esm'),
'@wokwi/elements': path.resolve(__dirname, '../wokwi-libs/wokwi-elements/dist/esm'),
},
},
optimizeDeps: {
include: ['avr8js', '@wokwi/elements'],
}
```
El archivo [package.json](frontend/package.json) referencia los paquetes locales:
El archivo `frontend/package.json` referencia los paquetes locales:
```json
{
@ -56,6 +59,16 @@ El archivo [package.json](frontend/package.json) referencia los paquetes locales
}
```
### Generación Automática de Metadata
El script `scripts/generate-component-metadata.ts` parsea el código fuente de wokwi-elements usando AST de TypeScript para extraer:
- Nombre del tag (`@customElement('wokwi-led')` → `wokwi-led`)
- Propiedades (`@property()` decorators → tipo, valor por defecto)
- Cantidad de pines
- Categoría, descripción y tags
El resultado se almacena en `frontend/public/components-metadata.json` y es consumido por el `ComponentRegistry` en tiempo de ejecución.
## Actualizar las Librerías de Wokwi
Para mantener tu proyecto actualizado con las últimas versiones de Wokwi:
@ -63,16 +76,14 @@ Para mantener tu proyecto actualizado con las últimas versiones de Wokwi:
### Opción 1: Actualizar todas las librerías (Recomendado)
```bash
cd e:\Hardware\wokwi_clon
# Script para actualizar todos los repositorios
./update-wokwi-libs.bat
update-wokwi-libs.bat
```
### Opción 2: Actualizar manualmente cada repositorio
```bash
cd e:\Hardware\wokwi_clon\wokwi-libs
cd wokwi-libs
# Actualizar wokwi-elements
cd wokwi-elements
@ -96,7 +107,7 @@ npm run build
### Opción 3: Actualizar a una versión específica
```bash
cd e:\Hardware\wokwi_clon\wokwi-libs\wokwi-elements
cd wokwi-libs/wokwi-elements
# Ver versiones disponibles
git tag -l
@ -109,16 +120,24 @@ npm install
npm run build
```
### Después de Actualizar wokwi-elements
Si actualizaste wokwi-elements, regenera la metadata de componentes para que nuevos componentes aparezcan en la UI:
```bash
cd frontend
npx tsx ../scripts/generate-component-metadata.ts
```
## Script de Actualización Automática
Se ha creado un script [update-wokwi-libs.bat](update-wokwi-libs.bat) para facilitar las actualizaciones:
El script `update-wokwi-libs.bat` facilita las actualizaciones:
```batch
@echo off
echo ========================================
echo Actualizando Wokwi Libraries
echo ========================================
echo.
cd wokwi-libs
@ -129,7 +148,6 @@ npm install
npm run build
cd ..
echo.
echo [2/3] Actualizando avr8js...
cd avr8js
git pull origin main
@ -137,7 +155,6 @@ npm install
npm run build
cd ..
echo.
echo [3/3] Actualizando rp2040js...
cd rp2040js
git pull origin main
@ -145,109 +162,165 @@ npm install
npm run build
cd ..
echo.
echo ========================================
echo Actualizacion completada!
echo ========================================
pause
```
## Cómo Se Usan las Librerías
### avr8js — Emulación AVR
El `AVRSimulator` (`frontend/src/simulation/AVRSimulator.ts`) usa avr8js para crear:
```typescript
import { CPU, avrInstruction, AVRTimer, AVRUSART, AVRADC, AVRIOPort } from 'avr8js';
// CPU ATmega328p a 16MHz
const cpu = new CPU(programMemory);
// Periféricos
const timer0 = new AVRTimer(cpu, timer0Config);
const timer1 = new AVRTimer(cpu, timer1Config);
const timer2 = new AVRTimer(cpu, timer2Config);
const usart = new AVRUSART(cpu, usart0Config, CLOCK);
const adc = new AVRADC(cpu, adcConfig);
const portB = new AVRIOPort(cpu, portBConfig); // pins 8-13
const portC = new AVRIOPort(cpu, portCConfig); // A0-A5
const portD = new AVRIOPort(cpu, portDConfig); // pins 0-7
// Loop de simulación (~60fps)
function runFrame() {
const cyclesToRun = Math.floor(267000 * speed);
for (let i = 0; i < cyclesToRun; i++) {
avrInstruction(cpu); // Ejecuta instrucción AVR
cpu.tick(); // Actualiza periféricos
}
requestAnimationFrame(runFrame);
}
```
### wokwi-elements — Componentes Visuales
Los componentes se renderizan de dos formas:
**1. DynamicComponent (sistema actual — 48 componentes)**
```typescript
import { ComponentRegistry } from './services/ComponentRegistry';
// Carga metadata desde /components-metadata.json
const registry = ComponentRegistry.getInstance();
const metadata = registry.getById('led');
// DynamicComponent crea el web component dinámicamente
// document.createElement(metadata.tagName) → <wokwi-led>
// Sincroniza propiedades React → web component
// Extrae pinInfo del DOM para wire connections
```
**2. React wrappers legacy (5 componentes)**
```tsx
// ArduinoUno.tsx — sigue en uso activo para el board principal
<wokwi-arduino-uno ref={ref} led13={led13} />
```
### PartSimulationRegistry — Comportamientos de Simulación
16 partes tienen lógica de simulación registrada que conecta los web components con el emulador AVR:
| Parte | Tipo | Comportamiento |
|-------|------|----------------|
| `led` | Output | Pin state → `element.value` |
| `rgb-led` | Output | Digital + PWM en R/G/B |
| `led-bar-graph` | Output | 10 LEDs independientes |
| `7segment` | Output | 8 segmentos (A-G + DP) |
| `pushbutton` | Input | Press/release → `setPinState()` |
| `pushbutton-6mm` | Input | Mismo que pushbutton |
| `slide-switch` | Input | Change event → pin state |
| `dip-switch-8` | Input | 8 switches independientes |
| `potentiometer` | Input | Valor → voltaje ADC |
| `slide-potentiometer` | Input | Misma lógica por SIG/OUT |
| `photoresistor-sensor` | Input/Output | Voltaje analógico + LED digital |
| `analog-joystick` | Input | VRX/VRY (ADC) + SW (digital) |
| `servo` | Output | Registros OCR1A/ICR1 → ángulo 0-180° |
| `buzzer` | Output | Web Audio API + Timer2 |
| `lcd1602` | Output | Protocolo HD44780 4-bit completo (16×2) |
| `lcd2004` | Output | Protocolo HD44780 4-bit completo (20×4) |
## Componentes Wokwi Disponibles (48)
### Boards (4)
- `wokwi-arduino-uno` — Arduino Uno R3
- `wokwi-arduino-mega` — Arduino Mega 2560
- `wokwi-arduino-nano` — Arduino Nano
- `wokwi-esp32-devkit-v1` — ESP32 DevKit v1
### Sensors (6)
- `wokwi-dht22` — Temperatura y humedad
- `wokwi-hc-sr04` — Ultrasónico de distancia
- `wokwi-pir-motion-sensor` — Sensor de movimiento PIR
- `wokwi-photoresistor-sensor` — Fotoresistor (LDR)
- `wokwi-ntc-temperature-sensor` — Sensor NTC
- `wokwi-analog-joystick` — Joystick analógico
### Displays (3)
- `wokwi-lcd1602` — LCD 16x2 con protocolo HD44780
- `wokwi-lcd2004` — LCD 20x4 con protocolo HD44780
- `wokwi-7segment` — Display de 7 segmentos
### Input (5)
- `wokwi-pushbutton` — Botón pulsador
- `wokwi-pushbutton-6mm` — Botón 6mm
- `wokwi-slide-switch` — Interruptor deslizante
- `wokwi-dip-switch-8` — DIP switch de 8 posiciones
- `wokwi-potentiometer` — Potenciómetro
### Output (5)
- `wokwi-led` — LED de colores
- `wokwi-rgb-led` — LED RGB
- `wokwi-led-bar-graph` — Barra de LEDs (10)
- `wokwi-buzzer` — Buzzer piezoeléctrico
- `wokwi-neopixel` — LED RGB direccionable (WS2812)
### Motors (2)
- `wokwi-servo` — Servo motor
- `wokwi-stepper-motor` — Motor paso a paso
### Passive (4)
- `wokwi-resistor` — Resistencia con código de colores
- `wokwi-slide-potentiometer` — Potenciómetro deslizante
- `wokwi-led-ring` — Anillo de LEDs
- `wokwi-membrane-keypad` — Teclado matricial
### Other (19)
- Componentes variados incluyendo `wokwi-ir-receiver`, `wokwi-ds1307`, breadboards, etc.
## Ventajas de Este Enfoque
### ✅ Ventajas
1. **Actualización Fácil**: Un simple `git pull` en cada repo te da las últimas mejoras
2. **Compatible con Wokwi**: Si Wokwi agrega nuevos elementos o mejoras a avr8js, automáticamente estarán disponibles
3. **Control de Versiones**: Puedes hacer checkout a versiones específicas si necesitas estabilidad
4. **Desarrollo**: Puedes modificar el código fuente si necesitas hacer debugging o agregar features
5. **Sin Dependencia de npm**: No dependes de que publiquen en npm
1. **Actualización Fácil**: Un simple `git pull` + rebuild te da las últimas mejoras
2. **Compatible con Wokwi**: Usas exactamente el mismo código que Wokwi.com
3. **Descubrimiento Automático**: Nuevos componentes aparecen automáticamente tras regenerar metadata
4. **Control de Versiones**: Puedes hacer checkout a versiones específicas
5. **Desarrollo Flexible**: Código fuente disponible para debugging y modificaciones
6. **Sin Dependencia de npm**: No dependes de que publiquen actualizaciones en npm
7. **100% Offline**: Funciona completamente sin internet después de la configuración inicial
### ⚠️ Consideraciones
1. **Espacio en Disco**: Los repositorios clonados ocupan más espacio (~200MB)
2. **Compilación**: Debes compilar los repositorios después de actualizarlos
3. **Tiempo de Build**: La primera instalación toma más tiempo
## Componentes Wokwi Disponibles
### Elementos Básicos
- `wokwi-led` - LED de colores (red, green, blue, yellow, white, orange)
- `wokwi-resistor` - Resistencia con código de colores
- `wokwi-pushbutton` - Botón pulsador
- `wokwi-slide-switch` - Interruptor deslizante
- `wokwi-potentiometer` - Potenciómetro
### Placas
- `wokwi-arduino-uno` - Arduino Uno R3
- `wokwi-arduino-mega` - Arduino Mega 2560
- `wokwi-arduino-nano` - Arduino Nano
- `wokwi-pi-pico` - Raspberry Pi Pico
- `wokwi-esp32-devkit-v1` - ESP32 DevKit v1
### Pantallas
- `wokwi-lcd1602` - LCD 16x2 con I2C
- `wokwi-neopixel` - LED RGB direccionable
- `wokwi-7segment` - Display de 7 segmentos
### Sensores
- `wokwi-dht22` - Sensor de temperatura y humedad
- `wokwi-hc-sr04` - Sensor ultrasónico de distancia
- `wokwi-pir-motion-sensor` - Sensor de movimiento PIR
- `wokwi-photoresistor-sensor` - Fotoresistor (LDR)
### Otros
- `wokwi-servo` - Servo motor
- `wokwi-membrane-keypad` - Teclado matricial 4x4
- `wokwi-ir-receiver` - Receptor infrarrojo
- `wokwi-ds1307` - Reloj de tiempo real (RTC)
## Uso de los Componentes
### Ejemplo: LED
```tsx
import { LED } from './components/components-wokwi/LED';
<LED
id="led1"
x={300}
y={200}
color="red"
value={true} // LED encendido
/>
```
### Ejemplo: Arduino Uno
```tsx
import { ArduinoUno } from './components/components-wokwi/ArduinoUno';
<ArduinoUno
x={50}
y={50}
led13={true} // LED interno encendido
/>
```
### Ejemplo: Botón
```tsx
import { Pushbutton } from './components/components-wokwi/Pushbutton';
<Pushbutton
x={400}
y={300}
color="red"
onPress={() => console.log('Presionado!')}
onRelease={() => console.log('Liberado!')}
/>
```
3. **Metadata**: Regenerar `components-metadata.json` después de actualizar wokwi-elements
## Troubleshooting
### Error: "Module not found: @wokwi/elements"
Asegúrate de que los repositorios estén compilados:
Asegúrate de que wokwi-elements esté compilado:
```bash
cd wokwi-libs/wokwi-elements
@ -257,19 +330,37 @@ npm run build
### Error: "Cannot find module 'avr8js'"
Verifica que el alias en `vite.config.ts` esté correcto y que avr8js esté compilado.
Verifica que el alias en `vite.config.ts` esté correcto y que avr8js esté compilado:
### Los componentes no se muestran
Asegúrate de importar `@wokwi/elements` en tus componentes:
```tsx
import '@wokwi/elements';
```bash
cd wokwi-libs/avr8js
npm install
npm run build
```
### Los componentes no se muestran en el picker
Regenera la metadata de componentes:
```bash
cd frontend
npx tsx ../scripts/generate-component-metadata.ts
```
### Nuevo componente de wokwi-elements no aparece
1. Actualiza wokwi-elements: `cd wokwi-libs/wokwi-elements && git pull && npm run build`
2. Regenera metadata: `cd frontend && npx tsx ../scripts/generate-component-metadata.ts`
3. Si necesita simulación, registra su comportamiento en `frontend/src/simulation/parts/`
### Los componentes se ven pero no responden a la simulación
Verifica que el componente tenga lógica de simulación registrada en `PartSimulationRegistry` (archivos `BasicParts.ts` o `ComplexParts.ts`). Solo los 16 componentes registrados tienen comportamiento interactivo.
## Referencias
- [Wokwi Elements Documentation](https://elements.wokwi.com/)
- [AVR8js Documentation](https://github.com/wokwi/avr8js/tree/main/demo)
- [AVR8js Repository](https://github.com/wokwi/avr8js)
- [Wokwi Simulator](https://wokwi.com)
- [Lit Documentation](https://lit.dev/) — Framework usado por wokwi-elements
- [Web Components Guide](https://developer.mozilla.org/en-US/docs/Web/Web_Components)