I came up with the following requirements. In addition it should use off-the-shelf hardware, be reliable, fairly robust and compact.
- Custom LED Matrix Display
- A way to drive it
- The NES version of Tetris
- Graphics streamed from NES emulator
- Controller support
- Usable with any laptop/computer
- Minimal color bleed between pixels
- Block Preview
- Score Display
- Hi-Score Display
- Integrated Speaker
- Support for multiple emulators
- Block statistics display
- Multiplayer ( NES version does not support this )
The basic idea is to have led strips stuck on a plate with a diffuser on top. These are driven by a micro-controller which receives data from a laptop/computer running emulator and some kind of custom script.
For the emulator I choose FCEUX, because it emulates Tetris very accurately, it has sound, joystick support and can be built for many platforms including raspberry pi. It also has a built in Lua interpreter which allows me to read pixels from the screen and send them to a serial port.
I used WS2812B LED strips, because they are widely available and fairly straightforward to drive. The LED strips act as a big shift register with individually addressable LEDs. They generate quite a lot of heat, so I decided to stick them on a sheet of aluminium to act as a heat sink.
People have written libraries for driving WS2812B chips for almost every platform, so I had a lot of options. In the end I settled with Arduino/AVR8. For the Arduino I used the Neopixels library and for the bare-metal AVR I used the light_ws2812 library. I had some ATMega16's so I used one of those. It has just enough RAM to hold 200 pixel values and then some.
There are really cheap 5 V power supplies designed specifically for powering these LED strips. Each LED draws 60 mA at full intensity, so a 12 A power supply is required for powering all 200 LEDs. I will also power the micro-controller, the score display and the Block Preview display from this supply, so max power will be a little over 12 A. I don't plan on running the display on max brightness, so it will probably draw around 4 - 6 A.
I had some salvaged seven segment displays from another project. The score display in the game has 6 digits, so I combined two 3 digit displays. I could have used the micro-controller to drive the display directly, but I'd still need a chip for multiplexing, so I opted for a simpler solution: The MAX7219 display driver. It has an SPI-like interface for writing to the display.
Block Preview Display
This could not be simpler: A 4x2 LED matrix using the same structure as the large matrix. It could even be chained to the data-out pin of the large LED matrix.