📜 ⬆️ ⬇️

Analogue ambilight from LED strip WS2812, arduino and kinder surprise

Ambilight is a Philips-developed side-lighting technology behind the TV box, which, according to the creators, helps the viewer dive even more into what is happening on the screen.

There are quite a lot of references to DIY Ambilight-like projects in the network, and commercial implementations of such functionality in third-party / opensource projects, for example, Lightpack , are also known .

About a year ago, I almost accidentally acquired a LED strip based on WS2812 RGB controlled diodes, hoping to use it in some Arduino project. The lack of time and controversial information about the possibility of working together with AVR controllers (that is, Arduino) led to the fact that the implementation was postponed for almost a year. What was my surprise when the entire mini-project for creating Ambilight and organizing its collaboration with XBMC took only two evenings, i.e. 5-6 hours, including finding a working solution, writing a sketch for the arduino and a configuration script to boblight, debugging their collaboration, cutting, soldering and mounting the tape, as well as laying an 8m cable from the arduino to the TV.
The purpose of this topic is to share with the community experience and surprise about how simple it was, and to set the direction for those who want to repeat it at home. It seems to me that with the necessary components, the repetition of my experience "on the table" will take no more than half an hour.

Plastic container from Kinder Surprise, used as a housing for the LED controller, glows beautifully in the dark:


