Introduction: Interactive Ambient Light

This is my first instructable!
Please bear with me while I struggle to write proper English. Feel free to correct me!

I started this project just after the 'Let it glow' competition started. I wish I had made much more and finished what I wanted to make. But between school and work, I haven't had as much time left as I wished.
Nevertheless, I leave here a report of my experiments as an instructable, so anyone can try and make what I did.
This instructable is not meant to serve as a guide and teach how to make this contraption. It isn't a guide for the beginners in electronics. It is more like sharing one idea and objective that I wish to pursue.
If you are a beginner/complete ignorant in electronics and wish to make something like this, I'm sorry! But we can try always help you. See the last step.

We have already seen many ambient light projects. Most of them use RGB LEDs:
- To illuminate a room with one color, setting an atmosphere to match your mood
- To create light effects from colour of TV/Monitor or from audio.
There are even a few in instructables.com

Related:
DIY Ambient Light Systems
Light Bar Ambient Lighting
Building your own ambient color lighting bars

Using this competition as an excuse, I started a project that has been on my mind for a while.
I've always wanted make something similar to these ambient lights and fill the walls in my room with RGB LEDs. But, taking it a step further, making all and each one of them controllable. This project will hopefully result on an open-source electronics kit for hobbyists and electronic tinkerers, allowing hardware/software hacking and sensory integration.

Here is a small preview of what I made:

Step 1: Exploring the Idea

I want to be able to fill the walls in my room with RGB LEDs, controlling colour and brightness for each led.
I am going to use a microcontroller for the ease of use and flexibility provided. Unfortunately I can't control hundreds of LEDs with the few pins available on microcontrollers. It would even be difficult to code the control of so many LEDs.
So I decided that I should divide all the LEDs in several smaller bars and for each bar I could use a microcontroller. Then I would use the communication capabilities of microcontrollers to share information between them. This information could be the colour and brightness of LEDs, patterns/sequences of colours and sensory information.
For each bar I decided to use 16 RGB LEDs. This results in a neither too big nor small bar. This way I use an acceptable number of resources for each led, reducing the costs for each bar.
Nevertheless, 16 RGB LEDs are 48 LEDs (3*16=48) for the microcontroller to control.
With costs in mind, I decided to use the cheapest microcontroller I could use. This means that the microcontroller will only have up to 20 I/O pins, not enough for 48 LEDs.
I do not wish to use charlieplexing or some kind of time splitting drive, since the goal of the project is illuminating a room.
The only alternative I could think of is using some kind of latched shift register!

Resuming:
- Make and interactive ambient light
- Make a standard bar of controllable LEDs
- Possibility of connecting several bars to fill a room
- Allow user adaptation/configuration and sensory integration

Step 2: Hardware

As said in the previous step, I wish to make several of bars to illuminate one room. This brings the cost issue to mind. I am going to try and make each bar the most cost-effective way possible.
The microcontroller I used was an AVR ATtiny2313. These are rather cheap and I had a few lying around. ATtiny2313 also has one Universal Serial Interface and one USART interface that will come to good use in the following steps.
I also had three MCP23016 - I2C 16bit I/O port expander lying around, just the right count! I used each port expander to control one colour of the 16 LEDs.
The LEDs... Unfortunately, were the cheapest I could find. They are 48 red, green and blue ~10000mcd 5mm with 20 deg angle. This shouldn't matter for now, since this is only one prototype. Despite this fact, the result is quite nice!

I am running the microcontroller at 8 MHz. The I2C bus is clocked at 400 kHz. The LED switching frequency is about 400 Hz.
This way, if I am capable of driving 48 LEDs without pushing it to the limit, I'll room for more later!

Step 3: Assembly

After designing the circuit, I built it in several breadboards, for prototyping purposes.
After several hours of cutting wires and assembling the circuit, I got this result:
One giant breadboard with 48 LEDs and tons of wire!

Step 4: Control?

