Monday, December 19, 2016

BLE-enabled Christmas light

The idea came from the light-themed Budapest Makers' Meetup and from the cheap Christmas LED strip that my wife bought for about 1 euro. Plus my other hobby project has not gone as smoothly as expected but produced a connection-oriented nRF51822 code and bang, the idea was born, let's couple the LED strip with the Bluetooth Low Energy System-on-Chip (SoC), add an Android application and let's see what comes out of it. This post is the tale of that adventure.

First, about the LED strip. This is a battery-operated device with two states: off or on. It has surprisingly low power consumption considering its 10 LEDs.

I removed the battery case and put it away - it will serve me well in other projects. Then I hooked up the LED strip with the nRF51822 as shown in the schematics below (click to enlarge).

As described in some previous blog posts, I use a breakout board containing little more than a sole nRF51822 and the Bus Pirate programmer to upload the application into the chip. The components on the breakout board (quartz, etc.) are not shown in the schematics. If you use the same type of breakout board that I do, make sure that you connect both GNDs together otherwise instability may be the result.

Other than that, the circuit is very simple. The LED strip is driven by P0.22 of the nRF51822. Even though the strip consumes in the mA range, I played safe and inserted a 2N7000 FET between the MCU and the LEDs. The 1 Ohm resistor was already part of the circuit in its original form so I thought it is a good idea to preserve it. One can also observe the 3.3V stabilizer circuit that transforms the POWER_INPUT (5V in my case) to the 3.3V consumed by the circuit. Any stabilizer circuit will do, I just point out that without the C1 condensator I experienced instability when the Bluetooth radio was in operation. The whole circuit sits nicely in a plastic electronic enclosure box.

Now on to the software.

Click here to download the nRF51822 sources.

Click here to download the Android sources.

The programmer software that drives the Bus Pirate tool is the same forked version that we used before. The project assumes the 12.1.0 version of the nRF5 SDK. I propose that you stick to this version too because upgrading the project to another version may involve a lot of work (as I experienced previously). Convert the soft device with the script, upload into the device with the, compile the code with the "make" command then upload the application with the While doing this, you need to modify SDK path and device files in the scripts/Makefile according to the directory layout of your system. After a power cycle, you can observe the device spitting out a large amount of debug messages on the debug serial port. Also, LED1 starts flashing showing BLE advertising activity.

Before installing the Android part, let's check that the device works correctly. Download nRF Connect from the Google Play store, start scanning for BLE devices, look for "ledctr" (the default name given to our device), connect and open the custom service with the 128-bit UUID of 274b15a4-b9cd-4e5e-94c4-1248b42b82f8 that it advertises. You should see something like this:

Write the following byte array into the characteristic with the UUID of 274b0000-b9cd-4e5e-94c4-1248b42b82f8.


This means 3 seconds ramp-up to 0x60 intensity (96%), no flashing, 3 seconds ramp-down from 0x60 intensity. If you see this light effect, the device is ready. Don't forget to disconnect: the application can handle only one active connection and there's no timeout mechanism implemented.

The BLE device implements the following light effect. First there is the ramp-up phase when the light intensity increases from 0 to a maximum. The ramp-up time and the maximum intensity can be set by means of BLE. Then there is the flashing phase when two states with different intensity come one after the other. The repetition counter, the length and the intensity of both states can be set. Then there is the ramp-down phase, when the intensity goes down from a maximum to zero. Here again the ramp-down time and the initial intensity can be set. All these phases are optional, if any of the time value is zero, that phase is skipped, if the repetition counter is zero then the flashing phase is skipped entirely.

The LED strip is capable of only on and off states hence the intensity effect is implemented by means of pulse-width modulation (PWM). The BLE application operates a 100 msec timer that updates the timeouts, intensity changes and state transitions. Look for the light_update_timer_handler function in main.c if you want to modify that functionality.

In order to create the Android project, follow the instructions in this blog post. Essentially you have to create an empty Android Studio project then replace the source tree under app/src with the content of the ZIP file that you downloaded previously.

The Android application has two major parts. First, it scans for BLE devices that advertise that unique UUID that I allocated to the application and lists those devices in a List. If the user clicks any of the devices, the Android application connects to the LED controller service with the unique UUID I mentioned before, retrieves the current state of the light effects and displays it by means of some SeekBars. The user can manipulate these parameters then update them on the device by pushing the "Set values" button. The device then starts to perform the light effect. The user can disconnect by pushing the "back" button.

One major deficiency of the application is that disconnection timeout was not implemented, neither in the device part, nor in the Android application. This means that the user has to take care that he/she disconnected from the device after modifications to the light effects were done. If that does not happen, the device stays forever in "connected" state which means that it will be impossible to connect to it again without resetting the device. I leave this exercise to the interested reader. :-)

The other problematic part is the lack of security. Anyone knowing how to connect to the device (either by knowing the format of the light effect blob or by just simply having the Android application installed) can manipulate the light effect. Personally I don't think it is a major issue because security can always be added later. Beside, what could possibly go wrong if a passersby can just change the light effect in my window?