The so-called RhythGame is a rhythm game controlled by a single esp32 microcontroller, programmed using micropython. A rhythm game is a game where you press buttons (or pads) in rhythm to music. Well known rhythm games include Dance Dance Revolution, StepMania and Guitar Hero.
Read on to learn about this rhythm game we made - the background, the design and the result.
For more in depth on the micropython code used to run this game, check out part 2 (coming soon!).
Basically, it started with Sebastian visiting an arcade somewhere. This arcade had an interesting rhythm game called MaiMai, which consists of a round screen surrounded by 8 equidistantly placed large buttons. From the center of the screen symbols appear one-by-one, after which each symbol rapidly accelerates towards one of the 8 buttons. Exactly when the symbol reaches the outer edge of the screen, the corresponding button must be pressed. All this of course happens in rhythm of a song, in true rhythm game fashion.
Example MaiMai gameplay (unaffiliated youtube link)
At this time we were playing around with microcontrollers (mcu) and micropython, but only doing small projects, having a bit of fun with testing out various sensors and beepers and blinking leds. However, we were looking for a larger project to undertake, where we could challenge our creativity. Making our own version of the MaiMai arcade game, controlled only by an ESP32 mcu running micropython, seemed like an interesting project. The resulting game (if successful) could be something that could provide actual entertainment and be shown off as a good example of how powerful such a small mcu actually can be.
The observant reader may have suspected that the name "RhythGame" is simply a misspelling of Rhythm Game. This is a reasonable assumption considering that RhythGame is indeed a rhythm game. However, the spelling is not a mistake, and has a deeper meaning that will be further explored in the following sections.
No, actually it was just an initial misspelling that stuck around since it's a unique name that is easy to remember.
We decided to go for the same round design that MaiMai uses. For the back plate we initially thought to use 3 mm plywood, cut with a laser cutter to a perfect circular shape. However this turned out to be way too flimsy for a game about rhythmically punching buttons, so instead we cut a round back plate as well as a frame from an old table. Unfortunately we could not use the laser cutter for such a large and thick plate so we had to use an electric saw. It's quite hard to cut a perfect circle with an electric cut saw (or maybe we are just incompetent), but with some sanding and polishing it turned out reasonably well.
Instead of using a round inner LCD screen, like MaiMai, we instead decided to use 8 RGB led strip tracks coming out of the center. As the leds in these strips were all individually controllable, our thought was that instead of the symbols going outwards in MaiMai, we would simply have points of light (perhaps with different colors!) going outwards at a certain pace. All of course controlled in pace with the music by our trusty esp32 mcu.
We also decided to do two layers of (RGBW) led strips along the inner edge of the frame, as can be seen below. These strips could be used for extra effects, such as blinking green on a hit and red on a miss. This made a grand total of 492 leds for the whole game, and as can also be seen below, this many leds is able to generate a fairly strong light!
The led strips used were of the type WS2812 and WS2813. The main reason for chosing exactly these strips was because that was what we had laying around.
The led strips have 3 connection pads, power, ground and signal (WS2813 has 2 signal pads, but they could be soldered together making them act as one signal pad). These leds required 5V power, and far far more power than the microcontroller itself could provide. At maximum power, each led consumes 60 mA, which gives a "worst-case" total of 29.5 A! Thus we used a separate 5V power supply that we connected directly to the power and ground pads on the led strips.
The signal pads on the led strips had to be connected to the mcu. Unfortunately the led strips require a 5V signal, while the mcu only provides a 3.3V one. Luckily, we found just what we needed on aliexpress for cheap: A logic level shifter. It is a small board that converts a 3.3V signal to 5V, and that worked perfectly.
Covering the whole thing with a transparent, but diffuse, acrylate plate on top would nicely diffuse the light and hide the led modules themselves (shown in images further down).
Keeping it tidy
To hide the power supply, mcu and other components we simply mounted them to the back side of the main plate. This did not look very pretty, but it (kind of) worked. The signal and power cables for the led strips were pulled through a hole in the middle of the plate. We also fastened some "legs" to the bottom of the plate, so the game could stand on its own on a table.
The touch pads
Each of the 8 led tracks needed its own button that could be pressed in rhythm with the moving led light (and music), in a similar fashion to the MaiMai game.
Rather than going for tactile buttons we instead decided to employ the in built touch functionality of the esp32 mcu. The way it works is that the mcu can measure the capacitance for each pin, which changes if the pin is touched.
Each pad consisted of plywood backing making up 1/8 of a full circle. To this backing we fastened a conductive copper tape, as can be seen in the images below. This conductive copper tape covered a fairly large area on the top, and also partially wrapped around to below the plywood plate, where a thin wire was soldered directly to the tape. This wire was then pulled through a hole in the back plate and connected to a separate pin on the mcu. Thus each touch pad corresponded to one separate pin on the mcu. By then using the micropython 'machine.TouchPad' class, the current capacitance of each pin could be read sequentially as a number. If the conductive copper tape on one of the pads was touched by something conductive, such as a human hand, the read capacitance value would change and the micropython code would register a touch. This worked very well, and even a very slight and quick single finger poke on one of the pads could be detected.
A very important part of music rhythm games is of course music (duh). However, as the mcu was already busy detecting touch input and controlling hundreds of leds, we decided to use a separate mp3 module to play the music.
We landed on this YX5300 mp3 module (link), which is connected to the microcontroller through UART. The mp3 files themselves are loaded onto a memory card which is inserted into the mp3 module. Then we can just send simple commands from the mcu through UART to the mp3 module to e.g. start/pause playing, go to the next song, etc.
Public appearances of RhythGame
So far, RhythGame has been seen in public three times:
JavaZone in Oslo 2018
Trondheim Developer Conference 2018
Google Devfest Trondheim 2018
Unfortunately, RhythGame does not work very well at the moment, after having collected dust for a year, and will need some maintenance. It is also still missing a couple of features, such as an easy way to select song and a score board (including current score, and high score for each song/difficulty). But who knows, perhaps some day you will be visiting an arcade in Hong Kong and right there in the middle of the hall is RhythGame, blasting tunes and entertaining people.