This is the most challenging part of the project.
I wanted to make one control algorithm generic enough for handling patterns/sequences and also controlling the brightness and colour of each LED.

To control the LEDs I have to send to the MCP23016 one frame of 4bytes (1 byte = 8 bits). One byte with the address of the IC correspondent to the colour, 1 byte with the command "write" and 2 bytes with the value of the 16bits (LEDs). The IC is connected to the LEDs as "sink", meaning, one logic value 0 at the pin will light the LED.
And now the challenging part, how to make PWM control for 48 LEDs?

Let's study PWM for one LED! PWM explained @ Wikipedia.
If I want the brightness of the LED at 50%, my PWM value is 50%. This means the LED, in one period of time, should be on the same amount of time as off.
Let's take a period of 1 second. PWM of 50% means that in this 1 second, the on time is 0.5 seconds and the off time is 0.5 seconds. PWM of 80%? 0.2 seconds off, 0.8 seconds on!
Easy, right?

In digital world: With period of 10 clock cycles, 50% means that for 5 cycles the LED is on, and for another 5 cycles the LED is off. 20%? 2 cycles on, 8 cycles off. 45%? Well, we can't really get 45%... Since the period is in cycles and we have only 10 cycles, we can only divide the PWM in steps off 10%.

This means the evolution of the pin should be, for 50%: 1,1,1,1,1,0,0,0,0,0; Or even 1,0,1,0,1,0,1,0,1,0;

In programming we can make this sequence of turning on and off an array. For each cycle we output to the pin the value of the index were the cycle is.
Did I make sense so far?

If we want to make LED0 50%, and LED1 20%, we can add both arrays.
For driving the LED0 pin: 1,1,1,1,1,0,0,0,0,0;
For driving the LED1 pin: 2,2,0,0,0,0,0,0,0,0;
Resulting in LED0+LED0: 3,3,1,1,1,0,0,0,0,0;
Outputing this sequence of numbers in the port expander IC, we would get the LED0 with 50% brightness and LED1 with 20%!!

Simple for 2 LEDs, right? Now we have to make this for 16 LEDs, for each colour!

For each one of these arrays, we have a combination of brightness for each colour (16 LEDs)
Every time we want another combination of colours, we have to change this array.

Step 5: Making It Easy!

The previous step is too much work for making a simple sequence...
So I decided to make a program, where we tell the colours of each LED in one step of the sequence and we get the three arrays of the step.
I made this program in LabView due to time constraints.

Step 6: First Experiments

Loading several steps in the microcontroller and we get something like this:


Sorry about the poor quality of the videos!

I defined the maximum number of steps of a sequence to 8, and limited the PWM to 20% jumps. This decision is based on the kind of control I am using and how much EEPROM the ATtiny2313 has.
In these experiments I tried to see what kind of effects I could make.
I must say I am pleased with the result!

Step 7: Real-time Control

As mentioned in previous steps, I wish to communicate with all the microcontrollers controlling the LEDs in my room. So I used the available USART interface in ATtiny2313 and connected it to my computer. I also made a program in LabView to control the LED bar.
In this program I am able to tell the microcontroller how long is the sequence, the colour of each LED and the time between steps of a sequence.
In the next video I'll demonstrate how I can change the colour of LEDs and define sequences.


Step 8: Conclusions

I think I was successful in this first approach of my project. I am able to control 16 RGB LEDs with little resources and constraints. It is possible to control each LED separately, creating any desired sequence.

Future work:

If I receive positive feedback from people, I may further develop this idea and make a full DIY Electronics Kit, with printed circuit boards and assembly instructions.

For my next version I'll:
-Change the microcontroller to one with ADC
-Change the MCP23016 for some other kind of serial-in parallel-out that can sink more current from LEDs
-Make open-source software to communicate with the microcontroller and control the LEDs
-Develop the communication between several microcontrollers.

Do you have any suggestion or question?
Or leave a comment!

Let It Glow!

Finalist in the
Let It Glow!