Introduction: Wireless Accelerometer Controlled Rgb-LED's

MEMS (Micro-Electro-Mechanical Systems) Accelerometers are in widespread use as tilt-sensors in mobile phones and cameras. Simple accelerometers are available both as ic-chip's and cheap development pcb-boards.
Wireless chips are also affordable and available in assembled circuits, with matched antenna-network and decoupling-caps onboard.

Hook both wireless board and accelerometer up to a microcontroller via serial interface and you have a wireless controller with nintendo-wii functions.

Then build a receiver with the same type of wireless chip and pwm-controlled rgb-LEDs, voila, you have wireless, tilt-controlled coloured room lightning.

Keep the transmitter-board level with breadboard facing up and the LED is cool blue, only blue led is active. Then tilt the transmitter in one direction and you mix in red or green depending on which direction you tilt it. Tilt all the way to 90 degrees, and you go trough all mixes of red and blue or green and blue until only red or green is active at 90 degrees tilt. Tilt a little in both x and y direction and you get a mix of all the colours. At 45degrees in all directions the light is an equal mix of red, green and blue, in other words, white light.

The parts used are available from internet hobby-electronic stores. Should be identifiable from some of the pictures.

Step 1: Transmitter With Accelerometer

The transmitter is based on the Atmel avr168 microcontroller. The convenient red board with the 168 is an arduino-board with voltage regulator and reset-circuit. The accelerometer is connected to the avr with bit-banged i2c bus, and the wireless board is connected with hardware SPI, (Serial Peripheral Interface).
The breadboard is completely wireless with the 4,8V batterypack strapped underneath.

The wireless board and the arduino wee accepts up to 9 V and have onboard linear voltage regulator, but the accelerometer needs 3,3V from the regulated rail on the wee.

Step 2: Receiver With RGB-LED

The Receiver is based on the atmel avr169 demoboard named butterfly. The board have a lot of features not used in this project. The wireless tranceiver is connected to PortB and the pwm-controlled led is connected to PortD. Power is supplied at the ISP-header, 4.5V is enough. The wireless board can tolerate 5V on i/o pins, but need 3.3V supply which is supplied by the onboard regulator.

The modified header-cable for the rf tranceiver is really convenient, and connects wireless board with power and hardware spi controller on the butterfly.

The shiftbright is a rgb-led pulse width modulation controller which accepts a 4 byte command which is latched in and then latched out on the output pins. Really easy to connect in series. Just shift out many command words, and the first shifted out will end up in the last connected LED in the daisy-chain.

Step 3: C-programming

The code is written in C as I didn't care for learning the "easier" processing language which arduino is based on. I wrote the SPI and rf tranceiver interface myself for the learning-experience, but borrowed the i2c assembler-code from avrfreaks.net. The shiftbright interface is bitbanged in C-code.
One problem which I encountered was small irradic variations in accelerometer-output, this made the led's flicker alot. I solved this with a software low-pass filter. A moving weighted average on the accelerometer-values.
The rf-tranceiver support hardware crc and ack with auto-retransmit, but for this project the realtime, smooth updating of the leds was more important. Every packet with accelerometer values does not need to arrive intact at the receiver, as long as corrupted packets is discarded. I had no problems with lost RF packets within 20 meters line of sight. But further away the link became unstable, and the leds did not update continously.

The main loop of the transmitter in pseudo-code:

initialize();

while(true){
Values = abs(get x,y,z accelerometer values());
RF_send(Values);
delay(20ms);
}

The main loop of the receiver in pseudo-code:

initialize();

while(true){
newValues = blocking_receiveRF());
rgbValues = rgbValues + 0.2*(newValues-rgbValues);
write rgbValues to shiftbrigth;
}

Step 4: The Result

I was amazed at how smooth and accurate the control was. You really have fingertip accuracy control of the colour.
The pwm-LED-controller has 10 bit resolution for each colour, which makes for millions of possible colours. Unfortunately the accelerometer has only 8 bit resolution which brings the number of theoretical colours down to the thousands. But it is still not possible to perceive any stepping in colour-change. I put the receiver in an IKEA-lamp and took a picture of different colours below. There is also a video, (horrible quality though)