Introduction: MatTris — Tetris on an LED Matrix
Meet MatTris, a DIY Tetris console built completely from scratch.
I was born in 1998, and my first introduction to Tetris was through those monochrome LCD handhelds that came loaded with 10 to 100 built-in games. That’s what inspired me to build my own version using modern hardware.
Years later, while working with addressable LEDs and microcontrollers, I wanted to recreate that same experience, but using hardware I designed myself.
This project began with the idea of using a WS2812B mini LED matrix as the display, paired with a microcontroller (Waveshare RP2040 Tiny) to control the matrix and handle all game logic.
To bring everything together, we designed a custom PCB that integrates a 14×20 LED matrix, input buttons, and a dedicated power management circuit. The entire system is powered by a LiPo cell, with an onboard power management IC responsible for charging and discharging the cell.
This Instructables covers the complete build process of this project; let's get started.
Supplies
The following materials were used in this project:
- Custom PCB (Provided by HQ NextPCB)
- RP2040 Tiny Waveshare board
- WS2812B 2020 Package LEDs
- 100 nF Capacitors 0603 Package
- 10 uF Capacitor 1206 Package
- IP5306
- 10 uH Inductor
- Indicator LED 0805 Package
- USB Type-C port
- Push Buttons 6x6 SMD
- 2 Ohms 1206 Package
- RP2040 Tiny Programmer
- 3D Printed Enclosure
Step 1: 3D MODEL
This project started in Fusion 360. We first imported the 3D models of the WS2812B 2020 package LEDs into Fusion, along with the CAD models of the SMD switches, USB Type-C port, RP2040 Tiny, and the battery.
We then designed a 91 × 47 mm PCB. The upper section of the board was dedicated to the RGB LEDs, where we used the pattern feature to create a 14-row by 20-column LED matrix. In the lower section, we placed the SMD switches following a Game Boy–style layout, with a D-pad consisting of UP, DOWN, LEFT, and RIGHT buttons, followed by the A and B buttons.
The RP2040 Tiny was placed on the backside of the PCB. Alongside this, we also modeled an enclosure to hold the PCB securely in place, cover the backside containing the battery, and make the device comfortable to hold. We even added a ring at the top of the enclosure, which serves as a design element and allows an ID card strap to be attached so the device can be worn as a badge or hung somewhere.
After finalizing the model, we exported the enclosure mesh and 3D printed it on my new Anycubic Kobra S1 using Hyper PLA, and the print turned out really clean. I had been using an Ender 3 for a long time, and this upgrade turned out to be exactly what I needed for projects like this.
We also exported key dimensions for component placement, board outline, and general layout reference. These dimensions were later used during the PCB design process.
XIAO TETRIS
Step 2: PCB DESIGN
The PCB design process begins with preparing the schematic for the project. In our case, we had previously worked with WS2812B 2020 package LEDs. These LEDs are not the easiest to work with because of their small size, but that same compact form factor is exactly what makes them ideal for matrix-based projects.
We reused the schematic from our earlier 8×8 Tiny Matrix project as a starting point. Instead of an 8×8 layout, we expanded the design to a 14×20 matrix by adding more LEDs.
We then added another section to the schematic for the RP2040 Tiny board, which was connected to six push buttons. All buttons are connected to GND and individual GPIO pins. When a button is pressed, it pulls the corresponding GPIO pin low, and the microcontroller registers this as a button press.
We used the Waveshare's RP2040 Tiny, which is an RP2040-based SMD development board designed to be mounted directly onto a PCB as a module, similar to ESP-12F or ESP32 modules. The RP2040 Tiny features castellated pads, which allow it to be soldered onto the backside of the PCB and integrated cleanly into the overall design.
Check out its wiki for more info—https://www.waveshare.com/wiki/RP2040-Tiny
For power, we’ve included our trusted IP5306—a power management IC we’ve used in many previous projects. It provides a stable 5V output from a 3.7V lithium cell and includes features like charging indication, low battery warning, and high/low voltage cutoffs, all essential for safe lithium cell operation.
Attachments
Step 3: STENCIL PROCESS
We started the circuit assembly process by applying solder paste to the PCB, but there was a slight problem. The number of components used in this project is quite large, which also means a very high number of pads. Because of this, using a solder paste dispensing syringe would be impractical. Instead, we used a custom stencil made specifically for this circuit.
A stencil is essentially a thin metal sheet with laser-cut slots and holes that match the component pads on the PCB. Using a stencil allows solder paste to be applied evenly across all pads. In industrial settings, where circuits are mass-produced, stencils are commonly used for this purpose.
- We first set up a makeshift PCB and stencil holder using extra PCBs. This setup helped keep the main PCB stationary and ensured it did not move during the process.
- After aligning the stencil openings with the PCB component pads, we applied solder paste over the stencil and used a scraper to spread it evenly across the slots. This process deposited a thin, uniform layer of solder paste onto each component pad, preparing the board for component placement.
Step 4: SMD COMPONENTS PLACEMENT PROCESS
Now comes another tedious process: SMD component placement. It is tedious because of the sheer number of LEDs used in this project. In total, we used 280 LEDs along with several other SMD components, bringing the overall component count to over 300. All of these components had to be placed manually.
- We started by placing the 100 nF decoupling capacitors in their designated locations. For the pick-and-place process, we used ESD-safe tweezers.
- Next, we placed all 280 SMD RGB LEDs onto their pads, making sure each LED was oriented correctly, as incorrect orientation would prevent the LEDs from working.
- After the LED placement, we added the remaining SMD components, which included the SMD push buttons and all the parts related to the power management circuit.
- Once all components were placed, the entire board was carefully lifted and placed onto an SMD reflow hotplate. The hotplate heats the PCB from below up to the solder paste melting temperature, which is around 200 °C. As a result, all the components are soldered securely to their pads.
Step 5: TESTING SMD LEDs
Before we move ahead with the placement of the RP2040 board on the backside of the PCB, we tested whether the LEDs were working or not. If the LEDs were not working and the RP2040 was already mounted on the back side of the PCB, we would not be able to use a hot plate to correct the LEDs.
We added jumper wires to the 5V, GND, and GPIO0 terminals of the RP2040. These jumper wires were then connected to a XIAO SAMD21 M0 development board.
We uploaded the sketch below to the XIAO, which turns on each LED in the chain one after another in green. This sketch was taken from the example sketches of the Adafruit NeoPixel library.
Step 6: RP2040 ASSEMBLY
After confirming that the LEDs were functioning, we move onto the RP2040 assembly process, which begins by turning the board over, placing 2040 Tiny in its location, and then soldering all the pads with its castellated terminals with a soldering iron.
Step 7: MAIN CODE
We then moved on to flashing the main firmware onto the RP2040 Tiny. Using the supplied FFC ribbon cable along with the USB adapter board, the microcontroller was put into BOOTSEL mode by holding the BOOTSEL button while connecting it to USB. Once detected, we uploaded the main code to the board.
Let's have a breakdown of the code we prepared for this project.
We use the following libraries that allow the LED matrix to work like a tiny pixel display.
- Adafruit_NeoPixel
- Adafruit_GFX
- Adafruit_NeoMatrix
Matrix configuration
The game runs on a 14×20 LED matrix, which matches the classic Tetris playfield.
MATRIX_PIN is the GPIO driving the WS2812B data line.
This section defines:
- LED layout direction (top-left origin, row-wise wiring)
- Color order (GRB, standard for WS2812B)
- Signal speed (800 kHz)
Button inputs
All buttons use INPUT_PULLUP, and pressing a button pulls the pin LOW
Timing and debounce control
These values controls Normal falling speed as well as Fast falling when speed button is held
and preventing accidental rapid movement or rotation.
Game grid and state
This section represents the playfield; 0 is an empty cell, and 1 is the occupied cell.
This tracks the current piece position, rotation state (0–3), and which tetromino is active.
Tetromino definitions (core of the game)
There are 7 pieces (I, O, T, S, Z, J, L); each piece can rotate 4 times, and each rotation is a 4×4 matrix.
Collision detection
This function checks if the piece is inside the matrix bounds and if it overlaps an already placed block.
If any block collides, placement is rejected.
Locking a piece into the grid
When a piece can’t fall anymore, its pixels are copied into the grid, and the piece becomes part of the playfield.
Line-clearing logic
This function scans each row, and if a row is completely filled, all rows above are shifted down and the top row is cleared.
Spawning new pieces & game over
This function randomly selects a new tetromino, which starts at the top center. If it cannot be placed immediately, the game is over.
When the game gets over, the screen turns red, the grid is cleared, and the game restarts.
Rendering the game
This function is an important one; it clears the screen and draws locked blocks in green. The actively falling pieces are drawn in blue.
In the setup function, the LED matrix is initialized, the brightness is set, the button pins are configured, the random number generator is seeded, and the first tetromino is spawned.
The loop() function handles button input for movement, rotation, and speed control, manages gravity-based falling using timers, performs collision detection, locks pieces in place, clears completed lines, and redraws the screen every frame.
Step 8: THROUGH HOLE COMPONENT PLACEMENT PROCESS
After testing the code, we installed the final through-hole component: the USB Type-C port.
We used a power-only Type-C connector with just positive and negative terminals and no data pins. The connector was placed from the top side of the PCB and soldered from the bottom side using a soldering iron.
With this step completed, the board assembly was finalized.
Step 9: POWER SOURCE
To power the project, we used a 3.7 V 650 mAh LiPo cell, with its positive and negative terminals soldered to the battery connector provided on the back side of the PCB.
Pressing the power button once turns the circuit ON, while pressing it twice turns the system OFF.
Since we use the IP5306 power-management IC, an onboard status LED provides visual feedback—blinking during charging, remaining solid when the battery is fully charged, and blinking again when the battery voltage drops to a low level.
Step 10: ENCLOSURE ASSEMBLY
We first place the main circuit over the 3D-printed enclosure, then use four M2.5 Torx bolts to secure the enclosure with the PCB. On the backside, we have given a window or a slot that allows the user to access the FPC Connector for reprogramming the RP2040 Tiny.
Step 11: RESULT
Here’s the end result of this small yet tedious build: a working RGB matrix–based handheld game console that runs a custom version of Tetris. We created the LED matrix board from scratch and paired it with an RP2040-based microcontroller and onboard power circuitry to make a truly portable handheld device.
For now, the setup works perfectly. We can control the tetromino shapes using the left and right buttons, rotate the shape using the rotate button, and even speed up the falling blocks.
The onboard LiPo cell provides around 4 hours of battery backup, which is quite decent. This runtime can be extended further by reducing the brightness of the LEDs, which lowers overall current consumption.
This game console can also be reused for future ideas. While the current implementation runs a homemade version of Tetris, the same hardware can later be used for other games, as an interactive badge, or as a general-purpose LED matrix display for text and simple graphics. Let me know in the comments what game I should try next on this device.
All the details are covered in this article—feel free to reach out if you need any help regarding the project.






