Ambi/Atmo-Light implementation using ATmega328 micro-controller and WS2812b LED strips
Go to file
King Kévin a5272f9a5b add videos test patterns (generated from pictures using ffmpeg) 2015-07-14 15:51:04 +02:00
firmware adjust to 50+1 LED instead of 60+1 since VLC does not support more than 16 per side (now using 16 on top/bottom, 9 on sides) 2015-07-14 11:07:33 +02:00
test-patterns add videos test patterns (generated from pictures using ffmpeg) 2015-07-14 15:51:04 +02:00
README improve instructions 2015-07-14 15:49:40 +02:00
parse_vlc_dump.rb add script to parse VLC atmolight fnordlight output 2015-07-14 15:39:02 +02:00
test.rb adjust to 50+1 LED instead of 60+1 since VLC does not support more than 16 per side (now using 16 on top/bottom, 9 on sides) 2015-07-14 11:07:33 +02:00
vlc-amtolight-dump.txt add script to parse the VLC fnordlight output 2015-07-14 11:05:52 +02:00
vlc-fnordlicht-dump.txt add VLC fnordlicht output logging instruction and example dump 2015-07-14 15:49:01 +02:00

README

project
=======

The CuVoodoo AtmoLight mimics the Philips ambient lighting.
The idea it to have LED on the back to the screen shine one the side with the same color as the border colors displayed on the screen, creating and ambient light.

recipe
======

To implement this I used:
- VLC with the included AtmoLight video filter to ouput the colors to be shown on the LEDs
- an Atmel ATMEga328P microcontroller at 16 MHz (i.e. Arduino Nano 3.0) to control the LEDs and show the values received from VLC over serial
- strips of WS2812B chains LEDs, individually controlled using a data line

The original AtmoLight offers only has 4 channels: top, bottom, left, right.
Each channel correspond to an LED strip, but all LED on the strip will show the same color.
But I am using a 60 LEDs WS2812B BlinkyTape LED strip, with individually controllable LEDs.
And I would like to use this capability to have a more fine grained ambient light.
Thankfully VLC comes with several AtmoLight device types, such as fnordlicht, which some offers more channels.
Plus VLC offers the possibility to divide the screen sides in "zones".
So to match the 16/9=1.78 aspect ratio of my screen I divided the LED strip in 19 LEDs for top and bottom, and 11 LEDs for the sides, for a close aspect ratio of 19/11=1.73.
Sadly VLC come with a limit of 16 zones per side.
At least with the 19/11 LEDs combination I can also do the 16/9 LEDs combination.

code
====

firmware
--------

This is the microcontroller (e.g. Arduino Nano 3.0) code.
Use `make` to compile and flash it.

`lib/uart.c` allows to talk over serial.
VLC will send the coloer values over USB, going to the serial UART.

`lib/ws2812b` allow to control WS2812B LED strips.
The LED strips are connected in parallel as follows:
- 11 LEDs on pin D2 (PD2) for the top first LED strip
- 08 LEDs on pin D3 (PD3) for the top second LED strip
- 11 LEDs on pin D4 (PD4) for the left LED strip
- 11 LEDs on pin D5 (PD5) for the bottom first LED strip
- 08 LEDs on pin D6 (PD7) for the bottom second LED strip
- 11 LEDs on pin D7 (PD8) for the right LED strip

`main.c` will parse the UART input data for fnordlicht commands and set the LED colors on the strip.
Don't forget to configure the AtmoLight VLC video filter accordingly:
- device type: fnordlicht
- count of fnordlicht's: 51
- number of zones on top: 16 (maximum)
- number of zones on bottom: 16 (maximum)
- zones on left/right side: 9 (to follow 16/9 aspect ratio)
- calculate an average value: yes
- channel 0 summary: zone 4 summary
- channel 1 left: zone 3 left
- channel 2 right: zone 1 right
- channel 3 top: zone 0 top
- channel 4 bottom: zone 2 bottom
- channel/zone assignment: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50
Only 50 LEDs will be used (16+9+16+6), but the 51st LED for the summary will trigger the output of the 50 LEDs.

other
-----

`test.rb` will connect to the microcontroller and run standard tests to see if all is working.

`parse_vlc_dump.rb` will parse the data from a file give a argument and format the data coming out of VLCs AtmoLight fnordlicht module.
This helps to see what data/commands VLC sends.
The easiest way to get data it to use 2 USB to UART converter with TX/RX interconnected, VLC using the first (ttyUSB0), and you getting the data on the other (ttyUSB1).
To set the baurdaute: `stty -F /dev/ttyUSB1 19200`.
To get the data: `xxd -ps /dev/ttyUSB1 > dump.txt`
To show the data: `./parse_vlc_dump.rb dump.txt`
A example for a white picture is available in `vlc-fnordlicht-dump.txt`

limitation
==========

In the current WS2812B implementation setting an LED colors requires 36 us.
Outputting the data to the WS2812B strips requires 38 us for a single LED on all pins/strips in parallel.
For 11 LEDs per strip is requires 368 us.

The fnordlicht protocol uses a baud rate of 19200 bps with 8N1 configuration.
Thus sending/receiving one byte requires 1.0s/(19200bps/(8+1)bits)= 469 us.
This leaves enough time to output the LED color values to the strips. 
To set the color of an LED it VLC to send a 15 bytes fnordlicht command.
Thus in one second for 50 LEDs we can show 1.0s/(19200bps/(8+1)bits/15bytes/51leds) = 0.5 fps.
This is not a particularly fast refresh rate.

And finally the VLC AtmoLight video filter module is only available in VLC <= 2.2.
This module has been removed for VLC 3.0.

links
=====

VLC AtmoLight video filter module README: https://github.com/videolan/vlc/blob/2.2.0-git/modules/video_filter/atmo/README.txt
VLC AtmoLight removal announcement (2015-05-10): https://mailman.videolan.org/pipermail/vlc-devel/2015-July/103679.html
VLC AtmoLight removal (2015-05-10): http://repo.or.cz/w/vlc.git/commit/6713041eebe0c4245de4f78dfeb5effecb797faf
VLC changelog: https://github.com/videolan/vlc/blob/master/NEWS
Fnordlicht protocol: https://raw.githubusercontent.com/fd0/fnordlicht/master/doc/PROTOCOL
WS2812B LEDs: http://www.world-semi.com/en/Driver/Lighting/WS2811/WS212B/