Friday, December 30, 2016

Two Games For One Light Strip

I saw a 1-D pong game on Hackaday some time ago. I thought it was just right for a project to work on in my spare time to give as a gift to my sister-in-law's family for Christmas. It was! It uses a PIC16F18855 microcontroller, a potentiometer to adjust brightness, big arcade buttons, and a WS2812b light strip (1 meter, 60 LEDs).

The linked project used an Atmel part but I wanted to try out a PIC part for a couple of reasons. First was because I had my free (to me) PIC programmer so... why not? Second was because of this Application Note (AN1606) from Microchip that describes using the Configurable Logic Cell (CLC) in a way to easily drive WS2811 LEDs. This was easily adapted to my use of the PIC16F18855 and WS2812b LEDs. Though instead of assembly I used the MPLAB Code Configurator to auto-generate my C code to configure the CLC and other peripherals.

The game is simple. Send the light over to your opponent. He must mash his button when the light is close to him (any of the 5 closest LEDs are lit) to return it back to you. You mash your button when the light comes close to you (again, the 5 closest LEDs) to return it to your opponent. If you don't press your button in time, you lose and your opponent gets a point. Depending on which of the 5 LEDs was lit when you pressed your button, the return speed of the light to your opponent will vary. The closer it was to the end of the strip, the faster the return speed; the further, the slower. So if you play well, it will make it difficult for your opponent to return your returns. If you hit too early, it will make it easier for opponent to send a fast one to you. Winning is first to 10 (win by 2) or first to 30. The score is shown after each point by lighting up the number of LEDs corresponding with each player's score. A green LED shows the "line," or the points the game is played to. This will move as the win-by-2 requirement comes into play. A dial on the side adjusts LED brightness.


But just one game? Surely there are more games you can play with two buttons and a strip of lights. There are! I also implemented (though not shown in the video) a "tug-of-war" game. There are two "lines" drawn using a red LED and a blue LED. Then a white LED starts in between these two. Every time you push your button, the white light moves forward. Every time your opponent presses his button, the white light moves backward. Where 1-D pong is about timing and precision, this one is about speed. It's just a button mashing game but it's pretty fun. I originally thought to use the entire strip but then you'd have to press your button as many times as your opponent plus 30. That's a lot. I changed it to be just 10 and sometimes that feels like a lot. The game typically stays in a deadlock until someone tires out. If you just won and are playing again with someone fresh, you'll probably lose. (Okay I'll probably lose. You could win 12 in a row, I'm sure.)

But just two games? Surely there are more games... Nope. That's it. Well, that's all I implemented, anyway. There probably are more but the creativity juice just isn't flowing right now. (But earlier you said "There are!" and not "There is!" I think you owe us another. (No.)) I thought about adding some sort of “secret” mode where you could use the brightness dial and the buttons to set the light strip to any color you wanted for “accent” lighting or something. I wasn’t really sure on it and I ran out of time so that didn’t happen.

My wife and I built the game using some poplar wood to mount it all to and to make boxes for the giant arcade buttons (they're so tall!). She's the better wood worker so I called on her for some help. I soldered it all together on some proto board but I'm pretty sure there was a short or something somewhere because once I put it all together (crammed it in the button box), the switch to change from 1-D pong to tug-of-war didn’t work. So my nephews and nieces only got 1-D pong and no tug-of-war. (Sad.) Making a PCB just for the game would help. It would definitely fit on a cheap-o 5cm x 5cm board that you can get for next to nothing nowadays. I also had some issues with crimp connectors. The far button’s LED wouldn’t light up (which it does when it’s that player’s turn to “serve”). It would work uncrammed from the box but would not after cramming. After attempting to fix both for some time, I gave up and shipped it as is. Lucky for me I have enough parts to make a second one. Time to start drawing up a PCB!

Look at all those wasted pins. The shame.

Ignore that I mixed red/white for power in one place... and reused red/white everywhere.
Another thing I would change was in the mounting of the light strip. We cut out a channel for the strip to sit in so the top was flush with the wood. Then we glued it down. I think that was a mistake. I’d use the plastic clips that are made just for these light strips and just screw down the clips. I hate glue.

The boxes for the buttons are very tall because the arcade buttons are tall. I’d like to find something with a lower profile next time. I figured arcade buttons ought to last a long time, though, and would be easy to repair if something were to happen. Tradeoffs (as always).

The rainbow animation at startup is okay but is kind of lame at lower levels of brightness. I should probably adjust the animation for maximum coolness (i.e. maximum wow-factor (i.e. maximum “take my money!”)) based on the set brightness level. (s/should probably/probably won’t/)

I used a PIC16F18855 because that was the chip used on my PIC programmer (the MPLAB Xpress board) and when I ordered chips I didn't want to find out my "something else" wasn't supported. This one I knew would work. Since ordering parts I've learned many more chips will work (see my previous post about that). I used less than half of the program memory and didn't come close to using all 28 pins. As is, I could use a PIC16F18324 (about 21 cents cheaper in quantity).

I even decided to be a grown up, get a GitHub account, and upload the code there. You can find it here. I don't expect anyone to improve it for me but I'm happy to collaborate.