I was asked to make something for the O’Reilly Strata Conference, which was held in Santa Clara at the end of February 2012. We needed some devices to capture votes from attendees who participated in Coco Krumme‘s Data Crush: Where Wine and Data Meet:
This new event at Strata will host wine tastings for participants, whose feedback data will be compiled and analyzed to extrapolate behavioral trends and factors influencing their responses.
At the event, we had several stations set up with different types of wine. It was your basic taste test, where the brands were concealed, and the architect of the experiment (Coco) used various methods to influence responses. After the participants drank the wine, they were instructed to proceed to the WineShade voting station and press the button whose label corresponded to the wine they just drank. As the experiment proceeded, the votes would be tallied on a central server.
I decided the best way to make this system was to shovel a bunch of newish technologies into the project: MakerBot, XBee, Arduino, Node.js. I believe it was Alasdair Allan who dubbed this the hipster stack. I believe it was Alex Howard who dubbed it the WineShade. But between the wine and solder fumes, my memory is suspect!
MakerBot If I’m going to make something physical, I knew my MakerBot Thing-O-Matic could make my life easier. At first, I thought I’d use the MakerBot to print out something to hold buttons and indicators in place, but I decided to go with some foam core for this. I had decided to use lampshades as the chassis for each station, and I needed something to cap it off. So I made a little tower to go on top of each one. I eventually went with something smaller than what you see here.
Arduino Mega I knew I’d need a lot of I/O, since each station would have three bargraphs and three buttons (though we ended up using only two each). I didn’t want to put too many components into this since I’d need to build them, so I decided to drive the bargraphs directly from the Arduino pins. To minimize the number of transistors, I decided to take advantage of persistence of vision, and multiplex the bargraph. I wrote a small library for the Adafruit LED bar graphs to do this, and posted it to GitHub. I’m just using one color, but the library could easily be extended to handle both of the bar graph’s colors.
Digi’s XBee These voting stations would be spread out all over the place, and needed a way to talk to a central server. I’ve had a lot of experience with Digi’s XBee modules, and I’ve always wanted to use the XBee Internet Gateway (XIG) in a project. XIG lives on a Digi ConnectPort X, and acts as a gateway between the XBee network and web servers (XIG can also talk to the IDigi cloud). I reached out to Rob Faludi, author of Building Wireless Sensor Networks, and he arranged to loan me a ConnectPort X2 Industrial and four XBee Pro modules. Thanks, Rob (and Digi)! I liked XIG so much that I bought a ConnectPort X2 Commercial (less RAM than the Industrial, but it works well for me).
Node.js If I’m going to have the XBees talking to the network, they better have a server to talk to. I usually reach for PHP or Perl for this sort of thing, but I decided I’d heard enough about Node.js (Beagle Bone‘s adoption of it got me really interested in it) that I better look into it. It worked great. It would have taken me longer to write this in PHP (or any of my usual languages) than it did for me to learn Node.js and implement it. Once I got my head around the asynchronous insanity, I could add whatever feature struck my fancy in a matter of minutes (OK, so some features needed more minutes than others).
The trickiest part of building each unit was connecting the Arduino Mega to all the pins on the buttons and LED displays. I decided to take an Adafruit perma-proto breadboard, solder some long male pins to it, and shape them so they’d plug into the double row of headers on the Arduino Mega. It was a kind of makeshift Arduino Mega tail shield, but it works. I threaded each strand of ribbon cable into a breadboard hole and up before soldering it down, which gave me quite a bit of strain relief.
I’ve got some documentation in process in the form of a GitHub repository that includes the Arduino code. It’s a pretty simple system: when the Arduino boots up, it sends a URL over the serial port that the XBee’s connected to (you’ll want to modify the
server string in the Arduino source), and XIG relays this to the server, and sends the response back to the Arduino over the XBee network. The server is a Node.js server that handles the requests from the Arduino: press a button, and a vote is registered. At each bootup (and after each button press), the Arduino gets the current vote tally from the Node server. That way, the Arduino doesn’t have to store any state at all! There’s also a primitive UI (/dash on the server) that lets you view the votes and manipulate them or reset them if needed. The
index.js file lists all the handlers, and the corresponding handler code is in