Snake on a Breadboard
"Got any games on your phone?"
"Not exactly."
Intro:
Simple to control, easy to program, and immortalized by the Nokia 6110, Snake has become a favorite project among engineers. Its been implemented in anything from LED matrices, LCDs, bookshelf lighting, and even windows of entire buildings. We'll be implementing Snake on a tiny breadboard and an OLED screen. People have certainly made tinier snake players, but this specifically uses a breadboard, removing the need to design PCBs or solder.
(You could just make an app on your phone, but we don't do things because they're easy.)
Prerequisites:
A basic understanding of circuits, how to breadboard, and a solid grasp of programming in Arduino.
Supplies
- Arduino Nano
- 2 reasonably high resistors (1kOhm)
- Tiny breadboard
- 2 Pushbuttons
- 22 AWG solid core wire
- 128 x 64 OLED
These are Amazon affiliate links so I earn a little commission with each sale. If you don't already have these supplies and want to support future projects of mine, follow these links! :)
Breadboard
In order to make our final product, we obviously have to assemble the hardware to program and test our project on. The system diagram for this project is fairly simple, since it only involves a total of 4 components.
1. Lay it out:
Take your components and lay them out on the board, ensuring that everything fits. Visualize what wires and pins you will be using and for what purposes. Make sure that your anticipated wires don't cross, because that makes for a messier breadboard. Write down what points you'll need to connect! Though this is a simple breadboard, it will make your life far easier during the wiring process and in general. Due to how small our workspace is, this is an incredibly important step.
Notes:
Because the OLED uses the I2C bus, pins A4 and A5 must be used. The size of the breadboard doesn't allow for a power and ground rail, so I used a few tricks to make everything work out. The positive voltage for the buttons are supplied by pins D13 and A2. I discovered that Arduino pins can not only supply current, but sink current as well, thus I used A3 as a ground for the right button. To maximize the space on the breadboard, I hung half of the Nano off of the board and supported the left side pins with a piece of foam.
2. Wire it out:
With a pair of wire strippers and a decent amount of 22 AWG solid core wire, neatly wire your components together. Using solid core for making semi-permanent breadboard projects is key, because you can trim them to length, unlike jumper wires. Make sure you don't leave a lot of excess length on your wires, it will make for a messy board. Trim the leads of the pull-down resistors so they fit flush with the board.
(You can also just follow what I've done above.)
Program and Test
To save yourself a headache later, make sure the OLED and the buttons work the way they're supposed to by making basic test programs.
1. Plan, plan, plan:
Just jumping right into code is not a wise practice. Trust me, I've tried! That's why you should outline how your program is gonna work. A program flow chart is a pretty solid way to plan out what your code needs to do and will definitely keep you on track. Take mine for example (above)
2. Code, code, code:
Frankly, this project is a bigger programming exercise than it is a hardware exercise. The only library I used was Adafruit's OLED library, not counting the supporting GFX and Wire libraries.
Make you install Adafruit's OLED library via the Arduino IDE's library manager.
I can't document every single line of code I wrote, but here are a few tips:
Tips:
Comments:
- First and foremost, write neat and useful comments while you code. Future you and others who read your code will definitely thank you.
Memory:
- With more complex projects like these, SRAM becomes quite the hot commodity. In the Adafruit library, the 128 x 64 OLED buffer takes up 1 kB alone, which is about half of the memory in an ATMega328p. Therefore smart memory management is more important than ever.
- With large data structures, the data held will accumulate and take up a lot of space. In order to reduce the memory footprint of my variables, I used smaller data types (like short and byte) when I could.
- Strings are usually stored in SRAM, but using the F() function will put them in PROGMEM instead, saving precious memory.
Millis:
- In order to achieve more accurate timing of game cycles, utilize the millis() function. There are plenty of good tutorials and examples online.
Pre-define:
- Use the #define preprocessor directive as an easy way to set permanent values in code.
Test:
- Test your code as you go. It will be a lot easier to rout out bugs.
Downloads
Enjoy!
Have fun with your new snake game!
(I know I won at 20 points in the video above, you can set the win condition higher in my code.)
Things to expand on:
- A battery for portability
- More secure buttons
- An even smaller snake game
- Even more games?