Thursday, 10 January 2013

Setting up an Arduino + LPD8806 ambilight using boblight with XBMC on Ubuntu

An Ambilight is a great thing - if it works. I want to write about some of the hoops I had to jump through to make it work. This is very Linux-specific, but you might take away something for other configurations too... Here is the original adalight tutorial, which I used to get this working and it is really worth reading.
I have a bit of a different setup here though, consisting of a regular desktop PC with a COM port, an Arduino Pro (no USB) with an ATmega328 and 40 RGB-LEDs driven by the LPD8806 chipset.

1. LPD8806 + Arduino - Setup

The first thing is to set up the Arduino to use the LPD8806 LED strip (translated datasheet). Here's a great tutorial on how to use it. I'll concentrate on the setup I mentioned above.
The strips/chips run at 2.7-5.5V and use the SPI protocol. The Arduino is great for this task because it has SPI hardware so you don't have to bit-bang the GPIO pins, saving you lots of processor cycles.

Take a look at your LED strip. You'll need to solder wires to all the connections on the input end of the strip, namely the DI, CI, GND and 5V connectors. NOTE: The DO and CO connectors are for output and pass signals on to the next strip/segment, so leave them alone unless you want to connect additional strips/segments. Now connect the DI line to Arduino pin 11 and the CI line to Arduino pin 13 to use hardware SPI and connect GND to GND on the Arduino.

One segment of the LED strip (Picture from Adafruit, Attribution-ShareAlike Creative Commons)

It makes sense to use only a few strip segments first for a test. If you have only ~5-6 strip segments, connect 5V to the 5V line of your Arduino.
If you have more than that your Arduino can not power the strip directly from the 5V line (forget the 3.3V line btw), depending on how you've connected your Arduino. The LEDs can draw ~60mA each on full white, so a strip segment can draw ~120mA. 6*0,12A = 0,72A + driver chips + the Arduino running. The regulator on the Arduino is rated for 1A only! Thus you need to connect a 5V power supply to the Arduino power jack and connect 5V on the strip to Vin on the Arduino.

To supply power from the PC I used power connectors from the PC power supply. I wanted to be able to detach the whole thing easily, so I ripped appart an extension cable and "epoxied" it to a slot cover. There the serial cable (an old serial mouse cable) and the power cable to the Arduino can be connected.

2. Arduino + PC - COM port level shifter

If you have an Arduino that features an USB port you can skip this section. Else you might want to read on.

For my setup I needed a RS232 to TTL level converter. Regular PC/RS232 serial port voltage levels are +/-12V, but the Arduino runs at 3.3 or 5V and thus you'll fry it if you connect it directly. I had a MAX3222 (other datasheet here) level shifter IC lying around, so I used that on a piece of prototype board. Here's the basic schematic. The capacitor values should be ok for 3.0-5.5V applications. For similar ICs the pin numbers may change or there are no EN/ or SHDN/ pins, but that should be easy to figure out. I additionally connected the RST pin, but you could probably also omit that.

Here's what my finished prototype board looks like. The power supply for the Arduino and the LEDs is on the right side.

3. LPD8806 + Arduino - Software

Once you have your connections set up and power supply figured out, you'll need to program the Arduino to drive the LED strip. Code for this can be downloaded from github, including instructions on how to install it in the Arduino IDE. Once you've done that, connect your Arduino to the PC, start the IDE and load an example sketch, e.g. "strandtest". Make sure to comment the line "LPD8806 strip = LPD8806(nLEDs, dataPin, clockPin);" and uncomment the line "LPD8806 strip = LPD8806(nLEDs);" instead, so hardware SPI is used. Also adjust "int nLEDs = 32;" to your strip length. After uploading the sketch your strip should run some tests and you can see if it works ok.

4. Arduino + PC - LEDstream

Now you need code to receive the LED data from the PC. This is done via a sketch called LEDstream_LPD8806 that is available on the Adalight github page. Download it and program it onto your Arduino using the IDE.

5. Arduino + PC - boblight

Boblight is a software that grabs parts of your screen, processes them to your needs and then sends them to boblight clients over a COM port or the network in various formats. We need to download and compile boblight from the source:
  • Change to your home directory: "cd ~"
  • Download boblight using Subversion:"svn checkout boblight-read-only"
  • Change to the directory: "cd boblight-read-only/"
  • Configure it: "./configure --without-portaudio --without-opengl --without-x11 --prefix=/usr"
  • Compile it: "make"
  • Install it: "sudo make install"
If there were no errors, boblight should be usable now.

6. Arduino + boblight - Communication setup

The LEDstream sketch running on the Arduino needs to receive the LED data in a specific format, so so we need to configure boblight to send data in that format. Locate your boblight.conf file. It should reside in "/etc/boblight.conf" on Ubuntu. Open it using an editor of your choice, e.g. nano or gedit: "sudo nano /etc/boblight.conf". Your [device] section should look like this:
  • Chose any name for your ambilight e.g. "name ambilight1".
  • The device type should be "type momo".
  • Output defines where the ambilight is connected. COM1 is /dev/ttyS0, an USB-COM interface could reside under /dev/ttyUSB0 or /dev/ttyACM0 instead. Use "ls /dev/tty*" to find out what serial ports you have.
  • Channels is the number of LEDs times the number of colors, 3*40 = 120.
  • The initialization sequence for your LEDstream program is "Ada" (416461h) this the first data sent. Then follow 2 bytes containing the number of LEDs and one byte of checksum for those bytes. The checksum is calculated by XORing the two bytes and 55h. In my case the three bytes are "00 28 7d" (40 LEDs = 0028h) 00^28^55 = 7d.
  • Interval specifies the update interval in microseconds. "interval 20000" means 50 updates per second and should be sufficient.
  • Then follows the baudrate of the com port. Use "rate 115200", the highest possible baud rate.
