Arduino Nunchuk 8x8 LED Matrix Maze Game

by Progetto Company in Circuits > Arduino

284 Views, 3 Favorites, 0 Comments

Arduino Nunchuk 8x8 LED Matrix Maze Game

maze_game_thumbnail.jpg
ChuckConnect Arduino Maze Game Demo

DISCLAIMER: CERTAIN COMPONENTS USED IN THIS TUTORIAL ARE FOR SALE BY THE AUTHOR


During this tutorial, you'll create a simple maze game using an Arduino, a Wii Nunchuck, and an 8x8 LED Matrix. All the code for this project is open source, and we'll build the code step by step so you can learn how it works and make your own modifications. Be sure to see the video above for a demo!

Supplies

supplies.jpg

To build this project, you'll need:

  1. An Arduino of some variety. I am using an Arduino Nano here, but this project should work with other Arduino boards. If you choose one with more SRAM and EEPROM, you can create larger mazes!
  2. Plenty of male-to-male and male-to-female jumper wires; I used 4 of each
  3. A half-pint breadboard or larger
  4. A ChuckConnect Wii Nunchuck connector kit: https://www.tindie.com/products/Progetto/chuckconnect-mountable-wii-nunchuck-connector-kit/
  5. An 8x8 LED Matrix with an I2C Backpack: https://www.adafruit.com/product/1614. You should be able to use a smaller matrix or one that's a different colour without modification. However, if it's a bi-colour LED matrix or has more pixels, you'll probably need to tweak the code.

Wiring

Maze Game_bb.jpg
wiring.jpg

The wiring for this project is simple as both devices use the I2C bus. See the diagram above. As for power, this project runs fine with power from the Arduino's USB port.

(Optional) PlatformIO Setup

platformio.jpg

The code used in this project is a bit more involved than any of our previous projects, and I wanted to split it into multiple files to keep the code tidy. To make things easier on myself, I decided to use Visual Studio Code for this project with the PlatformIO extension.

  1. Please follow this link to install Visual Studio Code: https://code.visualstudio.com/download
  2. Then, set up the Platform IO Extension: https://docs.platformio.org/en/stable/integration/ide/vscode.html#

If you're using a different Arduino board, you'll have to edit platform.ini; see here for details: https://docs.platformio.org/page/projectconf.html

If you prefer the Arduino IDE, you should be able to move the files from the lib/Maze directory to your Arduino Libraries folder and rename the main .cpp file you wish to run in src to a .ino file and install the libraries using the Arduino IDE. For more details and a potentially automated way to do this on Linux (I have not tested it), see this link: https://runningdeveloper.com/blog/platformio-project-to-arduino-ide/

Download & Open the Code

github.JPG
platformio_opne.jpg

This project's code is open source and can be found on GitHub: https://github.com/ProgettoCompany/WiiMazeExplorer

Please download or clone the code (as is your preference) and import it into PlatformIO:

  1. Start PlatformIO in Visual Studio Code (click on the extension on the left bar and click Open under Quick Access > PIO Home)
  2. Click Projects in PIO Home
  3. Click Add Existing and navigate to where you downloaded the code from GitHub

Setup & Test the LED Matrix

upload_code.jpg
step_4.gif

To use the LED Matrix with an Arduino requires installing some libraries; these libraries should be automatically installed by PlatformIO when you open the project.


If you're using the Arduino IDE, please follow the guide below to install the necessary libraries and test your LED matrix.

https://learn.adafruit.com/adafruit-led-backpack/1-2-8x8-arduino-wiring-and-setup


First, open main.cpp in the src folder and open step_4.cpp in the steps folder. Replace all of the code in main.cpp with the code from step_4.cpp. This code draws an upward-pointing arrow so the player knows which way is up and plays the end animation (a series of concentric squares), which happens if you win.


If you changed the I2C address using the jumpers on the backpack's rear, you will need to update the following line:

matrix.begin(0x70)

Note that you'll have to do this for all subsequent code files!


Upload the code using the dropdown in the top right.


Test the Wii Nunchuck

serial_monitor.jpg
serial_monitor2.jpg
PXL_20250415_031519993.jpg

First, open main.cpp in the src folder and open step_5.cpp in the steps folder. Replace all of the code in main.cpp with the code from step_5.cpp. This code prints the direction in which the joystick moves to the Serial Monitor and keeps track of the player's position in a global variable, similar to how we'll do it in the final version of the game.

