From b8bdaf4c65481176400a8c4bbfa5d5d2b13069ca Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Mar 2026 18:46:42 +0000 Subject: [PATCH] Translate Spanish docs to English and add SEO-optimised URL routing for documentation Co-authored-by: davidmonterocrespo24 <47928504+davidmonterocrespo24@users.noreply.github.com> --- docs/SETUP_COMPLETE.md | 258 +++++++++++++++--------------- docs/WOKWI_LIBS.md | 270 ++++++++++++++++---------------- docs/examples/README.md | 78 ++++----- frontend/public/sitemap.xml | 32 +++- frontend/src/App.tsx | 1 + frontend/src/pages/DocsPage.css | 2 + frontend/src/pages/DocsPage.tsx | 136 +++++++++++++--- 7 files changed, 449 insertions(+), 328 deletions(-) diff --git a/docs/SETUP_COMPLETE.md b/docs/SETUP_COMPLETE.md index c348051..c259dda 100644 --- a/docs/SETUP_COMPLETE.md +++ b/docs/SETUP_COMPLETE.md @@ -1,98 +1,98 @@ -# Estado del Proyecto - Velxio Arduino Emulator +# Project Status - Velxio Arduino Emulator -## Resumen de Funcionalidades Implementadas +## Summary of Implemented Features -### Repositorios de Wokwi Clonados y Configurados +### Wokwi Repositories Cloned and Configured -Repositorios oficiales de Wokwi en `wokwi-libs/`: +Official Wokwi repositories in `wokwi-libs/`: -| Repositorio | Estado | Descripción | -|-------------|--------|-------------| -| **wokwi-elements** | Compilado y en uso | 48+ componentes electrónicos Web Components | -| **avr8js** | Compilado y en uso | Emulación real de AVR8 (ATmega328p) | -| **rp2040js** | Clonado | Emulador RP2040 (futuro) | -| **wokwi-features** | Clonado | Documentación y features | +| Repository | Status | Description | +|------------|--------|-------------| +| **wokwi-elements** | Built and in use | 48+ electronic Web Components | +| **avr8js** | Built and in use | Real AVR8 emulation (ATmega328p) | +| **rp2040js** | Cloned | RP2040 emulator (future use) | +| **wokwi-features** | Cloned | Documentation and feature tracking | -### Emulación AVR Real (avr8js) +### Real AVR Emulation (avr8js) -| Feature | Estado | +| Feature | Status | |---------|--------| -| CPU ATmega328p a 16MHz | Funcionando | -| Timer0, Timer1, Timer2 | Funcionando | -| USART (Serial) | Funcionando | -| ADC (analogRead) | Funcionando | -| GPIO completo (PORTB/C/D) | Funcionando | -| Loop ~60fps (267k ciclos/frame) | Funcionando | -| Control de velocidad (0.1x - 10x) | Funcionando | -| Debugging paso a paso (step) | Funcionando | -| Monitoreo PWM (6 canales) | Funcionando | -| Inyección de pin externo (inputs) | Funcionando | +| ATmega328p CPU at 16MHz | Working | +| Timer0, Timer1, Timer2 | Working | +| USART (Serial) | Working | +| ADC (analogRead) | Working | +| Full GPIO (PORTB/C/D) | Working | +| Loop ~60fps (267k cycles/frame) | Working | +| Speed control (0.1x - 10x) | Working | +| Step-by-step debugging | Working | +| PWM monitoring (6 channels) | Working | +| External pin injection (inputs) | Working | -### Sistema de Componentes (48+) +### Component System (48+) -| Feature | Estado | +| Feature | Status | |---------|--------| -| Descubrimiento automático por AST | 48 componentes detectados | -| ComponentPickerModal con búsqueda | Funcionando | -| 9 categorías con filtros | Functioning | -| Thumbnails en vivo (web components) | Funcionando | -| DynamicComponent renderer genérico | Funcionando | -| Drag-and-drop en el canvas | Funcionando | -| Rotación (90° incrementos) | Funcionando | -| Diálogo de propiedades (click) | Funcionando | -| Selector de pines (doble-click) | Funcionando | -| Pin overlay (puntos cyan clickeables) | Funcionando | +| Automatic discovery via AST | 48 components detected | +| ComponentPickerModal with search | Working | +| 9 categories with filters | Working | +| Live thumbnails (web components) | Working | +| Generic DynamicComponent renderer | Working | +| Drag-and-drop on canvas | Working | +| Rotation (90° increments) | Working | +| Properties dialog (click) | Working | +| Pin selector (double-click) | Working | +| Pin overlay (clickable cyan dots) | Working | -### 16 Partes con Simulación Interactiva +### 16 Parts with Interactive Simulation -| Parte | Tipo | Estado | -|-------|------|--------| -| LED | Output | | -| RGB LED | Output (digital + PWM) | | -| LED Bar Graph (10 LEDs) | Output | | -| 7-Segment Display | Output | | -| Pushbutton | Input | | -| Pushbutton 6mm | Input | | -| Slide Switch | Input | | -| DIP Switch 8 | Input | | -| Potentiometer | Input (ADC) | | -| Slide Potentiometer | Input (ADC) | | -| Photoresistor | Input/Output | | -| Analog Joystick | Input (ADC + digital) | | -| Servo | Output | | -| Buzzer | Output (Web Audio) | | -| LCD 1602 | Output (HD44780 completo) | | -| LCD 2004 | Output (HD44780 completo) | | +| Part | Type | Status | +|------|------|--------| +| LED | Output | ✅ | +| RGB LED | Output (digital + PWM) | ✅ | +| LED Bar Graph (10 LEDs) | Output | ✅ | +| 7-Segment Display | Output | ✅ | +| Pushbutton | Input | ✅ | +| Pushbutton 6mm | Input | ✅ | +| Slide Switch | Input | ✅ | +| DIP Switch 8 | Input | ✅ | +| Potentiometer | Input (ADC) | ✅ | +| Slide Potentiometer | Input (ADC) | ✅ | +| Photoresistor | Input/Output | ✅ | +| Analog Joystick | Input (ADC + digital) | ✅ | +| Servo | Output | ✅ | +| Buzzer | Output (Web Audio) | ✅ | +| LCD 1602 | Output (full HD44780) | ✅ | +| LCD 2004 | Output (full HD44780) | ✅ | -### Sistema de Cables (Wires) +### Wire System -| Feature | Estado | +| Feature | Status | |---------|--------| -| Creación pin-a-pin con click | Funcionando | -| Preview en tiempo real (verde, punteado) | Funcionando | -| Routing ortogonal (sin diagonales) | Funcionando | -| Edición por segmentos (drag perpendicular) | Funcionando | -| 8 colores por tipo de señal | Funcionando | -| Offset automático para cables paralelos | Funcionando | -| Auto-actualización al mover componentes | Funcionando | -| Grid snapping (20px) | Funcionando | -| Selección y eliminación de cables | Funcionando | +| Pin-to-pin creation with click | Working | +| Real-time preview (green, dashed) | Working | +| Orthogonal routing (no diagonals) | Working | +| Segment editing (perpendicular drag) | Working | +| 8 colors by signal type | Working | +| Automatic offset for parallel wires | Working | +| Auto-update when moving components | Working | +| Grid snapping (20px) | Working | +| Wire selection and deletion | Working | -### Editor de Código +### Code Editor -| Feature | Estado | +| Feature | Status | |---------|--------| -| Monaco Editor (C++, dark theme) | Funcionando | -| Syntax highlighting + autocomplete | Funcionando | -| Botones Compile/Run/Stop/Reset | Funcionando | -| Compilación via arduino-cli backend | Funcionando | -| Mensajes de error/éxito | Funcionando | -| Font size configurable | Funcionando | +| Monaco Editor (C++, dark theme) | Working | +| Syntax highlighting + autocomplete | Working | +| Compile/Run/Stop/Reset buttons | Working | +| Compilation via arduino-cli backend | Working | +| Error/success messages | Working | +| Configurable font size | Working | -### Ejemplos (8 Proyectos) +### Examples (8 Projects) -| Ejemplo | Categoría | Dificultad | -|---------|-----------|------------| +| Example | Category | Difficulty | +|---------|----------|------------| | Blink LED | basics | beginner | | Traffic Light | basics | beginner | | Button Control | basics | beginner | @@ -102,41 +102,41 @@ Repositorios oficiales de Wokwi en `wokwi-libs/`: | Simon Says Game | games | advanced | | LCD 20x4 Display | displays | intermediate | -- Galería con filtros de categoría y dificultad -- Carga con un click (código + componentes + cables) +- Gallery with category and difficulty filters +- One-click load (code + components + wires) -### Integración Configurada +### Configured Integrations -| Item | Estado | +| Item | Status | |------|--------| -| Vite aliases para repos locales | | -| Package.json con `file:../wokwi-libs/...` | | -| TypeScript declarations para Web Components | | -| CORS backend (puertos 5173-5175) | | -| React Router (2 rutas) | | -| Zustand stores (editor + simulator) | | +| Vite aliases for local repos | ✅ | +| Package.json with `file:../wokwi-libs/...` | ✅ | +| TypeScript declarations for Web Components | ✅ | +| Backend CORS (ports 5173-5175) | ✅ | +| React Router (2 routes) | ✅ | +| Zustand stores (editor + simulator) | ✅ | -### Documentación +### Documentation -| Archivo | Descripción | -|---------|-------------| -| `README.md` | Instrucciones de instalación y uso | -| `docs/ARCHITECTURE.md` | Arquitectura detallada del proyecto | -| `docs/WOKWI_LIBS.md` | Guía de integración con Wokwi | -| `docs/SETUP_COMPLETE.md` | Este archivo — estado del proyecto | -| `CLAUDE.md` | Guía para asistentes IA | -| `update-wokwi-libs.bat` | Script de actualización automática | +| File | Description | +|------|-------------| +| `README.md` | Installation and usage instructions | +| `docs/ARCHITECTURE.md` | Detailed project architecture | +| `docs/WOKWI_LIBS.md` | Wokwi integration guide | +| `docs/SETUP_COMPLETE.md` | This file — project status | +| `CLAUDE.md` | Guide for AI assistants | +| `update-wokwi-libs.bat` | Automatic update script | -## Cómo Empezar +## Getting Started -### 1. Asegúrate de tener arduino-cli instalado +### 1. Ensure arduino-cli is installed ```bash arduino-cli version arduino-cli core install arduino:avr ``` -### 2. Inicia el Backend +### 2. Start the Backend ```bash cd backend @@ -144,44 +144,44 @@ venv\Scripts\activate uvicorn app.main:app --reload --port 8001 ``` -### 3. Inicia el Frontend +### 3. Start the Frontend ```bash cd frontend npm run dev ``` -### 4. Abre en el Navegador +### 4. Open in the Browser - Frontend: http://localhost:5173 - Backend API: http://localhost:8001 - API Docs: http://localhost:8001/docs -## Actualizar Librerías de Wokwi +## Update Wokwi Libraries ```bash -# Ejecutar script de actualización +# Run the update script update-wokwi-libs.bat -# Regenerar metadata de componentes (si actualizaste wokwi-elements) +# Regenerate component metadata (if you updated wokwi-elements) cd frontend npx tsx ../scripts/generate-component-metadata.ts ``` -## Próximos Pasos (Pendiente) +## Next Steps (Pending) -| Feature | Prioridad | Descripción | -|---------|-----------|-------------| -| Serial Monitor | Alta | UI para leer output USART de la simulación | -| Persistencia | Alta | SQLite para guardar/cargar proyectos | -| Undo/Redo | Media | Historial de edición para código y circuito | -| Multi-board | Media | Cambio de board en runtime (Mega, Nano, ESP32) | -| Validación de cables | Media | Validación eléctrica y resaltado de errores | -| Export/Import | Baja | Compartir proyectos como archivos | +| Feature | Priority | Description | +|---------|----------|-------------| +| Serial Monitor | High | UI for reading USART output from the simulation | +| Persistence | High | SQLite for saving/loading projects | +| Undo/Redo | Medium | Edit history for code and circuit | +| Multi-board | Medium | Board switching at runtime (Mega, Nano, ESP32) | +| Wire validation | Medium | Electrical validation and error highlighting | +| Export/Import | Low | Share projects as files | ## Troubleshooting -### Los componentes no se muestran +### Components are not displayed ```bash cd wokwi-libs/wokwi-elements @@ -196,7 +196,7 @@ npm install npm run build ``` -### arduino-cli no funciona +### arduino-cli does not work ```bash arduino-cli version @@ -204,29 +204,29 @@ arduino-cli core list arduino-cli core install arduino:avr ``` -### LED no parpadea en simulación +### LED does not blink in simulation -- Verifica que compilaste el código (botón Compile) -- Verifica que ejecutaste la simulación (botón Run) -- Revisa la consola del navegador para errores de port listeners -- Verifica el pin mapping en el diálogo de propiedades del componente +- Verify that you compiled the code (Compile button) +- Verify that you started the simulation (Run button) +- Check the browser console for port listener errors +- Verify the pin mapping in the component properties dialog -### Componente nuevo no aparece en el picker +### New component does not appear in the picker ```bash cd frontend npx tsx ../scripts/generate-component-metadata.ts ``` -## Estado General +## General Status -El proyecto tiene implementadas todas las funcionalidades core: +The project has all core features implemented: -- Editor de código profesional (Monaco) -- Compilación Arduino local (arduino-cli) -- Emulación AVR8 real con periféricos completos -- 48+ componentes electrónicos con descubrimiento automático -- 16 partes con simulación interactiva (LED, LCD, buttons, potentiometers, servo, buzzer) -- Sistema de cables ortogonales con edición visual -- 8 proyectos de ejemplo con galería filtrable -- Sistema de actualización automática para librerías Wokwi +- Professional code editor (Monaco) +- Local Arduino compilation (arduino-cli) +- Real AVR8 emulation with full peripherals +- 48+ electronic components with automatic discovery +- 16 parts with interactive simulation (LED, LCD, buttons, potentiometers, servo, buzzer) +- Orthogonal wire system with visual editing +- 8 example projects with a filterable gallery +- Automatic update system for Wokwi libraries diff --git a/docs/WOKWI_LIBS.md b/docs/WOKWI_LIBS.md index 095b0b5..72eec9a 100644 --- a/docs/WOKWI_LIBS.md +++ b/docs/WOKWI_LIBS.md @@ -1,40 +1,40 @@ # Wokwi Libraries Integration -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. +This project uses the official Wokwi repositories cloned locally, which allows keeping them up-to-date and compatible with the latest versions. The local repositories power both AVR emulation and the dynamic component system with 48+ electronic elements. -## Repositorios Clonados +## Cloned Repositories ### wokwi-elements -- **Ubicación**: `wokwi-libs/wokwi-elements/` -- **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 -- **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. +- **Location**: `wokwi-libs/wokwi-elements/` +- **Description**: Web Components (Lit) for 48+ electronic elements (LEDs, resistors, buttons, LCDs, sensors, etc.) +- **Repository**: https://github.com/wokwi/wokwi-elements +- **License**: MIT +- **Current usage**: Visual rendering of all components on the simulation canvas. A metadata generation script (`scripts/generate-component-metadata.ts`) parses the TypeScript source code to automatically discover all components, their properties, and pins. ### avr8js -- **Ubicación**: `wokwi-libs/avr8js/` -- **Descripción**: Emulador completo de microcontroladores AVR8 (ATmega328p) en JavaScript -- **Repositorio**: https://github.com/wokwi/avr8js -- **Licencia**: MIT -- **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. +- **Location**: `wokwi-libs/avr8js/` +- **Description**: Complete AVR8 microcontroller emulator (ATmega328p) in JavaScript +- **Repository**: https://github.com/wokwi/avr8js +- **License**: MIT +- **Current usage**: Real CPU emulation at 16MHz, with Timer0/1/2, USART, ADC, and GPIO ports (PORTB/C/D). Runs ~267,000 cycles per frame at ~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**: Clonado para futuro soporte de Raspberry Pi Pico +- **Location**: `wokwi-libs/rp2040js/` +- **Description**: Raspberry Pi Pico (RP2040) emulator in JavaScript +- **Repository**: https://github.com/wokwi/rp2040js +- **License**: MIT +- **Usage**: Cloned for future Raspberry Pi Pico support ### wokwi-features -- **Ubicación**: `wokwi-libs/wokwi-features/` -- **Descripción**: Documentación y tracking de features de Wokwi -- **Repositorio**: https://github.com/wokwi/wokwi-features +- **Location**: `wokwi-libs/wokwi-features/` +- **Description**: Wokwi documentation and feature tracking +- **Repository**: https://github.com/wokwi/wokwi-features -## Configuración del Proyecto +## Project Configuration ### Frontend (Vite) -El archivo `frontend/vite.config.ts` está configurado para usar los repositorios locales mediante aliases: +The `frontend/vite.config.ts` file is configured to use the local repositories via aliases: ```typescript resolve: { @@ -48,7 +48,7 @@ optimizeDeps: { } ``` -El archivo `frontend/package.json` referencia los paquetes locales: +The `frontend/package.json` file references the local packages: ```json { @@ -59,103 +59,103 @@ El archivo `frontend/package.json` referencia los paquetes locales: } ``` -### Generación Automática de Metadata +### Automatic Metadata Generation -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 +The `scripts/generate-component-metadata.ts` script parses the wokwi-elements source code using the TypeScript AST to extract: +- Tag name (`@customElement('wokwi-led')` → `wokwi-led`) +- Properties (`@property()` decorators → type, default value) +- Number of pins +- Category, description, and tags -El resultado se almacena en `frontend/public/components-metadata.json` y es consumido por el `ComponentRegistry` en tiempo de ejecución. +The result is stored in `frontend/public/components-metadata.json` and consumed by the `ComponentRegistry` at runtime. -## Actualizar las Librerías de Wokwi +## Updating the Wokwi Libraries -Para mantener tu proyecto actualizado con las últimas versiones de Wokwi: +To keep your project up-to-date with the latest versions of Wokwi: -### Opción 1: Actualizar todas las librerías (Recomendado) +### Option 1: Update all libraries (Recommended) ```bash -# Script para actualizar todos los repositorios +# Script to update all repositories update-wokwi-libs.bat ``` -### Opción 2: Actualizar manualmente cada repositorio +### Option 2: Update each repository manually ```bash cd wokwi-libs -# Actualizar wokwi-elements +# Update wokwi-elements cd wokwi-elements git pull origin main npm install npm run build -# Actualizar avr8js +# Update avr8js cd ../avr8js git pull origin main npm install npm run build -# Actualizar rp2040js +# Update rp2040js cd ../rp2040js git pull origin main npm install npm run build ``` -### Opción 3: Actualizar a una versión específica +### Option 3: Update to a specific version ```bash cd wokwi-libs/wokwi-elements -# Ver versiones disponibles +# View available versions git tag -l -# Cambiar a una versión específica +# Switch to a specific version git checkout v1.9.2 -# Recompilar +# Rebuild npm install npm run build ``` -### Después de Actualizar wokwi-elements +### After Updating wokwi-elements -Si actualizaste wokwi-elements, regenera la metadata de componentes para que nuevos componentes aparezcan en la UI: +If you updated wokwi-elements, regenerate the component metadata so that new components appear in the UI: ```bash cd frontend npx tsx ../scripts/generate-component-metadata.ts ``` -## Script de Actualización Automática +## Automatic Update Script -El script `update-wokwi-libs.bat` facilita las actualizaciones: +The `update-wokwi-libs.bat` script simplifies updates: ```batch @echo off echo ======================================== -echo Actualizando Wokwi Libraries +echo Updating Wokwi Libraries echo ======================================== cd wokwi-libs -echo [1/3] Actualizando wokwi-elements... +echo [1/3] Updating wokwi-elements... cd wokwi-elements git pull origin main npm install npm run build cd .. -echo [2/3] Actualizando avr8js... +echo [2/3] Updating avr8js... cd avr8js git pull origin main npm install npm run build cd .. -echo [3/3] Actualizando rp2040js... +echo [3/3] Updating rp2040js... cd rp2040js git pull origin main npm install @@ -163,24 +163,26 @@ npm run build cd .. echo ======================================== -echo Actualizacion completada! +echo Update complete! echo ======================================== pause ``` -## Cómo Se Usan las Librerías +## How the Libraries Are Used -### avr8js — Emulación AVR +### avr8js — AVR Emulation -El `AVRSimulator` (`frontend/src/simulation/AVRSimulator.ts`) usa avr8js para crear: +The `AVRSimulator` (`frontend/src/simulation/AVRSimulator.ts`) uses avr8js to create: +```typescript +import { CPU, avrInstruction, AVRTimer, AVRUSART, AVRADC, AVRIOPort } from 'avr8js'; ```typescript import { CPU, avrInstruction, AVRTimer, AVRUSART, AVRADC, AVRIOPort } from 'avr8js'; -// CPU ATmega328p a 16MHz +// ATmega328p CPU at 16MHz const cpu = new CPU(programMemory); -// Periféricos +// Peripherals const timer0 = new AVRTimer(cpu, timer0Config); const timer1 = new AVRTimer(cpu, timer1Config); const timer2 = new AVRTimer(cpu, timer2Config); @@ -190,67 +192,67 @@ 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) +// Simulation loop (~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 + avrInstruction(cpu); // Execute AVR instruction + cpu.tick(); // Update peripherals } requestAnimationFrame(runFrame); } ``` -### wokwi-elements — Componentes Visuales +### wokwi-elements — Visual Components -Los componentes se renderizan de dos formas: +Components are rendered in two ways: -**1. DynamicComponent (sistema actual — 48 componentes)** +**1. DynamicComponent (current system — 48 components)** ```typescript import { ComponentRegistry } from './services/ComponentRegistry'; -// Carga metadata desde /components-metadata.json +// Load metadata from /components-metadata.json const registry = ComponentRegistry.getInstance(); const metadata = registry.getById('led'); -// DynamicComponent crea el web component dinámicamente +// DynamicComponent creates the web component dynamically // document.createElement(metadata.tagName) → -// Sincroniza propiedades React → web component -// Extrae pinInfo del DOM para wire connections +// Syncs React props → web component +// Extracts pinInfo from the DOM for wire connections ``` -**2. React wrappers legacy (5 componentes)** +**2. Legacy React wrappers (5 components)** ```tsx -// ArduinoUno.tsx — sigue en uso activo para el board principal +// ArduinoUno.tsx — still actively used for the main board ``` -### PartSimulationRegistry — Comportamientos de Simulación +### PartSimulationRegistry — Simulation Behaviors -16 partes tienen lógica de simulación registrada que conecta los web components con el emulador AVR: +16 parts have registered simulation logic that connects the web components to the AVR emulator: -| Parte | Tipo | Comportamiento | -|-------|------|----------------| +| Part | Type | Behavior | +|------|------|----------| | `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) | +| `rgb-led` | Output | Digital + PWM on R/G/B | +| `led-bar-graph` | Output | 10 independent LEDs | +| `7segment` | Output | 8 segments (A-G + DP) | | `pushbutton` | Input | Press/release → `setPinState()` | -| `pushbutton-6mm` | Input | Mismo que pushbutton | +| `pushbutton-6mm` | Input | Same as 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 | +| `dip-switch-8` | Input | 8 independent switches | +| `potentiometer` | Input | Value → ADC voltage | +| `slide-potentiometer` | Input | Same logic via SIG/OUT | +| `photoresistor-sensor` | Input/Output | Analog voltage + digital LED | | `analog-joystick` | Input | VRX/VRY (ADC) + SW (digital) | -| `servo` | Output | Registros OCR1A/ICR1 → ángulo 0-180° | +| `servo` | Output | OCR1A/ICR1 registers → angle 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) | +| `lcd1602` | Output | Full HD44780 4-bit protocol (16×2) | +| `lcd2004` | Output | Full HD44780 4-bit protocol (20×4) | -## Componentes Wokwi Disponibles (48) +## Available Wokwi Components (48) ### Boards (4) - `wokwi-arduino-uno` — Arduino Uno R3 @@ -259,68 +261,68 @@ const metadata = registry.getById('led'); - `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 +- `wokwi-dht22` — Temperature and humidity sensor +- `wokwi-hc-sr04` — Ultrasonic distance sensor +- `wokwi-pir-motion-sensor` — PIR motion sensor +- `wokwi-photoresistor-sensor` — Photoresistor (LDR) +- `wokwi-ntc-temperature-sensor` — NTC temperature sensor +- `wokwi-analog-joystick` — Analog joystick ### Displays (3) -- `wokwi-lcd1602` — LCD 16x2 con protocolo HD44780 -- `wokwi-lcd2004` — LCD 20x4 con protocolo HD44780 -- `wokwi-7segment` — Display de 7 segmentos +- `wokwi-lcd1602` — LCD 16x2 with HD44780 protocol +- `wokwi-lcd2004` — LCD 20x4 with HD44780 protocol +- `wokwi-7segment` — 7-segment display ### 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 +- `wokwi-pushbutton` — Push button +- `wokwi-pushbutton-6mm` — 6mm push button +- `wokwi-slide-switch` — Slide switch +- `wokwi-dip-switch-8` — 8-position DIP switch +- `wokwi-potentiometer` — Potentiometer ### 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) +- `wokwi-led` — Colored LED +- `wokwi-rgb-led` — RGB LED +- `wokwi-led-bar-graph` — LED bar graph (10 LEDs) +- `wokwi-buzzer` — Piezoelectric buzzer +- `wokwi-neopixel` — Addressable RGB LED (WS2812) ### Motors (2) - `wokwi-servo` — Servo motor -- `wokwi-stepper-motor` — Motor paso a paso +- `wokwi-stepper-motor` — Stepper motor ### 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 +- `wokwi-resistor` — Resistor with color code +- `wokwi-slide-potentiometer` — Slide potentiometer +- `wokwi-led-ring` — LED ring +- `wokwi-membrane-keypad` — Matrix keypad ### Other (19) -- Componentes variados incluyendo `wokwi-ir-receiver`, `wokwi-ds1307`, breadboards, etc. +- Various components including `wokwi-ir-receiver`, `wokwi-ds1307`, breadboards, etc. -## Ventajas de Este Enfoque +## Advantages of This Approach -### Ventajas +### Advantages -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 +1. **Easy Updates**: A simple `git pull` + rebuild gives you the latest improvements +2. **Wokwi Compatible**: Uses exactly the same code as Wokwi.com +3. **Automatic Discovery**: New components appear automatically after regenerating metadata +4. **Version Control**: You can checkout to specific versions +5. **Flexible Development**: Source code available for debugging and modifications +6. **No npm Dependency**: You don't depend on npm package publications +7. **100% Offline**: Works completely without internet after initial setup -### Consideraciones +### Considerations -1. **Espacio en Disco**: Los repositorios clonados ocupan más espacio (~200MB) -2. **Compilación**: Debes compilar los repositorios después de actualizarlos -3. **Metadata**: Regenerar `components-metadata.json` después de actualizar wokwi-elements +1. **Disk Space**: Cloned repositories take more disk space (~200MB) +2. **Compilation**: You must rebuild the repositories after updating them +3. **Metadata**: Regenerate `components-metadata.json` after updating wokwi-elements ## Troubleshooting ### Error: "Module not found: @wokwi/elements" -Asegúrate de que wokwi-elements esté compilado: +Make sure wokwi-elements is built: ```bash cd wokwi-libs/wokwi-elements @@ -330,7 +332,7 @@ npm run build ### Error: "Cannot find module 'avr8js'" -Verifica que el alias en `vite.config.ts` esté correcto y que avr8js esté compilado: +Verify that the alias in `vite.config.ts` is correct and that avr8js is built: ```bash cd wokwi-libs/avr8js @@ -338,29 +340,29 @@ npm install npm run build ``` -### Los componentes no se muestran en el picker +### Components are not shown in the picker -Regenera la metadata de componentes: +Regenerate the component metadata: ```bash cd frontend npx tsx ../scripts/generate-component-metadata.ts ``` -### Nuevo componente de wokwi-elements no aparece +### New wokwi-elements component does not appear -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/` +1. Update wokwi-elements: `cd wokwi-libs/wokwi-elements && git pull && npm run build` +2. Regenerate metadata: `cd frontend && npx tsx ../scripts/generate-component-metadata.ts` +3. If it needs simulation, register its behavior in `frontend/src/simulation/parts/` -### Los componentes se ven pero no responden a la simulación +### Components are visible but do not respond to simulation -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. +Verify that the component has simulation logic registered in `PartSimulationRegistry` (files `BasicParts.ts` or `ComplexParts.ts`). Only the 16 registered components have interactive behavior. -## Referencias +## References - [Wokwi Elements Documentation](https://elements.wokwi.com/) - [AVR8js Repository](https://github.com/wokwi/avr8js) - [Wokwi Simulator](https://wokwi.com) -- [Lit Documentation](https://lit.dev/) — Framework usado por wokwi-elements +- [Lit Documentation](https://lit.dev/) — Framework used by wokwi-elements - [Web Components Guide](https://developer.mozilla.org/en-US/docs/Web/Web_Components) diff --git a/docs/examples/README.md b/docs/examples/README.md index cdea0fc..af14d8e 100644 --- a/docs/examples/README.md +++ b/docs/examples/README.md @@ -1,11 +1,11 @@ # Example Projects -Esta carpeta contiene las imágenes de preview para los 8 proyectos de ejemplo de la galería. +This folder contains the preview images for the 8 example projects in the gallery. -## Ejemplos Disponibles +## Available Examples -| ID | Título | Categoría | Dificultad | Componentes | -|----|--------|-----------|------------|-------------| +| ID | Title | Category | Difficulty | Components | +|----|-------|----------|------------|------------| | `blink-led` | Blink LED | basics | beginner | Arduino Uno | | `traffic-light` | Traffic Light | basics | beginner | 3 LEDs (R/Y/G) | | `button-led` | Button Control | basics | beginner | Button + LED | @@ -15,28 +15,28 @@ Esta carpeta contiene las imágenes de preview para los 8 proyectos de ejemplo d | `simon-says` | Simon Says Game | games | advanced | 4 LEDs + 4 buttons | | `lcd-hello` | LCD 20x4 Display | displays | intermediate | LCD 2004 | -Cada ejemplo incluye: -- Código Arduino completo -- Definiciones de componentes con posiciones -- Conexiones de cables con pines y colores +Each example includes: +- Complete Arduino sketch code +- Component definitions with positions +- Wire connections with pin names and colors -Los ejemplos se definen en `frontend/src/data/examples.ts` y se renderizan en la galería `ExamplesGallery.tsx` con filtros por categoría y dificultad. +The examples are defined in `frontend/src/data/examples.ts` and rendered in the `ExamplesGallery.tsx` gallery with category and difficulty filters. -## Cómo Crear Screenshots +## How to Create Screenshots -### Método 1: Captura Manual (Recomendado) +### Method 1: Manual Capture (Recommended) -1. Carga el ejemplo en el editor (http://localhost:5173/examples) -2. Haz click en el ejemplo para cargarlo -3. Ajusta el zoom del canvas si es necesario -4. Usa una herramienta de captura de pantalla para capturar solo el área del simulador -5. Guarda la imagen con el nombre correspondiente +1. Load the example in the editor (http://localhost:5173/examples) +2. Click the example to load it +3. Adjust the canvas zoom if needed +4. Use a screenshot tool to capture only the simulator area +5. Save the image with the corresponding name -### Método 2: Usando DevTools +### Method 2: Using DevTools -1. Abre el ejemplo en el navegador -2. Abre DevTools (F12) -3. Ve a la consola y ejecuta: +1. Open the example in the browser +2. Open DevTools (F12) +3. Go to the console and run: ```javascript const canvas = document.querySelector('.canvas-content'); html2canvas(canvas).then(canvas => { @@ -47,9 +47,9 @@ html2canvas(canvas).then(canvas => { }); ``` -## Nombres de Archivos +## File Names -Los archivos deben seguir el ID del ejemplo: +Files must follow the example ID: - `blink-led.png` — Blink LED - `traffic-light.png` — Traffic Light @@ -60,26 +60,26 @@ Los archivos deben seguir el ID del ejemplo: - `simon-says.png` — Simon Says Game - `lcd-hello.png` — LCD 20x4 Display -## Dimensiones Recomendadas +## Recommended Dimensions -- **Ancho**: 800px -- **Alto**: 500px -- **Formato**: PNG con fondo oscuro (#1e1e1e) +- **Width**: 800px +- **Height**: 500px +- **Format**: PNG with dark background (#1e1e1e) -## Placeholder Actual +## Current Placeholder -Mientras no haya imágenes, se muestra un placeholder con: -- Icono de la categoría (emoji grande) -- Número de componentes (azul cian) -- Número de cables (amarillo) -- Fondo degradado con borde punteado +While no images are available, a placeholder is shown with: +- Category icon (large emoji) +- Number of components (cyan blue) +- Number of wires (yellow) +- Gradient background with dashed border -## Agregar un Nuevo Ejemplo +## Adding a New Example -1. Agregar la definición en `frontend/src/data/examples.ts` con: +1. Add the definition in `frontend/src/data/examples.ts` with: - `id`, `title`, `description`, `category`, `difficulty` - - `code`: Sketch Arduino completo - - `components[]`: Tipo, posición, propiedades - - `wires[]`: Conexiones con `startPinName`, `endPinName`, `color` -2. (Opcional) Capturar screenshot y guardarlo aquí como `{id}.png` -3. El ejemplo aparecerá automáticamente en la galería con filtrado por categoría y dificultad + - `code`: Complete Arduino sketch + - `components[]`: Type, position, properties + - `wires[]`: Connections with `startPinName`, `endPinName`, `color` +2. (Optional) Capture a screenshot and save it here as `{id}.png` +3. The example will automatically appear in the gallery with category and difficulty filtering diff --git a/frontend/public/sitemap.xml b/frontend/public/sitemap.xml index 155dae9..1710363 100644 --- a/frontend/public/sitemap.xml +++ b/frontend/public/sitemap.xml @@ -17,12 +17,40 @@ - https://velxio.dev/docs + https://velxio.dev/docs/intro 2026-03-11 - weekly + monthly 0.8 + + https://velxio.dev/docs/getting-started + 2026-03-11 + monthly + 0.8 + + + + https://velxio.dev/docs/emulator + 2026-03-11 + monthly + 0.7 + + + + https://velxio.dev/docs/components + 2026-03-11 + monthly + 0.7 + + + + https://velxio.dev/docs/roadmap + 2026-03-11 + monthly + 0.6 + + https://velxio.dev/examples 2026-03-06 diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index b9e2fde..def404a 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -30,6 +30,7 @@ function App() { } /> } /> } /> + } /> {/* Canonical project URL by ID */} } /> {/* Legacy slug route — redirects to /project/:id */} diff --git a/frontend/src/pages/DocsPage.css b/frontend/src/pages/DocsPage.css index d7eb1d7..5277f90 100644 --- a/frontend/src/pages/DocsPage.css +++ b/frontend/src/pages/DocsPage.css @@ -180,6 +180,7 @@ border-radius: var(--radius); cursor: pointer; transition: color 0.15s, background 0.15s; + text-decoration: none; } .docs-sidebar-item:hover { @@ -406,6 +407,7 @@ padding: 9px 16px; cursor: pointer; transition: color 0.15s, border-color 0.15s, background 0.15s; + text-decoration: none; } .docs-pagination-btn:hover { diff --git a/frontend/src/pages/DocsPage.tsx b/frontend/src/pages/DocsPage.tsx index 4d7fb89..456c8e5 100644 --- a/frontend/src/pages/DocsPage.tsx +++ b/frontend/src/pages/DocsPage.tsx @@ -1,5 +1,5 @@ -import React, { useState } from 'react'; -import { Link } from 'react-router-dom'; +import React, { useState, useEffect } from 'react'; +import { Link, useParams, useNavigate } from 'react-router-dom'; import { useAuthStore } from '../store/useAuthStore'; import './DocsPage.css'; @@ -23,6 +23,8 @@ const IcoGitHub = () => ( /* ── Doc sections ──────────────────────────────────────── */ type SectionId = 'intro' | 'getting-started' | 'emulator' | 'components' | 'roadmap'; +const VALID_SECTIONS: SectionId[] = ['intro', 'getting-started', 'emulator', 'components', 'roadmap']; + interface NavItem { id: SectionId; label: string; @@ -36,6 +38,31 @@ const NAV_ITEMS: NavItem[] = [ { id: 'roadmap', label: 'Roadmap' }, ]; +/* ── Per-section SEO metadata ──────────────────────────── */ +interface SectionMeta { title: string; description: string; } +const SECTION_META: Record = { + 'intro': { + title: 'Introduction — Velxio Documentation', + description: 'Learn about Velxio, the free open-source Arduino emulator with real AVR8 and RP2040 CPU emulation and 48+ interactive electronic components.', + }, + 'getting-started': { + title: 'Getting Started — Velxio Documentation', + description: 'Get started with Velxio: use the hosted editor, self-host with Docker, or set up a local development environment. Simulate your first Arduino sketch in minutes.', + }, + 'emulator': { + title: 'Emulator Architecture — Velxio Documentation', + description: 'How Velxio emulates AVR8 (ATmega328p) and RP2040 CPUs. Covers the execution loop, peripherals (GPIO, Timers, USART, ADC, SPI, I2C), and pin mapping.', + }, + 'components': { + title: 'Components Reference — Velxio Documentation', + description: 'Full reference for all 48+ interactive electronic components in Velxio: LEDs, displays, sensors, buttons, potentiometers, and more. Includes wiring and property details.', + }, + 'roadmap': { + title: 'Roadmap — Velxio Documentation', + description: "Velxio's feature roadmap: what's implemented, what's in progress, and what's planned for future releases.", + }, +}; + /* ── Section content ───────────────────────────────────── */ const IntroSection: React.FC = () => (
@@ -461,11 +488,77 @@ const SECTION_MAP: Record = { /* ── Page ─────────────────────────────────────────────── */ export const DocsPage: React.FC = () => { - const [activeSection, setActiveSection] = useState('intro'); + const { section } = useParams<{ section?: string }>(); + const navigate = useNavigate(); const [sidebarOpen, setSidebarOpen] = useState(false); const user = useAuthStore((s) => s.user); + // Derive active section from URL; fall back to 'intro' + const activeSection: SectionId = + section && VALID_SECTIONS.includes(section as SectionId) + ? (section as SectionId) + : 'intro'; + + // Redirect bare /docs → /docs/intro so every section has a canonical URL + useEffect(() => { + if (!section) { + navigate('/docs/intro', { replace: true }); + } + }, [section, navigate]); + + // Capture the original values once on mount and restore them on unmount + useEffect(() => { + const origTitle = document.title; + const descEl = document.querySelector('meta[name="description"]'); + const origDesc = descEl?.getAttribute('content') ?? ''; + const canonicalEl = document.querySelector('link[rel="canonical"]'); + const origCanonical = canonicalEl?.getAttribute('href') ?? ''; + + return () => { + document.title = origTitle; + if (descEl) descEl.setAttribute('content', origDesc); + if (canonicalEl) canonicalEl.setAttribute('href', origCanonical); + document.getElementById('docs-jsonld')?.remove(); + }; + }, []); // runs once on mount; cleanup runs once on unmount + + // Update document title, meta description, canonical, and JSON-LD per section. + // No cleanup here — the mount effect above restores defaults on unmount, + // and on a section change the next run of this effect immediately overwrites. + useEffect(() => { + const meta = SECTION_META[activeSection]; + + document.title = meta.title; + + const descEl = document.querySelector('meta[name="description"]'); + if (descEl) descEl.setAttribute('content', meta.description); + + const canonicalEl = document.querySelector('link[rel="canonical"]'); + if (canonicalEl) canonicalEl.setAttribute('href', `https://velxio.dev/docs/${activeSection}`); + + // Inject / update JSON-LD structured data for this doc page + const ldId = 'docs-jsonld'; + let ldScript = document.getElementById(ldId) as HTMLScriptElement | null; + if (!ldScript) { + ldScript = document.createElement('script'); + ldScript.id = ldId; + ldScript.type = 'application/ld+json'; + document.head.appendChild(ldScript); + } + ldScript.textContent = JSON.stringify({ + '@context': 'https://schema.org', + '@type': 'TechArticle', + headline: meta.title, + description: meta.description, + url: `https://velxio.dev/docs/${activeSection}`, + isPartOf: { '@type': 'WebSite', url: 'https://velxio.dev/', name: 'Velxio' }, + inLanguage: 'en-US', + author: { '@type': 'Person', name: 'David Montero Crespo', url: 'https://github.com/davidmonterocrespo24' }, + }); + }, [activeSection]); + const ActiveContent = SECTION_MAP[activeSection]; + const activeIdx = NAV_ITEMS.findIndex((i) => i.id === activeSection); return (
@@ -509,13 +602,14 @@ export const DocsPage: React.FC = () => {
Documentation
@@ -538,29 +632,23 @@ export const DocsPage: React.FC = () => { {/* Prev / Next navigation */}
- {NAV_ITEMS.findIndex((i) => i.id === activeSection) > 0 && ( - + ← {NAV_ITEMS[activeIdx - 1].label} + )} - {NAV_ITEMS.findIndex((i) => i.id === activeSection) < NAV_ITEMS.length - 1 && ( - + {NAV_ITEMS[activeIdx + 1].label} → + )}