Showing posts with label ble. Show all posts
Showing posts with label ble. Show all posts

Saturday, December 23, 2017

Data from the light bulb

Once I read a blog post from Oona Räisänen that really inspired me. In her project she encoded a digital signal into the referee's whistle. I asked myself if there is any other household object that emits a radiation and could be used as a carrier for low-speed digital signal. I looked around and there was a light bulb.

Using light as signal transmitter is not at all a novelty. Beside all that optoelectronics stuff, recently Apple stirred some waves with their Li-Fi announcements that promises ultra-fast communication by means of a light bulb. I had something else in mind. I did not care about the speed, ad-hoc signal transmission of small data chunks that carry location IDs, sensor measurement was much more interesting for me. The use case would look like that you walk with your smartphone into a room lit by an innocently looking light bulb and presto, the smartphone picks up info from the light bulb without any special arrangement, e.g. you don't have to point your device anywhere. Speed and data size is of secondary concern in this use case which is a quite common scenario in the world of Internet of Things (IoT). Also, the light from the light bulb must look completely ordinary for human observer, e.g. no blinking, etc. This post is a tale of that adventure.

As I had prior experience with reading infrared signals from ordinary remote controls and sending them to the smartphone, I started with the method IR remote controls use to communicate with their receivers. Very shortly if you have not yet met this system: the emitter sends out period of "0s" (no light) and "1s" (IR light modulated by a certain frequency, typically 38 kHz). It is the length of these periods that carry the information. The common approach is that after a series of sync bursts, a digital 0 is encoded as a no light-light sequence of specified periods. A digital 1 is encoded similarly, except that the no light-light periods are different. You can observe this operation if you watch the light diode of an ordinary remote control through a smartphone camera. As the smartphone camera sensor "sees" in infrared (even though the manufacturers try to filter out this behaviour), you will see flashes of infrared light if you push a button on the remote.

Compared to the IR remote, we have an additional requirement: the human observer is not allowed to notice that the light bulb is doing something weird. For this purpose, I changed the modulation scheme. "No light" does not mean that the light bulb is switched off (that would result in a very annoying blinking sensation that humans are very sensitive to), only the modulation frequency is changed. In our system, the "light" periods are modulated with 38 kHz so that the popular IR remote decoder chips can be used, and the "no light" periods with 48 kHz. For the steep band pass input filters of those IR receiver chips, 48 kHz is essentially "no light". Considering the very noisy environment in the visible light domain, I also changed a popular IR modulation scheme, now the 0 bit is 564 microsec 48 kHz signal/564 microsec 38 kHz signal, the 1 bit is 1692 microsec 48 kHz signal/564 microsec 38 kHz signal. The whole payload is 20 bit long allowing to transmit a 16-bit value and a 4-bit data type selector. The data type selector lets the emitter send multiple types of data sequentially. In our demo, these are: station ID (for location), temperature and humidity (obtained from a DHT-22 sensor on the emitter board).

The system therefore consists of 3 elements: the emitter circuit that drives the light source, the adapter that receives these light signals and adapts them to the smartphone and finally the smartphone that acts upon those light signals.


  • In the prototype I am about to present the emitter is based on an Atmel Atmega328P microcontroller, in the form of an Arduino Pro Mini board.
  • The smartphone does not have light receiver and the Android application model cannot do real-time processing anyway so there is an adapter in between that on one side receives and decodes the light signals, on the other side interfaces with the smartphone by means of Bluetooth Low Energy (BLE). This element is implemented with two microcontrollers, an Atmega328P that does the real-time light signal processing and an nRF51822 SoC that deals with the BLE interface. As the nRF51822 is a quite capable ARM Cortex-M0 microcontroller, it is an interesting question why the light signal processing had to be offloaded to another microcontroller. The reason is the bad experiences I had regarding the real-time behaviour of the nRF51822 when its Bluetooth stack is operating.
  • The third element is a smartphone that connects to the receiver by means of BLE and displays whatever the adapter receives. This part is implemented in Android.
