Experience the perfect blend of challenge and simplicity with the QB Box, a modern take on the iconic 1978 handheld "video game." This DIY light-based game captivates your mind while keeping you engaged without overwhelming complexity. Ideal for gamers and enthusiasts who appreciate a touch of nostalgia with a contemporary twist.
You can built it on your own, buy a kit and build it, or buy the completed version.
Purchase The QB Box Kit HERE.
Purchase The QB Box Built Version HERE.
Next solder the 9 light buttons IMPORTANT: Ensure the RED paint on each button corresponds to the negative (-) marking on the PCB.
Inspect the buttons after soldering to ensure they are all sitting straight and flush.
Carefully push both sets of the male and female header pins together.
Place the female headers on the PCB.
Then place the Nano on top so the short side of the male header pins come through the holes on the Nano, making sure the USB port is facing up and toward the edge of the PCB.
Flip the PCB over and solder the header pins to the board. You can use a rubber band to hold it in place.
Solder the buzzer (Polarity does not matter)
Connect the 9V battery connector, with the red wire to VCC and black wire to GND.
Temporarily remove the Nano.
Route the 9V connector between the header pins and reinstall the Nano ensuring the USB port is towards the edge of the PCB.
If you purchased the kit from HackMakeMod, it includes these 3D printed parts. Otherwise, If you'd like to print any of these parts yourself for any reason the STL files can be downloaded here...
Pivot the PCB assembly down until it "clicks" into place.
Strip a small section of these two ends. Add a little solder to the connection terminals on the switch.
Solder these wires to the respective conductor pins on the toggle switch. Be careful to avoid melting the enclosure with the soldering iron.
Code:
3D Parts:
Overview and Updates:
QB Box Magic Square V1.3 is a modern twist on the 1980s "Magic Square" game from "Merlin The Electronic Wizard."
Additional Features:
Happy building and gaming with your QB Box!
You can built it on your own, buy a kit and build it, or buy the completed version.
Purchase The QB Box Kit HERE.
Purchase The QB Box Built Version HERE.
Assembly and Usage Guide:
Parts Checklist:- TPU Button Cover [Download]
- PLA Enclosure [Download]
- PLA Battery Cover [Download]
- QB Box PCB (Printed Circuit Board)
- Toggle Switch
- 9 x Light Buttons
- 9 x Resistors (1K Ohm each)
- Buzzer
- Connector for 9V Battery
- 2 sets of 15-Pin Header Pins (Female and Male)
- Arduino Nano or Nano Clone
- Battery (9V)
Pre-Assembly Note:
If you bought the kit from HackMakeMod, your Nano comes preloaded with the QB Box code. Otherwise, you can grab the code at the bottom of this article.
Component Soldering:
Begin with soldering the 9 resistorsNext solder the 9 light buttons IMPORTANT: Ensure the RED paint on each button corresponds to the negative (-) marking on the PCB.
Inspect the buttons after soldering to ensure they are all sitting straight and flush.
Carefully push both sets of the male and female header pins together.
Place the female headers on the PCB.
Then place the Nano on top so the short side of the male header pins come through the holes on the Nano, making sure the USB port is facing up and toward the edge of the PCB.
Flip the PCB over and solder the header pins to the board. You can use a rubber band to hold it in place.
Solder the buzzer (Polarity does not matter)
Connect the 9V battery connector, with the red wire to VCC and black wire to GND.
Temporarily remove the Nano.
Route the 9V connector between the header pins and reinstall the Nano ensuring the USB port is towards the edge of the PCB.
Initial Testing:
Temporarily connect the battery and test each light button. (NOTE: the lights will not all come on immediately since they start in a random pattern) Disconnect the battery after testing.The 3D Enclosure:
If you purchased the kit from HackMakeMod, it includes these 3D printed parts. Otherwise, If you'd like to print any of these parts yourself for any reason the STL files can be downloaded here...
- TPU Button Cover [Download]
- PLA Enclosure [Download]
- PLA Battery Cover [Download]
Toggle Switch Installation:
Fit the toggle switch into the larger rectangular hole in the enclosure, ensuring the conductor pins are above the Nano and the “O” marking is closest to the edge.PLA Enclosure Assembly:
Align the PCB edge (with Nano USB port) with the corresponding edge inside the PLA Main Enclosure.Pivot the PCB assembly down until it "clicks" into place.
Battery Connector:
Cut the RED wire near the top edge of the case from the PCB to the 9V connector.Strip a small section of these two ends. Add a little solder to the connection terminals on the switch.
Solder these wires to the respective conductor pins on the toggle switch. Be careful to avoid melting the enclosure with the soldering iron.
TPU Button Cover Installation:
Flip over the enclosure and fit the TPU Button Cover over the light buttons.Final Connections:
Reconnect the battery to the 9v connector and place it on the battery shelf in the enclosure.Closing the Enclosure:
Secure the build by attaching the PLA Bottom Cover.Enjoy Your QB Box!
Your QB Box is ready for use. Remember, patience and precision are crucial during assembly. If you encounter any issues, revisit your connections and check all your solder joints.Code:
Arduino Code:
// QB Box Magic Square V1.3
// A simple game, called Magic Square, I loved to play in the 1980s.
// This was one of multiple games availableon "Merlin The Electronic Wizard."
// https://en.wikipedia.org/wiki/Merlin_(console)
// I modified it slightly. On the original the goal was to get all lights
// lit except for the center. On my version, you must get all 9 lights to be lit.
// Enjoy! Chad Kapper / HackMakeMod 10//21
//
// V1.1
// -Added battery save timer
// -Changed Column PINs
//
// V1.2
// -Changed PINs for everything to give lights 2, 4, 5, 6, and 8 the ability to fade
//
// V1.3
// -Silent Mode (Hold button for 3 sec)
// -Changed LED Connection Order
//
// Orientation: ON/OFF Rocker Switch is the bottom
// A0 -> R1 (Keypad) Orange Solid
// A1 -> C1 (Keypad) Orange Stripe
// A2 -> R2 (Keypad) Blue Solid
// A3 -> C2 (Keypad) Blue Stripe
// A4 -> R3 (Keypad) Green Solid
// A5 -> C3 (Keypad) Green Stripe
// A6 -> NC
// A7 -> Leave open for RANDOM SEED
// 2 -> LED 7
// 3 ~> LED 4
// 4 -> LED 1
// 5 ~> LED 8
// 6 ~> LED 5
// 7 -> Not Used
// 8 -> LED 9
// 9 ~> LED 2
// 10 ~> LED 6
// 11 ~> Buzzer
// 12 -> LED 3
//
// Keep in mind the led[8] array is numbered like this because "0" is first in an array function.
// | 0 | 1 | 2 |
// | 3 | 4 | 5 |
// | 6 | 7 | 8 |
#include <Keypad.h>
char oneButton;
// Establishes the keypad...
const byte ROWS = 3;
const byte COLS = 3;
char keys[ROWS][COLS] =
{
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'}
};
byte rowPins[ROWS] = {A0, A2, A4}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {A1, A3, A5}; //connect to the column pinouts of the keypad
Keypad nineSquare(makeKeymap(keys), rowPins, colPins, ROWS, COLS); //initialize an instance of class nineSquare
const int ledPin[9] = {4, 9, 12, 3, 6, 10, 2, 5, 8}; //Uses pins for the LED outputs
int led[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; //Declares a variable for 9 LEDs
int buzzer = 11;
int moveCounter = 0;
unsigned long time;
unsigned long forgotten = 300000; //Amount of time of inactivity before sounding power save buzzer 1000 = 1 sec.
unsigned long buzDelay = 40;
//----------------------------SETUP----------------------------//
void setup()
{
Serial.begin(9600);
for (byte i = 0; i < 9; i = i + 1) //A 'for loop' saves time and typing to assign values to all the arrays
{ //Using the same 'i' variable to assign values on all four lines
pinMode(ledPin[i], OUTPUT); //Setting pins as outputs (LOW 0v / HIGH +5v)
digitalWrite(ledPin[i], LOW); //Setting pins to the OFF state.
led[i] = LOW; //Setting the LED variables to the OFF state.
}
pinMode(buzzer, OUTPUT);
randomSeed(analogRead(A6)); //This makes 'random' much more RANDOM
Serial.print("Waking up..."); //Start logging the program
nineSquare.setHoldTime(3000); //Amount of time to activate silent mode.
randomPat(); //Starts off the game with a random pattern.
buTone(); //Cool little start tone.
}
//+++++++++++++++++++++++++++++LOOP+++++++++++++++++++++++++++++//
void loop()
{
oneButton = nineSquare.getState();
if (oneButton == HOLD) // Silent mode
{
buzzer = 7;
}
oneButton = nineSquare.getKey();
if (oneButton)
{
moveCounter++;
time = millis();
}
if (oneButton == '1') // makes sure a key is actually pressed, equal to (oneButton != NO_KEY)
{
led[0] = !led[0];
led[1] = !led[1];
led[3] = !led[3];
led[4] = !led[4];
buTone();
printLayout();
}
if (oneButton == '2') // makes sure a key is actually pressed, equal to (oneButton != NO_KEY)
{
led[0] = !led[0];
led[1] = !led[1];
led[2] = !led[2];
buTone();
printLayout();
}
if (oneButton == '3') // makes sure a key is actually pressed, equal to (oneButton != NO_KEY)
{
led[2] = !led[2];
led[1] = !led[1];
led[5] = !led[5];
led[4] = !led[4];//Invert the state of the LED then...
buTone();
printLayout();
}
if (oneButton == '4') // makes sure a key is actually pressed, equal to (oneButton != NO_KEY)
{
led[0] = !led[0];
led[3] = !led[3];
led[6] = !led[6];
buTone();
printLayout();
}
if (oneButton == '5') // makes sure a key is actually pressed, equal to (oneButton != NO_KEY)
{
led[1] = !led[1];
led[3] = !led[3];
led[4] = !led[4];
led[5] = !led[5];
led[7] = !led[7];
buTone();
printLayout();
}
if (oneButton == '6') // makes sure a key is actually pressed, equal to (oneButton != NO_KEY)
{
led[2] = !led[2];
led[5] = !led[5];
led[8] = !led[8];
buTone();
printLayout();
}
if (oneButton == '7') // makes sure a key is actually pressed, equal to (oneButton != NO_KEY)
{
led[3] = !led[3];
led[4] = !led[4];
led[6] = !led[6];
led[7] = !led[7];
buTone();
printLayout();
}
if (oneButton == '8') // makes sure a key is actually pressed, equal to (oneButton != NO_KEY)
{
led[6] = !led[6];
led[7] = !led[7];
led[8] = !led[8];
buTone();
printLayout();
}
if (oneButton == '9') // makes sure a key is actually pressed, equal to (oneButton != NO_KEY)
{
led[4] = !led[4];
led[5] = !led[5];
led[7] = !led[7];
led[8] = !led[8];
buTone();
printLayout();
}
for (byte i = 0; i < 9; i = i + 1) //A 'for loop' saves time and typing to assign values to all the arrays
{
digitalWrite(ledPin[i], led[i]); //Apply that state
}
if (led[0] && led[1] && led[2] && led[3] && led[4] && led[5] && led[6] && led[7] && led[8])
{
winner();
delay(100);
for(int x = 0; x < 2; x++)
{
for(int i = 0; i < 6; i++)
{
tone(buzzer, 100 * i); // Send .2 KHz sound signal...
delay(100); // ...for 0.1 sec
noTone(buzzer); // Stop sound...
for(int a = 0; a < 9; a++)
{
led[a] = !led[a];
digitalWrite(ledPin[a], led[a]);
delay(1);
}
}
}
randomPat();
buTone();
}
delay(10);
if (millis() - time > forgotten)
{
buTone();
}
}
void allOFF()
{
for(int a = 0; a < 9; a++)
{
led[a] = LOW;
digitalWrite(ledPin[a], led[a]);
}
}
void allON()
{
for(int a = 0; a < 9; a++)
{
led[a] = HIGH;
digitalWrite(ledPin[a], led[a]);
}
}
void randomPat()
{
Serial.print("Random: ");
for(int a = 0; a < 9; a++)
{
int randy = random(2);
led[a] = randy;
if(randy == (led[0] && led[1] && led[2] && led[3] && led[4] && led[5] && led[6] && led[7] && led[8]))
{
led[8] = !led[8];
}
digitalWrite(ledPin[a], led[a]);
Serial.print(randy);
}
Serial.println(" ");
}
void buTone()
{
tone(buzzer, 400, 10);
delay(10);
tone(buzzer, 1500, 10);
delay(10);
tone(buzzer, 600, 30);
delay(10);
}
void winner()
{
tone(buzzer, 500, 10);
delay(30);
tone(buzzer, 700, 10);
delay(30);
tone(buzzer, 900, 20);
delay(40);
tone(buzzer, 1100, 20);
delay(40);
tone(buzzer, 1300, 40);
delay(50);
tone(buzzer, 1500, 40);
delay(50);
Serial.println("!!WINNER!!");
Serial.print(moveCounter);
Serial.println(" Moves");
moveCounter = 0;
}
void printLayout()
{
Serial.print("Pattern: ");
Serial.println(oneButton);
Serial.print(led[0]);
Serial.print(" ");
Serial.print(led[1]);
Serial.print(" ");
Serial.println(led[2]);
Serial.print(led[3]);
Serial.print(" ");
Serial.print(led[4]);
Serial.print(" ");
Serial.println(led[5]);
Serial.print(led[6]);
Serial.print(" ");
Serial.print(led[7]);
Serial.print(" ");
Serial.println(led[8]);
Serial.println();
}
3D Parts:
- TPU Button Cover [Download]
- PLA Enclosure [Download]
- PLA Battery Cover [Download]
Overview and Updates:
QB Box Magic Square V1.3 is a modern twist on the 1980s "Magic Square" game from "Merlin The Electronic Wizard."
Additional Features:
- Battery save timer (Will buzz after left unattended for 3 min)
- Silent Mode (activated by holding a button for 3 seconds)
Happy building and gaming with your QB Box!