Since I posted my video on my attempts so far at creating a sweeping light for a decorative lighthouse at my home, I have received a few requests to post what I have so far, even though the project has been on the back burner recently because of work obligations. I am posting what I have so far because many of you were interested in the arduino code as it is so far, and others were interested in how to use the 5V arduino to drive the 12V LED's. An overview of how it functions is shown in the video above.
The project uses an arduino micro and a cut up 12V LED strip to create a bright sweeping lighthouse light effect with 16 static LED segments. A virtual sweeping light is created by using software pulse-width modulation on 16 of the arduino's 20 digital output pins. An additional 3 pins are used as tactile button inputs which control the beam sweep speed, number of beams, and beamwidth, the last pin is reserved as an analog input for a light sensor (not yet implemented in this preliminary Instructable). The posted arduino code is an early version of the code I used in order to establish the basic functions of the lighthouse. Please feel free to modify them for your own purposes.
Step 1: Materials
The basics of the project as shown in the video include the following:
Prototyping breadboard and jumper wires - I also use ribbon cables with male-to-female jumper wires.
Arduino Micro - You can also use an Uno or any other arduino with enough digital I/O pins, but I really like this little guy.
LED strip - I happened to get one on clearance from Radio Shack (http://www.radioshack.com/radioshack-led-waterproof-flexi-strip-60-led-1m-white/2760329.html). This is marketed as being waterproof and is encased in a nice silicone tube. However, it is no longer waterproof when you cut it up.
Two IC high speed transistor arrays - NTE2018 or equivalent. You will be using these to drive the 12V LED's.
Three momentary push buttons
Cylindrical Housing for your LED strip segments - For those of you who are using the Radio Shack strip and have access to a 3D printer, I have designed such a housing. The 3D files were created in TinkerCAD. The STL files are posted on Thingiverse.
Hook-up wire for soldering to the LED segments
12V Battery or equivalent power supply - This supplies the power for the arduino and the LED's. The arduino has a built in 5V voltage regulator, but if you plan on keeping this project for the long term, I highly recommend adding an additional 5V voltage regulator between the 12V power rail and the power input of your arduino. This will protect the arduino and keep its internal voltage regulator cooler.
Simplified 5 Volt Alternative
The arduino code will also work at 5 volts on simple white LED's, so long as you use some current limiting resistors on your LED's and you limit the current output on your arduino to below 40 mA per pin and below 200 mA total. (These are the current limits of the arduino). In this case, you no longer need the transistor arrays and you can simply run the LED's from the arduino directly. This set-up is useful for testing your arduino circuit and code.
Step 2: Cutting up the LED strip
The LED strip I used has convenient cut points with metal leads for soldering after every 3 LED elements. Current limiting resistors are built into the strip, so you don't have to include these into your circuit. The strip also has a nice silicone waterproof sleeve, which I kept when I mounted the LED segments into my housing. However, keep in mind that the strip is no longer waterproof after we cut it up.
1. Cut up the strip across each of the leads, keeping some metal on each side of the cut point. This should yield about 20 segments, each with 3 LED's. Try to cut them all about the same length.
2. Solder some hook-up wire to the positive and ground leads on one side of each cut up segment. Slide off the sleeve prior to soldering it and put it back on when you're done. Since each segment has two ends to which you could potentially solder, be careful to pick one side and keep it consistent for ALL of your LED segments. (ie. ground on the left and positive on the right, as shown in the picture). In the picture, I have used black hook-up wire for ground and red hook-up wire for positive. I have also tried to keep the lengths of the hook-up wire consistent, and I have stripped the end of each wire so that I could plug these directly onto my breadboard for testing prior to mounting into the housing.
Step 3: The Arduino code
The attached code below is an arduino sketch called lighthouse1.ino. Please note that we are trying to fade 16 separate LED's in a specific sequence and timing pattern using pulse-width modulation (PWM). However, the arduino micro only has 7 pins which can be used for PWM in hardware. Therefore, we must implement PWM in software. Fortunately, Brett Hagman has already implemented this in his softPWM library for the arduino. Instructions for including and using this library are in the softPWM documentation.
Modify this code to your needs. You may notice that the loop() function simply contains a call to the lighthouse_mode() function. This is because there will be at least one more mode, a sleep_mode() in which the lights are turned off during the day while a solar cell charges the battery until it is dark enough to go back into lighthouse_mode.
The code defines multiple integer arrays with predefined values for the LED output pins, revolutions per minute, number of beams, and width the beams. An additional array contains the pin numbers for each of the three input buttons. The button pins themselves will be using the arduino's built-in pull-up resistors, so the button reading logic is reversed (the pin reads HIGH until the button is pressed and LOW when the button is pressed).
If you do not know how to load code onto your arduino, please read the Getting Started With Arduino Homepage.
Step 4: Setting up your circuit
Specs and pinout diagram for the micro are at http://arduino.cc/en/Main/arduinoBoardMicro.
Specs for the NTE2018 transistor arras are at http://www.alliedelec.com/images/products/datasheets/bm/NTE_ELECTRONICS/70215985.pdf.
1. Ground your components:
Connect your arduino to ground. The micro has 2 GND pins.
Connect one end of each of your pushbuttons to ground.
Connect the ground pin (pin 9) of each of the transistor array ICs to ground.
2. Connect pins 0, 1 and 2 to the ungrounded end of each of the three pushbuttons.
3. Connect pins 3 through 13 and A0 through A4 sequentially to each on the input pins of the transistor array ICs.
4. For testing purposes, connect each of the positive LED hook-up wires to the +12 volt rail and connect each of the ground LED hook-up wires to sequential output pins of the two 2018 transistor array ICs. (The transistor IC's work by allowing the current on the output pins to complete the circuit to ground when a small current (from the arduino) is applied to the corresponding input pins.)
5. The first image above gives a simplified wiring diagram showing the protoboard, arduino micro, the two transistor array ICs (each connected to ground and pins 3 and 11, respectively), a corresponding LED segment on each chip, and one of the three push buttons.
6. Connect the +12 V power to the VIN pin of the arduino. Alternatively, if you plan on using this circuit over the long term, I recommend placing a 5V voltage regulator (LM7805) between the 12V power and your arduino. A voltage regulator works by dissipating the difference between the 12V and 5V power as heat. Therefore, the heat dissipation occurs before power enters the arduino and protects the arduino's own voltage regulator. Another low power alternative is a switching voltage regulator, which is more expensive but much more efficient at converting voltages. This would be a good choice for battery powered applications. Look at Mouser or Digikey for DC/DC converter modules, or google something like "7805 switching regulator replacement".
7. Check the functioning of the program. When the program first boots it should blink pin 13. Then, it will start running the lighthouse code, cycling through the LED's in order. Also check the functioning of the buttons. Once you are satisfied with the functioning of the code, you can remove the LED's from the protoboard and move on to the next step.
Step 5: Mounting the LED's into the housing
If you have printed out my housing you will notice 3 parts, the main housing, a housing endcap and an inner retaining ring to help stabilize any wires that might pass through center of the body. The housing has 16 facets, each of which is wide enough to accommodate the width of each of the cut up Radio Shack LED segments with its silicone sleeve.
1. Fit the housing endcap may onto the end of the main housing. If the 3D print does not fit snugly, you can use some glue. Make sure that the facets of the housing body and endcap line up.
2. For each LED segment run the hookup wires through the hole at the bottom inside of each facet. Slightly bend the LED segment with its sleeve and fit it into the channels at the top and bottom of each facet. Once fitted into the channels, if the LED segment bends out too far, you can take it out and slightly trim the end opposite the hookup wire until it fits well. However, I like to keep a little tension in the channel, since it helps to keep the LED segments in place.
3. If you need, you can use the inner retaining ring to organize the wires to the inside wall of the main housing.
4. In my video, I used a ribbon cable with male-to-female jumper wires to connect up the protoboard to the housing with the LED's. The (+) side of each LED segment is connected to the +12V rail and the (-) side is connected to its corresponding output pin on the 2018 transistor IC. You typically need 32 wires (16x2) for this. However, since half of the wires are to +12V, you could potentially bring this number down to 17 wires (16 + one 12V wire) for this, if you set it up cleverly.
5. Apply power to the arduino and check to see if everything works as expected.
Step 6: Things still in the works
As I had mentioned before, this is a project I had started but is still a work in progress. Interest in my original video and 3D files on Thingiverse has prompted me to post what I had so far. I am still working on several other aspects of the code and circuit, listed below. I will outline my thoughts on each, but I am quite happy to receive any thoughts and suggestions.
Things in progress:
1. Solar charging of the 12V battery. - I would like to add circuitry which would solar charge the 12V battery during the day. The decorative lighthouse that I have has an existing 6V solar panel that I was hoping to use for this purpose. In order to get it to charge a 12V battery, I was thinking about using a joule thief type circuit to charge up the battery in a series of low-current, high voltage pulses (without blowing up the battery, of course). Since I am a hobbyist and not an electrical engineer, this may be a little beyond me, and I may just opt for a store bought 12V panel and solar charge regulator from Harbor Freight Tools. However, if anyone out there has suggestions, on how best to accomplish this, please let me know.
2. Low-power Sleep Mode - The arduino has a low power sleep mode which extends the life of the battery. We can add code to put the arduino to sleep during the day (sleep_mode) and activate the lighthouse when it gets dark (lighthouse_mode).
3. Dark/light detection - There is one free analog pin (A5) left on the arduino, which I intend to use as a light sensor. I figure that we can set the pin as an analog input with protective voltage divider resistors to keep the voltage below 5V to the pin. We can then sense when the voltage falls below a predefined threshold (darkness) and trigger the lighthouse_mode. Then we can trigger sleep_mode after a predefined time or when the voltage from the solar cell exceeds a certain threshold.
4. Saving preferred lighthouse parameters on the EEPROM - The microcontroller on the Arduino board has EEPROM: memory whose values are kept when the board is turned off. We can use the EEPROM to store the last settings set by the push buttons (revolutions per minute, number of beams, and beamwidth), so these won't have to be reset every time the arduino boots. FYI, the arduino EEPROM memory has a specified life of 100,000 write/erase cycles, so it might be prudent to add some logic to prevent too many writes to the EEPROM.