Firmware experiments on 8-bit AVR hardware.
Each subdirectory is a self-contained PlatformIO
project with its own platformio.ini, built and tested independently. There is
no shared build at the repository root.
| Project | Target | Description |
|---|---|---|
pedestrian-crossing |
ATmega328P | Button-requested crossing with an audible and 7-segment countdown |
A Miuzei ATmega328 board, an Arduino Uno R3 clone: ATmega328P at 16 MHz, 2 KB
SRAM, 32 KB Flash, ATmega16U2 USB-to-serial bridge. It enumerates as a genuine
Arduino (VID 2341, PID 0043) and needs no board-specific configuration.
PlatformIO provides the cross-compiler, the framework and the upload tool, so the only prerequisite is Python.
# Isolated install; puts `pio` on PATH without touching the system Python.
uv tool install platformioSerial upload requires access to the USB device. On most distributions that
means joining the dialout group, then logging out and back in:
sudo usermod -aG dialout "$USER"Every command takes -d to select the project, so there is no need to change
directory:
pio test -d pedestrian-crossing -e native # host unit tests, no board needed
pio run -d pedestrian-crossing -e uno # cross-compile firmware
pio run -d pedestrian-crossing -e uno -t upload # flash the board
pio device monitorclangd locates a compilation database by walking up from the file being
edited, so one per project is enough for any editor to resolve includes
correctly even with the repository root open:
pio run -d pedestrian-crossing -t compiledbThe resulting compile_commands.json embeds absolute paths from the machine
that produced it, so it stays untracked.
Logic that does not touch hardware lives in libraries that include nothing from the Arduino framework. Those compile with the host compiler and are tested natively in seconds, with no board attached. Code that does drive pins is kept thin enough to verify by inspection and on the bench.
CI runs the host tests and the firmware build on every push.