Arduino Projects By Mike, K4ICY
Weekend Radio Click Here for More Electronics Projects and Tutorials By Mike Maynard, K4ICY
Columns - a Retro Handheld Game for Arduino
PAGE UNDER CONSTRUCTION - BE PATIENT
Based on the 1989 Sega(R) arcade and console game Columns which was inspired by Tetris, this is a more modern take on a plausible handheld portable version as would have been envisioned in the late 1980's.
My version, employing an Arduino Nano (Or Uno) at its heart, uses a 6 x 13 matrix of addressable RGB LEDs, 2 x 8-LED 7-segment numerical displays, a few buttons, and
many other 'bells and whistles' including portable Li-ion power, stereo music and sound effects and even haptic feeback, plus the play of this colorful game is very fast paced and enjoyable!
This page should be considered as a journal only and not as a guaranteed guide to construction. If you have the skill and understanding to follow along, do so by all means, but I offer no warranty of success and all diagrams and description presented here should be considered "as-is."
Detailed description, Parts List, Schematic and Sketch are provided below:::
This is the operational circuit and module schematic for my build - Click on image to enlarge and download.
You may also CLICK HERE to Download the PDF...
The Sound Files, SKETCH and LIBRARIES are available (via MediaFire link) HERE:
The sound files (mp3s) must be copied (as a batch - INSIDE of a Folder Called "mp3") to two freshly formatted SD cards which are to be used in the DFPlayer Mini's.
Some files will be used as sound effects and others as background music. It is important not to drag and drop them individually as the DFPlayers see the files themselves and not the names.
A convenient ZIP file has also been provided. If you wish to change the music or sound effects to something you own or desire, just copy over the appropriate numbered files and re-do the above-mentioned procedure.
Current Prototype Sketch: (.ino file - place in folder of same name)
Requires FastLED.h and
LedControl.h libraries to
be installed - these are also in the above MediaFire link (Sound Files)
and remember to rename the folders without "-master" before installing
them in your IDE.
Audio Copyright Disclaimer :
I offer no warranty or claim to ownership over any of the
audio (sound, mp3, etc.) content and the builder must assume
My first concept was inked out in 1992
Way back when...
In 1992 at just 20 yrs of age, I envisioned a handheld version of Columns along the vein of the Coleco games of the years before. I was introduced to Columns on the Sega Genesis and was hooked for a bit, and yes, a version came bundled with the Sega Game Gear portable system just one year prior, but it was in the $150-$200 range, ate batteries and had a tiny screen. I imagined a version of Columns with the feel and playability of the Coleco handheld games of the 1980's with bright LEDs and I even imagined using some kind of faceted clear plastic lens to make that bejeweled look. The problem was that the awesomeness of RGB LED's hadn't even been invented yet! I thought of using the, then available red/yellow/green variety but with the rainbow of colors required to represent at least six different jewels, this would not work. Blue LED's were only on the scene since 1989 and were not produced with vivid brightness until the late 1990's. As you can see in the drawing, I would have been quite happy getting a hold of a full-color LED that was still future-tech. Also, there was the "elephant in the room," in that I had no knowledge on how to build the electronics for such a device, which was probably not possible for the homebrewer, even with a sea of PIC and PAL devices of the day. I did manage to code a fully-working version of Columns in MS QuickBasic 4.5 on my 286 PC and that knowledge has surely contributed to this project.
Some 27 years later I was formally introduced to the world of Arduino dev boards, AVRs and microcontrollers. I was practically weened on electronics and throughout my youth, my late father, a television repair man was a great tutor. He also fostered the love of coding with our early IBM 'clone' PCs, ZX-81's and TI-994a's. Later, Ham Radio would hone my analog electronics knowledge but once I discovered that a non-engineer and hobbyist such as I could marry the disciplines of electronics and coding, my mind began to race on the possibilities and I've formed a to-do list of awesome projects, many which were strictly impossible when I was a youth.
My goal for this project wasn't so much, a way to realize Columns in a retro handheld form factor but to teach myself more about microcontrollers. I wanted to first limit this project to the simple ATmega328p platform so that intermediate, and maybe newbies, could add something fantastic to their kit. I wanted to see how much I could stuff in this little AVR until it started to get upset... and that happened a few times. MY SKETCH IS POORLY WRITTEN!!! I know this, and I don't believe I'll ever correct a lifetime of bad code training. There are a lot of tweaks and shortcuts involved that may make this sketch hard to follow, but maybe there maybe some nuggets for many Arduino guys to discover.
GAME PLAY:Columns of 3 colored jewels drop one after another.
Arrange 3 or more jewels of the same color, horizontally, vertically or diagonally to remove them from the play field.
The object of the game is to make as many of the jewels as possible disappear. If the jewels pile up to the top of the play field, the game is over. Game play increases in speed as more jewels are removed!
Move the dropping columns with the LEFT or RIGHT buttons. The DROP button will rapidly drop the column for extra points. The ARRANGE button will change the order of the jewels from top to bottom.
Match more than 3 jewels at once for a bigger score! The "Magic Jewel" may appear randomly once per level and will make ALL jewels of the same color it lands on disappear!
Points are awarded for jewels removed and a bonus is given for extra jewels removed at once, and even more if multiple color combinations are removed. The "Magic Jewel" column is worth points as well.
The Level is increased as more jewels are removed and the game speed will increase along with points multipliers.
There is NO pause feature - as this would foster cheating! However, the builder could certainly add one to suit.
(ALSO: See Future Considerations...)
COMPONENT & MODULE LAYOUT:
The core of this game was first developed on an Arduino Uno R3 and later moved to an Arduino Nano. An attempt was made to use an Arduino Nano Every but it failed as it appears the libraries need to be updated or maybe it's that AVR's architecture. There should be no issues using an Arduino Mega, Due or other variety.
The 'star' of the show is the play field comprised of a grid of WS2812B addressable RGB LED wafers. WS2811's or other models compatible with FastLED should work fine. I purchased a sheet of 10 x 10 from Amazon, soldered them together appropriately to form a 6 x 13 tile field. All that's required to run these LEDs was an adequate power source.: 5 volts at 2 amps with a large electrolytic capacitor bridging the connection close to the LED array for power smoothing. These LEDs can be blindingly bright and consume upwards of 80 ma EACH which add up. At full brightness, about 3 amps are needed for my setup, however, because the sketch keeps them lit at a lower luminance, the current consumption it around 300 ma total.
The digital data input of the LED wafer comes from the Arduino through a 470 ohm resistor. This resistor is crucial as the tiny microprocessor embedded on each LED wafer can be damaged on current spikes. The resistor mitigates this possibility.
The luminance can be user-set via the Core Menu.
The game's info is provided via two x 8 number, 7-segment MAX7219 LED displays. This adds a real "old school" touch and allows for numbers to be displayed at any location, along with custom character made via sending 8-bit binary (bytes) to the devices. The luminance can be user-set via the Core Menu.
Sound is provided via 2 x DFPlayer Mini modules. Each use an SD card (no more than 1gig is required) loaded with redundant MP3 files. One module handles Sound Effects and the other, Background Music. )))STEREO((( sound is fed through a basic mixing/filter circuit into a PAM8403 PWM amplifier feeding two speakers via a "bridge" output. Most of the music files are natively in stereo and many of the sound effects have been edited to 'exist' in some portion of stereo space according to the sketch's determination. Many Arduino experimenters have had issues even getting the DFPlayer Mini's to work, let alone play nice, but I found that I could cue up sound files INSTANTLY via using the SoftwareSerial command in Arduino and addressing the players directly. Since I did this it is not readily possible to receive telemetry back from the players. Even though the receive line is wired through from the player's TX to the SoftwareSerial designated RX, this was done simply because SS takes up that pin regardless. There have been issues on my end with hash noise in the audio and I've tried to mitigate this with short lead lengths, large caps and even an inductor on the power feed of the final amp. The powered speaker outputs of the players are PWM bridge types and are not good for mixing but the DAC outputs worked fine. Both SOUND and MUSIC volumes can be set permanently via the Core Menu and temporarily together using the ARRANGE and DROP buttons during the Splash Screen.
Haptic Feedback is provided via two game controller rumble motors controlled by small 2N7000 MOSFETS and other component. When the columns land, you sideswipe a wall or resting jewel, and especially as jewels are removed - YOU FEEL IT! I've seen builders opt for the TO-220 high current MOSFETS which is overkill... just look up the datasheets for Pete's sake! ;-) The option to allow for operation (or not) is made through the Core Menu. Smaller motors, shakers or phone vibrators can be used.
POWER is a beast on my version and includes a buck converter (down voltage), boost converter (up voltage), the hacked battery management controller board from a Jackery brand cellphone lithium-ion power bank, a circuit to cut off game operation on the connection of a charger source and on-delay circuit to keep the battery board from going into protection mode because of the initial current requirements of the game. A BETTER SOLUTION could be had through a custom battery and power management circuit, as well as making things smaller. I found that I had fewer issues if I could get a solid 5v to the LED's, 7.5v to the Arduino and 4.2v to the DFPlayer Mini's.
I cannot and will not guarantee that if you (the builder) tries to replicate my design, you will have success!
Aside from keeping lead lengths short and organized, you should be considering device current consumption, voltages and power requirements.
START OFF SIMPLE!! You can't really screw up your Arduino dev board if you aren't powering any of the outboard devices from it. Solder together a few rows of the addressable LED wafers (try 6 x 6) according to my description and change the numbers in the sketch to:
const int xField = 9; // Play field vertical dimension
const int xFieldLimit = (xField - 3) ; // Can't address LEDs that don't exist
const int yField = 6; // Play field horizontal dimension
Once you wire up the play field the sketch should work fine without all the other devices attached... at least I believe. Now wire up the buttons and you should be able to play a basic game!
If this works, expand the addressable LED field to what you like but keep in mind that on an Arduino UNO or NANO, the memory for this sketch is pretty much stretched to the max and making a field larger than 6 x 13 (which is the standard for the Columns arcade and console game) may tax things and erratic behavior may occur.
If this works then try out connecting the two LED numerical displays. They should connect end-to-end but like the field LEDs, the power should be run from a separate source than the Arduino! Also, on the MAX7219 LED display modules the "LODA" is just the output of the first module that goes to the "CS" of the second. Everything else is mostly self-explanatory. If this runs you'll now have scores and info.
If all that works then the audio will be the hardest and trickiest part! They should work if you build according to the schematic but assume that the irritable cheap little modules are going to throw you for a loop.
Please refrain from messaging me with questions about it as I wouldn't know where to start, let alone, not psychic. As far as the component circuits are concerned, at least FIRST try building them on a proto-breadboard.
Why not add those rumble motors? - Arduino 101. If you can't get them for more than a few buck on eBay, then find an old 360 game controller and purge the ones from that one. The motors should be rated at 5v and won't draw too much current.
On Amazon or eBay... ALWAYS SEARCH separately for BEST DEALS and ratings regardless of any links that are provided here!
ARDUINO Nano or ARDUINO UNO R3 Support Arduino by purchasing authentic Arduino products!
100 pcs WS2812B Black LED Chips with Black PCB Heatsink (10mm3mm) WS2811 IC Built-in 5050 SMD RGB DC5V
Dim It Light Dimming Sheets
4PIN Conductive Silicone Soundless Tactile Tact Push Button Micro Switch Self-reset 8x8x5MM
8-Digit 7 Segment Module MAX7219 8 Bit Digital Segment LED Display
DFPlayer Mini MP3 Player Module
PAM8403 Module Super Mini Digital Amplifier Board 2 3W Class D 2.5V to 5V
2" 4Ohm 3W Full Range Audio Speaker
XL6009 DC-DC Adjustable Step-up Boost Power Converter Module
LM2596 Power Supply Module DC/DC Buck 3A
Jackery Portable Charger Bar 6000mAh Pocket-Sized External Battery Pack
FAIRCHILD SEMICONDUCTOR FQP27P06 P CHANNEL MOSFET, -60V, 27A, TO-220
NE555 Timer IC
Vibrator Rumble Motors Hammer Left Right Motor for Microsoft Xbox 360 Controller
2n7000 n-Channel MOSFET Transistor Assortment 60V 200mA to-92
For additional discrete components, check Digi-Key, Mouser, eBay and Amazon
A CASE FOR THAT:
The plan is to install the final project into an attractive 3D-Printed case of an appropriate aesthetic - maybe something with a Greco-Roman appeal. The more fascinating part will be in the play field! I plan on sandwiching several materials to give the appearance of real gem stones floating in the view screen. There is the layer of LEDs, of course, but then I could apply a diffuser to spread the light, since the current affect is that of small circles. Next, I would like to add a layer of acrylic gem stones. I own a batch of these already for this project and would like to try filing down the sides and bottom, affixing them together in a grid pattern. Next, will be the Dim-It LED display diffuser/darkener (link above) which will hide everything but the light, and finally a layer of scratch-resistant polycarbonate to hold everything in. A Dim-It sheet and polycarbonate layer will also be added on top of the numerical LED displays. With everything in the 3D-Printed case, custom laminated decals will be added to give the game a classic commercial look. A fantastic local print shop named DQP can handle that well.
Shown above: The two images on the right test to see how an acrylic hobby decoration gem stone may look when coupled with an RGB LED.
The image on the left is one of many concept renderings using Thea Render to experiment with different material characteristics such as light diffusion, background dimming, refraction and caustics.
There are definitely a few more tweaks I'd like to do to both the sketch and hardware, especially before I design and implement a 3D-printed enclosure. I've run out of memory to add any more so some features may be realized on an Arduino Mega. It's interesting to see that the Arduino IDE compiler says that I've only used 95% of programming space and only 71% of dynamic memory space. I'm pretty sure that the memory architecture of the AVR IC does a few gymnastics and thus, the measure of what is usable is not so cut and dry.
1) I would like to add a Slow-Down feature to the dropping column by pressing, maybe two of the buttons at once. I hear this is a feature to the console version of the game and would serve as a set of brakes to give the player a chance now and again.
2) I need to do more tweaking on the movement control at faster speeds. This is a "1st-world problem" of course, but after a few months of getting good at my version of columns I find that going Left or Right sends the column too far when the speed level is fast and it's hard to control things. ALSO, for some reason, moving Right at fast speeds causes more multi-space movements over going Left. Could one switch be more sensitive? Strange.
3) I'd like to enhance scoring and bonuses a bit more and somehow allow for a little more reward for certain strategies.
4) Battery Low warning during actual game play.
5) "Game Over" on the LED display... actually, "ga|ne Ouer" or not.
For an expanded memory platform:
1) I would like to add the Columns Flash alternate game. This one has you hovering at the top and doesn't go until you push Drop. The field is nearly filled up to start, and there's a blinking jewel at the bottom. The goal is to make your way down to that jewel as quickly as possible.
2) A timed version of Columns.
3) Doubles Columns, or competitive pairs Columns for two players to compete.
4) A more awesome Splash Screen.
5) A leader board and the use of three-letter player initials.
1) Maybe combine the START button in with the ON/OFF button.
2) A custom battery and power management board. This would save space.
3) Smaller speakers and rumble motors, for that matter; a smaller battery, smaller play field LEDs and smaller numerical display LED panels.
4) Custom PCB to reduce wiring.
LATER - I will add a game play and description video along with a more detailed breakdown of the sketch and circuits...
Other more specific
settings would be set inside the Global Variables section of the Sketch.
Play Field -
started off with this 10 x 10 sheet of WS2811 RGB LED (5050)
from BTF-Lighting, embedded on PCB wafers and classified as WS2812B.
The FastLED library sees them fine, but be sure to designate
part number type in the sketch command. Each wafer is
around each side and is easy to snap apart. Each wafer
shown in the following wiring diagram, a 6 x 13 element panel can be
created by breaking down the provided panel to give you a 6 x 10
element section. The LED wafers should always point the same
direction which is best for not only wiring, but the viewing angle (and
color fringing effect) of RGB sub-elements as viewed from a distinct
orientation. Attach another 4 x 3 element section on top and
x 3 section to the side of that. Stack three on top of each
for the preview column jewels.
The green wire path shown (above) represents the data signal line from the Arduino. You MUST insert a resistor (330 to 1k ohm) in the data line or the first LED segment may burn out. This is a documented issue noted by other builders. The data line is daisy-changed between each LED wafer [from D-Out to D-In] and is "Zig-Zag" wired from bottom to top. It 1st LED will be the one on the bottom right when viewed from the front. "Serpentine" wiring or any other scheme can be used as well except you will have to alter the part of the sketch that assigns each LED a number to match an X-Y array position.
The +5 Volt and Ground
should be distributed via 'rail' along the sides to held distribute the
current more evenly throughout the LED group as color changing could be
an issue. Power can be linked between all middle connections
FIRST - NEVER Power more
than 3 addressable RGB LEDs from the Arduino's power supply pins,
especially from USB power!
Each LED wafer will consume a minimal of 20ma each (for it's built-in microcontroller) when all RGB elements are completely off. Each element, R,G & B can typically consume up to 60ma EACH at full brightness and the total current draw for EACH wafer can be between 60 ~ 80ma total. This can add up! Under test, using my constructed panel at full brightness, I was drawing around 4.8 amps, and that is enough to easily set smaller bodge wires in a circuit on fire! Fortunately, at the default game setting for RGB LED Brightness of "170" and considering that the typical jewel play field will consist of not quite a full panel of more specific jewel colors, my setup measured around 300ma of current consumption. There is also a physical issue of heat creation and dissipation of the LEDs. They can get really hot if enclosed between sheets of plastic and ran too brightly without some kind of cooling... for example, I melted a Dim-It tinting sheet. Luckily it only left recessed dimples in the sheet and didn't permanently glue it to the LEDs.
WARNING: Upon starting up this sketch with an affixed LED panel such as this, for the first time, go into the Core Menu and make sure the RGB LED Brightness is set to 170, the default. Do this before connecting the LED panel. Use a wiring gauge that keeps things safe. 16 awg wire for the rails and 20 awg for the internals is fine. The data line can be any thin bodge wire.
Battery Managment System / Battery Voltage Reading -Working with Lithium-Ion rechargeable batteries is no light matter. If they are pierced or too much current is drawn for the cells or they are overcharged or underchaged, a violent fire or explosion is a sure result! A BMS circuit is a requirement for any project and there are many options and parts to choose from. There needs to include a few safety features as well. I felt that it would be easiest to 'hack' an existing cellphone external battery pack to save time and trouble.
So here are a few modifications I made to a Jackery brand 2A, "6000"Ahr charger pack:
You can get one on Amazon: Jackery Portable Charger Bar Power Outdoors
You do NOT need to take the unit apart as I have! There is no need but you won't be able to read the battery level without access to the cells and that feature will have to be dissabled in the Sketch.
176 bool batteryShow = false;
Simply run power via USB to your Arduino and connected modules, but if you're not affraid to crack one open...
1) The thermistor (on tiny wires) MUST stay affixed to the surface of both batteries to protect against thermal runaway. You can solder extension wires to the BMS board.
2) The Flashlight option supplies current to a white LED when the power button is held for more than 2 seconds. Determine the polarity by observing how the LED is oriented before you de-solder it. Run new wires to a 5v optoiscolator such as a 4N35. You cannot read one of the leads to the LED on an Arduino as the BMS only loads power when it detects a need for current from the LED. The signal from the opto can cue up the Core Menu or whatever.
3) Many BMS boards and phone chargers follow a certain protocol to limit or allow a maximum of current to a partiuclar phone, or it's like a "handshake" between devices. You can see some info on that HERE. For most devices, if you connect the Data+ and Data- on the USB output socket on the charger it supposedly will tell it that the device is to act like a "dedicated charger" and allow for the full current amount, which in this case is set to 2 amps.
4) Voltage Reading: Analog Pin A5, R6 and "R7". Not all BMS circuits allow to read a voltage potential between the battery's positive lead and ground potential as there are isolated configurations, but if it will read then the Arduino has a way to see the remaining charge left during operation. Most Arduino project schematics show using lower-value resistors in a resistor-divider for reading analog voltages. 1k to 10k ohm values on the top and bottom are fine for projects reading sensors, but a Li-ion battery can be drained by a parasitic path through little resistance and when the Arduino is off, the battery is still dying! Just use a higher resistor values such as 1M ohm and battery drain will be a thing of the past. So here is where "R7" (on the schematic) comes in. Normally, if you are using lower values (10k) than any paths inside of the Arduino AVR IC connected to the analog pin looks like a point of high-impedance, but if you ever read the voltage on an unused analog pin to ground potential, you may see something like 850k ohms! Since this is the case, when I use a 1M ohm as the top resistor in the divider network, the 850k ohms in the Arduino now acts as the bottom. Yes, it works. I used a 1M ohm to provide as little game-off battery leaking as possible without causing the analog reading any issues. You could try using the same resistance value as you measure on the Arduino pin and that will make the math simple, but I used trial an error, taking note of the high and low analog readings in a script and applying that to the math to yield a percentage of battery charge. You'll have to do some trial and error of your own if taking on this project or any that may use a Li-Ion charger to power.
More to come...