I finally got round to ordering some wireless bits for my Arduino collection recently - specifically two XBee Series 2.5 radios and two XBee shields (for easy solderless mounting). They've sat neglected for a few days until this afternoon when I finally managed to think of something to do with them.
The premise is simple. One arduino is the 'game' board (right hand side of the video), whilst the other is a simple scoreboard of sorts (left hand side, dinky red breadboard). Once the boards have synced with each other, a simple three second countdown process is triggered (complete with flashing lights and sound), and thereafter the game board illuminates its sole LED to be red, green, blue or white. The player gets a point for pressing the corresponding button of the same colour (accompanied by a green light on the scoreboard and a 'you did good' sound) and loses a point for pressing the wrong coloured button (triggering a red scoreboard light and a family fortunes-esque 'wah wah' sound). Note that the video below needs sound for the full effect!
Admittedly, it's not much to look at, but it gave me a chance to flex a bit more brain muscle than I have done with my recent Arduinode projects (which are, on the whole, simpler mashups in the more familiar bosom of server side coding). Some of the difficulties I encountered with this project and some thoughts on future improvements are detailed below.
Setting up the XBee radios correctly
Quite apart from having to hunt down my old Windows laptop to get the radios configured correctly (using the manufacturer's X-CTU software), I also messed up setting their destination addresses (I, er, set them to themselves, rather than each other). I would have been completely stuck if it weren't for the magnificent book Building Wireless Sensor Networks. To be honest, the official Arduino pages on the subject are actually pretty good, but I was too eager to get cracking and didn't read them as thoroughly as I should have.
Initiating reliable communication between the XBees
The first few transmissions from the sending Arduino seemed to get lost (including the awesome beep-beep-beep-go countdown). I still don't know why (any pointers appreciated) so in the end implemented a workaround in each Arduino's setup methods to effectively try and form a crude handshake before cracking on with the game. I experimented with various
delay settings but struggled with what I think was both XBees transmitting too much and not listening enough (a point Tom Igoe reinforces quite alot in the excellent Making Things Talk). In the end I settled with the game board doing most of the sending and the receiving board doing most of the listening. This seems to work fairly satisfactorily for now.
Detecting actual button presses, rather than just if a button was in a given state
By this I mean I needed to capture the action of pressing a button, and making sure whatever reaction needed to be taken only occurred once per genuine button press. This was surprisingly tricky, and still isn't perfect. I needed to make sure of a few things:
- You couldn't just hold all four buttons down and cheat your way to victory
- You didn't get the points if you pressed (and held) a button and the next colour was the same as the last
- You didn't lose points if you pressed (and held) a button and the next colour wasn't the same as the last.
Writing two sketches with one computer and one USB cable is time consuming
Not to mention the fact that the XBee shields require you to switch two jumpers each time you want to go from USB serial mode (e.g. to upload a sketch) to XBee serial mode (e.g. to communicate wirelessly). This process is fiddly and easy to forget which would occasionally leave me rather flummoxed.
As you can see in the video, I've got a medium ish breadboard and a tiny one. The end result does fit fairly well, but getting it all on in an intuitive layout was a challenge for someone who knows very little about electronics. Similarly, the XBee shields cover the 5V and VIN pins on the Arduino board (I needed 5V out on the game board and VIN on the receiver board). In the end I just stripped some wires, bent their ends to a 90 degree angle, and just hoped for the best:
The code and the boards are fairly quick and dirty prototypes. Obvious improvements could be:
- Actually do something with the user's points score. It is accumulated, but never fed back to the user (I don't have an LCD display and thought flashing an LED to count back your points would be a bit tedious)
- Fix the occasional double-press syndrome. I managed to steer clear of this in the video above, but it definitely does happen. It seems to be the sending board's fault, rather than the receiver getting confused
- Improve the startup mechanism. I know the way I've got the boards handshaking is rubbish. There's doubtless many better, more efficient ways to do it
- Make the receiving board do more than just receive. The communication could easily be bi-directional, it's just not at the moment.
- Hook it up to the web. Inevitably, things would be better if scores were submitted to an online site somewhere
- Last but not least, create a point to the game. At the moment a user can press buttons all day long with no end in sight. A clearly displayed (somehow) time limit of perhaps 30 seconds would give the whole affair a bit of va va voom.
You can of course find the source code on GitHub - as with the Arduinode projects most of the code has been written to be understandable first and elegant second.