Showing posts with label light effects. Show all posts
Showing posts with label light effects. Show all posts

Monday, January 2, 2017

Adding more power to the BLE-enabled Christmas light

The truth is that the low-voltage LED strip I used in the previous post was a backup solution. Originally I bought a 230V-operated Christmas light with two independent LED strips but adapting that beast to Bluetooth Low Energy turned out to be a bit more problematic than I expected. I had to learn a bit about power electronics first.

My LED light I used as a base in this post is a standard-issue Chinese-made device. Below you can see how it looks like, its original controller already stripped of its plastic protective housing.



The circuit is very similar to this one, except that mine had only two LED strips, instead of 4. In my version the controller chip had HN-803 marking and the strip-controlling thyristors are of type PCR 406. The modes the original controller supported were all zero-crossing ones so I retained this operation.

Very shortly about the zero-crossing vs. phase-angle mode of controlling thyristors or triacs. A good introduction can be found here. The thyristor is fed with a current that has frequent zero-crossings. This is necessary because once the thyristor is switched on, the simplest way to turn it off is to remove the current on the load. That is why the Graetz-bridge converting the 230V alternating current into direct current does not have the usual filtering capacitors. This guarantees that the current feeding the LED strips/thyristors has zero-crossings with 100 Hz frequency. After the zero-crossing the thyristor can be switched on again by just a mA-range current applied on its gate electrode. The phase difference between the zero-crossing and the moment the gate current is applied determines whether we use dimming or not. Then the thyristor will remain switched on until the next zero-crossing. As the frequency of these zero-crossings is just 100 Hz, pulse-width modulation we used in the previous post for dimming cannot be used, the human eye would notice the flickering with such a low PWM frequency. So the simple circuit I am going to present here can only be used to flash the LED strips but not for dimming them. Implementing phase angle-based dimming would not be too hard with the features of our microcontroller but I did not want to get into that in this post.

Warning: part of the circuits described in this post use high-voltage 230 V current. Do not try to build them if you do not have experience with high-voltage electronics because you risk electrocuting!

Our exercise looks very simple. We need to remove the HN-803 controller circuit, replace it with our nRF51822 BLE SoC and use 2 of the output pins of the SoC to turn on the thyristors. Once the SoC drives the output pin to low, the thyristor will switch off at the next zero-crossing which allows us to flash the LED strips with frequencies lower than 100 Hz. Unfortunately nothing is simple if high-voltage current is involved because this simple circuit would connect the ground of the microcontroller board to a wire with high-voltage current (HVGND on the schematic) risking electric shock if someone touches the microcontroller board or ground-connected metal parts (like connectors) when the circuit is in operation. So I built an optocoupler-based isolator pictured below (click to enlarge).





The isolator ensures that the microcontroller-side has nothing to do with high-voltage current so no special precautions need to be done when handling the MCU board. The isolator itself, along with the remaining parts of the original controller circuit (D1-D4, T1/T2 and of course, LED1 and LED2 representing the two LED strips) are placed in a separate enclosure box. R3 dissipates around 1W so make sure that the resistor in question can withstand this power, I used a 2W resistor.

Driving the low-voltage side of the optocoupler still requires about 5 mA so I introduced additional FETs on the SoC side to provide this current. The updated circuit looks like below (click to enlarge). This circuit can control one low-voltage LED strip (with dimming) and two high-voltage strips (with no dimming) at the same time.




In my implementation the isolator and the MCU boards are located in two enclosure boxes which allows modular deployment - if there are no high-voltage strips then the isolator box is not needed. The connection between the MCU and the isolator boxes are 4 mA current loops which is quite resistant to noise. So the connecting cable could be  much longer than in the image below.




Now on to the software.

Click here to download the nRF51822 code.

Click here to download the Android code.

Compilation instructions can be found in the previous post. One warning: if you built the previous version and uploaded into the SoC, make sure that you mass-erase the chip (mass-erase.sh script provided in the download bundle) and upload everything again (soft device and updated application) because the BLE service description has changed and the nRF51822 SDK writes data into the flash about the service characteristics.

Again I propose that before you start to experiment with the Android application, test the BLE device with a BLE debug tool like the nRF Connect for Mobile. You will see that the high-voltage LED strips are controlled by a new BLE characteristic (the old one controlling the low-voltage strip is still available unchanged).



The byte array written into this characteristic is a blob that describes the light effect. The blob has two identical sections, each of them 9 bytes long. One section starts with 1 byte for the repetition counter then 4 times 2 bytes, each 2 byte subsection having 1 byte for the time duration (in 0.1 sec units) and one byte for the bit mask of the LED strips (bit 0->1 if LED strip #1 is to be on, bit 1->1 if LED strip #2 is to be on).

Regarding the Android application, there are no too many surprises. I used the now deprecated TabActivity because I did not feel like playing around with fragments for this simple prototype. The screen has separate tabs for the low- and the high-voltage strips like this:



The disconnection deficiency described in the previous post is still there. Make sure that you disconnect from the device after each manipulation (by pressing the Back button) because neither the device nor the Android application implements disconnection timeout so if you stay connected, nobody else will be able to connect to the LED strip controller. Otherwise have fun with these BLE-enabled Christmas lights!

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 convert_s130.sh script, upload into the device with the upload_softdevice.sh, compile the code with the "make" command then upload the application with the upload.sh. 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.

036000000000000360

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?