Firmware¶
The firmware targets the Arduino Nano (ATmega328P). It is a small OOP C++
source tree under firmware/src/ (Main.cpp provides setup()/loop();
headers are included root-relative, e.g. #include <Cards/Card.h>). The build
system is PlatformIO, which pins the toolchain and
Arduino core so a clean checkout builds identically everywhere. The canonical
reference is
firmware/README.md.
Prerequisites¶
Install PlatformIO Core:
pip install platformio
Build¶
cd firmware
pio run # builds all environments
pio run -e nanoatmega328 # just the Nano (the current board)
The compiled image is written to .pio/build/<env>/firmware.hex.
Flash¶
Pick the environment that matches your board:
pio run -t upload -e nanoatmega328 # Arduino Nano, old bootloader (57600 baud)
pio run -t upload -e micro # Arduino Micro (early-prototype board)
The project's Nanos are older clones with the old bootloader. If an upload
times out on a newer board, its bootloader expects 115200 baud — switch the
environment to board = nanoatmega328new in platformio.ini.
The micro environment targets the Arduino Micro (ATmega32U4) that ran the
2015–2018 prototypes (see
the story). The pin map is
unchanged since then, so a Micro still runs the current firmware.
PlatformIO auto-detects the serial port; force it with
--upload-port /dev/ttyUSB0 (Linux CH340 clone), /dev/ttyACM0 (genuine), or
COMx (Windows).
Serial monitor¶
pio device monitor # 9600 baud, matching Serial.begin(9600)
Build switches¶
Compile-time switches live in src/Constants.h:
AUTOSTART_GAME— auto-starts a 2-player game on boot, skipping the player-count detection flow. Handy for testing.-
MOCK_CODE_DETECTOR/MOCK_OUTPUT_DEVICE— swap in the serial mocks fromsrc/Mock/in place of the real devices, so the game runs with missing hardware. The two are independent — mock one and keep the other real, or mock both:MOCK_CODE_DETECTORreads card codes from the serial console (type a code +<enter>) instead of the photoresistor card reader.MOCK_OUTPUT_DEVICEprints the balloon volume to serial (a percentage and an ASCII bar) instead of driving the pump/valve.
Pair them with
AUTOSTART_GAMEto boot straight into a game with no hardware attached (themake mock,make mock-code, andmake mock-outputtargets wrap these):
PLATFORMIO_BUILD_FLAGS="-D MOCK_CODE_DETECTOR -D MOCK_OUTPUT_DEVICE -D AUTOSTART_GAME" pio run -t upload -e nanoatmega328
DETECTOR_CALIBRATION— replaces the game loop with a card-reader bring-up harness that prints raw photoresistor values.<SPACE>pauses output;<TAB>switches to changes-only output. Use it to pick card-reader thresholds.
PLATFORMIO_BUILD_FLAGS="-D DETECTOR_CALIBRATION" pio run -t upload -e nanoatmega328
See also¶
- Wiring — which pins the firmware drives.
- Firmware Architecture — how the code is organized.
firmware/README.md— the canonical build reference.