All source files for this project are available here: https://github.com/Jianan-Li/Tiny-Tetris
Before talking about the Tiny Tetris itself, I need to say that there are a couple firsts with this project:
First time using the laser cutter to make enclosures.
First time using a stencil for applying solder paste.
First time using a toaster oven to reflow PCBs.
First time using an IC in QFN package with 0.5mm pitch (ATmega32u4).
There are two things I don’t like about my previous Tetris Gaming Device. First, it’s too bulky. It doesn’t fit in my pocket, so I can’t bring it anywhere with me. Second, it’s not rechargeable through usb. The battery used in the Tetris Gaming Device is a 7.4V 2S LiPo battery, so you’ll have to use the special LiPo charger to charge it instead of usb.
That’s why I decided to make the second generation of the Tetris Gaming Device. Introducing the Tiny Tetris!
The size of the Tiny Tetris is 94.0 mm (3.70 inches) x 49.5 mm (1.95 inches) x 17.1 mm (0.67 inch). It is powered by a 3.7V LiPo battery and is rechargeable through its micro usb port.
On the left side, there are two general purposes buttons, which I configured to adjust the brightness of the LED display in my demo program, and two indicator LEDs for power and charging respectively.
On the right side, we have a reset button that is connected to the reset pin on the MCU.
On the top, there is a pushbutton power switch. The circuitry used is essentially the same as the breakout board that Adafruit sells.
On the bottom, there is the micro usb port for both charging and programming the MCU (ATmega32u4), and also a 6-pin ICSP/ISP header for flashing the bootloader and setting the fuses with USBTiny or other AVR programmers.
There are a couple things I want to talk about in this post, including the enclosure design, the pcb design and component selection, and then the software.
First, let’s talk about the enclosure design. On the old Tetris, the enclosure is 3D printed on a Stratasys 3D printer. Since I wanted to experiment with different tools and machines in my projects, I decided to laser cut the enclosure for the Tiny Tetris in our student machines shop.
It’s not easy to get the power and speed settings right on a laser cutter, and you’ll have to design the kerf into each piece to get the correct dimensions. The picture above shows about a third of all the tests that I did using scrap acrylic pieces to get everything right.
The design I used consists of six pieces of acrylic: top, bottom, and the four sides. The side pieces have tabs both on the ends and sides, so all the sides pieces can be connected together, and then plug into the top and bottom pieces. The eight holes and the top and bottom pieces are for the flat head M2 screws. If you look carefully at the screw holes, you’ll see that they are countersink holes. I did this with the 3D engraving feature that is available on the Universal Laser Systems. It turns grayscale images into three-dimensional engravings, so all I have to do to countersink the holes is to draw a circular grayscale gradient around the holes.
I used the same technique to 3D engrave the area around the joystick/navigation switch to allow the movement of the switch without exposing too much circuit board from the top, and also the area around the micro usb port to be able to use any micro usb cable with this device.
The design of the buttons on this acrylic enclosure is inspired by this clock kit from Evilmadscientist. When pressed the acrylic would bend just enough to trigger the pushbutton mounted on the pcb inside.
Here is a picture showing the thickness breakdown and how everything is fastened together.
Next, let’s talk about the pcb design and component selection.
I went through a total of four iterations of the pcb design, and they are named Tetris v1.0 ~ Tetris v1.3 as indicated on the pcb. There is a huge difference between v1.1 and v1.2 since I made the decision to replace the ATtiny85 with the ATmega32u4, whereas the difference between v1.0 and v1.1, and v1.2 and v1.3 is not so significant.
Moving from v1.0 to v1.1, I changed the way that the 8-pin headers are connected to the pcb by increasing the hole size. Here are pictures showing the difference between the two.
Moving from v1.1 to v1.2, I decided to replace the ATtiny85 with the ATmega32u4. The main reason is that I realized I wanted to be able to measure the battery voltage and have the device automatically turn off when the voltage is below a certain threshold. This feature requires two more pins – one with ADC to measure the voltage and the other to kill the power – and this means that if I stick with the ATtiny85, some of the pins will have dual functionalities, and it would be even more troublesome to run SoftwareSerial at the same time. So in order to make the device more reliable and function more predictably, I decided to use the ATmega32u4 instead. But this is not a decision that can be made at any time of the day. I was lucky enough to find a small quantity of the ATmega32u4RC available on Digikey. Now if you don’t check Digikey regularly, you probably don’t know that all variants of the 32u4 have been out of stock for months, not only on Digikey but also other major distributors, due to the popularity of the chip. I couldn’t believe it when I accidentally found 71 of the RC version available on Digikey and immediately bought 10 of them.
Also, another change I made to the pcb design is that I added a tiny piece of pcb under the joystick so that it would be able to stick out above the top surface of the enclosure. In v1.1, the joystick is almost impossible to use when the pcb is mounted in the enclosure because it’s not as tall as the LED matrix. So i decided to add a small piece of pcb just for the joystick for better user experience. The two pcbs are aligned using two short pieces of resistor legs before and during the reflow process.
From v1.2 to v1.3, the only thing I changed is the location of the reset button, as I’ve found that it is easier to accidentally press the reset button when it’s located near the top on the right side of the device.
So in the final version, we have a total of five ICs on the board: MCP73831 for charging the battery, NC7WZ14 for latching the pushbutton power switch, TPS61240 for boosting the voltage from 3.7V to 5V, HT16K33 for driving the LED matrix and monitoring button presses, and ATmega32u4.
The joystick/navigation switch used here is the exact same part that was used on the Nokia 3230 cell phone. I remember asking my parents multiple times to buy that phone for me when I was in elementary school. The LED matrices are bought from Adafruit, and I bought two of every single color of the square dot matrix they carry. Finally the battery used in the Tiny Tetris is a 3mm thick 700mAh LiPo battery bought on ebay.
Here are some pictures I took when I was reflowing the boards.
Finally, let’s talk about the software. You might not believe it, but this is actually the first time I’ve ever written any C++ code. I wrote a total of four C++ classes, including a simplified version of the HT16K33 driver, the Tetris game, the Snake game, and a Draw/Paint program. I used the i2c.h instead of Wire.h for the I2C interface because I want to refresh the display at a fixed rate (50Hz) using a timer interrupt, and Wire.h made it impossible because it uses the timer interrupt to drive the I2C interface, and you can’t have one running inside the other.
Here are some pictures of the game play. I also did a demonstration in my short youtube video.
I mentioned above that I wanted to implement the self kill feature when the battery is below a preset value, so here is a GIF showing you what happens when the battery is low.
Before it turns itself off, a low battery symbol is displayed on the screen. After it flashes for 3 seconds, the kill pin on the 32u4 goes high, changing the state of the latching power switch circuit, and turning the device off.
LiPo Booster is a breadboard-friendly boost converter board based on the TPS61230 IC from Texus Instrument. It has an output voltage of 5V, and is designed to be used with a single cell LiPo battery.
For normal and half size breadboards, the LiPo Booster can be plugged into the power rails without blocking the vertical 5-pin strips. It can also be used with a tiny breadboard or breadboard of any sizes as shown below.
The Eagle design files and BOM can be found here: https://github.com/Jianan-Li/LiPo-Booster.
I printed my enclosure design and button\switch caps on a Dimension 1200 3D printer from Stratasys overnight on Monday. After going through a base bath to remove all the support material, everything fits together perfectly. Since I wanted to make the button\switch caps a different color than the main body, I spray painted them blue.
Here’s a picture showing the programming and charging ports (JST), along with the power and sound switches.
The top and bottom pieces are held together using four M3 screws.
Here are a few more pictures from different angles.
Figure 1: Tetris Gaming Device v2 Breadboard Prototype
For the past month, I’ve been working on the second version of my Tetris Gaming Device. This first picture shows you almost everything I’ve included in this version except for the two 8×8 RGB LED matrices.
One major difference between this one and the first version I made last September is that I’ve replaced the 74HC595 shift registers with LED driver ICs. The problem with using 74HC595 shift registers to drive the led matrix is that they can’t supply enough current though each channel. An example would be when you having text scrolling across the screen, and you can clearly see the dimming in columns that have more LED lit up than the others. To solve this problem, I decided to replace the two column (anode) driving shift registers with a single MIC5891 source driver from Micrel, and the six row (cathode) shift registers with three STP16DP05 constant current LED sink drivers from STMicroelectronics. After making these changes, the brightness of each LED won’t change at all no matter how many of them light up in each column. Absolutely fantastic!
Figure 2: Tetris Gaming Device v2 PCB, ordered from Advanced Circuits (4pcb.com)
I’ve also added several other components to the system. First of all, I’ve added an accelerometer breakout board to provide a motion controlled gaming experience. The IC on this breakout board is the MMA8452Q from Freescale. It talks to the ATmega328 over I2c at 800Hz and provides 3-axis acceleration with either 12-bit or 8-bit resolution. Next, I’ve added a vibration motor to provide extra physical feedback to the player. In the current Arduino sketch, I’ve decided to let it vibrate whenever a line is cleared for about half a second. Last but not least, I’ve added a second LED bargraph to make the pcb look more symmetric. The two bargraphs are individually controlled by the 328 and can be used for any kind and status indication.
Figure 3: Populated PCB with LED Matrices removed, everything hand soldered
This is my first time designing a PCB, and I inevitably made a couple mistakes in the PCB layout. The first major issue is that the eagle part I used for the LED Matrix is from one of SeeedStudio’s PCB, and its dimension is short by 1mm on each side. As a result I had to bend the pins on the two matrices in opposite directions to make them fit together. In future PCB designs, I’ll definitely check the dimensions for any part from non-major manufactures. Second, I placed the female programming headers way too close to the bottom edge of the board. I actually wanted the headers to be flush with the bottom edge, but, for reasons unknown, I just didn’t bother to check the actual dimension of the headers.
Figure 4: The PCB in its final form running Tetris!
I’ve already designed an enclosure for this PCB in solidworks, and it will be 3D printed tomorrow. Since I have a midterm this Wednesday, I don’t know if I’ll have time to make a video of me playing it right after the enclosure is done. However, I’ll definitely be on this week’s Show and Tell at 7pm on Wednesday, so be sure to check out that video or watch it live!