Let's start with the emitter. Below is the schematic (click to enlarge).






And this is how it looks like with the lighting LED beside the microcontroller card.






The source code can be found in this archive, in the light_sender/sketch subdirectory. You have to adapt the ARDUINO_DIR variable and probably the ISP_PROG and the ISP_PORT variables according to your programming tool. The AC input voltage may need to be adapted according to the lighting LED you choose. 38VAC effective value worked well for me for a wide range of lighting LEDs. The input voltage source also powers the microcontroller and this is really a sensitive area, I burnt a Pro Mini by screwing up something here. The problem is the large voltage drop hetween the LED supply voltage and the 3.3V that supplies the microcontroller. Before you insert the Pro Mini into its socket, make sure that VCC is 3.3V by setting TM1. Also, the Q2 FET has to be chosen carefully, the IRL540N type has drain-to-source breakdown voltage of 100V which is more than enough for this application.


The station ID (used for indoor location application) is hardcoded in light_sender.ino (STATION_ID). Optimally, every light bulb should have a different station ID.


Once the emitter is powered, it emits a steady 48 kHz signal which is "no light" in our encoding scheme. Every 1 second the emitter sends an encoded 20-bit value which is sequentially the station ID, temperature and humidity, the last two values are obtained from the DHT-22 sensor (U1). For the human observer, the light bulb is simply lit.


Now on to the adapter. Here is the schematic (click to enlarge).




And here is how it looks like.





The light receiver caused the most trouble for me. For starter, the photodiode required experiments. I played with 5 different diodes and eventually found the Osram SFH203 which worked well for me. If you cannot obtain this type, be prepared that you will also have to experiment. The next source of troubles was the IR receiver. Most IR receivers are integrated with the IR photodiode and these devices are made insensitive to visible light. Eventually I found VSOP58438 which has 2 problems: first it is obsolete and therefore it is hard to get, the second is that it is a 2mmx2mm square. Eventually my colleague helped me out and built a breakout board that you see in the foreground, with the Osram photodiode connected to it.


The rest is simpler. The Atmega328P (also provided in the form of an Arduino Pro Mini board) runs program that was originally designed as IR receiver. It can be found in this archive file (light_receiver/sketch/light_receiver.ino). The receiver library is Chris Young's IRLib with the timings modified for our modulation scheme. If the Atmega328P receives a value, it sends the value out on its serial output which you can observe SER_LIGHT_CODE pin.

The data goes into the nRF51822 SoC that I used in the form of a breakout board (here is an earlier post that describes the board and the development environment). Also, check out this post for instructions, how to compile and upload the project to the board. Here is the archive that contains the code for the nRF51822 SoC. The application in the nRF51822 SoC seems long but it is mostly boilerplate code, in reality its operation is very simple. Whenever it gets a value from the serial port, it writes that value into a BLE characteristic that has notification set. This means that whoever is subscribed to that notification, will get the event immediately, without polling the characteristic.


And finally, the reason why this topic is at all on an Android-themed blog: the detected values are consumed by an Android application. Click here to download the source code and read this blog post on how to convert the sources into an Android Studio project. The Android application is very similar with the previous ones, it scans for BLE endpoints with a unique UUID (274b15b0-b9cd-4e5e-94c4-1248b42b82f8 in our case) and when it finds one, connects to the endpoint using connection-oriented BLE. Then it subscribes to the light data characteristic (274b0100-b9cd-4e5e-94c4-1248b42b82f8) and when a new data comes from that characteristic, it evaluates the data type 4 bit and displays the lower 16 bit according to the data type.




Below is a small video showing how the thing works.




Observe the normal light sources and the small spot of smart light source that emits the data. The data is picked up from 3-4 meter distance.


Wednesday, June 14, 2017

Android weather station with a solar-powered BLE sensor

