Here’s an overview of how we implemented the Object Record installation. It’s fairly technical and a bit long, but hopefully not impenetrable.
The basic requirements were for a standalone box to reliably emit a remark when sensor values crossed a threshold (or, alternately, when a certain time had elapsed without a threshold event). The system had to be operable by the venue owner, which means nothing complex: ideally he or she should just have to plug it in. Here’s the first pass at the software flow:
We ended up using the Beaglebone Black as the main system controller; it’s a small embedded Linux machine. We chose this over a less complex microcontroller because the Beaglebone’s low price and large feature set allowed us to prototype freely without worrying about the network, memory, and other constraints that accompany 8-bit systems. (For example, at various points we considered a network connection to a DB, audio playback and a projector component; with the Beaglebone we knew we could handle any of these without much additional effort). Running Linux also allowed us to be relatively language-agnostic. All the code is written in Python, using the excellent Adafruit BBIO library to interface with the GPIOs.
Sensing with the Beaglebone
The Beaglebone’s GPIOs can be damaged by overvoltage, and the upper limit on analog input pins is only 1.8V (other systems generally operate at 3.3V or even 5V). This made some sensor options, like Sharp IRdistance sensors and ultrasonic rangefinders, less feasible to implement without level-shifting circuitry. Level-shifting an analog signal is nontrivial; however, should we need to implement these sensors, I thought placing an ATtiny85 in line with the sensors as an analog-to-digital converter would be an expedient solution. Thankfully, I never had to implement that part; instead, we stuck either to passives (a photocell with voltage divider straight out of EE 101), or I2C devices. The I2C devices required me to port each sensor’s excellent Adafruit library to Beaglebone, which was fun. You can see them below; please file a bug report if anything seems amiss! Here are the sensors we implemented:
- generic photocell from my parts bin
- TMP102 temperature sensor. Easy to use, very accurate, can be polled very frequently. (Library)
- VCNL4000 proximity and ambient light sensor. This was a delightful device; the proximity sensing was quite accurate but its range wasn’t long enough for most interactions we wanted to track. The ambient light sensor was very sensitive, however, and functioned well as an are-people-here indicator. (Library)
- We also implemented the very interesting TCS34725 RGBC color sensor, but did not include it in the final installation. (Library)
Communication with printer and sensors
Communication with the thermal printer happens over TTL serial; the lines are level-shifted using a Sparkfun board. The board itself is poorly designed and, weirdly, unidirectional on some lines and bi-directional on others. The competing Adafruit board would have been a much better choice. (Sparkfun have since revised their board, but I have not had a chance to test the new one.)
Because the thermal printers consume more than two amps when printing, power management was an issue. These high-efficiency DC-DC regulators proved reliable and easy to implement. They were used to drop the system’s 9V (required for reliable printer operation) down to 5V (max 1A) for the Beaglebone and sensors. The switching regulators also ensured that there would be no thermal issues due to the drop-down, even if the installation were to be powered indefinitely.
Working with the Thermal Printers
The thermal printers presented an additional challenge: between the first exploratory purchase many months ago and the purchases made for this installation, the manufacturer made a few small, undocumented changes that delayed progress for a few days. The most significant change was the printers’ operating voltages: for the first printer we tested, it was necessary to give the printer 12V (rather than the 9V spec it listed) in order to ensure high-quality, readable printing and paper advancing. However, subsequent printers would not operate at that voltage; they functioned more reliably within the spec they supplied.
The printers listed a 5 to 9V operating voltage, so nominally it should have been possible to power the entire system with a high-current 5V supply. However, I had observed the printer causing the rails to droop significantly when under load, and I chose to use the switching regulator (which requires at least a volt of dropdown room to provide a clean 5V) and a higher-voltage power supply to ensure the system would not brown out. (As an aside, it is difficult to find high-current wall warts on Amazon Prime – searching for “router power supplies” will get you devices that push around 3A at 5V, but finding that amperage at higher voltages is a bit of a detective game. Adafruit sells a few supplies at reasonable prices, as do Electronic Goldmine and All Electronics. However, shipping costs and times are not as favorable as an Amazon Prime solution.)
Software – Design for Reliability
Ensuring the system runs reliably meant not just starting a script on boot, but also tolerating unplanned failures and power outages. The Beaglebone’s Linux distribution (Angstrom) uses the systemd interface rather than cron jobs. See the code for my implementation of the .service and .timer files that ensure the proper script runs on boot and restarts a safe time after any failures. Further details of the software used to generate the text will appear in an upcoming post.
Bonus Tip: Planning a Protoboard
I love the Adafruit Perma-Proto line of boards; they’re a super-simple idea that make it easy to go from breadboard to permanent implementation. To plan out the circuit, I put the board in our photocopier and enlarged it to fill a page, which made it easy to fit all my labels and pin descriptions.
The work here was made possible by the existence of phenomenal open source projects like beagleboard.org and pyBBIO, without which I would have lost a lot of time. Many thanks as well to the patient folks over at the forums, who did their best to answer most of my dumb questions!