What i had


  1. Home Media Server / NAS based on Intel Celeron G1610 with Ubuntu Server 13.10 installed
  2. Ready arduino-compatible motherboard purchased on ebay
  3. 4 meters of such a RGB LED tape (for a 32 "screen it took less than three meters, about 140 diodes out of 240)
  4. About 8 meters of a symmetrical four-wire telephone cable (such as, for example, an ADSL modem is connected to a splitter), i.e. not twisted pair

Total costs a little more than 2,000 rubles, of which 1,800 rubles. - LED tape with delivery and 250 rubles for the Arduino (wires and a box from under the kinder surprise were found in the bins).
')

How it works


LED Strip WS2812

Each meter of tape consists of 60 SMD LEDs of frame size 5050 WS2812 with a three-channel PWM controller built into each diode. The difference between WS2812 and WS2811, with which they are sometimes confused, is actually the presence of LEDs (WS2811 is a separate controller chip, WS2812 are LEDs with a built-in controller). Without going into details , I will briefly describe the diode control protocol:
There are only three tires on the tape: ground, power and control. With the first two, everything is clear from the name (a stabilized voltage source + 5V is required), and the control works like this:
During the first 50 ms, the tape is initialized by grounding the control bus. After that, the controller sends a packet of 24-bit packets (8 bits for each color channel) containing brightness information, each packet is assigned to one diode. The data in the pack is not separated by anything, i.e. each next package goes directly to the previous one. Having received the entire pack (the pack length is 24 bits x the number of diodes in the tape), the controller of the first diode bites off its packet from it, uses the information for the intended purpose, and relays the rest of the pack forward. Thus, a packet from one 24-bit packet reaches the last diode.
I was lucky: I came across a library for Arduino FastSPI_LED2 , the authors of which managed not only to implement this protocol, but also to leave intact a certain amount of controller resources. The general logic of its operation is as follows: it is necessary to initialize the tape (the controller type is set, the arduino control pin, the number of diodes and their maximum brightness), specify an array of eight-bit brightness values ​​of each color for each diode and give the command to display the data, after which the control packet is sent on the tape, and the diodes change their color.

Boblight

Opensource-project boblight , according to the developers, is a set of tools for controlling LEDs connected to an external controller. I chose it because of the support of the USB serial interface, the simplicity of its implementation, and, most importantly, the presence of a native client for XBMC.
From the user's point of view, i.e. We are with you, everything is quite transparent. There is a boblight daemon that receives information about the displayed image via TCP / IP (taking into account the presence of the official boblight plugin for XBMC , there is no need to understand the operation of this protocol).
When the client receives data, the daemon analyzes the video in accordance with its configuration and sends information to the external controller about what should be and how it should be lit, in a form that the controller can understand. I chose the option in which data is transferred byte-by-byte via the USB serial port. As in the case of a tape, sending data is preceded by an initialization sequence, then the data for all the diodes go in a row.
A prerequisite for running boblightd is the presence of a configuration file in which the output device is set (I have / dev / ttyACM0), the number of channels (equal to three times the number of diodes, channel for each color of each diode), initialization sequence (default 0x55AA), hexadecimal the value of each of the primary colors, and also each diode is set in the following format:

[light] name right1 #,   ,       color red arduino 1 # ,            color green arduino 2 color blue arduino 3 hscan 80 100 #    ( ),             , ..     . vscan 97 100#  ,         ,        . ..   100           .     ,  94 97. 


Writing this manually was too lazy, so I wrote a small script that takes as arguments the number of diodes vertically and horizontally and the scan depth in percent, and gives the finished configuration file for boblightd (note, to change the output device, speed of the serial interface or update frequency , you need to edit the script):

Script to generate a configuration file for boblightd
 #!/bin/bash # A shell script to make boblight.conf file # Written by: TPertenava, based on default boblight.conf example # Last updated on: 22.10.2013 #set vars # -v vertical LED count # -h horizontal LED count # -d deepness of color detection (in percent) usage() { echo "Usage: $0 [-v <1|100>] [-h <1|100>] [-d <0|100>]" 1>&2; exit 1; } HOR= VER= DEEPNESS= while getopts "v:h:d:" OPTION; do case ${OPTION} in h) HOR=${OPTARG} ;; v) VER=$OPTARG ;; d) DEEPNESS=$OPTARG ;; esac #echo "s= ${o}" #${o} = ${OPTARG} done if [ -z "${VER}" ] || [ -z "${HOR}" ] || [ -z "${DEEPNESS}" ]; then usage fi echo "#Leds in vertical = $VER" echo "#Leds in horizontal = $HOR" function output { # $1 location {right top bottom left} # $2 hscan low # $3 hscan high exit } cat <<EOF [global] interface 127.0.0.1 port 19333 [device] name arduino output /dev/ttyACM0 EOF echo channels $(((2*$VER+2*$HOR)*3)) cat <<EOF #number of led's multiplied by 3 type momo interval 50000 # update interval in mks, 20000 for 50hertz rate 38400 prefix 55 AA # only for momo devices, divides RGB send, ie LEDs #arduino bootloader runs when opening the serial port for the first time #delay transmission one second after opening so we don't send shit to the bootloader delayafteropen 1000000 #debug on [color] name red rgb 0000FF [color] name green rgb 00FF00 [color] name blue rgb FF0000 EOF for (( i=1; i<=2*$HOR+2*$VER; i++)) do if ((1<=$i && $i<=$VER)) then LOCATION="right" VSCAN_HIGH=$((100-100*($i-1)/$VER)) VSCAN_LOW=$((100-100*$i/$VER)) HSCAN_LOW=$((100-$DEEPNESS)) HSCAN_HIGH=100 elif (($VER+1<=$i && $i<=$VER+$HOR)) then LOCATION="top" HSCAN_HIGH=$(echo "100-(($i-($VER+1))*100/$HOR)" | bc) HSCAN_LOW=$(echo "100-(($i-$VER))*100/$HOR" |bc) VSCAN_LOW=0 VSCAN_HIGH=$DEEPNESS elif (($VER+$HOR+1<=$i && $i<=2*$VER+$HOR)) then LOCATION="left" VSCAN_LOW=$((($i-($VER+$HOR+1))*100/$VER)) VSCAN_HIGH=$((($i-($VER+$HOR))*100/$VER)) HSCAN_LOW=0 HSCAN_HIGH=$DEEPNESS elif ((2*$VER+$HOR+1<=$i && $i<=2*$VER+2*2*$HOR)) then LOCATION="bottom" HSCAN_LOW=$((($i-(2*$VER+$HOR+1))*100/$HOR)) HSCAN_HIGH=$((($i-(2*$VER+$HOR))*100/$HOR)) VSCAN_LOW=$((100-$DEEPNESS)) VSCAN_HIGH=100 fi echo [light] echo name $LOCATION$i echo color red arduino $((3*$i-2)) echo color green arduino $((3*$i-1)) echo color blue arduino $((3*$i)) echo hscan $HSCAN_LOW $HSCAN_HIGH echo vscan $VSCAN_LOW $VSCAN_HIGH echo done 


The syntax for using the configuration creation script (I have 45 diodes horizontally and 28 vertically, scanning depth is 20 percent, the tape starts from the bottom right edge of the screen and is glued counter-clockwise):
 # ./boblight_config_generator -h 45 -v 28 -d 20 > /etc/boblight.conf # boblightd -f 

So we set up boblightd and run it in the background (with the -f option).

A detailed description of the configuration file can be found in the official repository of the boblight project .

The official boblight plugin is installed directly from the XBMC “add-on” menu:


The boblight-toolkit also includes the boblight-constant program, with which you can output an arbitrary color value for all diodes to the controller at once.
So, when executing a command
 $ boblight-constant FFFFFF 

, the ribbon will light up with white light with the maximum brightness of the controller. I used this program to debug the interaction between boblightd and the Arduino sketch, to which we now proceed.

Arduino


Oddly enough, this stage was also amazingly easy, thanks to the FastSPI_LED2 library mentioned above. Sketch for Arduino is simple to disgrace, it waits for the initial sequence (0x55AA) from the serial port, after waiting, initializes the data array for the LED, and then starts the array output function to the library on the tape. It should be noted separately that, strictly speaking, WS2812 is not an RGB, but a BRG diode, i.e. first in order is the information of the blue, then the red and green channels.

Sketch for Arduino
 // boblightd receiver for WS_2811, boblightd device type=momo, prefix 55 AA // capable at least for 20Hz input stream if LED count <= 150 // by TPertenava // last modified 22.10.13 #include "FastSPI_LED2.h" #define NUM_LEDS 138 // LED count #define CHANNELS NUM_LEDS*3 // each output for R, G and B #define LED_PIN 16 // arduino output pin #define BRIGHTNESS 96 // maximum brightness #define SPEED 38400 // virtual serial port speed, must be the same in boblight_config CRGB leds[NUM_LEDS]; void setup() { delay(2000); Serial.begin(SPEED); LEDS.setBrightness(BRIGHTNESS); LEDS.addLeds<WS2811, LED_PIN, BRG>(leds, NUM_LEDS); } byte values[NUM_LEDS][3]; // 2-level array, 1 level is for led number, 2 level is for rgb values void WaitForPrefix() { uint8_t first = 0, second = 0; while (second != 0x55 || first != 0xAA) { while (!Serial.available()); second = first; first = Serial.read(); } } void loop() { WaitForPrefix(); for (byte Led = 0; Led<NUM_LEDS; Led++) { for (byte Color = 0; Color<3; Color++) { while(!Serial.available()); values[Led][Color] = Serial.read(); } } memset(leds, 0, NUM_LEDS * sizeof(struct CRGB)); //filling Led array by zeroes for (byte Led = 0; Led < NUM_LEDS; Led++) { byte red = values[Led][0]; byte green = values[Led][1]; byte blue = values[Led][2]; leds[Led] = CRGB(blue, red, green); } LEDS.show(); } 


Hardware-iron part


Nutrition

The main issue is power supply. Arduino in my case receives power via USB, and the tape itself - from a separate power supply. To equalize the ground potential of the Arduino and the power source are connected. True, through an eight-meter telephone wire with a resistance of a couple of ohms. The nominal power of the tape indicated on the package is 18W / m, or 0.3W / diode. Thus, the rated power of a 140-diode tape segment is 42W. As a tape power source, I used a compact pulse PSU from a USB hub, 5V 3A, i.e. The maximum power output of a power supply unit is 15W. In accordance with this calculation, the maximum brightness of the diodes was reduced (see above Arduino sketch). (Yes, I know that in the datasheet diodes the supply voltage of 6..7V is indicated, I can’t say anything about this, it works well on + 5V, I didn’t measure line consumption).
Tape

On closer inspection, the tape looks like this:

Pay attention to the direction of the arrows, each diode has an input and output!
The tape was connected to the controller with a rather long cable (~ 8m), there was some risk here, but my fears were not confirmed - apparently, the bit error rate during transmission is very low - otherwise, in the absence of a signal, some diodes would “blink” instead of to be turned off. However, it is possible that in other conditions, in the presence of electromagnetic interference at frequencies close to the carrier of the control signal (about 800 kHz and harmonics), the result would be different.
I suspect that it would be nice to protect the output of the Arduino with a limiting resistor to prevent the consequences of accidental closure of the information input to power supply or from external interference (for example, from a thunderstorm) to a long wire. I did not do this, because the thought came later, and soldering inside a kinder surprise would be very inconvenient.
Installation

Installation thanks to the adhesive base of the tape was also not difficult:


To reduce drawdown on power, I made the tape joints in the corners with a rather thick AWG26 wire:


"Well, now there will be slides," or a video of the work of my Ambilight





In conclusion, it remains to add that I will be happy to answer all your questions.
Thanks for attention!

Source: https://habr.com/ru/post/200200/


All Articles