Intro: Designing a Multi Node LED PWM Lamp
Creating some blinky LED lights for Christmas has always been on my wish list. Last Christmas season I really started thinking about building something. My first thought was, each LED lamp could simply be connected to a pair of wires. The power to the LED lamps could be an AC signal that would sweep from a low frequency to a high frequency. A band-pass filter built into each lamp would turn on the LED when the frequency matched the center frequency of the band-pass filter. If the band-pass filters, were setup right, a LED chase sequence could be made. Really, by jumping to different frequencies instead of sweeping, any one of the LEDs could be turned on. Using an H-Bridge driver chip, driving the desired frequency down the wires should not be too hard.
Well, I just stink at analog design - I am more of software kinda of a guy. After a couple of bench tests, I quickly gave up on using analog.
What I really wanted was a LED lamp that could be fully controlled to display any color I wanted. Oh, and it should be capable of using PWM (pulse width modulation) so that the LEDs can be ramped on, or off in really cool patterns.
What follows in this instructable is a description of a really cool design based on the a Microchip microprocessor that fell out of my desire for Christmas tree lights.
Have a quick look at the video below to see quickly what the Kemper LED PWM Lamp Controller is capable of displaying.
Note, it is hard to get a good video of LEDs in action which are using PWM for intensity control. It is the same problem when you try to video a computer monitor. The 60Hz of the LEDs get into a beat frequency fight with the 30Hz of the camcorder. Therefore, while there are times that the video of the LEDs are a bit "glitchy", this is not really the case. The LEDs do not appear to have any glitches when viewed by the human eye. See the software step below for more discussion about video tapping of LEDs.
Step 1: Design Goals
After spending the Christmas break thinking about this project I came up with a wish list.
Here are some of the features (sorted in order) I wanted with my LED Controller:
1) Each LED lamp must be as inexpensive as possible. A string of 100 lamps will cost a bunch if each lamp cost a lot. Cost, therefore, is a major factor.
2) Each lamp will have a tiny micro on board which will drive the LEDs. The tiny micro will generate PWM signals so that the LEDs can be dimmed, or faded. LEDs can look harsh when simply switched on, and off. Using PWM signals the LEDs can be faded up and down without the hard edges normal to LEDs.
3) To keep wiring simple each lamp will accept commands using a two-wire interface. Power and communications will share the same two wires. The commands to the lamps will tell the on board micro which of the LEDs to drive with PWM.
4) Must look cool! I guess this should really be renumbered so it's number one.
Here are some of the minor design goals (no particular order):
1) For development, must be easy to reflash / reprogram in-circuit.
2) A PC should be able to generate the commands to the lamps. This makes developing patterns much easier than using another embedded micro.
3) Each lamp should have a unique address. Each LED, within a lamp, must also be uniquely addressable.
4) The command protocol should support MANY lamps on one string of wires. The current design supports 128 lamps on one string. With 4 LEDs per lamp that works out to 512 LEDs on one string of two wires! Also note, each of those 512 LEDs has full PWM driving it.
5) The protocol should have a command that says, "Start fading the LED from this level to that level". Once fading starts, other LEDs can also be setup and set into fading on the same lamp. In other words, setup an LED into a fading pattern and then forget it knowing that the LED will carry out the command. This implies multitasking software on the micro!
6) There should be global commands that affect all lamps at once. Therefore, all LEDs can be commanded using just one command.
Here are some really minor design goals (again, no particular order):
1) Need a way to have a lamp report back when a comm error occurs. This would allow the command to be resent.
2) The command protocol needs a way to have a fancy global match pattern. This would allow every x number of lamps to be selected with one command. This would make it easier to make chase patterns with large numbers of lamps. As an example, this would allow a command to be sent to every third lamp on a string of lamps. Then, the next command could be sent to the next group of three.
3) An auto comm polarity detect logic system would also be great. Then, the polarity of the two feed wires to the LED lamps becomes unimportant. See hardware section for more on this feature.
Step 2: Prototyping:
It's now early January and off I go. I found the 10F206 at Digikey and it is really cheap! So, I spin a proto board to hold a 10F206 micro from Microchip. I designed a quick board because the 10F2xx is not available in a DIP package. Bottom line, I did not want to hassle with the small chip. (I was so confident back in January)
I also went off and purchased a new CSS C compiler targeted at the 10F2xx micros. The 10F2xx family of chips is really cheap! With high hopes, I dived in and started writing lots of code.
The 10F206 has a whopping 24 bytes of RAM - the chip also sports 512 bytes of flash and one eight-bit timer. While the resources are sparse, the price is good at 41 cents in large quantities. My gosh, a million instructions per second (1 MIPS) for 41 cents! I just love Moore's Law. Evan at one off prices, the 10F206 from Digikey is listed at 66 cents.
I spent a bunch of time working with the 10F206. While working with the 10F206 I discovered that multitasking is absolutely required. The PWM output signals MUST be keep updated even while receiving new communication messages. Any interruption in updating the PWM signals will be seen as glitches on the LEDs. The human eye is really good at seeing glitches.
There are a couple of fundamental problems with the 10F206 chip. At least fundamental problems for my application. The first problem is that there are no interrupts! Catching the start of new communications using a polling loop makes for timing errors. A second problem is that there is only one timer. I just could not find a way to receive commands while maintaining the PWM outputs. The LEDs would glitch each time a new command was being received. Sharing the timer between receiving commands and driving the PWM outputs was also a major software hassle. I could not reset the timer while receiving a new character because the timer was also being used to control the PWM signals.
While working with the 10F206 I saw an article in Circuit Cellar about Freescale's new tiny MC9RS08KA1 micro. I love Freescale chips - I am a big fan of their BDM debugging. I used the Star12 chips a lot in the past (I wrote all the software for the GM Cadillac & Lacern ultrasonic system on a Star12 - my ultrasonic software is in production now on these two cars). So, I was really hopeful that their new tiny chips would be good. The price is right too, Digikey has these chips listed at 38 cents in large quantity.
Freescale was good and sent me some free samples. However, the Freescale 9RS08 chip seemed truly goofy - I could not make much headway with it. The chip also suffers with a lack of interrupts and only one timer. Oh well, at least I figured that all out without wasting money on spinning another proto board. See pics below.
Now I know - for my application I must have interrupts and more than one timer.
Back to Microchip, I found the 12F609 chip. It has interrupts and two timers. It also has 1K of flash and 64 bytes of RAM. Downside is the price; Digikey lists these chips at 76 cents in large quantity. Oh well, Moore's Law will take care of that soon enough. On the plus side, the 12F609 can also be ordered in DIP packages. On the minus side, I had to buy the next level up compiler - that kinda burned my @#$%&.
It's now April and I have learned a lot about what won't work. I have spun a board and wasted money on a compiler that I do not need. Still, testing so far is encouraging.
With the new compiler and 12F209 chips in DIP packages bench level testing went quickly. The testing confirmed I had the right chip. Time to spin another proto board! By this point, I am determined.
Step 3: 12F609 Development Board
OK, fresh off bench testing, I am ready to try another board spin.
In this board design, I really wanted to try the idea of sending power and communication over the same two wires. If comm errors were ignored, only two wires would be required. That is just down right cool! While sending communications over the power wires is cool, it is not required. All the lamps can be connected together on a single comm wire if desired. This would mean each lamp would require three wires with a fourth optional feedback status wire. See diagram below.
Power and communication can be combined using a simple H-Bridge. The H-Bridge can drive big currents without any problem. Many, high current LEDs, could be strung together on only two wires. The polarity of the DC power to the lamps can be switched very quickly with the H-Bridge. So, each lamp uses a full wave bridge to rectify the switching DC back into normal DC power. One of the micro pins connects to the raw incoming switching DC power so that the comm signal can be detected. A current limiting resistor protects the digital input on the micro. Inside the micro input pin, the raw switching DC voltage is clamped using the micro's internal camp diodes - the switching DC is clamped (zero to Vcc volts) by these diodes.
The full wave bridge which is rectifying the incoming power generates two diode drops. The two diode drops from the bridge is simply overcome by adjusting up the H-Bridge supply voltage. A six-volt H-Bridge voltage provides a nice five-volt supply at the micro. Individual limiting resistors are then used to trim the current through each LED. This power / comm schema seems to work very well.
I also wanted to try adding transistor outputs between the micro and the LEDs. During bench testing, if the 12F609 is pushed to hard (too much current in its output path) it will flicker all the outputs. The max current for the entire chip according to the datasheet that the 12F609 can support is 90mA, total. Well, that is not gonna work! I just might need much more current than that. Adding transistors gives me capability of 100mA per LED. The diode bridge is rated at 400mA so 100mA per LED capability just fits. There is a downside; the transistors cost 10 cents, each. At least the transistors I picked have built in resistors - the Digikey part number is MMUN2211LT1OSCT-ND. With the transistors in place, there is NO flickering of the LEDs. For production lamps I think the transistors won't be required if "normal" 20mA LEDs are used.
The development board designed in this step is just for testing and development. The board could be much smaller if smaller resistors were used. Eliminating the transistors would save a bunch of board space too. The in-circuit programming port could also be removed for production boards. The main point of the development board is just to prove out the power/comm scheme.
In fact, after receiving the boards, I discovered there is a problem with the layout of the board. The full wave bridge chip has a goofy pinout. I had to cut two traces and add two jumper wires to the bottom of each board. In addition, the traces to the LEDs and connector are just too thin. Oh well, live and learn. Will not be the first time I goofed a new board layout.
I had eight boards made using BatchPCB. They have the best prices but they are sooooo sloooow. It took weeks to the get the boards back. Still, if your price sensitive, BatchPCB is the only way to go. However, I am going to switch back to AP Circuits - they are super fast. I just wish they had a cheaper way to ship the boards out of Canada. AP Circuits dings me 25 bucks in shipping for each order. That hurts if I am only buying 75 bucks worth of boards.
It took me two days to solder up the eight little boards. It took another day to figure out that pull-up resistor R6 (see schematic) was messing with me. I guess the resistor R6 is just not needed. I was worried after reading the datasheet and it indicated there are no internal micro pull-ups on this input pin. In my design, the pin is actively driven all the time anyway so a pull-up is not really needed after all.
To send commands to the board I used simple 9600-baud messages from a Python program. The raw RS232 coming out of the PC is converted into TTL using a MAX232 chip. The RS232 TTL signal goes to the H-Bridge control input. The RS232 TTL also goes through an inverter gate in a 74HC04 chip. The inverted RS232 then goes to the other H-Bridge control input. So, with no RS232 traffic, the H-Bridge outputs 6 volts. For each bit on the RS232, the H-Bridge flips the polarity to -6 volts for as long as the RS232 bit lasts. See the block diagram pics below. The Python program is also attached.
For the LEDs, I bought a bunch from http://besthongkong.com. They had bright 120 degree LEDs in red/green/blue/white. Remember, the LEDs I used are only for testing. I bought a 100 of each color. Here are the numbers for the LEDs I used:
Blue: 350mcd / 18 cents / 3.32V @ 20mA
Green: 1500mcd / 22 cents / 3.06V @ 20mA
White: 1500mcd / 25 cents / 3.55V @ 20mA
Red: 350mcd / 17 cents / 2.00V @ 20mA
Using these four LEDs to populate the lamp, they add up to cost as much as the micro at 82 cents! Ouch.
Step 4: Software
The software really makes this project tick!
The source code in the 12F609 is really complicated. I am using ever last memory location! All 64 bytes have been consumed by my code. I have a whopping 32 bytes of flash left over as spare. So, I'm using 100% of the RAM and 97% of the flash. However, it amazing how much functionality you get for all that complexity.
Communication to each lamp is archived by sending eight-byte data packets. Each data packet ends with a checksum - so really, there is seven bytes of data plus a final checksum. At 9600 baud, one data packet takes just over 8 milliseconds to arrive.
The trick is to multitask while the packet of bytes is arriving. If any of the LEDs are active with a PWM signal, the output PWM must be keep updated even while receiving new packet bytes. That is the trick. It took me weeks and weeks to sort this out. I spent a huge amount of time working with my Logiport LSA trying to follow each bit. This is some of the most complicated code I have ever written. It is because the micro is just so limited. On micros that are more powerful it is easy to write loose/easy code and have the speedy micro rip through it without complaining. With the 12F609, any loose code with cost you plenty. All the micro source code is written in C except for the interrupt service routine.
Why have such large data packets you may ask. Well, because we want to have the LEDs ramp up and down on their own accord. Once a ramp profile is loaded, the LED can go off and start ramping even while receiving new commands for another LED. Each lamp has to receive and decode all data packet traffic even if the packet is not meant for it.
A LED profile consists of a start level, start dwell time, ramp rate, top level, top dwell time, ramp down rate, bottom level. See diagram attached. Wow, that is a lot for one LED. Now, multiply that times the number of LEDs. It becomes too much - I could only keep track of three LEDs with full ramp profiles. The fourth (white LED on the dev board) only has ramp from/to capability. It is a compromise. Have a look at the attached pic of a ramp profile.
The PWM signal is generated off a timer that is running at 64uS per tick. The eight bit timer rolls over every 16.38mS. This means the PWM signal is running at 61.04Hz. This is no good for video tapping! So, I used a software trick and jumped a couple of extra counts into the timer to stretch it out to 60Hz. This makes video tapping look much much better.
On each roll-over of the PWM timer (16.67mS) I update the ramp profile(s). Therefore, each ramp/dwell tick is 1/60 of a second, or 60Hz. The longest profile segment (using a count of 255) will last 4.25 seconds and the shortest (using a count of 1) lasts 17ms. This gives a nice range to work within. Have a look at the attached pic from the logic analyzer. To really see the detail in the pic, open the pic in its high resolution mode. This takes a couple of extra clicks on the instructable web site. There is also a drawing of a profile shown below.
Documenting the command protocol is on my todo list. I plan to write a datasheet type of document to describe to protocol completely. I've started a datasheet for the chip - a preliminary version is on my web site now.
Step 5: Potential Applications
For sure, I think a tree filled with these babies would be just awesome. I can envision a nice warm glow of green lights with light snow falling down through the tree. Maybe a slow fade from green to red with random falling snow. Chaser lights making a helix spiral pattern up and down the tree would be neat too. Of coarse, I'm going to park this tree out in the yard and drive the "Jones" next door crazy. There, try and beat that!
Anything that needs accent lighting is a target for these lamps. My brother in-law wants to put them in the bottom of his fish tank. A friend want to accent his hot rod engine - tromping on the gas pedal would ramp up a red flash of light. I was also considering build one of these with my lamps: https://www.instructables.com/id/LED_Paper_Craft_Lamps/ Would make for a great Cub Scouts project.
Folding LED String:
A string of LED lamps could be folded into shapes. Seven lamps could be folded into a seven segment LED pattern. A huge display could be made - would be a great count-down display for new years! Or maybe, a display to show the stock market - red digits on bad days and green on good. Maybe a big display showing outside temperature.
By hanging and arranging a string of LEDs, a 3D grid of LEDs could easily be created. There are some cool 3D LED array examples on YouTube. However, the existing examples I've seen look small and painful to wire. Maybe a big 3D grid out in the yard during Christmas too.
Everyone who's been in my lab, and has seen the lights, asks if they dance to music. I did a little digging, looks like it would be fairly easy to add a plug-in to WinAmp. The plug-in would send messages to an attached string of lamps so that the lights would be synced to the music that WinAmp was playing. Syncing some Christmas music to my Christmas tree would just be awesome.
Embedded Baby Orangutan B-328 Robot Controller with H-Bridge:
The little controller from Pololu would be perfect. See: http://www.pololu.com/catalog/product/1220 This board already has an H-Bridge ready to go. Lamp patterns can be programmed into the micro so the PC could be turned off.
By adding 802.15.4 the lamps could become wireless. For Christmas tree lights spread around the house, this would be great. Or, adding lamps to every window in a large building complex would be possible. Cool.
Rotating 'Lighthouse Beacon:
My son had a school project to build a Lighthouse. The idea was to build a cheesy battery powered light with a paper clip switch so that the Lighthouse would actual light up. No son of mine will go to school with that when he can have a full blown rotating beacon! Have a look at the attached pics and video.
Step 6: Summary
It truly amazes me that each lamp has 2 MIPS of horsepower in a SOIC-8 for 80 cents. As a string of lamps gets extended by adding more lamps the amount of MIPS on the string also goes up. In other words this is a scalable design. A string of 16 lamps is humming along with 32 MIPS of processing power. Just amazing.
There is still a lot of work yet to be done.
The development board needs to be updated. There are a couple of layout bugs that need correcting. The comm error output wiring does not seem to work with the transistor output. Not yet sure why - I have not spent any time sorting this out yet. The receiving communication code needs a bit more work too. By watching the LEDs I can see there are comm errors every so often. It appears there is an average of one random error per 1000 messages.
I need to find an SMD manufacture who would be willing to make lamp boards for me. Maybe Spark Fun would be interested? I have a buddy in Hong Kong that might be able to find me a manufacture. Board assembly must be automated. It is just not feasible to build these boards by hand like I did.
A PC interface board needs to be developed. This should be really easy - it is just a matter of taking the time to getting it done.
Cost is king - a minimized lamp cost (80 cents for the micro + three LEDs at 10 cents each + board / resistors / 20 cent diode bridge) a total of maybe $1.50 bucks. Add assembly, wiring, and profit and we're talking $2.00 to $2.50 per lamp. Will geeks pay $40 bucks for a string of 16 RGB lamps on a string?
Bottom line, I hope there is interest from the DIY crowd. With some positive feedback I will continue to pursue turning this idea into a product. I could envision selling the chips, lamp dev boards, and complete light strings. Given me some feedback and let me know what you think.
For more information and continued development news visit my web site at http://www.powerhouse-electronics.com