Arduino-based multi-module bomb-defusal game. A single master controller discovers every connected module over I²C, sets a per-round "version" seed, and tracks whether each module is solved or failed before the main timer expires.
| Path | Description |
|---|---|
Master/ |
Main controller that discovers modules, displays timer/version, drives buzzer/LEDs, and orchestrates start/end commands. |
ModuleComms/ |
Shared library that wraps I²C Master/Slave communication (command opcodes, status codes, and helper classes). |
Keypad/ , Symbols/, SimonSays/, Cables/, etc. |
Concrete module implementations. |
- Transport: I²C (SDA/SCL) plus power (5 V or 3.3 V) and optional INT line for per-module LEDs.
- Discovery: The Master performs a sweep (1–126) sending
CMD_IDENTIFY. Modules withModuleComms::Slaverespond withCMD_IDENTIFYand are stored in the Master's address table. - Runtime commands:
CMD_START_GAME/CMD_END_GAMECMD_SET_VERSION/CMD_GET_VERSIONCMD_SET_STATUS/CMD_GET_STATUS
- Status codes:
STATUS_UNSOLVED,STATUS_PASSED,STATUS_FAILED. - Every module instantiates
Slave(address, gameLoopFn, resetStateFn, solvedLedPin)and callsmodule.begin()insetup()thenmodule.slaveLoop()insideloop().
Each module exports the same edge connector pinout:
VCCGNDSDASCL
Keep bus cables short; add 4.7 kΩ pull-ups to SDA/SCL if the master backplane does not provide them.
- Install the Arduino IDE or
arduino-cli, plus any board cores you use (e.g., MiniCore for bare ATmega328p). - Install libraries:
LiquidCrystal,ModuleComms(this repo’sModuleComms/folder can be added to your Arduinolibrariesfolder),TM1637Display, etc. - Open the desired sketch (
Master/Master.ino,Keypad/Keypad.ino, …) and select the correct board/port. - Upload to each MCU.
avrdude -c usbasp -p m328p -B 10 -U lfuse:w:0xE2:m- Master – Handles timer, version display, buzzer, and dispatches start/end/status commands to every discovered module. Implements safety lockouts and a strike system.
- Keypad – Features Binary/Math puzzles selected per-round via Master version. Uses an LCD + keypad, handles mistakes, drives the module solved LED, and now exposes a
resetState()hook so the Master can clear the UI when the game ends. - Symbols, SimonSays, Cables, etc. – Skeletons or in-progress modules. See each folder for the current sketch.
- KeypadTester (
KeypadTester/KeypadTester.ino) – Serial-based keypad reader that prints the character, matrix row/col, and pin numbers. Use this when wiring a new keypad board. - Mux/OLED tester (
Symbols/mux_test/mux_test.ino) – UsesSoftwareWireto talk to a TCA9548A multiplexer at0x70, scan channels, and confirm SSD1306 displays at0x3Crespond. - ModuleComms library – Can be copied into
~/Documents/Arduino/libraries/ModuleCommsfor reuse across sketches.
- Initialize I²C and digital IO.
- Discover modules by scanning 1–126 for
CMD_IDENTIFY. - Generate and send a round “version” (seed) to each module.
- Issue
CMD_START_GAMEto kick off module gameplay. - Poll statuses; when every module reports
STATUS_PASSED, declare victory, otherwise handle strikes/timeouts.
- Improve ModuleComms serial logging / diagnostics output.
- Add better button debouncing and post-fail lockout inside Simon Says.
- Expand documentation for remaining modules (Cables, Symbols puzzles, etc.).
For standalone ATmega328P builds, group peripherals by hardware ports (Port B, Port C, Port D) instead of assigning pins ad-hoc. This helps reduce cross-coupling bugs and makes register-level debugging easier.
Given the fixed buses:
I2C:A4/A5(TWI hardware)UART:D0/D1(hardware serial)
the most practical remaining zones are mid Port D and upper Port B.
| Peripheral | Function | Arduino Pin(s) | ATmega328P Pin(s) | Rationale |
|---|---|---|---|---|
| Serial | RX / TX | D0 / D1 |
2 / 3 |
Dedicated UART hardware |
| I2C | SDA / SCL | A4 / A5 |
27 / 28 |
Dedicated TWI hardware |
| Buttons | Left / Fwd / Right | D2, D3, D8 |
4, 5, 14 |
D2/D3 can use external interrupts if needed |
| Victory LED | Output | A0 |
23 |
Moves output off busy digital bus |
| OLED (SPI) | SCK | D13 |
19 |
Hardware SPI clock line |
This mapping is useful both in firmware design and in thesis-level documentation when discussing low-level hardware constraints.