Lighting a room is always a complicated task. This is especially true if you're an engineer. You see, we all love blinking lights, RGB LEDs, really any combination of those things. When it came time to figure out the ligting situation for my room, I immediately knew that lots of LEDs would be involved. The room is 4 x 4 meters. WS2812 strips come in 4m length at 60 LEDs per meter. This cannot simply be a coincidence - it was meant to be! This is cool and all, but lots of problems remain to be solved. Luckily, they all were.
Your common garden-variety LED needs at least 20mA to light up brightly.. Each of our RGB LEDs has three of them inside. There are 60 of those per meter, 4 meters per strip, and four strips - one for each room side. That means we're talking about 20 x 3 x 60 x 4 x 4 = 57600 mA at full brightness. Let me rephrase that. The strips require a 5V supply, and will consume 57.6 Amperes at full brightness. This is a problem. First of all, where exactly does one get a 60A 5V supply? And also, how exactly does one deliver it to these lights? The problem is actually not trivial. A single power supply would not do, and not for the reason you'd think. These strips have resistance. If you supply power from one end, by the time the power arrives to the other end, the voltage would have dropped due to the resistance. There is a voltage drop on the way back too. These LEDs really need at least 4V to work well. So we can handle only a 1V drop total, or 0.5V on each way. Ohm's law really kills us here. V = I x R. Solving for R we get 82 milliohms. Sadly the resistance of one of the strips is actually 2 ohms. Ouchy. This means that powering the whole thing from one end is simply not going to work. It is, in fact, even worse. The wires we use to provide the power also have resistance. Allright, so what do we do? Let's split the four strips into two segments, and power each one in the middle. This makes the situation much more palatable. On one side I used a PC power supply, and on another two parallel 5V15A supplies. They are both well isolated, so there was no potential difference between grounds or signal integrity issues.
Well, in reality my room is a bit smaller than 4 x 4 meters, so I did not fit the entire 60 x 4 x 4 = 960 LEDs in. I only needed 924 LEDs to encircle my room's ceiling. Next step was controlling them all. Given what I wanted to do with them, I knew that I'd need a micro with lots of RAM. I conveniently had an ATmega1284p around. It has 16KB of RAM, which is plenty for a few 3 x 924 = 2772 byte buffers. I wrote the code to output the control signals for the LEDs, with a rather simple api: a function to get the current RGB value for an LED, one to set, and a few to send the framebuffer to the LEDs (with or without a sync pulse, with or without waiting). You will find that function in LEDs.c - it is the one with a large chunk of inline assembly.
What good is a few hundred RGB LEDs without fancy effects? I implemented a few patterns, and more modes can easily be added as there is plenty of flash space left on the ATMega.
So how does all this get controlled? I mentioned various patterns being controllable. How? By a remote control of course. Both the main control board and the remote use nordic nRF24-series wireless chips for communication. I had a very nice fob with a nordic chip, an ATTiny micro, and a battery already, so I used it for this project. Sparkfun used to carry them under the name "nordic fob." Sadly they no longer do, but you can still make this circuit and put it into any other kind of enclosure easily. The remote has 5 buttons: left, right, up, down, center. I use the center button to switch modes, left and right adjust color for modes that support that, up and down adjust brightness. The battery life of the remote is about three months on the battery, which is really not bad at all. The protocol is simple and easily extensible, if you so choose. It is defined in protocol.h
The code is split into two parts, as you might expect: one for the remote and one for the light control board. They share the common nRF24 driver (nwk.c) and the protocol defines. Each provides the low level spi and cs/ce primitives for the driver. Remote in Remote.c and control board in nwk_hwr.c. You can find all the source code and the pre-built binaries => [HERE] <= as always. The license is the same as all my other projects: Free for non-commercial use, as long as you provide attribution in source and with all supplied binaries/hardware. For commercial use contact me to discuss.
The schematic is easy. Sparkfun still publishes the schematic of the nordic fob [here]. My light control board is also simple, and very spartan. The micro has a 24MHz crystal connected to it for precise timekeeping, light control signal is output on pin D1. nRF chip is also connected to PORTD, as follows: MISO = D2, MOSI = D3, SCK = D4, nCS = D5, CE = D6. That is actually all there is to it. Power is supplied by one of the same 5V supplies as for the lights (the one that is closer).
Lessons learned and improvements to make: Really, what I should do is construct better power supplies, with sense lines running down from the top of the wires, since even now there is a significant voltage drop over the wires that run the height of the room. With sense lines, a supply could at least compensate for that drop. Really, if I were re-doing this project today, it would be running on a Cortex-M0+, controlled over BTLE, and the supplies would be hidden in the attic, so that the wires from them could be shorter. Perhaps someday soon I'll get around to doing this. In the meantime my room is well lit by 2772 LEDs in 924 groups of 3. The light created looks very cool, even if a bit eerie. Nothing in the room casts a shadow.