Step-by-step guide
Download the full bundle from the Download page and unzip. You'll find two folders: Mega/ and nano/. Open Mega/MainMega.ino in Arduino IDE 2.x, select ATmega2560 (or ATmega2560 (Mega 2560)) as the board, and the correct COM port.
// Mega/
// MainMega.ino ← open this file
// attract.h ← attract mode + wheel selector
// GameStyleOne.h ← traditional scoring (full)
// GameStyleStubs.h← Styles 2–4 (stub, ready to fill)
// commands.h ← all TYPE:PAYLOAD strings
// switches.h ← all switch ID #defines
// nano/
// nano_universal.ino ← open this for each Nano
// switch_ids.h ← shared switch ID constants
The RS485 bus uses four wires between all boards: A, B (the differential pair), GND, and +5V. All Nanos and the Mega share the same A and B lines — this is the multi-drop topology.
- Mega:
Serial1(pins 18/19) → MAX485 → bus - Each Nano:
Serial(pins 0/1) → MAX485 → same bus - DE/RE pins on all MAX485 modules tied together to
D2on each board - Add 120Ω termination resistors across A/B at each end of the bus
// MainMega.ino — serial port assignments
// Serial1 (pins 18/19) → RS485 bus → all Nanos
// Serial2 (pins 16/17) → Sound board (DFPlayer etc.)
// Serial3 (pins 14/15) → Display / lights board
#define RS485_DE_PIN 2 // MAX485 transmit enable
void setup() {
Serial.begin(115200); // USB debug
Serial1.begin(115200); // RS485 bus
Serial2.begin(115200); // Sound board
Serial3.begin(115200); // Display/lights board
pinMode(RS485_DE_PIN, OUTPUT);
digitalWrite(RS485_DE_PIN, LOW); // start in receive
// Init solenoid pins
for (int i = 0; i < NUM_SOLENOIDS; i++) {
pinMode(solenoids[i].pin, OUTPUT);
digitalWrite(solenoids[i].pin, LOW);
}
}
Open nano/nano_universal.ino. Set MY_ADDRESS to a unique number for this Nano (0–4). Then fill in the switch table at the top — each row is one switch: pin, ID, solenoid pin, hold pin, pulse duration, debounce time.
#define MY_ADDRESS 0 // unique per Nano
#define DE_PIN 2 // MAX485 DE pin — always D2
#define BAUD_RATE 115200
// Type 1 Sensor: solPin=-1, holdPin=-1
// Type 2 Reaction: solPin>=0, holdPin=-1 (fires local coil)
// Type 3 Flipper: add #define DUAL_WOUND at top
// pin | switchID | solPin | holdPin | pulseMs | debounceMs
static const SwEntry SW[] = {
{ 3, SW_SLINGSHOT_LEFT, 5, -1, 25, 5 },
{ 4, SW_SLINGSHOT_RIGHT, 6, -1, 25, 5 },
{ 7, SW_POP_BUMPER_TOP, 8, -1, 20, 5 },
{ 9, SW_POP_BUMPER_LEFT, 10, -1, 20, 5 },
{ 11, SW_POP_BUMPER_RIGHT, 12, -1, 20, 5 },
};
// ── NOTHING BELOW THIS LINE NEEDS EDITING ──
For a Type 1 sensor Nano (rollover lanes, targets, cabinet switches), set solPin = -1 and holdPin = -1. The Nano just debounces and reports — no local solenoid fires.
#define MY_ADDRESS 1 // Nano 1
static const SwEntry SW[] = {
{ 3, SW_ROLLOVER_F, -1, -1, 0, 10 },
{ 4, SW_ROLLOVER_I, -1, -1, 0, 10 },
{ 7, SW_ROLLOVER_R, -1, -1, 0, 10 },
{ 9, SW_ROLLOVER_E, -1, -1, 0, 10 },
};
Each solenoid on the Mega side uses one N-channel MOSFET (IRLZ44N or TIP120). Gate → Mega digital pin, Drain → coil negative, Source → GND. A 1N4007 flyback diode goes across each coil (cathode to +V).
// Mega solenoid pin assignments
#define PIN_TROUGH 22 // ball trough kicker
#define PIN_KNOCKER 23 // knocker (game over)
#define PIN_UPPER_L 24 // upper left flipper assist
#define PIN_UPPER_R 25 // upper right flipper assist
#define PIN_SLING_LEFT 26 // left slingshot (also Type 2)
#define PIN_SLING_RIGHT 27 // right slingshot
#define PIN_POP_LEFT 28 // left pop bumper
#define PIN_POP_RIGHT 29 // right pop bumper
#define PIN_POP_CENTER 30 // center pop bumper
#define SOL_PULSE_MS 30 // default coil pulse duration
#define TROUGH_PULSE_MS 60 // trough kicker needs longer
// Fire from game code:
fireSolenoid(IDX_TROUGH, TROUGH_PULSE_MS);
fireSolenoid(IDX_KNOCKER); // uses SOL_PULSE_MS default
Upload MainMega.ino to the Mega first. Open Serial Monitor at 115200 baud — you should see [ Micro PinOS ] Main Mega ready. and Styles loaded: 4.
Then upload nano_universal.ino to each Nano (change MY_ADDRESS each time). Trigger a switch manually — the Mega Serial Monitor should show the event being received.
// Mega Serial Monitor output:
[ Micro PinOS ] Main Mega ready.
Styles loaded: 4
// When a Nano switch fires (e.g. slingshot left):
// Mega receives frame "S0:1\n" on Serial1
// dispatchEvent(0, 1) called
// → currentGame->onShot(SW_SLINGSHOT_LEFT)
// → addScore(50), fireSolenoid(IDX_SLING_LEFT)
// → sendSound("SLING") on Serial2