The ultimate test of the low energy consumption is a sensor that can survive on its own, without maintenance. My Android weather station supported by BLE weather sensors has been functioning for more than a year but this year has not passed without adventures in the battery front. First the station was powered by 2 AA NiMh batteries - that was 2 weeks of lifetime. Then came the motorcycle battery, that took much longer to expire but eventually the battery itself failed. Now the 2 sensors run on a discarded laptop battery which may not be able to power a laptop but powers nicely the two sensors with their combined 5 mA consumption.

5 mA, however, is a lot so when I found this solar-powered lamp at Jysk, I immediately realized that I had to turn the lamp into the solar-powered version of this weather sensor. Why another weather sensor? Because I wanted to concentrate on the solar-powering aspects and wanted to reuse as much as possible from the old sensor. This prototype may serve as a template, however, for different kind of sensors too.

Let's see first the solar lamp that I used as a base.




Solar lamp already containing the weather sensor. The two red LEDs indicate that the solar cell is charging the battery.

This is a quite cheap device with a solar cell on top and a circuit built around the XD5252F LED driver that takes care of everything from the charging of the small NiMh battery (if there's sunlight) to switching on the LED (if there's darkness). Unfortunately the circuit is so specialized to solar LED lamps that I could not reuse too much of it except for the solar panel and the LED itself. The solar panel is not very high-powered, it is a 2V, 20 mA cell. So it became clear immediately that the Android client app has to work more (consuming more energy) to obtain sensor data while the sensor has to sleep more to conserve its own battery that charges only very slowly from the low-powered solar cell. Also, surviving the night (or longer periods without sufficiently strong sunlight) requires a quite beefy battery in the sensor if we want it to transmit BLE messages to the Android application frequently enough.

Click here to download the sources of the Android application. Read this post to figure out, how to create an Android Studio project from the downloaded sources.

The previous Android app has been therefore changed so that instead of 15 seconds of scanning, it now scans for 70 seconds. The sensor sleeps 60 seconds then transmits the measurements for 5 seconds. This results in a quite low, 4 mAh energy consumption daily that even the low-powered solar cell can refill if sunny periods occur time to time. To make sure that the sensor survives long without enough sunlight, a 2700 mAh Li-Ion battery was installed (of the 14500 type, with the AA form factor). As in the previous version, the measurement data is transmitted in the BLE advertisement packets. I wanted to transmit battery indicator in this case too so I dropped one byte from the 8-byte long station ID (so it is now 7 bytes long) and instead of that byte now the supply voltage of the microcontroller is transmitted. It is generally 3.3V, if it drops below that then the battery is really not charging. This additional measurement data required that the sensor's UUID be changed, that's how the Android app recognizes this new parameter and displays in a graph.



Battery indicator in the measurement screen of the new sensor

The schematics of the sensor can be seen below (click to enlarge).







Sensor circuit installed into the solar lamp case

Nothing much changed from the previous version, except for the solar cell-battery charger power chain. I wanted to save myself the pain of designing a Li-Ion charger so I used building block already avalable: this DC-DC converter to produce 5V from the solar cell's varying output voltage and this battery charger circuit to take care of the Li-Ion battery. The result is a less than optimal efficiency (almost 50% of the solar cell's energy is lost during the different up-down conversions) but at least it is easy to reproduce. And if you like the sensor, you can always design a much better charging circuit. :-)

Click here to download the nRF51822 sources. Read this blog post for compilation instructions.

The nRF51822 microcontroller application has not changed a lot either. The most serious modification is the way the delays are implemented, now the sleeping periods between two measurements are implemented in a very low-power way and that results in a consumption in the inactive periods of about 100 microamperes.

And one thing more! Check out my low-cost robot project!

Thursday, January 7, 2016

Data transfer to Android device over infared link

The three previous parts (here, here and here) of this series introduced the infrared-to-Android gateway. Even though those prototypes captured the signals of an ordinary IR remote, I already hinted that I was aiming for something more exciting. In this part, we will replace the IR remote with our own IR transmitter. Once we have our own IR transmitter, we will be able to transfer our own data over IR light. This data link is not reliable enough to transfer large amount of data but in lot of the cases that's not required. E.g. to transfer the data of a temperature/humidity sensor, 32 bit is more than enough.

