Repository navigation
Virtual Board
This directory contains a native C++17 substitute for the ATmega328P controller. It implements the same bounded COBS + CRC-8 + opcode protocol as the firmware and listens on:
tcp://127.0.0.1:8765
It is intentionally isolated from the PC host configuration. Board settings
are stored in a separate 1 KiB virtual MCU EEPROM image
(virtual-mcu-eeprom.bin by default). The current 40-byte settings/name value plus
its CRC byte, 20 learned-RF records, and wear-levelled reset journal use the
same canonical addresses, checksums, and no-version migration policy as the
physical MCU.
The emulator is split behind injectable hardware interfaces:
-
ISensors: INA-like supply/current values, tLED, tBT, door, and Bluetooth -
IRelays: R1-R8 plus the two direction/enable side mappings -
IPwm: availability, selection, and all 16 logical 0-4095 PWM channels -
IAddressableLeds: 11 WS2811/WS2812 pixels plus global brightness -
IDisplays: TM1637 text, 16x2 LCD text, and buzzer state -
IEeprom: byte-addressable persistent MCU EEPROM
VirtualBoard owns protocol/state-machine behavior and accepts those
interfaces in its constructor, so tests or future firmware-facing adapters can
replace any emulated peripheral independently.
Requirements available from PATH:
- CMake 3.20+
- Ninja
- a working GCC
g++with C++17 support
Windows Git Bash, Linux, or macOS shell:
chmod +x ./build.sh
./build.shThe script selects the matching project-owned CMake configure, build, and test
presets, then discovers tools from PATH (or CXX). It contains no
machine-specific toolchain paths. The same presets can be used directly:
cd Tools/VirtualBoard
cmake --preset release
cmake --build --preset release --parallel
ctest --preset releaseStart the board:
./.build/release/bin/virtual_board.exeChoose another EEPROM image or endpoint if desired:
./.build/release/bin/virtual_board.exe \
--eeprom ./state/test-board.eeprom \
--bind 127.0.0.1 \
--port 8765Point the PC host at it exactly like a serial device:
controller exec --port tcp://127.0.0.1:8765 hello
controller monitor --port tcp://127.0.0.1:8765
controller tui --port tcp://127.0.0.1:8765The server accepts one active controller client at a time and automatically accepts a replacement after disconnect.
Type help in the virtual-board console. Important controls are:
door open|closed|toggle
tled 28.25
tbt 25.75
bt off|on|blink
voltage 12.10
current 325
key 1 down
key 1 up
relay 5 on
pwm 0 2048
strip pixel 3 255 80 0 128
strip fill 0 0 255
strip clear
menu 4
segments DEMO
lcd Enclosure open
reset 0x08
show
quit
Door and Bluetooth changes generate immediate asynchronous device events.
key supports click, double, hold, repeat, and release gestures. To simulate
an RF learn, first issue RF_LEARN_START from the host and then enter:
rflearn 0xABCDEF 24 1 350
Generate the raw receive event used by host automation with:
rfrecv 0xABCDEF 24 1 350
The emulator looks up the code in its learned-remote table and includes that
entry ID, or 0xFF when unmatched.
reset defaults to watchdog cause 0x08; an explicit cause can be supplied
to simulate another MCU reset source. Both protocol reset modes and this
console control advance the same wear-levelled counter in the virtual MCU
EEPROM. That EEPROM image remains independent of the PC host's JSON
configuration.
Use --no-stdin for unattended test runs.
- HELLO with build hash/date/time identity
- fixed 48-byte live STATUS and configurable streaming; byte 43 is the captured reset cause and bytes 44..47 are the persistent reset count in little-endian order; RF-received, buzzer-busy, Running, host-offline, and hot-temperature flags have the production meanings in bits 7 and 12..15
- exact schema-3 GET/SET_SETTINGS, including output-persistence, packed display/motion-hold options, relay-restore state, and the optional eight-byte operator name, persisted as the current 40-byte MCU value plus CRC
- tLED/tBT temperature identities and values
- direct PWM set/get/all-off and RGB; STATUS/PWM_VALUES report hardware
availability, and the removed mode opcode
0x13remains reserved - addressable LED opcode
0x16, including per-pixel/fill RGB and brightness - safe side relay mapping, direct relays, and all-off; the firmware's local
front-panel relay commissioning page is represented through menu state,
while unadvertised opcode
0x34remains unsupported - the current 14-page board menu directory, schema-2 visibility/order, direct page selection, and save-last-page behavior
- exact front-panel snapshot plus TM1637/LCD text overrides; DisplayText targets 3/4 capture and release the PC-presented panel just like the MCU
- host-owned Idle/Running application state through opcode
0x45 - schema-2 MCU-timed macro begin/append/run/query/cancel over a 127-byte circular queue; queued records reuse ordinary peripheral opcodes
- macro buffer/status events plus reserved sequence
0xFEdispatch evidence, letting the host refill ahead and verify each device-side execution time - bounded cooperative I2C write/read/repeated-start transactions and leases;
simulated devices answer at
0x27,0x3F,0x40, and0x41 - RF transmit plus single, multi, indefinite, list/remove/replace learning
over all 20 persistent MCU slots; new codes remain unmapped, while assigned
key/menu/relay/side/PWM actions use production repeat and 350 ms momentary
semantics; removed partial-map opcode
0x26remains reserved - key events including gestures 5=down and 6=up
- timestamped door, Bluetooth, PWM-channel, RF-learn, macro, and reset events; the high bit marks the appended device-microsecond timestamp
- reset event type 7 encoded as
[0x87, cause, count LE u32, deviceMicros LE u32] - raw RF receive event type 8 with code/timing fields and learned ID
- application/bootloader reset requests as a persistent-EEPROM soft reset; each request advances the MCU-owned reset journal and emits reset event 7
The emulator deliberately does not claim AVR-cycle or electrical fidelity:
- wall-clock scheduling substitutes for AVR timers and interrupt latency;
- connected I2C devices use deterministic register bytes, not analog/bus-fault models or a PCF8574/INA219/PWM electrical implementation;
- relay direction/enable semantics and policy are preserved, but native tests (not the virtual relay bank) verify the configured 1..255 ms break and 5 ms cross-side direction interlock;
- host-menu directory opcodes
0x42..0x44are unsupported because the current production firmware does not advertise them; PC-presented menus use the production DisplayText capture/release path instead.
Every acknowledgement carries
[requestOpcode, error, deviceMicros LE u32]. Macro timing is therefore
measured at the emulated MCU rather than inferred from host/network arrival.
Automations invoke named macros through the same playback path, so direct,
scripted, TUI, API, and bridge requests share cancellation and timing rules.
Unit tests cover framing/CRC, maximum payloads, HELLO capabilities, STATUS, temperature/front-panel/menu/I2C schemas, semantic extension tails, all 20 RF slots, mapped-action execution/repeat suppression/momentary expiry, macro cancellation, events, and canonical EEPROM persistence. A second native target compiles the production key, relay, buzzer, shift-register, and DS18B20 sources against an Arduino mock.
./build.shFor a real TCP protocol smoke test, run the server and then:
./.build/release/bin/virtual_board_smoke.exe 127.0.0.1 8765A successful exchange prints the authenticated PCController identity,
its native build hash, confirmation that a raw addressable-LED fill command
was acknowledged, the 48-byte reset telemetry fields, and a validated
type-7 reset event whose persistent count advances by one.
- π Getting started and operations
- πΊοΈ Repository and file map
- ποΈ Front panel and menus
- π§ Hardware initialization and tuning
- βοΈ Host configuration and integrations
- π§ Hosted front-panel menus
- π Portable WebUI
- π Protocol and network API
- π§© C library API
βοΈ Control-surface capability matrix
- ποΈ Build and packaging tool
- πΎ Firmware tool
- π₯οΈ Host Controller
- π§ͺ Virtual Board
- π¦ Dependency maintenance
- π‘οΈ Toolchain bootstrap and safe programming
- π§ Memory and feature tradeoffs
- π¦ CI/CD and releases
- π© Urboot-Custom reproducible fork
- π Audit and traceability tools
- β Project acceptance
- π Requirements backlog
- 𧬠Local-library variant comparison