A good explanation of all boblight.conf parameters can be found here.

name ambilight1
type momo
output /dev/ttyS0
channels 120
prefix 41 64 61 00 28 7d
interval 20000
rate 115200
delayafteropen 1000000

7. Arduino + boblight - Color setup

I had a lot of problems with the "calibration" of the LEDs. Hue wasn't always correct and black was displayed as white, because everything was much, much to bright. I ended up with a rather strange color setup that is working for me(tm), but ymmv...

name red
rgb FF0000
gamma 2.1
adjust 0.12
blacklevel 0.01

rgb 00FF00
gamma 2.1
adjust 0.12
blacklevel 0.01

name blue
rgb 0000FF
gamma 2.2
adjust 0.1
blacklevel 0.01

8. Arduino + boblight - Screen grabbing setup

The boblight deamon boblightd grabs regions of the screen, calculates the average of a region and attributes that data to a certain pixel. This needs to be set up properly so your LEDs reflect the correct parts of the screen. The settings depend on how you've laid out your backlight. Here's mine:

 Open your boblight.conf again. The logic for setting up an LED works like this:
  • Every single light/LED starts with "[light]"
  • Then follows its name e.g. "left1" "left2", "top1", ...
  • Then the colors (see section 7 above) sent to the device for it:
  • "color COLOR DEVICE INDEX" e.g. "color red ambilight1 1", "color green ambilight1 2", ...
  • Next the hscan parameters specifies where the screen capture region starts and ends. The value is in per cent of the screen, starting at the left border. A value of "hscan 75 100" would thus capture a region starting at 75% of the screen up to the end of the screen. It ist best not to make the regions extend into the screen too much (max. ~5-15%)
  • The vscan parameters works similar.
A complete section of light setup can be seen in the boblight wiki. I did my configuration by hand, but there's a configuration script and a windows tool available that can maybe save you some work.
Here's my boblight.conf as a reference.

Once you've set up boblight you can test it out. Open a terminal and start the boblight deamon with "boblightd" and watch the output. It should connect to the Arduino ok and display no errors. Open a second terminal and use the tool boblight-constant with a color you want to set, e.g. "boblight-constant FF0000" (red). There's also a tool called colorswirl in the adalight code base you could give a try. If you want to adjust settings in boblight.conf, kill the boblightd process in the first terminal, adjust the settings and restart it. Experiment until you like your colors, brightness etc.

9. boblight + XBMC - Startup

The boblight deamon needs to be available when the system resp. XBMC starts up. It makes sense to activate it upon system boot. You can do this by editing your /etc/rc.local as root, e.g. "sudo nano /etc/rc.local". Add the line "boblightd -f" (runs boblightd in the background) somewhere in the lower part.

10. boblight + XBMC - Addon

Make sure boblightd is running either by rebooting or running "boblight -f". To make boblight work in XBMC you need the addon, which you can download from within XBMC. Go to settings and enable it. Now your boblight should turn on whenever you play a video. Here's a good test video to see if all LEDs and regions work correctly, but I also use Darwin Deez - Radar detector as a test video a lot ;)
Should you need to adjust settings in boblight.conf you will have to restart boblightd.  It is running in the background though and you'll have to kill it first. Use "ps -A | grep boblightd" to find its process id, then kill the process with "sudo kill PROCESS_ID" using whatever process id the previous command told you. Then you can edit boblight.conf and afterwards restart boblightd with "boblightd -f".

11. Profit ;)

Enjoy your Ambilight!


Trucker said...

I'm into trying to get together boblight but could nothing about programming and do not understand how you get up prefix. I need a prefix for 37 Leds and one of 116 Leds. I would really have to understand how I get it. I get it to work with the finished congfig files I can find online for 25,50,100 etc. I really need help. regards Stefan

Kim said...

6. tells shows how to do this - if you're using the LEDstream program and an Arduino, aka Adalight...
Take the number of leds you have as a hex number. You can e.g. use the Windows calculator set to programmers view and switch the decimal system to hexadecimal. 37 LEDs decimal is 25h. You need two bytes in the prefix, so prepend a 0 -> thus 00 25. To get the checksum part use the XOR operation on all the values and an additional 55h: 00h XOR 25h XOR 55h = 70h (112 decimal). For 116 LEDs you'll get 21h
Now you have the last part of your prefix: 00 25 70 resp. 00 74 21 the rest is in 6.

Good luck.

fall deaf said...

Hey, nice job! I especially like the slot with the molex connector and serial port, super professional looking.

Roma Rom said...

AmbiBox 2.1.3 released

for Windows users only
AmbiBox support Adalight device (up to 200 zones).
Capture in games, videoplayers with DirectX 9/10/11 (with PlayClaw).
Official support Windows 8. Use the method screen capture = Windows 8

Post a Comment