diff --git a/frontend/src/__tests__/gallery-run-gate.audit.test.ts b/frontend/src/__tests__/gallery-run-gate.audit.test.ts new file mode 100644 index 00000000..c885c0db --- /dev/null +++ b/frontend/src/__tests__/gallery-run-gate.audit.test.ts @@ -0,0 +1,116 @@ +import { describe, expect, it } from 'vitest'; +import { exampleProjects as examples } from '../data/examples'; +import { buildInputFromStore } from '../simulation/spice/storeAdapter'; +import { BOARD_PIN_GROUPS } from '../simulation/spice/boardPinGroups'; +import { verifyCircuit } from '../simulation/verify/circuitVerifier'; +import { stripBrandPrefix, isBoardComponentType } from '../utils/exampleToBuildNetlistInput'; +import type { PinSourceState } from '../simulation/spice/types'; +import type { BoardKind } from '../store/useSimulatorStore'; + +/** + * Gallery audit: which examples would the Run button REFUSE to start? + * + * EditorToolbar's `checkOrBlock` runs `verifyCircuitFromStore()` before every Run and + * returns false when the verifier reports errors — the compile never fires and the user + * gets a "run anyway?" modal. So a circuit error is not cosmetic: it is the difference + * between an example that runs and one that appears dead. + * + * This mattered because the defects hide until the circuit solves END TO END. c3-button + * wired its button to pins that do not exist, so the netlist never closed and nobody saw + * that its LED had no series resistor. Fixing the pin names surfaced a 506 mA LED that + * had been wrong since the example was written. + * + * Reproduces the Run gate exactly: same worst-case snapshot (every wired digital pin + * forced HIGH at the board's vcc, rails skipped), same buildInputFromStore, same + * verifyCircuit. Real ngspice, no browser. + */ + +function boardKindOf(example: (typeof examples)[number]): BoardKind | null { + const bt = (example as { boardType?: string }).boardType; + return (bt as BoardKind) ?? null; +} + +/** The board component id an example's wires refer to (legacy examples say 'arduino-uno'). */ +function boardIdsOf(example: (typeof examples)[number]): Set { + const declared = new Set(example.components?.map((c) => c.id) ?? []); + const refs = new Set(); + for (const w of example.wires ?? []) { + for (const ep of [w.start, w.end]) if (!declared.has(ep.componentId)) refs.add(ep.componentId); + } + return refs; +} + +async function runGate(example: (typeof examples)[number]) { + const kind = boardKindOf(example); + const components = (example.components ?? []) + .filter((c) => !isBoardComponentType(c.type)) + .map((c) => ({ + id: c.id, + metadataId: stripBrandPrefix(c.type), + properties: c.properties ?? {}, + })); + const wires = (example.wires ?? []).map((w) => ({ + id: w.id, + start: { componentId: w.start.componentId, pinName: w.start.pinName }, + end: { componentId: w.end.componentId, pinName: w.end.pinName }, + color: '#666', + waypoints: [], + })); + + const boards = kind + ? [...boardIdsOf(example)].map((id) => { + const group = BOARD_PIN_GROUPS[kind] ?? BOARD_PIN_GROUPS.default; + const pinStates: Record = {}; + const wired = new Set(); + for (const w of wires) { + if (w.start.componentId === id) wired.add(w.start.pinName); + if (w.end.componentId === id) wired.add(w.end.pinName); + } + for (const pinName of wired) { + if (group.gnd.includes(pinName)) continue; + if (group.vcc_pins.includes(pinName)) continue; + if (Number.isNaN(Number.parseInt(pinName, 10))) continue; + pinStates[pinName] = { type: 'digital', v: group.vcc }; + } + return { id, boardKind: kind, pinStates }; + }) + : []; + + const input = buildInputFromStore({ components, wires, boards }); + return verifyCircuit(input); +} + +describe('gallery: no example is blocked by its own circuit', () => { + const candidates = examples.filter( + (e) => (e.components?.length ?? 0) > 0 && (e.wires?.length ?? 0) > 0, + ); + + it('audits every wired example and reports the blockers', async () => { + const blocked: Array<{ id: string; board: string; codes: string[]; detail: string }> = []; + for (const ex of candidates) { + let res; + try { + res = await runGate(ex); + } catch { + continue; // unbuildable snapshot — the real app treats that as "don't block" + } + if (res.errors.length) { + blocked.push({ + id: ex.id, + board: (ex as { boardType?: string }).boardType ?? '(sin placa)', + codes: [...new Set(res.errors.map((e) => e.code))], + detail: res.errors[0].message.slice(0, 110), + }); + } + } + + if (blocked.length) { + console.log( + `\n=== ${blocked.length} de ${candidates.length} ejemplos con el Run BLOQUEADO ===`, + ); + for (const b of blocked) + console.log(` ${b.board.padEnd(20)} ${b.id.padEnd(36)} ${b.codes.join(',')} ${b.detail}`); + } + expect(blocked.map((b) => `${b.id} [${b.codes.join(',')}]`)).toEqual([]); + }, 600_000); +}); diff --git a/frontend/src/components/simulator/SimulatorCanvas.tsx b/frontend/src/components/simulator/SimulatorCanvas.tsx index 76ce6c25..1912cffd 100644 --- a/frontend/src/components/simulator/SimulatorCanvas.tsx +++ b/frontend/src/components/simulator/SimulatorCanvas.tsx @@ -1,4 +1,8 @@ -import { useSimulatorStore, getEsp32Bridge, getBoardSimulator } from '../../store/useSimulatorStore'; +import { + useSimulatorStore, + getEsp32Bridge, + getBoardSimulator, +} from '../../store/useSimulatorStore'; import { getProBoard } from '../../lib/proBoardRegistry'; import { useElectricalStore } from '../../store/useElectricalStore'; import { openDeviceGateway } from '../../lib/openDeviceGateway'; @@ -6,7 +10,7 @@ import React, { useEffect, useState, useRef, useCallback } from 'react'; import { createPortal } from 'react-dom'; import { Undo2, Redo2 } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import { ESP32_ADC_PIN_MAP } from '../velxio-components/Esp32Element'; +import { adcPinMapFor } from '../velxio-components/Esp32Element'; import { ComponentPickerModal } from '../ComponentPickerModal'; import { ComponentPropertyDialog } from './ComponentPropertyDialog'; import { CustomChipDialog } from '../customChips/CustomChipDialog'; @@ -62,7 +66,11 @@ import { useIsCoarsePointer } from '../../utils/useTouchDevice'; import type { ComponentMetadata } from '../../types/component-metadata'; import type { BoardKind } from '../../types/board'; import { BOARD_KIND_FQBN, boardDisplayName } from '../../types/board'; -import { boardGateDecision, proBoardFeatureName, triggerProUpgradePrompt } from '../../lib/proBoardGate'; +import { + boardGateDecision, + proBoardFeatureName, + triggerProUpgradePrompt, +} from '../../lib/proBoardGate'; import { FlashModal } from './FlashModal'; import { isTauri as isTauriRuntimeFn } from '../../desktop/tauriBridge'; import { isEsp32Family } from '../../types/boardOptions'; @@ -266,9 +274,10 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { // body (not a tiny pin overlay) and we want to let them pick a pin from a // list. `kind` distinguishes board vs component so we can pull the right // metadata for the dialog title. - const [pinPicker, setPinPicker] = useState< - { kind: 'component' | 'board'; targetId: string } | null - >(null); + const [pinPicker, setPinPicker] = useState<{ + kind: 'component' | 'board'; + targetId: string; + } | null>(null); // Component property dialog const [showPropertyDialog, setShowPropertyDialog] = useState(false); @@ -459,9 +468,11 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { // DRAG_PROMOTE_THRESHOLD_PX, we cancel the passthrough and start a real // drag — so the user can rearrange interactive parts live without first // pausing the simulation. - const pendingTouchDragRef = useRef< - { componentId: string; startX: number; startY: number } | null - >(null); + const pendingTouchDragRef = useRef<{ + componentId: string; + startX: number; + startY: number; + } | null>(null); const touchOnPinRef = useRef(false); const lastTapTimeRef = useRef(0); @@ -763,9 +774,7 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { clientY: pending.startY, }), ); - target.dispatchEvent( - new MouseEvent('mouseleave', { bubbles: false }), - ); + target.dispatchEvent(new MouseEvent('mouseleave', { bubbles: false })); } } touchPassthroughRef.current = false; @@ -901,8 +910,7 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { const cur = useSimulatorStore .getState() .components.find((c) => c.id === touchDraggedComponentIdRef.current); - const snapped = - cur && snapPositionToBreadboard(cur, nx, ny, simState.components); + const snapped = cur && snapPositionToBreadboard(cur, nx, ny, simState.components); if (snapped) { nx = snapped.x; ny = snapped.y; @@ -1085,7 +1093,9 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { world.x, world.y, ); - useSimulatorStore.getState().updateWire(wire.id, { waypoints: newWaypoints, autoRouted: false }); + useSimulatorStore + .getState() + .updateWire(wire.id, { waypoints: newWaypoints, autoRouted: false }); useSimulatorStore.getState().setSelectedWire(wire.id); } lastTapTimeRef.current = 0; @@ -1340,7 +1350,9 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { // Potentiometer: forward analog value as ADC millivolts if (tag === 'wokwi-potentiometer' && selfEndpoint.pinName === 'SIG') { - const adcInfo = ESP32_ADC_PIN_MAP[gpioPin]; + // Per CHIP: the S3's ADC pins are absent from the classic map (knob did + // nothing) and the C3/C6 would have pushed GPIO0 to channel 9 instead of 0. + const adcInfo = adcPinMapFor(lookupKey)[gpioPin]; if (adcInfo) { const onInput = (e: Event) => { const pct = parseFloat((e.target as any).value ?? '0'); // 0–100 @@ -1527,8 +1539,7 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { const cur = useSimulatorStore .getState() .components.find((c) => c.id === draggedComponentId); - const snapped = - cur && snapPositionToBreadboard(cur, nx, ny, simState.components); + const snapped = cur && snapPositionToBreadboard(cur, nx, ny, simState.components); if (snapped) { nx = snapped.x; ny = snapped.y; @@ -1801,12 +1812,7 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { // and just opens the property dialog — no history entry needed. const start = dragStartPosRef.current; const isClick = posDiff < 5 && timeDiff < 300; - if ( - !isClick && - start && - draggedComponentId && - !draggedComponentId.startsWith('__board__') - ) { + if (!isClick && start && draggedComponentId && !draggedComponentId.startsWith('__board__')) { // Seat BEFORE recording the move, so undo restores the pre-drag // position in one step instead of leaving the part mid-seat. seatDroppedComponent(draggedComponentId); @@ -1836,9 +1842,7 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { // convention used in Figma / Miro / draw.io. const leftButton = e.button === 0; const middleOrRight = e.button === 1 || e.button === 2; - const isPanGesture = - middleOrRight || - (leftButton && !wireInProgress && !showPropertyDialog); + const isPanGesture = middleOrRight || (leftButton && !wireInProgress && !showPropertyDialog); if (isPanGesture) { e.preventDefault(); @@ -2229,8 +2233,7 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { // primary way to pick pins, so the tiny overlay squares are hidden — // they're hard to hit with a finger anyway. Desktop shows overlays on // hover / while wiring only — selection alone doesn't light them up. - const showPinsForComponent = - !dialogOpen && !isTouchDevice && (wireInProgress || isHovered); + const showPinsForComponent = !dialogOpen && !isTouchDevice && (wireInProgress || isHovered); return (
{ // light them up (a selected breadboard lit 170 squares permanently). // Hidden when a dialog is open. Hidden entirely on touch — there the // PinPickerDialog (tap component → list of pins) replaces the overlays. - const showPinsForComponent = - !dialogOpen && !isTouchDevice && (wireInProgress || isHovered); + const showPinsForComponent = !dialogOpen && !isTouchDevice && (wireInProgress || isHovered); // Breadboards are the physical base of a circuit — everything plugs into // them — so they always sit at the very back: below boards (z 0), other @@ -2431,161 +2433,197 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => {
{(() => { const headerJsx = ( -
-
- {/* Status LED */} - +
+
+ {/* Status LED */} + - {/* Active board selector (multi-board) — hidden when no boards */} - {boards.length > 0 ? ( - - ) : ( - - {t('editor.canvas.noBoard')} - - )} + {/* Active board selector (multi-board) — hidden when no boards */} + {boards.length > 0 ? ( + + ) : ( + + {t('editor.canvas.noBoard')} + + )} - {/* Undo / Redo — canvas-scoped, mirrors the Ctrl+Z / Ctrl+Y + {/* Undo / Redo — canvas-scoped, mirrors the Ctrl+Z / Ctrl+Y handler in EditorPage. Tooltip surfaces the description of the command that would be applied. Disabled when the stack is exhausted in that direction. */} - - - - {/* Serial Monitor toggle */} - - - {/* ESP32-CAM webcam stream toggle */} - {activeBoard?.boardKind === 'esp32-cam' && ( - - )} - - {/* WiFi status indicator + IoT-gateway launcher (ESP32 + Pico W) */} - {activeBoard && - (isEsp32Kind(activeBoard.boardKind) || - activeBoard.boardKind === 'pi-pico-w') && - activeBoard.wifiStatus && - (() => { - // The Pico W virtual net assigns its IP deterministically when - // the sketch connects; the bridge reports 'started' carrying the - // IP. Treat that as got_ip so the badge matches the ESP32 (green, - // clickable → the same /api/gateway proxy). - const rawStatus = activeBoard.wifiStatus.status; - const status = - activeBoard.boardKind === 'pi-pico-w' && - rawStatus === 'started' && - activeBoard.wifiStatus.ip - ? 'got_ip' - : rawStatus; - const hasIp = status === 'got_ip'; - const sessionId = getTabSessionId(); - const clientId = `${sessionId}::${activeBoard.id}`; - const backendBase = - (import.meta.env.VITE_API_BASE as string | undefined) ?? - 'http://localhost:8001/api'; - const gatewayUrl = `${backendBase}/gateway/${clientId}/`; - - const openGateway = () => { - if (!hasIp) return; - // A private overlay (velxio.dev) can install a synchronous - // gate to keep the IoT gateway behind a paid plan. When it - // returns true it has already handled the click (e.g. shown - // an in-place upgrade modal), so we don't open the tab. - // OSS builds have no hook → always open. - const gate = (window as unknown as { - __velxio_iot_gateway_open_gate__?: () => boolean; - }).__velxio_iot_gateway_open_gate__; - if (gate && gate()) return; - // Pico W runs in THIS tab — a new tab would background and - // freeze the emulation. Show the page in an in-app iframe. - if (activeBoard.boardKind === 'pi-pico-w') { - openDeviceGateway(gatewayUrl); - } else { - window.open(gatewayUrl, '_blank'); + + + + {/* Serial Monitor toggle */} + + + {/* ESP32-CAM webcam stream toggle */} + {activeBoard?.boardKind === 'esp32-cam' && ( + + )} + + {/* WiFi status indicator + IoT-gateway launcher (ESP32 + Pico W) */} + {activeBoard && + (isEsp32Kind(activeBoard.boardKind) || activeBoard.boardKind === 'pi-pico-w') && + activeBoard.wifiStatus && + (() => { + // The Pico W virtual net assigns its IP deterministically when + // the sketch connects; the bridge reports 'started' carrying the + // IP. Treat that as got_ip so the badge matches the ESP32 (green, + // clickable → the same /api/gateway proxy). + const rawStatus = activeBoard.wifiStatus.status; + const status = + activeBoard.boardKind === 'pi-pico-w' && + rawStatus === 'started' && + activeBoard.wifiStatus.ip + ? 'got_ip' + : rawStatus; + const hasIp = status === 'got_ip'; + const sessionId = getTabSessionId(); + const clientId = `${sessionId}::${activeBoard.id}`; + const backendBase = + (import.meta.env.VITE_API_BASE as string | undefined) ?? + 'http://localhost:8001/api'; + const gatewayUrl = `${backendBase}/gateway/${clientId}/`; + + const openGateway = () => { + if (!hasIp) return; + // A private overlay (velxio.dev) can install a synchronous + // gate to keep the IoT gateway behind a paid plan. When it + // returns true it has already handled the click (e.g. shown + // an in-place upgrade modal), so we don't open the tab. + // OSS builds have no hook → always open. + const gate = ( + window as unknown as { + __velxio_iot_gateway_open_gate__?: () => boolean; + } + ).__velxio_iot_gateway_open_gate__; + if (gate && gate()) return; + // Pico W runs in THIS tab — a new tab would background and + // freeze the emulation. Show the page in an in-app iframe. + if (activeBoard.boardKind === 'pi-pico-w') { + openDeviceGateway(gatewayUrl); + } else { + window.open(gatewayUrl, '_blank'); + } + }; + return ( + + + + + + + + + ); + })()} + + {/* BLE status indicator (ESP32 boards only) */} + {activeBoard && isEsp32Kind(activeBoard.boardKind) && activeBoard.bleStatus && ( { strokeLinecap="round" strokeLinejoin="round" > - - - - + - ); - })()} + )} - {/* BLE status indicator (ESP32 boards only) */} - {activeBoard && isEsp32Kind(activeBoard.boardKind) && activeBoard.bleStatus && ( - - - - - - )} + + + + {t('editor.canvas.scope')} + +
- {/* Oscilloscope toggle */} - -
+
+ {/* Zoom controls */} +
+ + + +
-
- {/* Zoom controls */} -
- - - + + + + + {t('editor.canvas.add')} + +
- - {/* Component count */} - - - - - - {components.length} - - - {/* Add Component */} - -
-
); return headerSlot ? createPortal(headerJsx, headerSlot) : headerJsx; })()} @@ -2906,8 +2915,7 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { // Suppressed while a dialog is open. Hidden entirely on touch // since the PinPickerDialog (tap board to open list) replaces // the overlays — fingers can't reliably hit a 12px pin anyway. - const showPins = - !dialogOpen && !isTouchDevice && (wireInProgress || isHovered); + const showPins = !dialogOpen && !isTouchDevice && (wireInProgress || isHovered); return ( { bar is pinned top-center so it never covers pins near the wire. - COMPONENT selection stays touch-only — desktop already has the Delete key + the right-click rotate menu. */} - {!wireInProgress && !interactionRunning && + {!wireInProgress && + !interactionRunning && (() => { if (selectedWireId) { const wire = wires.find((w) => w.id === selectedWireId); @@ -3085,7 +3094,13 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { } else { const c = components.find((x) => x.id === targetId); const rot = c ? Number(c.properties?.rotation) || 0 : 0; - const pos = calculatePinPosition(targetId, pinName, (c?.x ?? 0) + 6, (c?.y ?? 0) + 6, rot); + const pos = calculatePinPosition( + targetId, + pinName, + (c?.x ?? 0) + 6, + (c?.y ?? 0) + 6, + rot, + ); worldX = pos?.x ?? (c?.x ?? 0) + pin.x; worldY = pos?.y ?? (c?.y ?? 0) + pin.y; } @@ -3166,11 +3181,11 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { return ( ) ?? {}, + attrs: (props.attrs as Record) ?? {}, }} onClose={() => setCustomChipComponentId(null)} onSave={(data) => { @@ -3249,11 +3264,7 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { type="button" title={color} onClick={() => { - recordUpdateWire( - wireContextMenu.wireId, - { color: wire.color }, - { color }, - ); + recordUpdateWire(wireContextMenu.wireId, { color: wire.color }, { color }); setWireContextMenu(null); }} style={{ @@ -3529,13 +3540,7 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { setFlashModalFor(null); return null; } - return ( - setFlashModalFor(null)} - /> - ); + return setFlashModalFor(null)} />; })()} {/* Board Options modal (ESP32 only) */} @@ -3562,7 +3567,9 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => { {boardToRemove && (() => { const board = boards.find((b) => b.id === boardToRemove); - const label = board ? boardDisplayName(board) : t('editor.canvas.removeConfirm.boardFallback'); + const label = board + ? boardDisplayName(board) + : t('editor.canvas.removeConfirm.boardFallback'); const connectedWires = wires.filter( (w) => w.start.componentId === boardToRemove || w.end.componentId === boardToRemove, ).length; diff --git a/frontend/src/components/velxio-components/Esp32Element.ts b/frontend/src/components/velxio-components/Esp32Element.ts index 8af5e9f3..b43afb08 100644 --- a/frontend/src/components/velxio-components/Esp32Element.ts +++ b/frontend/src/components/velxio-components/Esp32Element.ts @@ -350,6 +350,45 @@ export const ESP32_ADC_PIN_MAP: Record = { + 0: { adc: 1, ch: 0, chn: 0 }, + 1: { adc: 1, ch: 1, chn: 1 }, + 2: { adc: 1, ch: 2, chn: 2 }, + 3: { adc: 1, ch: 3, chn: 3 }, + 4: { adc: 1, ch: 4, chn: 4 }, +}; + +/** ESP32-S3: ADC1 channels 0..9 are GPIO1..10. (ADC2 = GPIO11..20 shares the same + * channel indices in the engine, so it is left out rather than aliased wrongly.) */ +const ESP32S3_ADC_PIN_MAP: Record = Object.fromEntries( + Array.from({ length: 10 }, (_, ch) => [ch + 1, { adc: 1 as const, ch, chn: ch }]), +); + +/** The ADC map for a board kind. Unknown kinds fall back to the classic ESP32. */ +export function adcPinMapFor(boardKind: string): Record { + if (boardKind.includes('c3') || boardKind.includes('c6')) return RISCV_C_ADC_PIN_MAP; + if (boardKind.includes('s3')) return ESP32S3_ADC_PIN_MAP; + return ESP32_ADC_PIN_MAP; +} + // ─── Board config by variant ────────────────────────────────────────────────── interface BoardConfig { diff --git a/frontend/src/data/examples-100-days.ts b/frontend/src/data/examples-100-days.ts index d65c8b0e..ff0c2249 100644 --- a/frontend/src/data/examples-100-days.ts +++ b/frontend/src/data/examples-100-days.ts @@ -1969,8 +1969,13 @@ CITY = "city" i2c = I2C(0, scl=Pin(22), sda=Pin(21)) oled = ssd1306.SSD1306_I2C(128, 64, i2c) -touch_next = Pin(14, Pin.IN) -touch_sel = Pin(27, Pin.IN) +# PULL_DOWN, no Pin.IN a secas: los botones van entre 3V3 y el pin, asi que sin +# pull-down el pin queda FLOTANDO cuando el boton esta abierto y pin.value() no +# vale nada. En una placa de verdad se lee ruido; aqui el nodo resuelve a 3,3 V y +# los dos botones parecen pulsados para siempre, con wait_for_release() girando +# en vacio. Es el mismo fallo que en hardware, no un artefacto del emulador. +touch_next = Pin(14, Pin.IN, Pin.PULL_DOWN) +touch_sel = Pin(27, Pin.IN, Pin.PULL_DOWN) # ================= UTILS ================= def wifi_connect(): @@ -2298,7 +2303,7 @@ class SSD1306_SPI(SSD1306): { id: 'w-oled-scl', start: { componentId: 'esp32', pinName: '22' }, end: { componentId: 'oled1', pinName: 'CLK' }, color: '#ff8800' }, // Buttons — HIGH-when-pressed (one side to 3V3, other to GPIO). Code // reads pin.value() == 1 on press, so they sit between 3.3V and the - // input pin. Add Pin.PULL_DOWN in MicroPython if the pin floats. + // input pin, with Pin.PULL_DOWN in the sketch so the open state reads 0. { id: 'w-btn-next-3v3', start: { componentId: 'esp32', pinName: '3V3' }, end: { componentId: 'btn-next', pinName: '1.l' }, color: '#ff4444' }, { id: 'w-btn-next-gpio', start: { componentId: 'btn-next', pinName: '2.l' }, end: { componentId: 'esp32', pinName: '14' }, color: '#aa66ff' }, { id: 'w-btn-sel-3v3', start: { componentId: 'esp32', pinName: '3V3' }, end: { componentId: 'btn-sel', pinName: '1.l' }, color: '#ff4444' }, diff --git a/frontend/src/data/examples.ts b/frontend/src/data/examples.ts index cf6c12b3..a477196b 100644 --- a/frontend/src/data/examples.ts +++ b/frontend/src/data/examples.ts @@ -153,10 +153,30 @@ void loop() { code: '', components: [{ type: 'velxio-ssd1306-i2c-4pin', id: 'oled', x: 470, y: 100, properties: {} }], wires: [ - { id: 'w-vcc', start: { componentId: 'arduino-uno', pinName: '5V' }, end: { componentId: 'oled', pinName: 'VCC' }, color: '#ff4444' }, - { id: 'w-gnd', start: { componentId: 'arduino-uno', pinName: 'GND.2' }, end: { componentId: 'oled', pinName: 'GND' }, color: '#000000' }, - { id: 'w-sda', start: { componentId: 'arduino-uno', pinName: 'A4' }, end: { componentId: 'oled', pinName: 'SDA' }, color: '#22aaff' }, - { id: 'w-scl', start: { componentId: 'arduino-uno', pinName: 'A5' }, end: { componentId: 'oled', pinName: 'SCL' }, color: '#ff8800' }, + { + id: 'w-vcc', + start: { componentId: 'arduino-uno', pinName: '5V' }, + end: { componentId: 'oled', pinName: 'VCC' }, + color: '#ff4444', + }, + { + id: 'w-gnd', + start: { componentId: 'arduino-uno', pinName: 'GND.2' }, + end: { componentId: 'oled', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'w-sda', + start: { componentId: 'arduino-uno', pinName: 'A4' }, + end: { componentId: 'oled', pinName: 'SDA' }, + color: '#22aaff', + }, + { + id: 'w-scl', + start: { componentId: 'arduino-uno', pinName: 'A5' }, + end: { componentId: 'oled', pinName: 'SCL' }, + color: '#ff8800', + }, ], }, { @@ -212,10 +232,30 @@ void loop() { code: '', components: [{ type: 'velxio-ssd1306-i2c-4pin', id: 'oled', x: 470, y: 100, properties: {} }], wires: [ - { id: 'w-vcc', start: { componentId: 'esp32', pinName: '3V3' }, end: { componentId: 'oled', pinName: 'VCC' }, color: '#ff4444' }, - { id: 'w-gnd', start: { componentId: 'esp32', pinName: 'GND' }, end: { componentId: 'oled', pinName: 'GND' }, color: '#000000' }, - { id: 'w-sda', start: { componentId: 'esp32', pinName: '21' }, end: { componentId: 'oled', pinName: 'SDA' }, color: '#22aaff' }, - { id: 'w-scl', start: { componentId: 'esp32', pinName: '22' }, end: { componentId: 'oled', pinName: 'SCL' }, color: '#ff8800' }, + { + id: 'w-vcc', + start: { componentId: 'esp32', pinName: '3V3' }, + end: { componentId: 'oled', pinName: 'VCC' }, + color: '#ff4444', + }, + { + id: 'w-gnd', + start: { componentId: 'esp32', pinName: 'GND' }, + end: { componentId: 'oled', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'w-sda', + start: { componentId: 'esp32', pinName: '21' }, + end: { componentId: 'oled', pinName: 'SDA' }, + color: '#22aaff', + }, + { + id: 'w-scl', + start: { componentId: 'esp32', pinName: '22' }, + end: { componentId: 'oled', pinName: 'SCL' }, + color: '#ff8800', + }, ], }, // ── Pure ESP-IDF (issue #139): user app_main(), no Arduino core. ── @@ -268,9 +308,24 @@ void app_main(void) { type: 'wokwi-led', id: 'led-ext', x: 470, y: 100, properties: { color: 'red' } }, ], wires: [ - { id: 'w-gpio2-r', start: { componentId: 'esp32', pinName: '2' }, end: { componentId: 'r-led', pinName: '1' }, color: '#e74c3c' }, - { id: 'w-r-led', start: { componentId: 'r-led', pinName: '2' }, end: { componentId: 'led-ext', pinName: 'A' }, color: '#e74c3c' }, - { id: 'w-gnd', start: { componentId: 'led-ext', pinName: 'C' }, end: { componentId: 'esp32', pinName: 'GND' }, color: '#2c3e50' }, + { + id: 'w-gpio2-r', + start: { componentId: 'esp32', pinName: '2' }, + end: { componentId: 'r-led', pinName: '1' }, + color: '#e74c3c', + }, + { + id: 'w-r-led', + start: { componentId: 'r-led', pinName: '2' }, + end: { componentId: 'led-ext', pinName: 'A' }, + color: '#e74c3c', + }, + { + id: 'w-gnd', + start: { componentId: 'led-ext', pinName: 'C' }, + end: { componentId: 'esp32', pinName: 'GND' }, + color: '#2c3e50', + }, ], }, { @@ -329,10 +384,30 @@ void loop() { code: '', components: [{ type: 'velxio-ssd1306-i2c-4pin', id: 'oled', x: 470, y: 100, properties: {} }], wires: [ - { id: 'w-vcc', start: { componentId: 'raspberry-pi-pico', pinName: '3V3' }, end: { componentId: 'oled', pinName: 'VCC' }, color: '#ff4444' }, - { id: 'w-gnd', start: { componentId: 'raspberry-pi-pico', pinName: 'GND.3' }, end: { componentId: 'oled', pinName: 'GND' }, color: '#000000' }, - { id: 'w-sda', start: { componentId: 'raspberry-pi-pico', pinName: 'GP4' }, end: { componentId: 'oled', pinName: 'SDA' }, color: '#22aaff' }, - { id: 'w-scl', start: { componentId: 'raspberry-pi-pico', pinName: 'GP5' }, end: { componentId: 'oled', pinName: 'SCL' }, color: '#ff8800' }, + { + id: 'w-vcc', + start: { componentId: 'raspberry-pi-pico', pinName: '3V3' }, + end: { componentId: 'oled', pinName: 'VCC' }, + color: '#ff4444', + }, + { + id: 'w-gnd', + start: { componentId: 'raspberry-pi-pico', pinName: 'GND.3' }, + end: { componentId: 'oled', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'w-sda', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP4' }, + end: { componentId: 'oled', pinName: 'SDA' }, + color: '#22aaff', + }, + { + id: 'w-scl', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP5' }, + end: { componentId: 'oled', pinName: 'SCL' }, + color: '#ff8800', + }, ], }, { @@ -389,10 +464,30 @@ void loop() { code: '', components: [{ type: 'velxio-ssd1306-i2c-4pin', id: 'oled', x: 470, y: 100, properties: {} }], wires: [ - { id: 'w-vcc', start: { componentId: 'stm32-bluepill', pinName: '3V3' }, end: { componentId: 'oled', pinName: 'VCC' }, color: '#ff4444' }, - { id: 'w-gnd', start: { componentId: 'stm32-bluepill', pinName: 'GND' }, end: { componentId: 'oled', pinName: 'GND' }, color: '#000000' }, - { id: 'w-sda', start: { componentId: 'stm32-bluepill', pinName: 'PB7' }, end: { componentId: 'oled', pinName: 'SDA' }, color: '#22aaff' }, - { id: 'w-scl', start: { componentId: 'stm32-bluepill', pinName: 'PB6' }, end: { componentId: 'oled', pinName: 'SCL' }, color: '#ff8800' }, + { + id: 'w-vcc', + start: { componentId: 'stm32-bluepill', pinName: '3V3' }, + end: { componentId: 'oled', pinName: 'VCC' }, + color: '#ff4444', + }, + { + id: 'w-gnd', + start: { componentId: 'stm32-bluepill', pinName: 'GND' }, + end: { componentId: 'oled', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'w-sda', + start: { componentId: 'stm32-bluepill', pinName: 'PB7' }, + end: { componentId: 'oled', pinName: 'SDA' }, + color: '#22aaff', + }, + { + id: 'w-scl', + start: { componentId: 'stm32-bluepill', pinName: 'PB6' }, + end: { componentId: 'oled', pinName: 'SCL' }, + color: '#ff8800', + }, ], }, { @@ -442,15 +537,38 @@ void loop() { delay(200); // simple debounce } }`, - components: [ - { type: 'wokwi-ky-040', id: 'enc1', x: 360, y: 90, properties: {} }, - ], + components: [{ type: 'wokwi-ky-040', id: 'enc1', x: 360, y: 90, properties: {} }], wires: [ - { id: 'w-enc-clk', start: { componentId: 'enc1', pinName: 'CLK' }, end: { componentId: 'arduino-uno', pinName: '2' }, color: '#f59e0b' }, - { id: 'w-enc-dt', start: { componentId: 'enc1', pinName: 'DT' }, end: { componentId: 'arduino-uno', pinName: '3' }, color: '#10b981' }, - { id: 'w-enc-sw', start: { componentId: 'enc1', pinName: 'SW' }, end: { componentId: 'arduino-uno', pinName: '4' }, color: '#3b82f6' }, - { id: 'w-enc-vcc', start: { componentId: 'enc1', pinName: 'VCC' }, end: { componentId: 'arduino-uno', pinName: '5V' }, color: '#ef4444' }, - { id: 'w-enc-gnd', start: { componentId: 'enc1', pinName: 'GND' }, end: { componentId: 'arduino-uno', pinName: 'GND' }, color: '#1f2937' }, + { + id: 'w-enc-clk', + start: { componentId: 'enc1', pinName: 'CLK' }, + end: { componentId: 'arduino-uno', pinName: '2' }, + color: '#f59e0b', + }, + { + id: 'w-enc-dt', + start: { componentId: 'enc1', pinName: 'DT' }, + end: { componentId: 'arduino-uno', pinName: '3' }, + color: '#10b981', + }, + { + id: 'w-enc-sw', + start: { componentId: 'enc1', pinName: 'SW' }, + end: { componentId: 'arduino-uno', pinName: '4' }, + color: '#3b82f6', + }, + { + id: 'w-enc-vcc', + start: { componentId: 'enc1', pinName: 'VCC' }, + end: { componentId: 'arduino-uno', pinName: '5V' }, + color: '#ef4444', + }, + { + id: 'w-enc-gnd', + start: { componentId: 'enc1', pinName: 'GND' }, + end: { componentId: 'arduino-uno', pinName: 'GND' }, + color: '#1f2937', + }, ], tags: ['rotary', 'encoder', 'ky-040', 'input', 'knob', 'arduino'], }, @@ -1273,14 +1391,32 @@ void loop() { }, ], code: '', - components: [ - { type: 'wokwi-mpu6050', id: 'mpu1', x: 460, y: 150, properties: {} }, - ], + components: [{ type: 'wokwi-mpu6050', id: 'mpu1', x: 460, y: 150, properties: {} }], wires: [ - { id: 'mpu-vcc', start: { componentId: 'stm32-bluepill', pinName: '3V3' }, end: { componentId: 'mpu1', pinName: 'VCC' }, color: '#ff4444' }, - { id: 'mpu-gnd', start: { componentId: 'stm32-bluepill', pinName: 'GND' }, end: { componentId: 'mpu1', pinName: 'GND' }, color: '#000000' }, - { id: 'mpu-sda', start: { componentId: 'stm32-bluepill', pinName: 'PB7' }, end: { componentId: 'mpu1', pinName: 'SDA' }, color: '#22aaff' }, - { id: 'mpu-scl', start: { componentId: 'stm32-bluepill', pinName: 'PB6' }, end: { componentId: 'mpu1', pinName: 'SCL' }, color: '#ff8800' }, + { + id: 'mpu-vcc', + start: { componentId: 'stm32-bluepill', pinName: '3V3' }, + end: { componentId: 'mpu1', pinName: 'VCC' }, + color: '#ff4444', + }, + { + id: 'mpu-gnd', + start: { componentId: 'stm32-bluepill', pinName: 'GND' }, + end: { componentId: 'mpu1', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'mpu-sda', + start: { componentId: 'stm32-bluepill', pinName: 'PB7' }, + end: { componentId: 'mpu1', pinName: 'SDA' }, + color: '#22aaff', + }, + { + id: 'mpu-scl', + start: { componentId: 'stm32-bluepill', pinName: 'PB6' }, + end: { componentId: 'mpu1', pinName: 'SCL' }, + color: '#ff8800', + }, ], tags: ['stm32', 'blue pill', 'i2c', 'mpu6050', 'imu', 'sensor', 'qemu'], }, @@ -1330,14 +1466,32 @@ void loop() { }, ], code: '', - components: [ - { type: 'wokwi-ds1307', id: 'rtc1', x: 460, y: 150, properties: {} }, - ], + components: [{ type: 'wokwi-ds1307', id: 'rtc1', x: 460, y: 150, properties: {} }], wires: [ - { id: 'rtc-vcc', start: { componentId: 'stm32-bluepill', pinName: '3V3' }, end: { componentId: 'rtc1', pinName: 'VCC' }, color: '#ff4444' }, - { id: 'rtc-gnd', start: { componentId: 'stm32-bluepill', pinName: 'GND' }, end: { componentId: 'rtc1', pinName: 'GND' }, color: '#000000' }, - { id: 'rtc-sda', start: { componentId: 'stm32-bluepill', pinName: 'PB7' }, end: { componentId: 'rtc1', pinName: 'SDA' }, color: '#22aaff' }, - { id: 'rtc-scl', start: { componentId: 'stm32-bluepill', pinName: 'PB6' }, end: { componentId: 'rtc1', pinName: 'SCL' }, color: '#ff8800' }, + { + id: 'rtc-vcc', + start: { componentId: 'stm32-bluepill', pinName: '3V3' }, + end: { componentId: 'rtc1', pinName: 'VCC' }, + color: '#ff4444', + }, + { + id: 'rtc-gnd', + start: { componentId: 'stm32-bluepill', pinName: 'GND' }, + end: { componentId: 'rtc1', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'rtc-sda', + start: { componentId: 'stm32-bluepill', pinName: 'PB7' }, + end: { componentId: 'rtc1', pinName: 'SDA' }, + color: '#22aaff', + }, + { + id: 'rtc-scl', + start: { componentId: 'stm32-bluepill', pinName: 'PB6' }, + end: { componentId: 'rtc1', pinName: 'SCL' }, + color: '#ff8800', + }, ], tags: ['stm32', 'blue pill', 'i2c', 'ds1307', 'rtc', 'clock', 'qemu'], }, @@ -1395,10 +1549,30 @@ void loop() { code: '', components: [{ type: 'wokwi-ssd1306', id: 'bpoled1', x: 460, y: 120, properties: {} }], wires: [ - { id: 'bpo-vcc', start: { componentId: 'stm32-blackpill', pinName: '3V3' }, end: { componentId: 'bpoled1', pinName: 'VIN' }, color: '#ff4444' }, - { id: 'bpo-gnd', start: { componentId: 'stm32-blackpill', pinName: 'GND' }, end: { componentId: 'bpoled1', pinName: 'GND' }, color: '#000000' }, - { id: 'bpo-sda', start: { componentId: 'stm32-blackpill', pinName: 'PB7' }, end: { componentId: 'bpoled1', pinName: 'DATA' }, color: '#22aaff' }, - { id: 'bpo-scl', start: { componentId: 'stm32-blackpill', pinName: 'PB6' }, end: { componentId: 'bpoled1', pinName: 'CLK' }, color: '#ff8800' }, + { + id: 'bpo-vcc', + start: { componentId: 'stm32-blackpill', pinName: '3V3' }, + end: { componentId: 'bpoled1', pinName: 'VIN' }, + color: '#ff4444', + }, + { + id: 'bpo-gnd', + start: { componentId: 'stm32-blackpill', pinName: 'GND' }, + end: { componentId: 'bpoled1', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'bpo-sda', + start: { componentId: 'stm32-blackpill', pinName: 'PB7' }, + end: { componentId: 'bpoled1', pinName: 'DATA' }, + color: '#22aaff', + }, + { + id: 'bpo-scl', + start: { componentId: 'stm32-blackpill', pinName: 'PB6' }, + end: { componentId: 'bpoled1', pinName: 'CLK' }, + color: '#ff8800', + }, ], tags: ['stm32', 'black pill', 'f411', 'i2c', 'ssd1306', 'oled', 'qemu'], }, @@ -1407,7 +1581,12 @@ void loop() { title: 'STM32: Weather Station (BMP280 + OLED)', description: 'A complete I2C dashboard on the STM32 Blue Pill: read temperature and pressure from a BMP280 and render them live on an SSD1306 OLED, both sharing the same I2C1 bus (BMP280 0x76, OLED 0x3C, SCL=PB6/SDA=PB7). Exercises I2C read and write on one bus.', - libraries: ['Adafruit BMP280 Library', 'Adafruit Unified Sensor', 'Adafruit SSD1306', 'Adafruit GFX Library'], + libraries: [ + 'Adafruit BMP280 Library', + 'Adafruit Unified Sensor', + 'Adafruit SSD1306', + 'Adafruit GFX Library', + ], category: 'sensors', difficulty: 'intermediate', boardFilter: 'stm32-bluepill', @@ -1454,18 +1633,64 @@ void loop() { ], code: '', components: [ - { type: 'velxio-bmp280', id: 'wbmp1', x: 470, y: 80, properties: { temperature: '23.5', pressure: '1011.2' } }, + { + type: 'velxio-bmp280', + id: 'wbmp1', + x: 470, + y: 80, + properties: { temperature: '23.5', pressure: '1011.2' }, + }, { type: 'wokwi-ssd1306', id: 'woled1', x: 470, y: 250, properties: {} }, ], wires: [ - { id: 'w-bmp-vcc', start: { componentId: 'stm32-bluepill', pinName: '3V3' }, end: { componentId: 'wbmp1', pinName: 'VCC' }, color: '#ff4444' }, - { id: 'w-bmp-gnd', start: { componentId: 'stm32-bluepill', pinName: 'GND' }, end: { componentId: 'wbmp1', pinName: 'GND' }, color: '#000000' }, - { id: 'w-bmp-sda', start: { componentId: 'stm32-bluepill', pinName: 'PB7' }, end: { componentId: 'wbmp1', pinName: 'SDA' }, color: '#22aaff' }, - { id: 'w-bmp-scl', start: { componentId: 'stm32-bluepill', pinName: 'PB6' }, end: { componentId: 'wbmp1', pinName: 'SCL' }, color: '#ff8800' }, - { id: 'w-oled-vcc', start: { componentId: 'wbmp1', pinName: 'VCC' }, end: { componentId: 'woled1', pinName: 'VIN' }, color: '#ff4444' }, - { id: 'w-oled-gnd', start: { componentId: 'wbmp1', pinName: 'GND' }, end: { componentId: 'woled1', pinName: 'GND' }, color: '#000000' }, - { id: 'w-oled-sda', start: { componentId: 'wbmp1', pinName: 'SDA' }, end: { componentId: 'woled1', pinName: 'DATA' }, color: '#22aaff' }, - { id: 'w-oled-scl', start: { componentId: 'wbmp1', pinName: 'SCL' }, end: { componentId: 'woled1', pinName: 'CLK' }, color: '#ff8800' }, + { + id: 'w-bmp-vcc', + start: { componentId: 'stm32-bluepill', pinName: '3V3' }, + end: { componentId: 'wbmp1', pinName: 'VCC' }, + color: '#ff4444', + }, + { + id: 'w-bmp-gnd', + start: { componentId: 'stm32-bluepill', pinName: 'GND' }, + end: { componentId: 'wbmp1', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'w-bmp-sda', + start: { componentId: 'stm32-bluepill', pinName: 'PB7' }, + end: { componentId: 'wbmp1', pinName: 'SDA' }, + color: '#22aaff', + }, + { + id: 'w-bmp-scl', + start: { componentId: 'stm32-bluepill', pinName: 'PB6' }, + end: { componentId: 'wbmp1', pinName: 'SCL' }, + color: '#ff8800', + }, + { + id: 'w-oled-vcc', + start: { componentId: 'wbmp1', pinName: 'VCC' }, + end: { componentId: 'woled1', pinName: 'VIN' }, + color: '#ff4444', + }, + { + id: 'w-oled-gnd', + start: { componentId: 'wbmp1', pinName: 'GND' }, + end: { componentId: 'woled1', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'w-oled-sda', + start: { componentId: 'wbmp1', pinName: 'SDA' }, + end: { componentId: 'woled1', pinName: 'DATA' }, + color: '#22aaff', + }, + { + id: 'w-oled-scl', + start: { componentId: 'wbmp1', pinName: 'SCL' }, + end: { componentId: 'woled1', pinName: 'CLK' }, + color: '#ff8800', + }, ], tags: ['stm32', 'blue pill', 'i2c', 'bmp280', 'ssd1306', 'weather', 'dashboard', 'qemu'], }, @@ -1510,14 +1735,54 @@ void loop() { { type: 'wokwi-7segment', id: 'seg1', x: 470, y: 140, properties: { common: 'cathode' } }, ], wires: [ - { id: 's-a', start: { componentId: 'stm32-bluepill', pinName: 'PA0' }, end: { componentId: 'seg1', pinName: 'A' }, color: '#ff5555' }, - { id: 's-b', start: { componentId: 'stm32-bluepill', pinName: 'PA1' }, end: { componentId: 'seg1', pinName: 'B' }, color: '#ff9955' }, - { id: 's-c', start: { componentId: 'stm32-bluepill', pinName: 'PA2' }, end: { componentId: 'seg1', pinName: 'C' }, color: '#ffdd55' }, - { id: 's-d', start: { componentId: 'stm32-bluepill', pinName: 'PA3' }, end: { componentId: 'seg1', pinName: 'D' }, color: '#88dd55' }, - { id: 's-e', start: { componentId: 'stm32-bluepill', pinName: 'PA4' }, end: { componentId: 'seg1', pinName: 'E' }, color: '#55ddcc' }, - { id: 's-f', start: { componentId: 'stm32-bluepill', pinName: 'PA5' }, end: { componentId: 'seg1', pinName: 'F' }, color: '#5599ff' }, - { id: 's-g', start: { componentId: 'stm32-bluepill', pinName: 'PA6' }, end: { componentId: 'seg1', pinName: 'G' }, color: '#aa77ff' }, - { id: 's-com', start: { componentId: 'stm32-bluepill', pinName: 'GND' }, end: { componentId: 'seg1', pinName: 'COM' }, color: '#000000' }, + { + id: 's-a', + start: { componentId: 'stm32-bluepill', pinName: 'PA0' }, + end: { componentId: 'seg1', pinName: 'A' }, + color: '#ff5555', + }, + { + id: 's-b', + start: { componentId: 'stm32-bluepill', pinName: 'PA1' }, + end: { componentId: 'seg1', pinName: 'B' }, + color: '#ff9955', + }, + { + id: 's-c', + start: { componentId: 'stm32-bluepill', pinName: 'PA2' }, + end: { componentId: 'seg1', pinName: 'C' }, + color: '#ffdd55', + }, + { + id: 's-d', + start: { componentId: 'stm32-bluepill', pinName: 'PA3' }, + end: { componentId: 'seg1', pinName: 'D' }, + color: '#88dd55', + }, + { + id: 's-e', + start: { componentId: 'stm32-bluepill', pinName: 'PA4' }, + end: { componentId: 'seg1', pinName: 'E' }, + color: '#55ddcc', + }, + { + id: 's-f', + start: { componentId: 'stm32-bluepill', pinName: 'PA5' }, + end: { componentId: 'seg1', pinName: 'F' }, + color: '#5599ff', + }, + { + id: 's-g', + start: { componentId: 'stm32-bluepill', pinName: 'PA6' }, + end: { componentId: 'seg1', pinName: 'G' }, + color: '#aa77ff', + }, + { + id: 's-com', + start: { componentId: 'stm32-bluepill', pinName: 'GND' }, + end: { componentId: 'seg1', pinName: 'COM' }, + color: '#000000', + }, ], tags: ['stm32', 'blue pill', 'gpio', '7-segment', 'display', 'counter'], }, @@ -1560,14 +1825,32 @@ void loop() { }, ], code: '', - components: [ - { type: 'wokwi-rgb-led', id: 'rgb1', x: 470, y: 150, properties: {} }, - ], + components: [{ type: 'wokwi-rgb-led', id: 'rgb1', x: 470, y: 150, properties: {} }], wires: [ - { id: 'rgb-r', start: { componentId: 'stm32-bluepill', pinName: 'PA0' }, end: { componentId: 'rgb1', pinName: 'R' }, color: '#ff3333' }, - { id: 'rgb-g', start: { componentId: 'stm32-bluepill', pinName: 'PA1' }, end: { componentId: 'rgb1', pinName: 'G' }, color: '#33cc33' }, - { id: 'rgb-b', start: { componentId: 'stm32-bluepill', pinName: 'PA2' }, end: { componentId: 'rgb1', pinName: 'B' }, color: '#3366ff' }, - { id: 'rgb-com', start: { componentId: 'stm32-bluepill', pinName: 'GND' }, end: { componentId: 'rgb1', pinName: 'COM' }, color: '#000000' }, + { + id: 'rgb-r', + start: { componentId: 'stm32-bluepill', pinName: 'PA0' }, + end: { componentId: 'rgb1', pinName: 'R' }, + color: '#ff3333', + }, + { + id: 'rgb-g', + start: { componentId: 'stm32-bluepill', pinName: 'PA1' }, + end: { componentId: 'rgb1', pinName: 'G' }, + color: '#33cc33', + }, + { + id: 'rgb-b', + start: { componentId: 'stm32-bluepill', pinName: 'PA2' }, + end: { componentId: 'rgb1', pinName: 'B' }, + color: '#3366ff', + }, + { + id: 'rgb-com', + start: { componentId: 'stm32-bluepill', pinName: 'GND' }, + end: { componentId: 'rgb1', pinName: 'COM' }, + color: '#000000', + }, ], tags: ['stm32', 'blue pill', 'gpio', 'rgb-led', 'led'], }, @@ -1614,8 +1897,18 @@ void loop() { { type: 'wokwi-pushbutton', id: 'btn1', x: 470, y: 160, properties: { color: 'green' } }, ], wires: [ - { id: 'btn-sig', start: { componentId: 'stm32-bluepill', pinName: 'PA0' }, end: { componentId: 'btn1', pinName: '1.l' }, color: '#22aaff' }, - { id: 'btn-gnd', start: { componentId: 'stm32-bluepill', pinName: 'GND' }, end: { componentId: 'btn1', pinName: '2.l' }, color: '#000000' }, + { + id: 'btn-sig', + start: { componentId: 'stm32-bluepill', pinName: 'PA0' }, + end: { componentId: 'btn1', pinName: '1.l' }, + color: '#22aaff', + }, + { + id: 'btn-gnd', + start: { componentId: 'stm32-bluepill', pinName: 'GND' }, + end: { componentId: 'btn1', pinName: '2.l' }, + color: '#000000', + }, ], tags: ['stm32', 'blue pill', 'gpio', 'button', 'input', 'pushbutton'], }, @@ -1657,13 +1950,26 @@ void loop() { }, ], code: '', - components: [ - { type: 'wokwi-slide-switch', id: 'sw1', x: 470, y: 160, properties: {} }, - ], + components: [{ type: 'wokwi-slide-switch', id: 'sw1', x: 470, y: 160, properties: {} }], wires: [ - { id: 'sw-sig', start: { componentId: 'stm32-bluepill', pinName: 'PA0' }, end: { componentId: 'sw1', pinName: '2' }, color: '#22aaff' }, - { id: 'sw-gnd', start: { componentId: 'stm32-bluepill', pinName: 'GND' }, end: { componentId: 'sw1', pinName: '1' }, color: '#000000' }, - { id: 'sw-vcc', start: { componentId: 'stm32-bluepill', pinName: '3V3' }, end: { componentId: 'sw1', pinName: '3' }, color: '#ff4444' }, + { + id: 'sw-sig', + start: { componentId: 'stm32-bluepill', pinName: 'PA0' }, + end: { componentId: 'sw1', pinName: '2' }, + color: '#22aaff', + }, + { + id: 'sw-gnd', + start: { componentId: 'stm32-bluepill', pinName: 'GND' }, + end: { componentId: 'sw1', pinName: '1' }, + color: '#000000', + }, + { + id: 'sw-vcc', + start: { componentId: 'stm32-bluepill', pinName: '3V3' }, + end: { componentId: 'sw1', pinName: '3' }, + color: '#ff4444', + }, ], tags: ['stm32', 'blue pill', 'gpio', 'switch', 'input', 'slide-switch'], }, @@ -1710,14 +2016,32 @@ void loop() { }, ], code: '', - components: [ - { type: 'wokwi-stepper-motor', id: 'stp1', x: 470, y: 150, properties: {} }, - ], + components: [{ type: 'wokwi-stepper-motor', id: 'stp1', x: 470, y: 150, properties: {} }], wires: [ - { id: 'stp-ap', start: { componentId: 'stm32-bluepill', pinName: 'PA0' }, end: { componentId: 'stp1', pinName: 'A+' }, color: '#ff5555' }, - { id: 'stp-an', start: { componentId: 'stm32-bluepill', pinName: 'PA1' }, end: { componentId: 'stp1', pinName: 'A-' }, color: '#ff9955' }, - { id: 'stp-bp', start: { componentId: 'stm32-bluepill', pinName: 'PA2' }, end: { componentId: 'stp1', pinName: 'B+' }, color: '#55aaff' }, - { id: 'stp-bn', start: { componentId: 'stm32-bluepill', pinName: 'PA3' }, end: { componentId: 'stp1', pinName: 'B-' }, color: '#aa77ff' }, + { + id: 'stp-ap', + start: { componentId: 'stm32-bluepill', pinName: 'PA0' }, + end: { componentId: 'stp1', pinName: 'A+' }, + color: '#ff5555', + }, + { + id: 'stp-an', + start: { componentId: 'stm32-bluepill', pinName: 'PA1' }, + end: { componentId: 'stp1', pinName: 'A-' }, + color: '#ff9955', + }, + { + id: 'stp-bp', + start: { componentId: 'stm32-bluepill', pinName: 'PA2' }, + end: { componentId: 'stp1', pinName: 'B+' }, + color: '#55aaff', + }, + { + id: 'stp-bn', + start: { componentId: 'stm32-bluepill', pinName: 'PA3' }, + end: { componentId: 'stp1', pinName: 'B-' }, + color: '#aa77ff', + }, ], tags: ['stm32', 'blue pill', 'gpio', 'stepper', 'motor'], }, @@ -1760,12 +2084,42 @@ void loop() { { type: 'wokwi-stepper-motor', id: 'stp1', x: 560, y: 120, properties: {} }, ], wires: [ - { id: 'u-step', start: { componentId: 'arduino-uno', pinName: '3' }, end: { componentId: 'drv1', pinName: 'STEP' }, color: '#f59e0b' }, - { id: 'u-dir', start: { componentId: 'arduino-uno', pinName: '4' }, end: { componentId: 'drv1', pinName: 'DIR' }, color: '#10b981' }, - { id: 'u-1a', start: { componentId: 'drv1', pinName: '1A' }, end: { componentId: 'stp1', pinName: 'B+' }, color: '#ff5555' }, - { id: 'u-1b', start: { componentId: 'drv1', pinName: '1B' }, end: { componentId: 'stp1', pinName: 'B-' }, color: '#ff9955' }, - { id: 'u-2a', start: { componentId: 'drv1', pinName: '2A' }, end: { componentId: 'stp1', pinName: 'A+' }, color: '#55aaff' }, - { id: 'u-2b', start: { componentId: 'drv1', pinName: '2B' }, end: { componentId: 'stp1', pinName: 'A-' }, color: '#aa77ff' }, + { + id: 'u-step', + start: { componentId: 'arduino-uno', pinName: '3' }, + end: { componentId: 'drv1', pinName: 'STEP' }, + color: '#f59e0b', + }, + { + id: 'u-dir', + start: { componentId: 'arduino-uno', pinName: '4' }, + end: { componentId: 'drv1', pinName: 'DIR' }, + color: '#10b981', + }, + { + id: 'u-1a', + start: { componentId: 'drv1', pinName: '1A' }, + end: { componentId: 'stp1', pinName: 'B+' }, + color: '#ff5555', + }, + { + id: 'u-1b', + start: { componentId: 'drv1', pinName: '1B' }, + end: { componentId: 'stp1', pinName: 'B-' }, + color: '#ff9955', + }, + { + id: 'u-2a', + start: { componentId: 'drv1', pinName: '2A' }, + end: { componentId: 'stp1', pinName: 'A+' }, + color: '#55aaff', + }, + { + id: 'u-2b', + start: { componentId: 'drv1', pinName: '2B' }, + end: { componentId: 'stp1', pinName: 'A-' }, + color: '#aa77ff', + }, ], tags: ['arduino', 'uno', 'stepper', 'motor', 'a4988', 'driver'], }, @@ -1808,12 +2162,42 @@ void loop() { { type: 'wokwi-stepper-motor', id: 'stp1', x: 560, y: 120, properties: {} }, ], wires: [ - { id: 'e-step', start: { componentId: 'esp32', pinName: '26' }, end: { componentId: 'drv1', pinName: 'STEP' }, color: '#f59e0b' }, - { id: 'e-dir', start: { componentId: 'esp32', pinName: '27' }, end: { componentId: 'drv1', pinName: 'DIR' }, color: '#10b981' }, - { id: 'e-1a', start: { componentId: 'drv1', pinName: '1A' }, end: { componentId: 'stp1', pinName: 'B+' }, color: '#ff5555' }, - { id: 'e-1b', start: { componentId: 'drv1', pinName: '1B' }, end: { componentId: 'stp1', pinName: 'B-' }, color: '#ff9955' }, - { id: 'e-2a', start: { componentId: 'drv1', pinName: '2A' }, end: { componentId: 'stp1', pinName: 'A+' }, color: '#55aaff' }, - { id: 'e-2b', start: { componentId: 'drv1', pinName: '2B' }, end: { componentId: 'stp1', pinName: 'A-' }, color: '#aa77ff' }, + { + id: 'e-step', + start: { componentId: 'esp32', pinName: '26' }, + end: { componentId: 'drv1', pinName: 'STEP' }, + color: '#f59e0b', + }, + { + id: 'e-dir', + start: { componentId: 'esp32', pinName: '27' }, + end: { componentId: 'drv1', pinName: 'DIR' }, + color: '#10b981', + }, + { + id: 'e-1a', + start: { componentId: 'drv1', pinName: '1A' }, + end: { componentId: 'stp1', pinName: 'B+' }, + color: '#ff5555', + }, + { + id: 'e-1b', + start: { componentId: 'drv1', pinName: '1B' }, + end: { componentId: 'stp1', pinName: 'B-' }, + color: '#ff9955', + }, + { + id: 'e-2a', + start: { componentId: 'drv1', pinName: '2A' }, + end: { componentId: 'stp1', pinName: 'A+' }, + color: '#55aaff', + }, + { + id: 'e-2b', + start: { componentId: 'drv1', pinName: '2B' }, + end: { componentId: 'stp1', pinName: 'A-' }, + color: '#aa77ff', + }, ], tags: ['esp32', 'stepper', 'motor', 'a4988', 'driver'], }, @@ -1856,12 +2240,42 @@ void loop() { { type: 'wokwi-stepper-motor', id: 'stp1', x: 560, y: 120, properties: {} }, ], wires: [ - { id: 'p-step', start: { componentId: 'raspberry-pi-pico', pinName: 'GP3' }, end: { componentId: 'drv1', pinName: 'STEP' }, color: '#f59e0b' }, - { id: 'p-dir', start: { componentId: 'raspberry-pi-pico', pinName: 'GP4' }, end: { componentId: 'drv1', pinName: 'DIR' }, color: '#10b981' }, - { id: 'p-1a', start: { componentId: 'drv1', pinName: '1A' }, end: { componentId: 'stp1', pinName: 'B+' }, color: '#ff5555' }, - { id: 'p-1b', start: { componentId: 'drv1', pinName: '1B' }, end: { componentId: 'stp1', pinName: 'B-' }, color: '#ff9955' }, - { id: 'p-2a', start: { componentId: 'drv1', pinName: '2A' }, end: { componentId: 'stp1', pinName: 'A+' }, color: '#55aaff' }, - { id: 'p-2b', start: { componentId: 'drv1', pinName: '2B' }, end: { componentId: 'stp1', pinName: 'A-' }, color: '#aa77ff' }, + { + id: 'p-step', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP3' }, + end: { componentId: 'drv1', pinName: 'STEP' }, + color: '#f59e0b', + }, + { + id: 'p-dir', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP4' }, + end: { componentId: 'drv1', pinName: 'DIR' }, + color: '#10b981', + }, + { + id: 'p-1a', + start: { componentId: 'drv1', pinName: '1A' }, + end: { componentId: 'stp1', pinName: 'B+' }, + color: '#ff5555', + }, + { + id: 'p-1b', + start: { componentId: 'drv1', pinName: '1B' }, + end: { componentId: 'stp1', pinName: 'B-' }, + color: '#ff9955', + }, + { + id: 'p-2a', + start: { componentId: 'drv1', pinName: '2A' }, + end: { componentId: 'stp1', pinName: 'A+' }, + color: '#55aaff', + }, + { + id: 'p-2b', + start: { componentId: 'drv1', pinName: '2B' }, + end: { componentId: 'stp1', pinName: 'A-' }, + color: '#aa77ff', + }, ], tags: ['raspberry pi pico', 'rp2040', 'stepper', 'motor', 'a4988', 'driver'], }, @@ -2858,37 +3272,146 @@ void loop() { } `, components: [ - { type: 'wokwi-ili9341', id: 'tft1', x: 460, y: 60, properties: {} }, - { type: 'wokwi-pushbutton', id: 'btn-fwd', x: 220, y: 420, properties: { color: 'red', label: 'FWD' } }, - { type: 'wokwi-pushbutton', id: 'btn-back', x: 220, y: 520, properties: { color: 'blue', label: 'BACK' } }, - { type: 'wokwi-pushbutton', id: 'btn-left', x: 130, y: 470, properties: { color: 'green', label: 'LEFT' } }, - { type: 'wokwi-pushbutton', id: 'btn-right', x: 310, y: 470, properties: { color: 'green', label: 'RIGHT' } }, + { type: 'wokwi-ili9341', id: 'tft1', x: 460, y: 60, properties: {} }, + { + type: 'wokwi-pushbutton', + id: 'btn-fwd', + x: 220, + y: 420, + properties: { color: 'red', label: 'FWD' }, + }, + { + type: 'wokwi-pushbutton', + id: 'btn-back', + x: 220, + y: 520, + properties: { color: 'blue', label: 'BACK' }, + }, + { + type: 'wokwi-pushbutton', + id: 'btn-left', + x: 130, + y: 470, + properties: { color: 'green', label: 'LEFT' }, + }, + { + type: 'wokwi-pushbutton', + id: 'btn-right', + x: 310, + y: 470, + properties: { color: 'green', label: 'RIGHT' }, + }, ], wires: [ // Power - { id: 'w-tft-vcc', start: { componentId: 'raspberry-pi-pico', pinName: '3V3' }, end: { componentId: 'tft1', pinName: 'VCC' }, color: '#ff0000' }, - { id: 'w-tft-gnd', start: { componentId: 'raspberry-pi-pico', pinName: 'GND.5' }, end: { componentId: 'tft1', pinName: 'GND' }, color: '#000000' }, + { + id: 'w-tft-vcc', + start: { componentId: 'raspberry-pi-pico', pinName: '3V3' }, + end: { componentId: 'tft1', pinName: 'VCC' }, + color: '#ff0000', + }, + { + id: 'w-tft-gnd', + start: { componentId: 'raspberry-pi-pico', pinName: 'GND.5' }, + end: { componentId: 'tft1', pinName: 'GND' }, + color: '#000000', + }, // SPI bus + control lines to the ILI9341. MISO is GP16 — the // sketch's 3-arg Adafruit_ILI9341(CS, DC, RST) constructor uses // hardware SPI0, whose MISO pin is GP16. The driver writes only // (no register reads), so MISO is electrically idle, but the // wire is included so the circuit is didactically complete. - { id: 'w-tft-sck', start: { componentId: 'raspberry-pi-pico', pinName: 'GP18' }, end: { componentId: 'tft1', pinName: 'SCK' }, color: '#ff8800' }, - { id: 'w-tft-mosi', start: { componentId: 'raspberry-pi-pico', pinName: 'GP19' }, end: { componentId: 'tft1', pinName: 'MOSI' }, color: '#ff8800' }, - { id: 'w-tft-miso', start: { componentId: 'raspberry-pi-pico', pinName: 'GP16' }, end: { componentId: 'tft1', pinName: 'MISO' }, color: '#ffaa44' }, - { id: 'w-tft-cs', start: { componentId: 'raspberry-pi-pico', pinName: 'GP17' }, end: { componentId: 'tft1', pinName: 'CS' }, color: '#00aaff' }, - { id: 'w-tft-dc', start: { componentId: 'raspberry-pi-pico', pinName: 'GP20' }, end: { componentId: 'tft1', pinName: 'D/C' }, color: '#00cc00' }, - { id: 'w-tft-rst', start: { componentId: 'raspberry-pi-pico', pinName: 'GP21' }, end: { componentId: 'tft1', pinName: 'RST' }, color: '#cc0000' }, - { id: 'w-tft-led', start: { componentId: 'raspberry-pi-pico', pinName: 'GP22' }, end: { componentId: 'tft1', pinName: 'LED' }, color: '#ffffff' }, + { + id: 'w-tft-sck', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP18' }, + end: { componentId: 'tft1', pinName: 'SCK' }, + color: '#ff8800', + }, + { + id: 'w-tft-mosi', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP19' }, + end: { componentId: 'tft1', pinName: 'MOSI' }, + color: '#ff8800', + }, + { + id: 'w-tft-miso', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP16' }, + end: { componentId: 'tft1', pinName: 'MISO' }, + color: '#ffaa44', + }, + { + id: 'w-tft-cs', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP17' }, + end: { componentId: 'tft1', pinName: 'CS' }, + color: '#00aaff', + }, + { + id: 'w-tft-dc', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP20' }, + end: { componentId: 'tft1', pinName: 'D/C' }, + color: '#00cc00', + }, + { + id: 'w-tft-rst', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP21' }, + end: { componentId: 'tft1', pinName: 'RST' }, + color: '#cc0000', + }, + { + id: 'w-tft-led', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP22' }, + end: { componentId: 'tft1', pinName: 'LED' }, + color: '#ffffff', + }, // Buttons signal + GND each - { id: 'w-btn-fwd', start: { componentId: 'raspberry-pi-pico', pinName: 'GP10' }, end: { componentId: 'btn-fwd', pinName: '1.l' }, color: '#ff4444' }, - { id: 'w-btn-back', start: { componentId: 'raspberry-pi-pico', pinName: 'GP11' }, end: { componentId: 'btn-back', pinName: '1.l' }, color: '#4477ff' }, - { id: 'w-btn-left', start: { componentId: 'raspberry-pi-pico', pinName: 'GP12' }, end: { componentId: 'btn-left', pinName: '1.l' }, color: '#44cc44' }, - { id: 'w-btn-right', start: { componentId: 'raspberry-pi-pico', pinName: 'GP13' }, end: { componentId: 'btn-right', pinName: '1.l' }, color: '#cccc44' }, - { id: 'w-gnd-fwd', start: { componentId: 'btn-fwd', pinName: '2.l' }, end: { componentId: 'raspberry-pi-pico', pinName: 'GND.1' }, color: '#000000' }, - { id: 'w-gnd-back', start: { componentId: 'btn-back', pinName: '2.l' }, end: { componentId: 'raspberry-pi-pico', pinName: 'GND.2' }, color: '#000000' }, - { id: 'w-gnd-left', start: { componentId: 'btn-left', pinName: '2.l' }, end: { componentId: 'raspberry-pi-pico', pinName: 'GND.3' }, color: '#000000' }, - { id: 'w-gnd-right', start: { componentId: 'btn-right', pinName: '2.l' }, end: { componentId: 'raspberry-pi-pico', pinName: 'GND.4' }, color: '#000000' }, + { + id: 'w-btn-fwd', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP10' }, + end: { componentId: 'btn-fwd', pinName: '1.l' }, + color: '#ff4444', + }, + { + id: 'w-btn-back', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP11' }, + end: { componentId: 'btn-back', pinName: '1.l' }, + color: '#4477ff', + }, + { + id: 'w-btn-left', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP12' }, + end: { componentId: 'btn-left', pinName: '1.l' }, + color: '#44cc44', + }, + { + id: 'w-btn-right', + start: { componentId: 'raspberry-pi-pico', pinName: 'GP13' }, + end: { componentId: 'btn-right', pinName: '1.l' }, + color: '#cccc44', + }, + { + id: 'w-gnd-fwd', + start: { componentId: 'btn-fwd', pinName: '2.l' }, + end: { componentId: 'raspberry-pi-pico', pinName: 'GND.1' }, + color: '#000000', + }, + { + id: 'w-gnd-back', + start: { componentId: 'btn-back', pinName: '2.l' }, + end: { componentId: 'raspberry-pi-pico', pinName: 'GND.2' }, + color: '#000000', + }, + { + id: 'w-gnd-left', + start: { componentId: 'btn-left', pinName: '2.l' }, + end: { componentId: 'raspberry-pi-pico', pinName: 'GND.3' }, + color: '#000000', + }, + { + id: 'w-gnd-right', + start: { componentId: 'btn-right', pinName: '2.l' }, + end: { componentId: 'raspberry-pi-pico', pinName: 'GND.4' }, + color: '#000000', + }, ], }, { @@ -3338,16 +3861,56 @@ void loop() { ], wires: [ // SDA bus (shared) - { id: 'wire-sda', start: { componentId: 'arduino-uno', pinName: 'A4' }, end: { componentId: 'ssd1306-1', pinName: 'DATA' }, color: '#2196f3' }, - { id: 'wire-sda-rtc', start: { componentId: 'ssd1306-1', pinName: 'DATA' }, end: { componentId: 'rtc1', pinName: 'SDA' }, color: '#2196f3' }, + { + id: 'wire-sda', + start: { componentId: 'arduino-uno', pinName: 'A4' }, + end: { componentId: 'ssd1306-1', pinName: 'DATA' }, + color: '#2196f3', + }, + { + id: 'wire-sda-rtc', + start: { componentId: 'ssd1306-1', pinName: 'DATA' }, + end: { componentId: 'rtc1', pinName: 'SDA' }, + color: '#2196f3', + }, // SCL bus (shared) - { id: 'wire-scl', start: { componentId: 'arduino-uno', pinName: 'A5' }, end: { componentId: 'ssd1306-1', pinName: 'CLK' }, color: '#ff9800' }, - { id: 'wire-scl-rtc', start: { componentId: 'ssd1306-1', pinName: 'CLK' }, end: { componentId: 'rtc1', pinName: 'SCL' }, color: '#ff9800' }, + { + id: 'wire-scl', + start: { componentId: 'arduino-uno', pinName: 'A5' }, + end: { componentId: 'ssd1306-1', pinName: 'CLK' }, + color: '#ff9800', + }, + { + id: 'wire-scl-rtc', + start: { componentId: 'ssd1306-1', pinName: 'CLK' }, + end: { componentId: 'rtc1', pinName: 'SCL' }, + color: '#ff9800', + }, // Power + ground for both devices - { id: 'wire-gnd', start: { componentId: 'arduino-uno', pinName: 'GND.1' }, end: { componentId: 'ssd1306-1', pinName: 'GND' }, color: '#000000' }, - { id: 'wire-gnd-rtc', start: { componentId: 'ssd1306-1', pinName: 'GND' }, end: { componentId: 'rtc1', pinName: 'GND' }, color: '#000000' }, - { id: 'wire-vcc', start: { componentId: 'arduino-uno', pinName: '5V' }, end: { componentId: 'ssd1306-1', pinName: 'VIN' }, color: '#ff0000' }, - { id: 'wire-vcc-rtc', start: { componentId: 'ssd1306-1', pinName: 'VIN' }, end: { componentId: 'rtc1', pinName: 'VCC' }, color: '#ff0000' }, + { + id: 'wire-gnd', + start: { componentId: 'arduino-uno', pinName: 'GND.1' }, + end: { componentId: 'ssd1306-1', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'wire-gnd-rtc', + start: { componentId: 'ssd1306-1', pinName: 'GND' }, + end: { componentId: 'rtc1', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'wire-vcc', + start: { componentId: 'arduino-uno', pinName: '5V' }, + end: { componentId: 'ssd1306-1', pinName: 'VIN' }, + color: '#ff0000', + }, + { + id: 'wire-vcc-rtc', + start: { componentId: 'ssd1306-1', pinName: 'VIN' }, + end: { componentId: 'rtc1', pinName: 'VCC' }, + color: '#ff0000', + }, ], }, { @@ -3429,10 +3992,30 @@ void loop() { { type: 'wokwi-ds1307', id: 'rtc1', x: 480, y: 200, properties: {} }, ], wires: [ - { id: 'w-sda', start: { componentId: 'arduino-uno', pinName: 'A4' }, end: { componentId: 'rtc1', pinName: 'SDA' }, color: '#0066cc' }, - { id: 'w-scl', start: { componentId: 'arduino-uno', pinName: 'A5' }, end: { componentId: 'rtc1', pinName: 'SCL' }, color: '#ffaa00' }, - { id: 'w-vcc', start: { componentId: 'arduino-uno', pinName: '5V' }, end: { componentId: 'rtc1', pinName: 'VCC' }, color: '#ff0000' }, - { id: 'w-gnd', start: { componentId: 'arduino-uno', pinName: 'GND' }, end: { componentId: 'rtc1', pinName: 'GND' }, color: '#000000' }, + { + id: 'w-sda', + start: { componentId: 'arduino-uno', pinName: 'A4' }, + end: { componentId: 'rtc1', pinName: 'SDA' }, + color: '#0066cc', + }, + { + id: 'w-scl', + start: { componentId: 'arduino-uno', pinName: 'A5' }, + end: { componentId: 'rtc1', pinName: 'SCL' }, + color: '#ffaa00', + }, + { + id: 'w-vcc', + start: { componentId: 'arduino-uno', pinName: '5V' }, + end: { componentId: 'rtc1', pinName: 'VCC' }, + color: '#ff0000', + }, + { + id: 'w-gnd', + start: { componentId: 'arduino-uno', pinName: 'GND' }, + end: { componentId: 'rtc1', pinName: 'GND' }, + color: '#000000', + }, ], }, { @@ -5021,7 +5604,7 @@ void loop() { id: 'dual-pico-bidirectional-handshake', title: '[2× Pico W] Bidirectional Digital Handshake', description: - 'Two Picos signal each other over independent digital lines. Pico A drives GP15 (data) and watches GP14 (ack); Pico B reads GP15 and pulses GP14 on every transition to acknowledge. Each board\'s Serial Monitor logs every event, so you can see the round-trip on both sides.', + "Two Picos signal each other over independent digital lines. Pico A drives GP15 (data) and watches GP14 (ack); Pico B reads GP15 and pulses GP14 on every transition to acknowledge. Each board's Serial Monitor logs every event, so you can see the round-trip on both sides.", category: 'communication', difficulty: 'beginner', boardFilter: 'raspberry-pi-pico', @@ -5162,7 +5745,7 @@ void loop() { id: 'dual-pico-digital-mirror', title: '[2× Pico W] Digital GPIO Mirror', description: - 'Simplest possible cross-board test. Pico A toggles GP15 every 500 ms; Pico B reads GP15 as a digital input and mirrors its state to its built-in LED. Watch each Pico\'s Serial Monitor to confirm the wire is alive.', + "Simplest possible cross-board test. Pico A toggles GP15 every 500 ms; Pico B reads GP15 as a digital input and mirrors its state to its built-in LED. Watch each Pico's Serial Monitor to confirm the wire is alive.", category: 'basics', difficulty: 'beginner', boardFilter: 'raspberry-pi-pico', @@ -5343,6 +5926,10 @@ void loop() { components: [ { type: 'wokwi-pushbutton', id: 'btn1', x: 420, y: 120, properties: {} }, { type: 'wokwi-led', id: 'led1', x: 420, y: 260, properties: { color: 'red' } }, + // 220 ohm entre cada GPIO y su LED — (5V - ~2V) / 220R ~= 14 mA, por debajo + // de los 20 mA del LED. La resistencia en serie que le faltaba: sin ella el verificador de + // circuito calcula un cortocircuito y se niega a ejecutar el ejemplo. + { type: 'wokwi-resistor', id: 'r-led1', x: 420, y: 200, properties: { value: '220' } }, ], wires: [ { @@ -5354,7 +5941,7 @@ void loop() { { id: 'w-led', start: { componentId: 'arduino-uno', pinName: '13' }, - end: { componentId: 'led1', pinName: 'A' }, + end: { componentId: 'r-led1', pinName: '1' }, color: '#ff4444', }, { @@ -5369,6 +5956,12 @@ void loop() { end: { componentId: 'arduino-uno', pinName: 'GND' }, color: '#000000', }, + { + id: 'w-led-r', + start: { componentId: 'r-led1', pinName: '2' }, + end: { componentId: 'led1', pinName: 'A' }, + color: '#ff4444', + }, ], }, { @@ -5534,54 +6127,65 @@ void loop() { { type: 'wokwi-led', id: 'led7', x: 620, y: 80, properties: { color: 'purple' } }, { type: 'wokwi-led', id: 'led8', x: 660, y: 80, properties: { color: 'white' } }, { type: 'wokwi-led', id: 'led9', x: 700, y: 80, properties: { color: 'red' } }, + // 220 ohm entre cada GPIO y su LED — (5V - ~2V) / 220R ~= 14 mA, por debajo + // de los 20 mA del LED. Una resistencia en serie por LED. Sin ellas el verificador de circuito + // ve un cortocircuito y bloquea el Run del ejemplo entero. + { type: 'wokwi-resistor', id: 'mr-led2', x: 420, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'mr-led3', x: 460, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'mr-led4', x: 500, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'mr-led5', x: 540, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'mr-led6', x: 580, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'mr-led7', x: 620, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'mr-led8', x: 660, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'mr-led9', x: 700, y: 20, properties: { value: '220' } }, ], wires: [ { id: 'w2', start: { componentId: 'arduino-uno', pinName: '2' }, - end: { componentId: 'led2', pinName: 'A' }, + end: { componentId: 'mr-led2', pinName: '1' }, color: '#ff2222', }, { id: 'w3', start: { componentId: 'arduino-uno', pinName: '3' }, - end: { componentId: 'led3', pinName: 'A' }, + end: { componentId: 'mr-led3', pinName: '1' }, color: '#ff8800', }, { id: 'w4', start: { componentId: 'arduino-uno', pinName: '4' }, - end: { componentId: 'led4', pinName: 'A' }, + end: { componentId: 'mr-led4', pinName: '1' }, color: '#ffcc00', }, { id: 'w5', start: { componentId: 'arduino-uno', pinName: '5' }, - end: { componentId: 'led5', pinName: 'A' }, + end: { componentId: 'mr-led5', pinName: '1' }, color: '#22bb22', }, { id: 'w6', start: { componentId: 'arduino-uno', pinName: '6' }, - end: { componentId: 'led6', pinName: 'A' }, + end: { componentId: 'mr-led6', pinName: '1' }, color: '#2244ff', }, { id: 'w7', start: { componentId: 'arduino-uno', pinName: '7' }, - end: { componentId: 'led7', pinName: 'A' }, + end: { componentId: 'mr-led7', pinName: '1' }, color: '#aa44ff', }, { id: 'w8', start: { componentId: 'arduino-uno', pinName: '8' }, - end: { componentId: 'led8', pinName: 'A' }, + end: { componentId: 'mr-led8', pinName: '1' }, color: '#ffffff', }, { id: 'w9', start: { componentId: 'arduino-uno', pinName: '9' }, - end: { componentId: 'led9', pinName: 'A' }, + end: { componentId: 'mr-led9', pinName: '1' }, color: '#ff2222', }, { @@ -5632,6 +6236,54 @@ void loop() { end: { componentId: 'arduino-uno', pinName: 'GND' }, color: '#000000', }, + { + id: 'w2-r', + start: { componentId: 'mr-led2', pinName: '2' }, + end: { componentId: 'led2', pinName: 'A' }, + color: '#ff2222', + }, + { + id: 'w3-r', + start: { componentId: 'mr-led3', pinName: '2' }, + end: { componentId: 'led3', pinName: 'A' }, + color: '#ff8800', + }, + { + id: 'w4-r', + start: { componentId: 'mr-led4', pinName: '2' }, + end: { componentId: 'led4', pinName: 'A' }, + color: '#ffcc00', + }, + { + id: 'w5-r', + start: { componentId: 'mr-led5', pinName: '2' }, + end: { componentId: 'led5', pinName: 'A' }, + color: '#22bb22', + }, + { + id: 'w6-r', + start: { componentId: 'mr-led6', pinName: '2' }, + end: { componentId: 'led6', pinName: 'A' }, + color: '#2244ff', + }, + { + id: 'w7-r', + start: { componentId: 'mr-led7', pinName: '2' }, + end: { componentId: 'led7', pinName: 'A' }, + color: '#aa44ff', + }, + { + id: 'w8-r', + start: { componentId: 'mr-led8', pinName: '2' }, + end: { componentId: 'led8', pinName: 'A' }, + color: '#ffffff', + }, + { + id: 'w9-r', + start: { componentId: 'mr-led9', pinName: '2' }, + end: { componentId: 'led9', pinName: 'A' }, + color: '#ff2222', + }, ], }, { @@ -5687,54 +6339,64 @@ void loop() { { type: 'wokwi-led', id: 'mled7', x: 620, y: 80, properties: { color: 'purple' } }, { type: 'wokwi-led', id: 'mled8', x: 660, y: 80, properties: { color: 'white' } }, { type: 'wokwi-led', id: 'mled9', x: 700, y: 80, properties: { color: 'red' } }, + // 220 ohm entre cada GPIO y su LED — (5V - ~2V) / 220R ~= 14 mA, por debajo + // de los 20 mA del LED. Una resistencia en serie por LED, como en el resto de la galeria. + { type: 'wokwi-resistor', id: 'msr-mled2', x: 420, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'msr-mled3', x: 460, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'msr-mled4', x: 500, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'msr-mled5', x: 540, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'msr-mled6', x: 580, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'msr-mled7', x: 620, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'msr-mled8', x: 660, y: 20, properties: { value: '220' } }, + { type: 'wokwi-resistor', id: 'msr-mled9', x: 700, y: 20, properties: { value: '220' } }, ], wires: [ { id: 'mw2', start: { componentId: 'arduino-uno', pinName: '2' }, - end: { componentId: 'mled2', pinName: 'A' }, + end: { componentId: 'msr-mled2', pinName: '1' }, color: '#ff2222', }, { id: 'mw3', start: { componentId: 'arduino-uno', pinName: '3' }, - end: { componentId: 'mled3', pinName: 'A' }, + end: { componentId: 'msr-mled3', pinName: '1' }, color: '#ff8800', }, { id: 'mw4', start: { componentId: 'arduino-uno', pinName: '4' }, - end: { componentId: 'mled4', pinName: 'A' }, + end: { componentId: 'msr-mled4', pinName: '1' }, color: '#ffcc00', }, { id: 'mw5', start: { componentId: 'arduino-uno', pinName: '5' }, - end: { componentId: 'mled5', pinName: 'A' }, + end: { componentId: 'msr-mled5', pinName: '1' }, color: '#22bb22', }, { id: 'mw6', start: { componentId: 'arduino-uno', pinName: '6' }, - end: { componentId: 'mled6', pinName: 'A' }, + end: { componentId: 'msr-mled6', pinName: '1' }, color: '#2244ff', }, { id: 'mw7', start: { componentId: 'arduino-uno', pinName: '7' }, - end: { componentId: 'mled7', pinName: 'A' }, + end: { componentId: 'msr-mled7', pinName: '1' }, color: '#aa44ff', }, { id: 'mw8', start: { componentId: 'arduino-uno', pinName: '8' }, - end: { componentId: 'mled8', pinName: 'A' }, + end: { componentId: 'msr-mled8', pinName: '1' }, color: '#ffffff', }, { id: 'mw9', start: { componentId: 'arduino-uno', pinName: '9' }, - end: { componentId: 'mled9', pinName: 'A' }, + end: { componentId: 'msr-mled9', pinName: '1' }, color: '#ff2222', }, { @@ -5785,6 +6447,54 @@ void loop() { end: { componentId: 'arduino-uno', pinName: 'GND' }, color: '#000000', }, + { + id: 'mw2-r', + start: { componentId: 'msr-mled2', pinName: '2' }, + end: { componentId: 'mled2', pinName: 'A' }, + color: '#ff2222', + }, + { + id: 'mw3-r', + start: { componentId: 'msr-mled3', pinName: '2' }, + end: { componentId: 'mled3', pinName: 'A' }, + color: '#ff8800', + }, + { + id: 'mw4-r', + start: { componentId: 'msr-mled4', pinName: '2' }, + end: { componentId: 'mled4', pinName: 'A' }, + color: '#ffcc00', + }, + { + id: 'mw5-r', + start: { componentId: 'msr-mled5', pinName: '2' }, + end: { componentId: 'mled5', pinName: 'A' }, + color: '#22bb22', + }, + { + id: 'mw6-r', + start: { componentId: 'msr-mled6', pinName: '2' }, + end: { componentId: 'mled6', pinName: 'A' }, + color: '#2244ff', + }, + { + id: 'mw7-r', + start: { componentId: 'msr-mled7', pinName: '2' }, + end: { componentId: 'mled7', pinName: 'A' }, + color: '#aa44ff', + }, + { + id: 'mw8-r', + start: { componentId: 'msr-mled8', pinName: '2' }, + end: { componentId: 'mled8', pinName: 'A' }, + color: '#ffffff', + }, + { + id: 'mw9-r', + start: { componentId: 'msr-mled9', pinName: '2' }, + end: { componentId: 'mled9', pinName: 'A' }, + color: '#ff2222', + }, ], }, @@ -9710,30 +10420,121 @@ void loop() { } `, components: [ - { type: 'wokwi-ili9341', id: 'tft1', x: 380, y: 40, properties: {} }, - { type: 'wokwi-pushbutton', id: 'btn_fwd', x: 360, y: 330, properties: { color: 'green' } }, - { type: 'wokwi-pushbutton', id: 'btn_back', x: 470, y: 330, properties: { color: 'red' } }, - { type: 'wokwi-pushbutton', id: 'btn_left', x: 580, y: 330, properties: { color: 'blue' } }, - { type: 'wokwi-pushbutton', id: 'btn_right', x: 690, y: 330, properties: { color: 'yellow' } }, + { type: 'wokwi-ili9341', id: 'tft1', x: 380, y: 40, properties: {} }, + { type: 'wokwi-pushbutton', id: 'btn_fwd', x: 360, y: 330, properties: { color: 'green' } }, + { type: 'wokwi-pushbutton', id: 'btn_back', x: 470, y: 330, properties: { color: 'red' } }, + { type: 'wokwi-pushbutton', id: 'btn_left', x: 580, y: 330, properties: { color: 'blue' } }, + { + type: 'wokwi-pushbutton', + id: 'btn_right', + x: 690, + y: 330, + properties: { color: 'yellow' }, + }, ], wires: [ - { id: 'd-sck', start: { componentId: 'esp32', pinName: '18' }, end: { componentId: 'tft1', pinName: 'SCK' }, color: '#27ae60' }, - { id: 'd-mosi', start: { componentId: 'esp32', pinName: '23' }, end: { componentId: 'tft1', pinName: 'MOSI' }, color: '#3498db' }, - { id: 'd-miso', start: { componentId: 'esp32', pinName: '19' }, end: { componentId: 'tft1', pinName: 'MISO' }, color: '#9b59b6' }, - { id: 'd-cs', start: { componentId: 'esp32', pinName: '5' }, end: { componentId: 'tft1', pinName: 'CS' }, color: '#e67e22' }, - { id: 'd-dc', start: { componentId: 'esp32', pinName: '2' }, end: { componentId: 'tft1', pinName: 'D/C' }, color: '#f1c40f' }, - { id: 'd-rst', start: { componentId: 'esp32', pinName: '4' }, end: { componentId: 'tft1', pinName: 'RST' }, color: '#ecf0f1' }, - { id: 'd-vcc', start: { componentId: 'esp32', pinName: '3V3' }, end: { componentId: 'tft1', pinName: 'VCC' }, color: '#e74c3c' }, - { id: 'd-led', start: { componentId: 'esp32', pinName: '3V3' }, end: { componentId: 'tft1', pinName: 'LED' }, color: '#e74c3c' }, - { id: 'd-gnd', start: { componentId: 'esp32', pinName: 'GND' }, end: { componentId: 'tft1', pinName: 'GND' }, color: '#2c3e50' }, - { id: 'd-bf-s', start: { componentId: 'esp32', pinName: '32' }, end: { componentId: 'btn_fwd', pinName: '1.l' }, color: '#16a085' }, - { id: 'd-bf-g', start: { componentId: 'esp32', pinName: 'GND' }, end: { componentId: 'btn_fwd', pinName: '2.l' }, color: '#000000' }, - { id: 'd-bb-s', start: { componentId: 'esp32', pinName: '33' }, end: { componentId: 'btn_back', pinName: '1.l' }, color: '#c0392b' }, - { id: 'd-bb-g', start: { componentId: 'esp32', pinName: 'GND2' }, end: { componentId: 'btn_back', pinName: '2.l' }, color: '#000000' }, - { id: 'd-bl-s', start: { componentId: 'esp32', pinName: '25' }, end: { componentId: 'btn_left', pinName: '1.l' }, color: '#2980b9' }, - { id: 'd-bl-g', start: { componentId: 'esp32', pinName: 'GND' }, end: { componentId: 'btn_left', pinName: '2.l' }, color: '#000000' }, - { id: 'd-br-s', start: { componentId: 'esp32', pinName: '26' }, end: { componentId: 'btn_right', pinName: '1.l' }, color: '#f39c12' }, - { id: 'd-br-g', start: { componentId: 'esp32', pinName: 'GND2' }, end: { componentId: 'btn_right', pinName: '2.l' }, color: '#000000' }, + { + id: 'd-sck', + start: { componentId: 'esp32', pinName: '18' }, + end: { componentId: 'tft1', pinName: 'SCK' }, + color: '#27ae60', + }, + { + id: 'd-mosi', + start: { componentId: 'esp32', pinName: '23' }, + end: { componentId: 'tft1', pinName: 'MOSI' }, + color: '#3498db', + }, + { + id: 'd-miso', + start: { componentId: 'esp32', pinName: '19' }, + end: { componentId: 'tft1', pinName: 'MISO' }, + color: '#9b59b6', + }, + { + id: 'd-cs', + start: { componentId: 'esp32', pinName: '5' }, + end: { componentId: 'tft1', pinName: 'CS' }, + color: '#e67e22', + }, + { + id: 'd-dc', + start: { componentId: 'esp32', pinName: '2' }, + end: { componentId: 'tft1', pinName: 'D/C' }, + color: '#f1c40f', + }, + { + id: 'd-rst', + start: { componentId: 'esp32', pinName: '4' }, + end: { componentId: 'tft1', pinName: 'RST' }, + color: '#ecf0f1', + }, + { + id: 'd-vcc', + start: { componentId: 'esp32', pinName: '3V3' }, + end: { componentId: 'tft1', pinName: 'VCC' }, + color: '#e74c3c', + }, + { + id: 'd-led', + start: { componentId: 'esp32', pinName: '3V3' }, + end: { componentId: 'tft1', pinName: 'LED' }, + color: '#e74c3c', + }, + { + id: 'd-gnd', + start: { componentId: 'esp32', pinName: 'GND' }, + end: { componentId: 'tft1', pinName: 'GND' }, + color: '#2c3e50', + }, + { + id: 'd-bf-s', + start: { componentId: 'esp32', pinName: '32' }, + end: { componentId: 'btn_fwd', pinName: '1.l' }, + color: '#16a085', + }, + { + id: 'd-bf-g', + start: { componentId: 'esp32', pinName: 'GND' }, + end: { componentId: 'btn_fwd', pinName: '2.l' }, + color: '#000000', + }, + { + id: 'd-bb-s', + start: { componentId: 'esp32', pinName: '33' }, + end: { componentId: 'btn_back', pinName: '1.l' }, + color: '#c0392b', + }, + { + id: 'd-bb-g', + start: { componentId: 'esp32', pinName: 'GND2' }, + end: { componentId: 'btn_back', pinName: '2.l' }, + color: '#000000', + }, + { + id: 'd-bl-s', + start: { componentId: 'esp32', pinName: '25' }, + end: { componentId: 'btn_left', pinName: '1.l' }, + color: '#2980b9', + }, + { + id: 'd-bl-g', + start: { componentId: 'esp32', pinName: 'GND' }, + end: { componentId: 'btn_left', pinName: '2.l' }, + color: '#000000', + }, + { + id: 'd-br-s', + start: { componentId: 'esp32', pinName: '26' }, + end: { componentId: 'btn_right', pinName: '1.l' }, + color: '#f39c12', + }, + { + id: 'd-br-g', + start: { componentId: 'esp32', pinName: 'GND2' }, + end: { componentId: 'btn_right', pinName: '2.l' }, + color: '#000000', + }, ], }, @@ -9785,8 +10586,18 @@ except KeyboardInterrupt: { type: 'wokwi-led', id: 'pi3b-led', x: 540, y: 160, properties: { color: 'red' } }, ], wires: [ - { id: 'w-sig', start: { componentId: 'raspberry-pi-3', pinName: 'GPIO17' }, end: { componentId: 'pi3b-led', pinName: 'A' }, color: '#e74c3c' }, - { id: 'w-gnd', start: { componentId: 'pi3b-led', pinName: 'C' }, end: { componentId: 'raspberry-pi-3', pinName: 'GND' }, color: '#000000' }, + { + id: 'w-sig', + start: { componentId: 'raspberry-pi-3', pinName: 'GPIO17' }, + end: { componentId: 'pi3b-led', pinName: 'A' }, + color: '#e74c3c', + }, + { + id: 'w-gnd', + start: { componentId: 'pi3b-led', pinName: 'C' }, + end: { componentId: 'raspberry-pi-3', pinName: 'GND' }, + color: '#000000', + }, ], }, { @@ -9839,16 +10650,66 @@ except KeyboardInterrupt: { type: 'wokwi-led', id: 'pi3r-led5', x: 540, y: 380, properties: { color: 'blue' } }, ], wires: [ - { id: 'w1', start: { componentId: 'raspberry-pi-3', pinName: 'GPIO17' }, end: { componentId: 'pi3r-led1', pinName: 'A' }, color: '#e74c3c' }, - { id: 'w2', start: { componentId: 'raspberry-pi-3', pinName: 'GPIO27' }, end: { componentId: 'pi3r-led2', pinName: 'A' }, color: '#e67e22' }, - { id: 'w3', start: { componentId: 'raspberry-pi-3', pinName: 'GPIO22' }, end: { componentId: 'pi3r-led3', pinName: 'A' }, color: '#f1c40f' }, - { id: 'w4', start: { componentId: 'raspberry-pi-3', pinName: 'GPIO5' }, end: { componentId: 'pi3r-led4', pinName: 'A' }, color: '#2ecc71' }, - { id: 'w5', start: { componentId: 'raspberry-pi-3', pinName: 'GPIO6' }, end: { componentId: 'pi3r-led5', pinName: 'A' }, color: '#3498db' }, - { id: 'g1', start: { componentId: 'pi3r-led1', pinName: 'C' }, end: { componentId: 'raspberry-pi-3', pinName: 'GND' }, color: '#000000' }, - { id: 'g2', start: { componentId: 'pi3r-led2', pinName: 'C' }, end: { componentId: 'raspberry-pi-3', pinName: 'GND' }, color: '#000000' }, - { id: 'g3', start: { componentId: 'pi3r-led3', pinName: 'C' }, end: { componentId: 'raspberry-pi-3', pinName: 'GND' }, color: '#000000' }, - { id: 'g4', start: { componentId: 'pi3r-led4', pinName: 'C' }, end: { componentId: 'raspberry-pi-3', pinName: 'GND' }, color: '#000000' }, - { id: 'g5', start: { componentId: 'pi3r-led5', pinName: 'C' }, end: { componentId: 'raspberry-pi-3', pinName: 'GND' }, color: '#000000' }, + { + id: 'w1', + start: { componentId: 'raspberry-pi-3', pinName: 'GPIO17' }, + end: { componentId: 'pi3r-led1', pinName: 'A' }, + color: '#e74c3c', + }, + { + id: 'w2', + start: { componentId: 'raspberry-pi-3', pinName: 'GPIO27' }, + end: { componentId: 'pi3r-led2', pinName: 'A' }, + color: '#e67e22', + }, + { + id: 'w3', + start: { componentId: 'raspberry-pi-3', pinName: 'GPIO22' }, + end: { componentId: 'pi3r-led3', pinName: 'A' }, + color: '#f1c40f', + }, + { + id: 'w4', + start: { componentId: 'raspberry-pi-3', pinName: 'GPIO5' }, + end: { componentId: 'pi3r-led4', pinName: 'A' }, + color: '#2ecc71', + }, + { + id: 'w5', + start: { componentId: 'raspberry-pi-3', pinName: 'GPIO6' }, + end: { componentId: 'pi3r-led5', pinName: 'A' }, + color: '#3498db', + }, + { + id: 'g1', + start: { componentId: 'pi3r-led1', pinName: 'C' }, + end: { componentId: 'raspberry-pi-3', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'g2', + start: { componentId: 'pi3r-led2', pinName: 'C' }, + end: { componentId: 'raspberry-pi-3', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'g3', + start: { componentId: 'pi3r-led3', pinName: 'C' }, + end: { componentId: 'raspberry-pi-3', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'g4', + start: { componentId: 'pi3r-led4', pinName: 'C' }, + end: { componentId: 'raspberry-pi-3', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'g5', + start: { componentId: 'pi3r-led5', pinName: 'C' }, + end: { componentId: 'raspberry-pi-3', pinName: 'GND' }, + color: '#000000', + }, ], }, { @@ -9895,10 +10756,30 @@ except KeyboardInterrupt: { type: 'wokwi-led', id: 'pi4-led', x: 540, y: 300, properties: { color: 'blue' } }, ], wires: [ - { id: 'w-btn', start: { componentId: 'raspberry-pi-4', pinName: 'GPIO2' }, end: { componentId: 'pi4-btn', pinName: '1.l' }, color: '#00aaff' }, - { id: 'w-btn-gnd', start: { componentId: 'pi4-btn', pinName: '2.l' }, end: { componentId: 'raspberry-pi-4', pinName: 'GND' }, color: '#000000' }, - { id: 'w-led', start: { componentId: 'raspberry-pi-4', pinName: 'GPIO17' }, end: { componentId: 'pi4-led', pinName: 'A' }, color: '#3498db' }, - { id: 'w-led-gnd', start: { componentId: 'pi4-led', pinName: 'C' }, end: { componentId: 'raspberry-pi-4', pinName: 'GND' }, color: '#000000' }, + { + id: 'w-btn', + start: { componentId: 'raspberry-pi-4', pinName: 'GPIO2' }, + end: { componentId: 'pi4-btn', pinName: '1.l' }, + color: '#00aaff', + }, + { + id: 'w-btn-gnd', + start: { componentId: 'pi4-btn', pinName: '2.l' }, + end: { componentId: 'raspberry-pi-4', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'w-led', + start: { componentId: 'raspberry-pi-4', pinName: 'GPIO17' }, + end: { componentId: 'pi4-led', pinName: 'A' }, + color: '#3498db', + }, + { + id: 'w-led-gnd', + start: { componentId: 'pi4-led', pinName: 'C' }, + end: { componentId: 'raspberry-pi-4', pinName: 'GND' }, + color: '#000000', + }, ], }, { @@ -9946,14 +10827,32 @@ except KeyboardInterrupt: }, }, ], - components: [ - { type: 'wokwi-rgb-led', id: 'pi4-rgb', x: 560, y: 160, properties: {} }, - ], + components: [{ type: 'wokwi-rgb-led', id: 'pi4-rgb', x: 560, y: 160, properties: {} }], wires: [ - { id: 'w-r', start: { componentId: 'raspberry-pi-4', pinName: 'GPIO17' }, end: { componentId: 'pi4-rgb', pinName: 'R' }, color: '#e74c3c' }, - { id: 'w-g', start: { componentId: 'raspberry-pi-4', pinName: 'GPIO27' }, end: { componentId: 'pi4-rgb', pinName: 'G' }, color: '#2ecc71' }, - { id: 'w-b', start: { componentId: 'raspberry-pi-4', pinName: 'GPIO22' }, end: { componentId: 'pi4-rgb', pinName: 'B' }, color: '#3498db' }, - { id: 'w-com', start: { componentId: 'pi4-rgb', pinName: 'COM' }, end: { componentId: 'raspberry-pi-4', pinName: 'GND' }, color: '#000000' }, + { + id: 'w-r', + start: { componentId: 'raspberry-pi-4', pinName: 'GPIO17' }, + end: { componentId: 'pi4-rgb', pinName: 'R' }, + color: '#e74c3c', + }, + { + id: 'w-g', + start: { componentId: 'raspberry-pi-4', pinName: 'GPIO27' }, + end: { componentId: 'pi4-rgb', pinName: 'G' }, + color: '#2ecc71', + }, + { + id: 'w-b', + start: { componentId: 'raspberry-pi-4', pinName: 'GPIO22' }, + end: { componentId: 'pi4-rgb', pinName: 'B' }, + color: '#3498db', + }, + { + id: 'w-com', + start: { componentId: 'pi4-rgb', pinName: 'COM' }, + end: { componentId: 'raspberry-pi-4', pinName: 'GND' }, + color: '#000000', + }, ], }, { @@ -9999,11 +10898,36 @@ except KeyboardInterrupt: { type: 'wokwi-led', id: 'pi5-led', x: 560, y: 320, properties: { color: 'red' } }, ], wires: [ - { id: 'w-vcc', start: { componentId: 'raspberry-pi-5', pinName: '5V' }, end: { componentId: 'pi5-pir', pinName: 'VCC' }, color: '#e74c3c' }, - { id: 'w-pir-gnd', start: { componentId: 'pi5-pir', pinName: 'GND' }, end: { componentId: 'raspberry-pi-5', pinName: 'GND' }, color: '#000000' }, - { id: 'w-out', start: { componentId: 'pi5-pir', pinName: 'OUT' }, end: { componentId: 'raspberry-pi-5', pinName: 'GPIO4' }, color: '#f1c40f' }, - { id: 'w-led', start: { componentId: 'raspberry-pi-5', pinName: 'GPIO17' }, end: { componentId: 'pi5-led', pinName: 'A' }, color: '#e74c3c' }, - { id: 'w-led-gnd', start: { componentId: 'pi5-led', pinName: 'C' }, end: { componentId: 'raspberry-pi-5', pinName: 'GND' }, color: '#000000' }, + { + id: 'w-vcc', + start: { componentId: 'raspberry-pi-5', pinName: '5V' }, + end: { componentId: 'pi5-pir', pinName: 'VCC' }, + color: '#e74c3c', + }, + { + id: 'w-pir-gnd', + start: { componentId: 'pi5-pir', pinName: 'GND' }, + end: { componentId: 'raspberry-pi-5', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'w-out', + start: { componentId: 'pi5-pir', pinName: 'OUT' }, + end: { componentId: 'raspberry-pi-5', pinName: 'GPIO4' }, + color: '#f1c40f', + }, + { + id: 'w-led', + start: { componentId: 'raspberry-pi-5', pinName: 'GPIO17' }, + end: { componentId: 'pi5-led', pinName: 'A' }, + color: '#e74c3c', + }, + { + id: 'w-led-gnd', + start: { componentId: 'pi5-led', pinName: 'C' }, + end: { componentId: 'raspberry-pi-5', pinName: 'GND' }, + color: '#000000', + }, ], }, { @@ -10055,12 +10979,42 @@ except KeyboardInterrupt: { type: 'wokwi-led', id: 'pi5-green', x: 540, y: 320, properties: { color: 'green' } }, ], wires: [ - { id: 'w-r', start: { componentId: 'raspberry-pi-5', pinName: 'GPIO17' }, end: { componentId: 'pi5-red', pinName: 'A' }, color: '#e74c3c' }, - { id: 'w-y', start: { componentId: 'raspberry-pi-5', pinName: 'GPIO27' }, end: { componentId: 'pi5-yellow', pinName: 'A' }, color: '#f1c40f' }, - { id: 'w-g', start: { componentId: 'raspberry-pi-5', pinName: 'GPIO22' }, end: { componentId: 'pi5-green', pinName: 'A' }, color: '#2ecc71' }, - { id: 'g-r', start: { componentId: 'pi5-red', pinName: 'C' }, end: { componentId: 'raspberry-pi-5', pinName: 'GND' }, color: '#000000' }, - { id: 'g-y', start: { componentId: 'pi5-yellow', pinName: 'C' }, end: { componentId: 'raspberry-pi-5', pinName: 'GND' }, color: '#000000' }, - { id: 'g-g', start: { componentId: 'pi5-green', pinName: 'C' }, end: { componentId: 'raspberry-pi-5', pinName: 'GND' }, color: '#000000' }, + { + id: 'w-r', + start: { componentId: 'raspberry-pi-5', pinName: 'GPIO17' }, + end: { componentId: 'pi5-red', pinName: 'A' }, + color: '#e74c3c', + }, + { + id: 'w-y', + start: { componentId: 'raspberry-pi-5', pinName: 'GPIO27' }, + end: { componentId: 'pi5-yellow', pinName: 'A' }, + color: '#f1c40f', + }, + { + id: 'w-g', + start: { componentId: 'raspberry-pi-5', pinName: 'GPIO22' }, + end: { componentId: 'pi5-green', pinName: 'A' }, + color: '#2ecc71', + }, + { + id: 'g-r', + start: { componentId: 'pi5-red', pinName: 'C' }, + end: { componentId: 'raspberry-pi-5', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'g-y', + start: { componentId: 'pi5-yellow', pinName: 'C' }, + end: { componentId: 'raspberry-pi-5', pinName: 'GND' }, + color: '#000000', + }, + { + id: 'g-g', + start: { componentId: 'pi5-green', pinName: 'C' }, + end: { componentId: 'raspberry-pi-5', pinName: 'GND' }, + color: '#000000', + }, ], }, ];