So what can we expect from IR-based data transfer with respect to more popular, radio-based transfer? There are advantages and disadvantages.

  • Advantage for the IR solution is that it is extremely cheap and also extremely power-efficient.
  • Advantage for radio is that IR-based solution always requires line of sight, while radio waves can - to some extent - traverse walls, etc.
  • Advantage for radio is that the IR transmitter has to be aimed at the receiver, if for some reason the receiver and the transmitter move with respect to each other, they lose contact very easily.
There's also the question of range. Ordinary TV remotes work up to 3-4 meters of distances which is nice for an inexpensive consumer device but is not enough even for indoor sensor network use cases. In this part I try to figure out what the distance limit may be.

For starter, this question is not defined precisely. With sophisticated optics, high-powered transmitters and careful targeting, IR data transfer can be accomplished over significant distances. But we said that we are looking for cheap hardware so we can't rely on sophisticated devices. We need some sort of optics but this should be simple and cheap. That's why I went to a second-hand toy shop and bingo, I found the IR transmitter of Thinkway Toys' Lazer Stunt Chaser. The small toy car has long been lost, but the handgun-like IR transmitter somehow made its way to Hungary. This cheap, plastic toy is a marvelous device. It promises 12 meters of effective range and even though the mounting of the IR light source and the plastic optics is made of cheap materials, it is surprisingly efficient. It even has a normal (red) LED emitting its light through the transparent housing of the infrared LED which produces visible red light circle of about 10 cm of diameter facilitating the targeting of the IR transmitter.

So how far can it transmit our IR codes? In order to try it out, I took apart Thinkway's IR transmitter and replaced the circuitry driving the IR LED with mine. The new emitter circuit is based on an Arduino Pro Mini 3.3V/8MHz and the schematics looks like this:





The software works on any Atmel ATmega328p-based boards, e.g. on Arduino Uno. If your MCU uses power source with higher voltage than 3.3V, adapt R2 accordingly. E.g. for an 5V Arduino Uno board, you need about 160 Ohm.

So this is how I hacked my circuit into the IR transmitter.




Note the two LEDs: the IR led in the tube-like mounting and the ordinary red LED behind it that is used for targeting. Also, note how the IR LED is connected to the ATmega328p's PD3 pin - IRLib which is the software used to construct the transmitter selects OC2B PWM output so the primary Timer2 PWM pin (PB3) would not work.

Click here to download the source code of the IR transmitter.

Open sketch/Makefile and update the ARDUINO_DIR according to your installation. Also, update ISP_PROG according to the programming tool you use to deploy the code. I used USBtinyISP, the Makefile is set accordingly. If your board has USB programming port (like the Arduino Uno has), then setting ISP_PROG is unnecessary.

In order to deploy the code into the ATmega328p, say:

make ispload

if you use a programming tool or simply

make upload

if you don't need a tool.

About the code. The application emits a 32-bit NEC IR code every 4 seconds. The value of the code is increasing. The application is based on the same IRLib library as the receiver was, this time the only modification necessary was that I disabled all the receiver routines as this device does not receive any data. And that's my response to all the people worrying about the security of the Internet of Things: if the Thing is physically unable to receive any data then it cannot be hacked, period.

Even though this application is not particularly energy-efficient, care was taken to implement the sleeping part with the lowest possible energy consumption. Hence the delay logic does not use the Arduino delay() function but puts the MCU into deep sleep and triggers the watchdog timer to launch a new iteration. Read Nick Gammon's excellent analysis of ATmega328p power saving techniques for further explanation.

So what are my experiences? Using the infrared-to-Android gateway I presented previously which is based on a basic IR receiver circuit (TSOP1738) without any optics and the IR transmitter hacked into a Thinkway toy, which uses cheap plastic optics, I was able to transmit codes to a distance of about 10 meters (and then receive the code on the Android device over BLE). Of course, not every transmission was successful. My experience is that the code needs to be repeated about 5 times if you want to be nearly 100% sure that it arrives (100% can never be achieved). One important take-away is that the targeting LED in the Thinkway toy was not there by chance, in order to target the IR receiver, you really need that aid of visible red light circle. But that's about it: 2 LEDs, a cheap MCU and some optics and you can connect sensors from an entire room to one relatively expensive BLE unit. Also, these IR-connected sensors need very little energy. So it is worth considering the advantages/disadvantages.

