Ship IoT with Beaglebone Black, TI Sensortags, and DeviceHive - Part 1
Winter is Coming
As I write this, it is mid-October. For those of us who live in the northern lands, our thoughts are turning towards turning up the thermostats to fight off the chill.
Trouble is, some of these old houses aren't very well insulated, and they are filled with warm spots and cold spots. Thermostats regulate temperature based on the sensor inside them, and they are pretty good at it. But I was thinking, what sense does it make to have the thermostat regulate its own temperature, making it nice and comfortable where the thermostat sensor is? I want it nice and comfortable where I am, not where the thermostat is! And I move around. And I move around into cold spots in these old houses. I may be in the kitchen, or basement, or spare room, or sleeping. This needs to be fixed.
Tech to the Rescue!
Texas Instruments offers Sensortags, develpment kits for their CC2650 ultra low-power Bluetooth MCU chips. Combined with a BeagleBone Black (powered by an ARM Cortex-A8 CPU at 1GHz, the Texas Instruments Sitara AM3358BZCZ100), they will be the basis for our solution here.
We're going to connect these using DeviceHive - an open source device management platform developed by DataArt Solutions, and available as a data service on the wot.io data service exchange™. DeviceHive helps you manage devices after they are deployed—handling registration, commands sent to and data received from the device, and a number of other useful tools. From DeviceHive, we'll use the wot.io data service exchange to integrate with additional data services from our partner exchange and finish our system.
If you want to follow along with this demo, here's what you'll need:
- One BeagleBone Black
- A USB Bluetooth 4.0 Low Energy dongle that works with Linux
- TI CC2541 SensorTag Development Kit (now superseded by the newer CC2650, but very similar)
- A USB to Serial-TTL cable that runs at 3.3V (Not 5!), like one from Adafruit, or from Digi-Key
- Our gateway demo code: https://github.com/wotio/shipiot-ti-sensortag-beaglebone-devicehive
- The bluepy Python library by Ian Harvey
There are a number of ways you can connect to your Beaglebone Black for development. I hooked up a 3.3V USB to Serial adapter (remember, not 5V!) to the console port, an Ethernet connection for outbound network access and SSHing in, and USB for power. I've got a little USB power board with a switch on it from Digispark, which is very handy when doing USB-powered hardware stuff, and will save your USB ports some wear and tear. The Bluetooth dongle is connected to the Beaglebone Black's USB port.
Note: You'll need to have the Bluetooth dongle plugged in before you boot or it may not work. There are known issues with hot-plugging Bluetooth dongles on this board.
Here's what my setup looked like:
Here is the block diagram for what I'm planning, and the message flow. To keep things simple for now, we'll be talking about the data services in Part Two of this blog entry.
On the left, we have the two TI Sensortag boards. On each board we have the SHT21 sensor, and the TI CC2541 (or CC2650) controller. The SHT21 communicates via I2C. The CC2541 MCU speaks Bluetooth, and communicates with the bluepy utilities on the Beaglebone Black. The Node.js gateway applications uses those bluepy utils to poll the Sensortags.
In turn, the gateway uses Web Sockets to talk to the DeviceHive service on the wot.io data service exchange. It first handles device registration, which will tell the DeviceHive service there is a new device if it has not seen it before. Once registered, it creates a persistent Web Socket connection, periodically sends sensor readings, and listens for commands from DeviceHive. (We aren't using any of those commands for this demo, but it's easy to do using the wot.io DeviceHive adapter. It's especially powerful when those commands are generated dynamically by custom logic in a wot.io data service, say, in response to sensor readings from some other device!)
The wot.io DeviceHive adapter can then subscribe to receive the device notification data that the gateway sends to DeviceHive. We've configured wot.io to route those device messages to a number of interesting data services. But details on that will have to wait for Part Two!
First we need to talk to the Bluetooth Sensortags. I used the the bluepy Python library by Ian Harvey for this, as it includes a sample module that's already set up to speak Sensortag. Great time-saver!
If you are using the current CC2650 sensortags, it should work out of the box. If instead you have the older CC2541 Sensortags, in
bluepy/sensortag.py, you should comment out these lines:
262 #if arg.keypress or arg.all: 263 # tag.keypress.enable() 264 # tag.setDelegate(KeypressDelegate())
Those lines support features that aren't present on the older Sensortag, and it will error on initialization.
Some tools you should know about for working with bluetooth include
gatttool is useful.
You can bring up and down your Bluetooth interface just like you would with Ethernet, perform scans, and other things as well:
hci0: Type: BR/EDR Bus: USB BD Address: 5C:F3:70:68:C0:B8 ACL MTU: 1021:8 SCO MTU: 64:1 DOWN RX bytes:1351 acl:0 sco:0 events:60 errors:0 TX bytes:1333 acl:0 sco:0 commands:60 errors:0 root@beaglebone:~# hciconfig hci0 up root@beaglebone:~# hciconfig hci0: Type: BR/EDR Bus: USB BD Address: 5C:F3:70:68:C0:B8 ACL MTU: 1021:8 SCO MTU: 64:1 UP RUNNING PSCAN RX bytes:2201 acl:0 sco:0 events:97 errors:0 TX bytes:2022 acl:0 sco:0 commands:97 errors:0
We need to get the Bluetooth MAC address of the Sensortags we are using. From the console on the Beaglebone Black, we will use the
hcitool utility to get it. Here's the procedure, do it one at a time for each tag if you have multiple:
- Insert a fresh CR2032 battery into the Sensortag.
- Press the side button to initiate pairing; the LED will begin blinking rapidly (and dimly!)
On the Beaglebone console, initiate a Bluetooth LE scan:
root@beaglebone:~# hcitool lescan LE Scan ... 78:A5:04:8C:15:70 (unknown) 78:A5:04:8C:15:70 SensorTag
Once you get your tag's Bluetooth MAC address, you can hit control-C to cancel the scan.
Once you know the MAC address, you can use the tools included in
bluepy to easily talk to the tag. Try it out like this (first making sure the LED is blinking on the tag by pressing the switch, if it went to sleep):
root@beaglebone:~# ./sensortag.py 78:A5:04:8C:15:71 --all Connecting to 78:A5:04:8C:15:71 ('Temp: ', (24.28125, 20.36246974406589)) ('Humidity: ', (24.686401367187493, 32.81072998046875)) ('Barometer: ', (23.440818905830383, 979.6583064891607)) ('Accelerometer: ', (-0.03125, 0.015625, 1.015625)) ('Magnetometer: ', (-12.847900390625, 36.224365234375, 166.412353515625)) ('Gyroscope: ', (-3.0059814453125, 3.082275390625, -0.98419189453125))
The sensor on the tag we'll be using for this demo is the SHT21 temperature and humidity sensor. We will use temperature to start, but we could easily expand our algorithms to take humidity into account, and adjust the heat accordingly. There are tons of other applications possible here, too!
Note also that I further modified the
sensortag.py script to give us raw numerical output for the temperature and humidity, separately, using the
-Z flags. This made subsequent code simpler.
DeviceHive lets devices register themselves with a DeviceHive server instance, and then send along data. There are mechanisms in DeviceHive to send data and commands back to the devices as well, which could be used to update firmware, or take actions based on processing in one or more data service providers.
Here's a quick walk-through of the hardware setup, gateway code, and a demonstration of the Sensortags sending data through to the DeviceHive device management platform:
To Be Continued
That wraps up part one of this demo, which covers the hardware and device management setup. In the next installment, we'll look at the data services, and cook up the magic that will control our thermostat. Stay tuned!
UPDATE: Part Two is now published.