Chrismas 2006, I decide it would be cool to do some sort of funky lighting display for Christmas next year. So when Novermber starts to roll around - I realize I gotta get cracking!
Not the greatest video in the world - but shows you it in action. (Poor) naration describes some of the basic patterns.
I used 8 shrubs out front, running 4 colored light strands to each, run by 2 Dimwatt boards. The Linux machine in my basement sends UDP packets to the two boards (about 15 a second), giving it color-level/dimness commands.
To control several different colored light strands independently, on each bush. (I have 8 in front of my house)
To be able to control dimness of each strand - as opposed to simple on/off
To be inexpensive - This means largley using the standard 120v light strands you can buy anywhere for about $1.50 ea.
To be "de-centralized" - If I have a group of features somewhere I am lighting - I'd like to place one controller by them and connect the ligts into it, rather than run all the channels back to a "central" location
To be expandable - maybe more features next year, on trees, yard decorations, etc.?
To allow many (5, 10, 20, 30?) "updates" a second - meaning I could change the dimness levels several times per second.
Having done several designs with the Microchip PIC18F4550 16-bit microcontroller w/ integrated USB support, I used that as core. It has built-in RAM and ROM, plus GPIOs to control different lighting channels, and other things like timers, comparitors, etc. which I would need.
My plan was to connect one or more of these boards to a host via USB, and have the host specify dimness levels on each channel for my board to drive. I could then write software on a host system (Linux) which would create and generate all the fance display patterns, pumping them out to the dimmer boards. Creating new lighting patterns, and adding any else to the display (i.e., interaction, syncing to music, etc,) would then be a matter of host software, not changing firmware.
My first difficulty came when looking at some of the different cable lengths I would need - for example, stretching from the host system (in my basement) to the various lighting locations (outside). USB's maximum cable length exceded these limits. I came up running long(er)-haul USB over CAT-5. There are many prodcts that do this on the web, altough integrating these would blow my budget. In attempting to research how to do this myself, the only real conclusion I could come to was that this was quite illegal as far as the USB specification goes, and though I may get it to work, it would only do so with some big USB violations
For this reason, it was apparent that USB was not going to be viable for this. I had two other quick & easy ideas that I quickly shot-down:
RS-232 - This would have been indeed quick and easy, and easily dealt with the cable-length limits, but I didn't like the idea of having to start adding more and more serial ports to a host to accomplish this. Escpecially since my existing host is a Mini-ITX box, with two USB ports on it - one of which is in use. (USB being the only way to add serial ports to this machine). Adding more would now requires USB hubs, and USB-to-serial dongles, etc.
I2C - Yes, people do run long crazy I2C busses. I2C is brain-dead simple, especially if you have a single-initiator setup, as this would be. Since the host drives the clock - and there is no lower-limit - you could run the bus down to (almost) DC - meaning that you can (almost) always correct any signal/noise issues by making the bus run even slower. As we're only talking single-byte (per channel) color commands some 10-30 times a second, we don't need a lot of speed. If speed is a factor, there are many documented ways of terminating an I2C bus when operating as a proper transmission line. I wound up shooting this down for a bunch of general tiny issues - like now needing an I2C bus on the host CPU, to having to multi-drop this kind of a bus, to worrying about signaling problems even at speeds such as 19200 baud, if there were more dimmer channels over longer distances on the bus.
So what did I go with?
Ethernet obviously had a lot of pros going for it in this design:
My host already had it/was running it
A cheap switch (like, one I already had laying around) would interconnect multiple boards
Cable length? No problem!
And a few cons:
Complexity of hardware
Complexity of software
I was delighted to find a handy-little device also from Microchip called the ENC28J80. This was a 10-BaseT Ethernet controller with a simple SPI (3-wire) interface to the CPU. I figured this would be easy to pull-off, but just in-case, I'd still lay-out the 18F4550's on-chup USB as a backup plan.
AC dimming was a part of the project I had to learn a bit about, and it is an extensive topic by itself, so I've split it off onto a page of its own. Dimming 101
So here's what I came up with:
The board uses two separate DC regulators, one for the CPU, and one for the Ethernet controller. This was because the CPU can run anywhere from about 2VDC to 6VDC, and the Ethernet controller must run at +3.3VDC. Running the CPU at +5V would be easiest if the board were connected as a USB device (ie USB powered). The ethernet controllers is spec'ed to be +5v I/O tolerant, and the CPU to allow +3.3v I/O, however, when I ran the CPU at +5v it got very hot, and acted very very flakey. After dropping the CPU to +3.3v, all my problems went away.
My plan for power was to locate the board outside, in a water-tight enclosure, and run separate DC lines to it. As there would be some voltage drop when run over a long cable (at such a low voltage), I figured I'd run +7.5v to the boards - minus the drop from the cable - then regulate down to +5v and/or +3.3v. As it turns out in the end, I started getting worried about extreme outdoor temperatures, and very very wet/snowy/icy locations, so I kept the boards indoors. They are powered off a +5v disk-drive power supply, and regulated down to +3.3v.
I used Ethernet as my sole communication medium. Though I know from prior designs that USB will work, I have not used it with Dimwatt.
Actual running board with PIC programming/debug cable connected.
Lights and wiring
As I said, I used regular outdoor lights. I took 4 different colored strands, and wound them toger into bundles for each shrub. I cut the AC plug off each of the 4 strands in each bundle, and soldered each pair into a a single 8-conductor 22AWG cable. I used a lot of shrink tubing on each wire, then the entire bundle, and wound up with something that was quite slim and waterright. Each bundle then now had a single grey cable, powering each of the 4 strands. As much of a pain as this was to solder, it was a lot easier running each shrub through a tiny hole in my house, then connecting them directly to Dimwatt's screw terminals - than having to run extension chords, and dealing with connecting plugs onto my board.
And it took a lot of lights!
There was one very strange and unforseen problem I ran into. After running for about a day - the lights would suddenly stop, is if they were not receiving any more commands from the network. The lights were still held at a constant dimness level, so I knew the board was still running - but they were never changing the light settings.
A quick power bounce of the boards fixed this. Further investigation showed that a quick power bounced of an intermediate network hub fixed it as well!
I theorized the problem to be as follows: I am sending tons and tons of UDP packets to my boards. The boards however are never sending any responses. Since the network hub knows where to forward packets to by watching the MAC addresses transfered from its ports - since it was never seeing anything transmitted from our boards - over time it would erase the MAC entries from it's own fowarding tables, thus loosing the ability to know where to route packets to.
The solution was very very trivial. Every few minutes I send an ICMP "ping" to each of the boards, which (due to the PIC TCP stack), the boards responds to. This transmission is enough to keep the hub's MAC address tables alive, for trouble-free continued operation.
There are three main software components:
Linux application - generates color patterns, sends them as UDP packets to Dimwatts
Runs on the dimwatt board - handles network, and dimming.
Firmware and Schematics
I have not posted these for two reasons:
The schematics I need to clean up - as you can see on the pictures, there is a bit of rework I needed on the board. I want to encorporate the changes into the schematics, then I will post.
The firmware was based largley on Microchip's TCP Stack version 3.60, which is available on Microchip's web site here. I don't know if I can re-distribute it, I have to check. If not, I will post all the Dimwatt-specific stuff (dimming, zero-cross, etc.) Also, 3.60 of the stack had support for many Microchip CPUs and eval boards, but not the 18F4550 - so I had to add that in (minor tweak).
Notes and Future Considerations
Microchip has a newer CPU called the 18F97J60 which has built-in Ethernet (instead of USB). Had I know this from the beginning, I may have just used it.
I created a simple little (iPhone-friendly) web page, which I can use to
control and debug the lights. The page lets me turn individual color/strands
on and off to debug wiring, and lets me manually select which patterns
to run to debug them.