Wednesday, April 22, 2015

Infrared imaging with Android devices


One of the most evident sensors of Android devices is the camera. An ordinary smartphone's camera is able to capture a lot of interesting information but has its limitations too. Most evidently, its viewing angle depends on the position of the device (so it is not fixed and hard to measure) and its bandwidth is (mostly) restricted to the visible light. It is therefore an exciting idea to connect special cameras to Android devices.




In this post, I will present an integration of FLIR Lepton Long-wavelength Infrared Camera to an Android application over Bluetooth Low Energy connection. Long-wavelength IR (LWIR) cameras are not new. Previously, however, they were priced in the thousands of dollars range (if not higher). Lepton is still pricey (currently about 300 USD) but its price is low enough so that mere mortals can play with it. FLIR sells a smartphone integration product (called FLIR One) but it is currently only available for iPhone and locks the camera to one device. Our prototype allows any device with BLE connection to access this very special camera.

The prototype system presented here needs a relatively long list of external hardware components and it is also not trivial to prepare these components. This list is the following:


  • An Android phone with Bluetooth 4.0 capability. I used Nexus 5 for these experiments.
  • An FLIR Lepton module. My recommendation is the FLIR Dev Kit from Sparkfun that has the camera module mounted on a breakout panel that is much easier to handle than the original FLIR socket.
  • A BeagleBone Black card with an SD Card >4GB.
  • A BLED112 BLE dongle from Silicon Labs (formerly Bluegiga).
The software for the prototype can be downloaded in two packages.

  • This package contains the stuff for the embedded computer.
  • This package is the Android application that connects to it.
Once you got all these, prepare the ingredients.

1. Hook up the FLIR camera with the BeagleBone Black