If you're using the Arduino IDE, install the NintendoExtensionCtrl library for this part.

In case you're interested, the reason this library was chosen was because many other libraries did not work, and this popular library utilized too much SRAM for the Arduino Nano: https://github.com/madhephaestus/WiiChuck

Upload the code and open the Serial Monitor using the dropdown in the top right.

Generating the Maze

step_6.gif
serial_monitor3.jpg

We're going to use Maze library now. I chose not to split it into parts for simplicity, but we'll only start with using a couple of functions at a time. Once again, open main.cpp in the src folder and open step_6.cpp in the steps folder. Replace all of the code in main.cpp with the code from step_6.cpp.

If you're using the Arduino IDE, you'll need to copy the Maze library code to your libraries folder (move the source files from within the Maze library's src subfolder but not the subfolder itself).

Maze.hpp lists two types: MazePosition and Maze.

  1. MazePosition stores a row and a column and is used for storing positions in the maze, including the start and end, as well as the player's current position.
  2. Maze handles the maze itself, including generation and some helper functions. Internally, the maze is a two-dimensional array of bytes, including the start, end, walls and empty spaces.

To generate the maze, we use a recursive backtracking algorithm, heavily based on professor-l's implementation: https://github.com/professor-l/mazes/blob/master/scripts/backtracking.js

For an excellent explanation of how the algorithm works and an animation of it in action, see their website:

https://professor-l.github.io/mazes/

The rest of the code just prints out the generated maze to the serial monitor and prints a portion of the maze to the LED matrix, as well as the blinking character at the maze's start position. The character blinks at a configurable frequency to distinguish it from the maze's walls.

Moving the Character Around and Adding Game Logic

step_7.gif
serial_monitor4.jpg

Start by replacing the code in main.cpp with the code in step_7.cpp.

We're almost there now. I've added back the nunchuck controller code and you should be able to move the character around on the display and the serial monitor, the movement might feel a little clunkier depending on the size of the maze as it takes a bit for the Arduino to print the maze to the serial monitor, to disable that behaviour, comment out:

#define DEBUG_PLAYER_POSITION

You'll notice the player is always in the same pixel and that we move the maze around it to give the illusion of movement; this is a common practice in video games. We also make sure the player can't go through walls by checking if the pixel the player is trying to move to is a wall. If it is, we don't move the player.

Lastly, the end position also blinks like the player, and when the player reaches the end, we play the win animation and generate a fresh maze.

The maze gameplay is finished; the rest of the code just adds quality-of-life features.

Using EEPROM

step_8.gif

EEPROM stands for Electrically Erasable Programmable Read-Only Memory; the Arduino Nano has 1 KB of it, and it allows us to store data between resets and power cycles. For now, we'll store the matrix's current brightness and allow it to be toggled with the Z button on the Nunchuck controller.

Replace the code in main.cpp with the code in step_8.cpp and upload it to your Arduino.

Storing the Maze in EEPROM

step_9.gif

Replace the code in main.cpp with the code in final.cpp and upload it to your Arduino.

This is the final code! We made it. The maze is now stored in EEPROM and can be regenerated (and saved to EEPROM) using the C button on the Nunchuk controller. Note that 1 KB or 1000 bytes limits the size of the maze we can generate as each cell in the maze is stored as one byte, and the brightness takes one byte. Plus, we create a simple checksum at the end of the maze to see if we're reading a valid maze. This checksum is incredibly simple and likely could be improved.

The way the maze is stored in EEPROM could be optimized for better memory efficiency. Perhaps the coordinates of the start and the end of the maze could be stored first, and then the maze could be stored as bits where 1 is a wall and 0 is empty. This would be much more complicated, but if you're looking for a coding challenge, give it a shot! One problem you might run into, however, is that the SRAM required to load larger mazes into the Arduino's memory could cause the program to freeze, requiring further memory optimization.

Conclusion

PXL_20250314_030912820.TS_exported_0.jpg

Congratulations, you have created a maze game! Feel free to remix and improve this project to make it your own! Maybe add a case, battery power, or more levels and game mechanics like obstacles or enemies. You could also use a bigger display or one with multiple colours!

If you have any questions, comments or concerns, feel free to email me at progettocompany@gmail.com

Happy hacking!

John Wolf

Progetto Company