All code is available here.
Hooking up Bluetooth to Spacebrew
We began with a technical challenge: integrate Bluetooth into a Spacebrew project. We wound up focusing on Bluetooth Low Energy, or BLE. The advantages of a Bluetooth connection include the fact that Bluetooth devices advertise themselves, so that a project could potentially use information from devices that serendipitously come into its range (even if all they advertise is their name). Additionally, the Bluetooth connection would be immediate within the space, and therefore we wouldn't need to depend upon an internet connection.
We wound up making a spatial instrument using two types of information. First, we incorporated information sent automatically from the devices -- the RSSI (more on that later). Second, we used information deliberately sent by participants -- in our case, by pressing a button.
The final setup connected the instrument itself, which was a giant button attached to an Arduino with a BLE shield, to a central node.js app via BLE. The node.js app then communicated via Spacebrew to a Processing app, which created lovely music based on the information sent from the instruments. Ultimately, it created tones when the buttons were held down, and the speed and pitch of the tones were based on the RSSI number
We created the template for the wooden box from here.
We used the RedBear BLE Shield for Arduino. Their Arduino libraries are available from them, along with examples. We started with the SimpleControls example for our sketch. The commented code for our sketch is available on Github here. This includes code that lights the LED on the buttons whenever they're connected, giving some nice physical feedback. Note that the BLE shield sends information byte-by-byte using numbers using the hexadecimal system.
To make a node.js app that would communicate with the computer's bluetooth receiver, we used the Noble library, available on Github. Our app, also available here, accesses information coming from the computer's Bluetooth receiver. We've commented the app so that it's hopefully useful, but we can point out a few points:
.discoverServices() is how we initially located the services we would be using in the app. BLE Shield's service on which it broadcasts information is '713d0000503e4c75ba943148f18d941e'.
When the app locates the relevant service, it uses ".discoverCharacteristics" to identify specific characteristics associated with that service.
Finally, ".notify" is how the app subscribes to a specific characteristic. Once subscribed, the app can read data on that characteristic as it's sent. In our app, we included a listener: [characteristic].on('read', ...).
BASIC FACTS ABOUT BLUETOOTH:
Bluetooth devices have certain “services,” or information they can broadcast. In the case of the BLE Shield, our app picked up four services: ‘1800’, ‘1801’, ‘180A’, and (brace yourself) ‘713d0000503e4c75ba943148f18d941e’. These are numbers in hexidecimal form. There are certain standard services, which you can find here. You see that three of the four we detected match services on this list. If we listen to service 180A, for example, which is Device Information, we can tell what hardware revision our BLE Shield uses. (It uses revision ‘A’). But the last one, actually third in the list of four, is the service on which our BLE Shield broadcasts messages we cam have more control over.
Associated with each service are "characteristics," which carry specific data. The read and write characteristics associated with our relevant service are ‘713d0002503e4c75ba943148f18d941e’ and ‘713d0003503e4c75ba943148f18d941e’. The former is a "notify" characteristic, which means it has readable information. (Note that the method in the library for subscribing to a characteristic is "notify"). We therefore tap into this characteristic to read our data.
RSSI, or "received signal strength indicator," is data sent by the device. You can read more detailed information here, but essentially it gives an indication of how strong the signal is, which correlates roughly with the distance between the button device and the computer with the bluetooth receiver.
Ultimately, our node.js app updated the RSSI number every 100th of a second, averaging the last 100 values. It then sent that information to Processing via Spacebrew every half-second. It sent button information whenever that value changed.
HELPFUL DEBUGGING TOOL:
Partway through our process, we were led (by the author of the Noble library) to a developer tool called LightBlue. This app provides an easy way to access the bluetooth receiver in a computer, and allows for far easier debugging while writing the node app. Instead of writing line by line of code and sending output to the console, this allowed us to see peripherals in range immediately and see what services and characteristics were available.
We created two custom data types in the node.js app: one for sending RSSI data, and one for sending information when the button state changes.
The Processing side is set up with two subscribers, listening for the same two custom data types we send from the node app. Note that, because we knew exactly what two shields we were listening for, we pre-set the names in the Processing app. But you could write the app just as easily to substitute the names being broadcast from the BLE devices, so long as you set up the node app to send that information. We've commented the Processing app as well, which is available here. The Processing app then created tones (choosing from 50 pre-loaded sounds) whenever it received an "on" button-press, with the speed and pitches based on the RSSI value sent from the BLE devices.
The result was a fun, atmospheric instrument that invited people to explore their space. And the light-up buttons didn't hurt.