Fortunately the BBB's SPI interface is completely compatible with the Lepton's so the "hardware" just needs a couple of wires. Do the following connections (P9 refers to the BBB's P9 extension port).


FLIR BBB
CS P9/28 (SPI1_CS0)
MOSI P9/30 (SPI1_D1)
MISO P9/29 (SPI1_D0)
CLK P9/31 (SPI1_SCLK)
GND P9/1 (GND)
VIN P9/4 (DC, 3.3V)


2. Prepare the BBB environment

I use Snappy Ubuntu. Grab the SD card and download the image as documented here. Before flashing the SD card, we have to update the device tree in the image so that the SPI port is correctly enabled. Unpack bt_ircamera.zip that you have just downloaded and go to the dt subdirectory. There you find a device tree file that I used for this project. Beside the SPI1 port, it also enables some serial ports. These are not necessary for this project but may come handy.

Compile the device tree:

dtc -O dtb -o am335x-boneblack.dtb am335x-boneblack.dts

The output is the binary device tree (am335x-boneblack.dtb) that needs to be put into the kernel image file. Let's suppose that the downloaded image file is ubuntu-15.04-snappy-armhf-bbb.img and you have an empty directory at /mnt/img. Then do the following:

fdisk -l ubuntu-15.04-snappy-armhf-bbb.img

Look for the first partition and note the partition image name and the offset:

ubuntu-15.04-snappy-armhf-bbb.img1   *        8192      139263       65536    c  W95 FAT32 (LBA)
...

Note that the actual partition image name may differ depending on the Snappy image you downloaded. Calculate the offset as 8192*512=4194304
Now mount the partition:

mount -o loop,offset=4194304 ubuntu-15.04-snappy-armhf-bbb.img /mnt/img

Then copy the dtb into the image, unmount and write the image to SD card (on my computer the SD card interface is /dev/sdc, check before you issue the dd command!):

cp am335x-boneblack.dtb /mnt/img/a/dtbs
umount /mnt/img
dd if=ubuntu-15.04-snappy-armhf-bbb.img of=/dev/sdc bs=32M

Now you have an SD card that you can insert into the BBB and boot from it. Once you reached the Ubuntu prompt and logged in (ubuntu/ubuntu), there's one thing more: the Snappy prototype application depends on the libpng package which is not part of the default Snappy image. But before you do it, check whether the SPI device was enabled correctly:
root@localhost:~# ls /dev/spidev1.0                                            
/dev/spidev1.0

Now about the png library. Download the armhf image from this location:

wget http://ports.ubuntu.com/pool/main/libp/libpng/libpng12-0_1.2.50-1ubuntu2_armhf.deb


Copy it to the BBB (update your card's IP address according to your network policies):
scp libpng12-0_1.2.50-1ubuntu2_armhf.deb ubuntu@192.168.1.115:~

Then go to the BBB console and install the deb package:
sudo mount -o remount,rw /
sudo dpkg -i libpng12-0_1.2.50-1ubuntu2_armhf.deb
sudo mount -o remount,ro /

3. Prepare the BLE dongle

The BLED112 stores the GATT tree in its firmware, hence in order to provide the GATT services that connect the BBB with the Android device, a new firmware needs to be generated and installed in the dongle. The config files are located in the config subdirectory in the bt_ircamera.zip archive. Follow the steps in this post to generate and install the new firmware. Once you are done, you can simply plug the dongle into the USB port of the BBB.

4. Install the prototype applications

The prototype system has two parts. The application running on the BBB acts as BLE server, fetches images from the FLIR camera and transmits them over BLE. The Android application acts as BLE client, fetches images from the BLE server and displays them. The BBB part is located in bt_ircamera.zip and the Android part is in IRCamera.zip. The latter is just the source part of the Android Studio project tree - I omitted all the garbage that Android Studio generates into the project folders. For the BBB installation, follow the instructions in this blog post. Launch the BBB application like this as root:
/apps/ircamera.sideload/1.0.0/bin/ircamera /dev/ttyACM0
and you are ready to go. On the Android side, select the BLE node with the name "test", connect, click the "Take picture" button, wait for the image to download and there you are. Note that the images are saved on the SD card, which means that they also appear in the stock "Photos" application.

Now at last we can get to the technical issues with this prototype. One interesting aspect is that there is no standard BLE service that provides the functionalities - image capture triggering, image fetching - our system needs. That's not a problem, we defined our own BLE service. It is easiest to follow this service in irc_gattBLED112.xml (bt_ircamera.zip, config subdirectory).

The service has a custom UUID, generated randomly:

<service uuid="274b15a3-b9cd-4e5e-94c4-1248b42b82f8" advertise="true">

Also, its 3 GATT characteristics are in the non-standard UUID domain:

<characteristic uuid="00000000-b9cd-4e5e-94c4-1248b42b82f8" id="irc_len">
...
<characteristic uuid="00000001-b9cd-4e5e-94c4-1248b42b82f8" id="irc_offs">
...
<characteristic uuid="00000002-b9cd-4e5e-94c4-1248b42b82f8" id="irc_pic">

The interaction goes like the following. The BLE client connects and reads the irc_len characteristic. This characteristic is tagged as "user" on the BLE server side meaning that the BLE application must generate the value on the fly, when the attribute is read. In our case, reading this attribute fetches an image from the FLIR camera, converts it into PNG format and stores it in the apps' data folder, returning only the PNG file size. The Android application now can fetch the image piece by piece. First the Android application writes the irc_offs characteristic to inform the BLE server, what is the starting location of the fragment it wants to fetch. Then it reads the irc_pic characteristic which returns a maximum of 20 bytes of image data. This makes the image download very slow (takes about 10-20 second to download a general 5-6 Kbyte image to the Android application) but the restriction comes from a BLE protocol layer. Maybe the old RFCOMM from Bluetooth Classic would have been actually a better option for this application.

Update: I updated the client/server application to make the download faster (it is still quite slow). In order to speed up, I removed the explicit setting of the file offset (so the irc_offs characteristic is not used anymore). This made the download faster but there's still room for improvement.

Other than the issue with fragment size, both applications are pretty straighforward. Maybe the colors of the IR image are worth discussing a bit. The FLIR camera returns a matrix of 80x60 pixels, each pixel has a depth of 12 bit. Grayscale presentation is the most evident option but most displays have only 256 gray colors. In order to make the IR shades more visible, I used fake coloring. The algorithm is very simple: after the image is fetched, the maximum and the minimum IR intensity is calculated and the range between the two are mapped into a rainbow gradient of 400 colors.

Friday, February 6, 2015

BLED112 on BeagleBone

In the previous post I demonstrated, how a Bluetooth Low Energy dongle can be used to connect a PC and an Android device. While this is sort of project is appealing, connecting PCs and smartphones is not such an interesting use case. It is much more interesting, however, to transfer the PC-side program directly to an embedded device and that's what I will demonstrate in this post.

The Android application used in this post did not change, you can download it here. The BLE server application was updated according to the embedded platform's requirement, you can download the new version here.

There are two baskets of embedded platforms out there. One of them is optimized for low power consumption. They are too limited to run a full-scale operating system therefore their system is often proprietary. Arduino (of which we have seen the RFDuino variant) is one of them but there are many more, e.g. Bluegiga modules also have a proprietary application model. We can typically expect power consumption in the 1-10 mA range with some platforms offering even lower standby consumption.

The other basket contains scaled-down computers and they are able to run stripped down versions of a real operating system. Their power consumption is in the 100-500 mA range and they often sport 100s of megabytes of RAM and gigabytes of flash memory. They are of course not comparable to low power platforms when it comes to power consumption but their much higher performance (which can be relevant for computation-intensive tasks) and compatibility with mainstream operating systems make them very attractive for certain tasks. The card I chose is BeagleBoard Black and my main motivation was that Ubuntu chose this card as a reference platform for its Ubuntu Core variant.

The point I try to make in this post is how easy it is to port an application developed for desktop PC to these embedded computers. Therefore let's just port the BLE server part of the CTS example demo to BeagleBone Black.

There are a handful of operating systems available for this card. I chose Snappy Ubuntu - well, because my own desktop is Ubuntu. Grab an SD card and prepare a Snappy Ubuntu boot media according to this description. It worked for me out of the box. You can also start with this video - it is really that easy. Once you hooked up the card with your PC, let's prepare the development environment.

First fetch the ARM cross-compiler with this command (assuming you are on Ubuntu or Debian):

sudo apt-get install gcc-arm-linux-gnueabihf

Then install snappy developer tools according to this guide.

Then unpack the BLE server application into a directory and set up these environment variables.

export CROSS_COMPILE=arm-linux-gnueabihf-; export ARCH=arm

Enter the beagle_conn_example directory that you unpacked from the ZIP package and execute:

make

This should re-generate cts_1.0.0_all.snap which is already present in the ZIP archive in case you run into problems with building the app. The snap is the new package format for snappy. Then you can install this package on the card.

snappy-remote --url=ssh://192.168.1.123 install ./cts_1.0.0_all.snap

You have to update the IP address according to what your card obtained on your network. The upload tool will prompt you for username/password, it is ubuntu/ubuntu by default.

Update the GATT tree in the BLED112 firmware as described in the previous post. Plug the BLED112 dongle into the BeagleBoard's USB port. Then open a command prompt on the BeagleBoard either using the serial debug interface or by connecting to the instance with ssh and execute the following command:

sudo /apps/cts.sideload/1.0.0/bin/cts /dev/ttyACM0

The familiar console messages appear and you can connect with the Android app as depicted in the image below.


One thing you can notice here is that Snappy's shiny new package system is not ready yet. In order for this package to access the /dev/ttyACM0 device (to which the BLED112 is mapped without problem), it has to run as root. This is something that the Snappy team is yet to figure out. The experience, however, is smooth enough that application development can be started now.