This project was created because I wanted to have something I could make in a weekend that would be simple enough to understand and tinker with, but also look cool when done. An Arduino + LED Strip was the perfect combo, as you can get your introduction to the Arduino writing simple code to produce some neat light patterns.
I already knew that I wanted to make a nightlight for my daughter's room, so this project was a good fit. When you enter the room the IR Sensor detects the motion and provides a back light for the bed and more than enough light to see around the room and change a diaper or whatnot. In my case it's a crib I'm back lighting, but no reason it couldn't be any bed for a kid or adult.
The project uses all components that you could pick up at Radio Shack and purchase + complete in day, so I think it's a great project, especially for a child wanting to learn some programming... what better way then writing some code to drive a light show in your room.
I submitted this Instructable into the Coded Creations Contest, so if you like it, I'd love your vote! Enjoy.
Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.
Step 1: Materials
All of the electrical components can be picked up at Radio Shack in store. Other than the LED Strip all other components can be purchased elsewhere, but the links to Radio Shack are included below so you can check stock at your local Radio Shack in case of a "spontaneous weekend project"
- Arduino Uno - Arduino Uno
- 12v Wall Transformer - 12 Enercell Transformer + Adaptaplug M (for Arduino)
- Needs to be a 2.1mm size, center positive 12v dc plug. The Arduino can run on 9v input, however the Tricolor strip needs the 12v tap into Vin on the Arduino.
- Recommend a UL Listed Transformer for safety
- I used the 1.5 amp supply linked above with no problems, so be sure to get a supply rated atleast at 1.5 A
- Tricolor LED Strip - Radio Shack Tricolor LED
There are certainly a variety of LED strips available to work with an Arduino, so if you are up writing the software to drive the strips, then select any variety. I personally would recommend any protocol that supports latching in the RGB values versus some strips which would require continuously refreshing the values to keep the strip lit.
- PIR Sensor (Passive Infrared Sensor) - PIR Sensor
- There are a variety of PIR Sensors out there. For the purpose of this instructable we're using the simple 3 pin sensor.
- Alternate Activation Method - An alternate way to trigger the lighting is discussed later
- 22-Gauge Wire
- Male/Female Jumper Connections
- Wood for frame
Step 2: Structure
For the wood structure to hold the LED strip I used some scrap 1/4" thick MDF sheets. Measure the thickness of the LED strip and use a table saw or hand saw to cut strips to the desired thickness.
If the bed has a straight back then it's a straightforward single piece. In my case the back of the crib curves and using a straight piece would mean that much of the intensity of the LED would be lost behind the crib. So I created the structure pictured. The idea is to get a contour as close to the bed back as possible, but keep in mind you don't want the strip visible, so it should be a 3 inches or so below the top of the bed headboard.
I'm sure there are cleaner ways to make this structure, but here's what I did taking advantage of the MDF:
On the bed back, use a tape measure and measure the colored lines in the picture. Then cut one board to the length of the red line. Cut the other board to the length of the yellow + blue + green lines. Measure and cut two dowel rods to the purple length and drill matching sized holes in the "red" board and "yellow/blue/green board".
The idea now is to bend the yellow and green portions down to touch the red portion as shown in the dashed lines. The MDF will give and partly tear by the stress of the bend occuring where the purple dowel meets the upper board. Now apply glue to attach the yellow portion to the red portion, and the green portion to the red portion. Secure in place with a clamp or tape as the glue dries. Additionally I applied glue into the tear. Keep in mind this structure will hold a very light weight LED strip and Arduino, so it doesn't need to carry much weight.
After you have the structure I took my smallest drill bit (1/32") and made holes for nails in the blue portion so that a nail can go through the board and into the wall to hold the structure onto the wall.
Step 3: The LED Strip and Arduino
I'd first recommend following the instructions with the LED strip and test code from the Radio Shack website to make sure the strip works.
Take masking tape and attach the strip to the wooden structure, being careful that the tape does not cover the LEDs.
Mount the Arduino to the end of the structure with the LED strip connections.
Step 4: Motion Detection (or Other Activation)
There are a variety of PIR (passive infrared) motion detectors out there, so you'll need to check the data sheet on your particular sensor. None are very difficult to understand.
There is a Vcc and Gnd pin that connect to Vcc and Gnd on the Arduino, 5 volts.
There is a "data" connection that indicates if motion has been detected. This can be connected to either a digital or analog input of the Arduino. In this case I used A4.
Many PIR sensors have potentiometers to adjust detection range/sensitivity and duration of a high signal when movement is detected. In the case of my PIR sensor there is a potentiometer labelled 104 which adjusts the ON time period. The max setting has the ON value set for 20 seconds when motion is detected, the min setting ON value for one second. The 105 potentiometer adjusts sensitivity.
You'll also want to be sure to make wiring long enough to place the sensor where you want. In my case the sensor goes under the bed, so that any movement on the bed itself won't trigger the lights, only activity outside the bed will.
Options other than motion detection could be:
- Light Sensor - When the Arduino detects a transition from light to dark it kicks in the LED strip
- Push Button -
- Connected to the Arduino to trigger the LED strip. The added benefit is that one can keep track of the number of button presses to drive the length of time the LED strip is lit.
- Digital Outlet Timer - See the materials section for example hardware. In this case the Arduino would immediatly boot to run the LED strip, and when the outlet timer expires the Arduino and LEDs would loose power
Step 5: Software
The LED Strip from Radio Shack comes with a link to test code for the Arduino. This formed the basis of the attached program, however the Radio Shack version uses a hard coded set of patterns, and modifying these patterns is a lot of work for little results.
I created a new method to drive the strip that takes two components:
- colors - Array of RBG (Red Blue Green) colors
- illum - Array of magnitudes/intensities (0.0 = 0% = OFF, 1.0 = 100% = FULL ON)
This allows you to generate a more dynamic range of patterns quickly without having to specify as much information each sequence. Just multiply each component of the RBG hex value by the magnitude and drive that the strip (done in the light_strip() function).
Brief diversion into how the low level LED code works
The code to actually drive the bits to the LED strip in the send_strip() function doesn't need to be modified, but if your are curious about what is going on with the code to drive the LED, read on....
Here is the Link to Radioshack Support files for TriColor Strip which contain the data sheet for the LED Strip. This strip works on the TM1803 protocol which is 24 bits to define a color (8 bits Red, 8 bits Blue, 8 bits Green). One a segment of the strip receives 24 bits, the next data will pass over the segment and move to the next segment. In this manner the first 24 bits drive segment 1, the next 24 bits are for segment 2, etc....
To actually transmit those bits, you will see that to drive a 0 you need to set the data pin to HIGH (logical 1) for 0.78 microseconds and then set the data pin to LOW (logical 0) for 1.55 microseconds. To drive a 1 bit you need the opposite timing, HIGH for 1.55 microseconds and LOW for 0.78 microseconds.
So for example if you wanted to send over a value of 0110 in binary, you would actual need to transmit
HIGH for 0.78us, LOW for 1.55us, HIGH for 1.55us, LOW for 0.78us,HIGH for 1.55us, LOW for 0.78us,HIGH for 0.78us, LOW for 1.55us
So how is this achieved in the code, in the send_strip() function?
The code loops over all 24 bits, and based on if each bit is 1 or 0 it performs a different operation. Let's take 1 for example, the code first executes DATA_1 which sets the output pin to HIGH, then performs 28 no-operation (nop) assembly instructions. The Arduino Uno has a clock speed of 16 MHz, which means each instruction is completing at an approximate 62.5 nanosecond time. Thus the coded 28 no-ops will take 28 times 62.5 nanoseconds to complete, which is 1750 nanoseconds = 1.75 microseconds. This is a little over the 1.55us time we are looking for, but is okay due to the fact the DATA_1 operation does not complete immediately by the time the first nop is hit, so basically the first couple nop's don't count toward the time a the signal is high. To develop code like this you would ideally use an oscilliscope to add/remove nop statements, and measuring the resultant time on the oscilliscope, until you hit that 1.55us sweet spot in the data sheet.
Luckily most LED strips have Arduino libraries that has already figured this out for the user, but it is still good to know how the code achieves the timing in the data sheet.
I've commented the code well enough that I won't go into any more the specifics on how it works, but as I mentioned earlier, I think just the idea of creating more interesting light patterns would be a great way to learn some simple coding and debugging skills.
The overall flow of the program is:
- Boot the Arduino
- Wait for Motion
- Draw a Rainbow
- Draw 20 more patterns
- Restart the program
Good luck and enjoy! If you enjoyed the Instructable, I'd love your vote for the Coded Creation Contest.
Participated in the