Oldest “Neil Webber” reference

Inspired by finding some thirty-year-old code of mine online, I wondered if there were any even older references… and I found one!

In the summer of 1979, having just graduated high school, I worked on a macro intepreter for the Initial Graphics Exchange Specification while I was a summer intern at the National Bureau of Standards (now called NIST). I wrote an interpreter for the MACRO statements that were proposed as part of that specification.

I found several copies of the full version 1.0 IGES specification online. This one is in text form:


Being text you can easily search it for “Neil Webber” and find my name. 🙂

The actual design of the MACRO language syntax is a hoot and reflects the FORTRAN language practices of the time. For example, variable typing is determined by the first letter of the variable name.

I didn’t design this language syntax all I did was implement a processor that could run the macros and generated IGES statements from them. I vaguely remember that I called the program “bigmac” because it was a macro processor and it was “big” (meaning 64K-ish). It ran on a PDP11 under v6 Unix.

The IGES 1.0 document was published in 1980. This is the oldest reference to any of my work that I can find – partly because I’m pretty sure this would be the oldest bit of my work that was ever referenced anywhere.

I have not, unfortunately, been able to find any copies of the source code of the macro processor. I’m pretty sure NBS released it because part of the point of asking me to implement it as a summer intern was to show that the MACRO capability wasn’t “too hard”. I’m sure my program was probably an embarrassing mess of bad technique; on the other hand, having a summer intern implement the MACRO processor probably helped make the argument that it wasn’t “too hard” to do. 🙂

Thirty year old code almost still compiles (and does still work!)

Thirty years ago, in February of 1987, I published some code of mine on net.sources:









There is so much deliciousness in this old post, including evidence that my affinity for the word “actually” goes a long way back.

Because I was a hardcore Amiga nerd back then (as opposed to simply now being an all-around hardcore nerd), I also submitted the program for inclusion in the “Fred Fish Amiga Source Disks” that he (Fred Fish) used to curate. It was included on disk #66 and still available as “MallocTest” online here:


For reasons surpassing understanding, I decided to download that code, unpack the archive (that itself took some research), and see if it still compiles and works.


Well, almost. It generated over 40 warnings on my Mac, mostly related to modern declarations of C library functions vs the mismatched (if even present at all) declarations in the code.

It did generate one fatal error – one of my functions does not return a value but is not declared void. I’m pretty sure that’s because the “void” type wasn’t universal back then, and in any case it was common practice to just fall out the bottom of what were implicitly void functions (that had been implicitly declared as “int”).

So, I had to fix that to get it to compile; here’s the diff that made the thirty-year old compile:

> void add_to_events (struct memevent *);
< add_to_events (m)
> void add_to_events (m)

With that change, it still compiles and works! The code itself is a time capsule of everything that was wrong with software development back in the late 80’s, including most importantly the fact that the malloc/free library on a given machine might have a bug in it that this feeble test could uncover (which, apparently, it did, though I have since forgotten which platform I was researching malloc/free problems on at the time).

Presented, for your amusement: https://github.com/outofmbufs/MallocTest1987


FeelTech FY3224S Grounding Modification

I have one of those cheap FeelTech FY3224S  (FY3200S 24Mhz version) function generators. Sometimes sold under different brand names, including “Moo Hoo” and no-name at all, and sold by  “banggood” (not making that up!), amazon, and other online stores.

There is an extensive thread about these on eevblog.com that includes this post about getting a shock from the device:

I was just using my Feeltech FY3224S and felt something biting me…the culprits turned out to be electrons…I was getting a shock.  When I measured AC voltage with a multi-meter from any of the ground points on the Feeltech (e.g. the outside of the BNC connectors) to AC ground, I had around 19vrms

Here’s another blog referencing this same problem: http://www.dalbert.net/?p=322. He measured 82V peak-to-peak. On my device I measured 45V rms or so with nothing connected to the outputs, and measuring between the BNC grounds and earth ground. As all of these write-ups point out, there isn’t enough current to be dangerous; you “just” get a tingle. The problem is caused by the use of a switched-mode power supply not properly implemented for use with floating DC outputs (which this device has).

The best, but most complex, fix is to rip out the switched-mode power supply and replace it with a linear supply suited for floating-DC output configurations.

An easier solution, which many others have also done, is simply to tie the DC grounds to earth ground. In other words, don’t let the DC outputs float. I decided to do that, with a switch enabling me to go back to the original (floating) configuration if ever needed for some specific reason.

The eevblog thread is full of examples of people doing exactly what I did, so it’s not anything new. I’m just documenting it here on the assumption someone might find it useful anyway.

The original back of my generator looked like this:

You will note that the A/C input is two-prong and is not polarized.

I had a so-called “mickey-mouse” (C5/C6) power inlet that doesn’t take up much more space than the original two-prong inlet. I enlarged the opening as necessary with a rasp to accommodate the three-prong inlet. I also had a suitably-sized SPDT round rocker switch (SPST would have sufficed) and mounted it as shown below:


The idea of mounting it there is that the ground symbol already present serves as the label for the down-position of the switch; I wired the switch so that when it was down the BNC grounds would in fact be grounded to the earth ground. If you are wondering why the C5/C6 connector is sometimes called “mickey mouse” take a closer look at the above picture and you should be able to figure it out.

This picture shows the inside wiring:

I added the green wires going from the ground on the power inlet to one side of the SPDT switch, and from the center (pole) to the ground lugs on the back-side BNC connectors. But what about the front connectors? Well, all the DC grounds on this device are all connected together, so grounding these back here grounds them all. Obviously, the same observation leads to the conclusion that I did not need to tie both ground lugs together back here; just connecting to one or the other would have been sufficient. However, these two connectors are hooked up to the main board by two separate wire assemblies each with its own separate plug/jack, so by wiring both grounds here the grounding will still be effective even if one of those plugs works its way loose someday. But, realistically, that green connection between the two BNC ground lugs is superfluous.

In the original configuration the input power was not polarized; consequently sometimes the front panel switch was interrupting the hot A/C lead and sometimes it was interrupting the neutral A/C lead, depending on how you plugged the unit into the wall. A three-prong plug is obviously inherently polarized, and I made sure to hook up the power inlet such that the hot side went to the switch so that the input power would be fully cut off at the switch when the device is off (vs the circuit being interrupted only on the return/neutral leg).

I buzzed out the connections to make sure I knew which one was which:

This shows that the connections, when viewed from the back of the mickey-mouse connector, match up with the connections when viewing the plug face-on (the picture shows the not-connected configuration). From there I looked up which prong in an outlet was hot vs neutral. I was reasonably certain I knew this but looked it up again anyway. I carefully labeled and checked my approach 17 times to make sure I wasn’t confusing myself between the “outlet left/right” view and what I would see when soldering the back of the connector.

Obligatory safety disclaimer: don’t try any of this if you aren’t knowledgeable and skilled with 110VAC circuits. I’m not even going to tell you which one of the prongs is hot vs neutral because if you need me to tell you that, you probably shouldn’t be doing this!

Once I wired up the 110V inputs everything was ready to go back together. Here is is all buttoned up:

I used my label maker with a black-on-clear cartridge to add the FLOAT label at the top of the switch. The ground symbol already there serves adequately as a reminder for the other position. I didn’t quite get the FLOAT label lined up exactly right. I could fix it, but the switch is going to stay in the “ground” position 99.99% of the time, and all this is in the back of the unit, and only some of my overly OCD friends will notice or care. It stays as is.

With everything buttoned back up I tested the grounding:

This is showing 600 microvolts with the rear switch in the ground position. I should mention that the other multimeter lead was hooked up to a convenient ground elsewhere in my lab set up and that ground was coming from a different wall outlet. Many of my circuits are “home run” back to the panel so there might in fact have been a hundred feet (or more) of romex between these two ground connections. So a non-zero ground potential difference doesn’t surprise me, if we consider “600 microvolts” to be “non-zero” (and not a meter artifact either).

In the original, floating, configuration we get 48 volts:

That will tingle! Obviously the switch will usually be left in the grounded position and if I need a floating function generator I’ll just have to be careful, or spring for a “real” piece of kit instead of this $60 cheap, but rather useful, hack piece of equipment.

One last point, as mentioned in the eevblog threads and elsewhere. The USB port on this device is not ground-isolated. So if you want to float the device (the original configuration), AND you have a computer plugged into the USB port, AND if your computer is grounded (which it won’t be if you have a laptop running off a battery), then the USB ground will de-float the generator output. I suppose it’s also possible that if your computer is floating then the 45 volt “tingle” might make it to your laptop? Ick. In any case, it’s something to be aware of.

I did buy a USB isolator board from Adafruit. This can be used externally if I ever need to float this generator AND have the USB hooked up; alternatively I may explore permanently installing it into the device on general principles. The primary use for the USB port is for defining custom waveforms, which is something I don’t have any immediate need to do. So for now the USB isolation goes onto the “to-do” list and in the meantime I’ve got a function generator that will no longer “tingle” me unless I want it to.

Update: FY2300H

There is another version of the generator out now, the FY2300H (model numbers go backwards? lol!). A 60MHz version is more expensive than my 24MHz version: $330 vs around $90 for mine, but also obviously can provide faster waveforms. Here’s one at Amazon: https://www.amazon.com/Kuman-Generator-Arbitrary-Intuitive-Interface/dp/B06ZY2958F/

They seem to be available at varying prices for other speeds at AliExpress. The cheapest is $80 for a 6MHz version, and I found links for $130 for a 25MHz version though they were out of stock as I write this.

Note this interesting broken-english description:

With the new design of power supply, the utility model eliminates the disadvantage of small amplitude signal interference of the power supply of the hand-held instrument. (10mV small signal still has the perfect signal feature)

and as you can see from the pictures, it has an external wall-wart power supply. Presumably they provide one that is implemented properly and thus fixes the AC mains leakage problem of the power supply built into the FY3200 series. If I didn’t already have my other unit I’d probably buy one of these, even at the higher price (which will likely come down over time if you wait) rather than perform the modifications shown here, especially since that would give me a generator that could DC-float without AC mains leakage whereas the grounding modification only fixes the leakage when you aren’t floating the generator outputs.

pfsense router – almost 1 year uptime

I’m running a pfsense router on a (somewhat obsolete now but still serviceable) dedicated soekris box as the router for my (40 acre) hilltop “empire”. I have a somewhat complicated network topology: my Time Warner cable modem is in a building at the bottom of my hill but my house is uphill about a quarter-mile (as the wires run) away. I have a multi-mode fiber connection between the cable modem downhill and the router uphill, from which four internal networks emanate:

  • HILLTOP: my internal network.
  • GARAGE: runs back down the hill (on another fiber pair) to a separate maintenance equipment garage building.
  • DMZ: a true, isolated, DMZ topology for a few servers I want to allow access to from the network at large.
  • PUBLICWIFI: a no-password open-WiFi network for my guests; it is also appreciated by maintenance personnel working on stuff up here on the hill. Access control for this otherwise-open WiFi access point is provided primarily by the fact that the signals don’t reach the edge of my property line (at least in all the places I’ve tested for this). If you can get the signal the presumption is you should probably be allowed to surf the internet on my dime 🙂

The pfsense software makes it easy to configure these networks with appropriate firewall rules; for example no traffic is routed between the PUBLICWIFI network and any of the other networks (other than the WAN network to the outside world of course).

About a year ago I put the router on a UPS just because the mean time between power failures up here is about 2-3 months. Anecdotally, thunderstorms are the primary source of periodic, short, power outages/glitches.

Here’s the network statistics report:

Statistics for the hilltop network

As always, you may wish to click to view the image full size.

During the 322 days of uptime:

  • 2.5 terabytes have arrived at my router from the internet. That’s about 7-8GB per day, most of which is presumably netflix or porn (for network tests of course).
  • Of the 2.5TB, 2TB went to the house network and 0.5TB went to the maintenance building where my property manager works.
  • The DMZ served out 5.6GB (a whopping 17MB per day). There are some status servers on this network that my property manager and I periodically surf to check in on things if I’m not here.
  • The public WiFi pulled 20GB down from the internet (about 62MB/day). The maintenance workers don’t seem to surf very much porn 🙂

I had a 12-pair multi-mode fiber installed to run up/down the hill and I am using two of the pairs. One pair runs from the cable modem up to my router. Another one runs back down the hill to the GARAGE to carry the (internal) network back down into the maintenance building. These runs are each about 1300 feet, or about 400 meters. The fiber transceivers I’m using (StarTech MCMGBSC055) are supposed to be good for 550m at 1Gb and appear to be functioning well. There are zero errors across the board except for one output error recorded in the entire year. My guess (and it is purely a guess) is that the output error occurred during a power failure. My router is on a UPS but the transceivers are not, so a power failure that happens during a packet transmission might show up as an output error. Otherwise I’m at a loss to explain how there could be an *output* error detected by the router; I’m guessing what really happened is that the ethernet connection between the router and the fiber transceiver went down when the power failed in the middle of a packet transmission. The router is on the UPS but other network gear is not; the only point of the UPS here is to shield the router from the strain of unnecessary power-glitch reboots; it is not intended to keep my network up during outages.

Knowing a little bit about the waveforms and the technology that makes all this stuff work, I am always impressed that stuff like this actually *does* work.

So far the 1Gb link is faster than my cable modem connection. I’m not going to be able to go to 10Gb without laying new (single mode) fiber. The fiber run is in a conduit with periodic access/pull points, so supposedly this will be possible, but it won’t be especially cheap or easy. Since I have some spare pairs I may be able to get more bandwidth in the future with link aggregation; I’ll worry about that technical problem when/if my internet connection exceeds 1Gbps from the ISP (when is google fiber coming here?!!!)

555 Timer Chip and the importance of bypass capacitors

DISCLAIMER: There’s nothing in this post that hasn’t been said in a zillion other posts about 555 timer chips, power rail decoupling capacitors, and bypass capacitors. I just wanted to see it all for myself and then of course I felt compelled to document what I had learned.


I built myself the standard astable configuration of a 555 timer, operating at a calculated 125Hz and measured at 119Hz:

I implemented this on a breadboard with reasonably-neat/short/organized leads, and hooked it up to the oscilloscope to see how it was working:

The yellow trace is the output of the 555 chip and looks pretty reasonable at this scale. The blue trace is hooked up to the 5V rail, AC coupled. Everything looks plausible at this scale, but let’s look closer:

Here we’re zoomed into the rising edge of one clock cycle. You may wish to click on the images to bring them up in full resolution in their own browser tab. Again the yellow trace is the 555 output; it’s pretty nasty and appears to peak at almost 7V and then ring out a bunch. But even worse look what’s happening to the 5V supply rail – the blue trace. I’ve got it on AC coupling so the steady-state 5V DC is “zero” and the excursions from there represent garbage on the power rail. It’s dipping down more than 3V then shooting back up before eventually settling back down at 5V. I’m driving this with an Agilent E3610A lab bench power supply so there is no question that the supply itself is high quality. The problem is the 555 chip is notorious for high current draw and other nasty effects during transition, and we can see that here.

The common solution to this is to put one or more capacitors between the +5V and ground to decouple the chip from the power supply – to serve as “reservoirs” of charge from which these current spikes can be drawn without pulling down the Vcc rail itself.

So, following the cookbooks, I put a 2.2”F electrolytic capacitor across the power rails, and got this:

This is obviously a gazillion times better Now the instantaneous dip on the Vcc rail is just about 1V instead of 3V and it no longer spikes upwards at all. The clock output is also tremendously cleaner, though by no means “clean”. At least now it just shoots up to 5V, stays up there for about 300ns, then heads back down and eventually settles at about 4V (off to the right of this capture it finally settles there).

In this particular case 2.2”F seemed to be sufficient; I tried other values all the way up to 470”F and saw no real change in the curves.

What did make a big different in the curves was the precise location of the capacitor. This is a really good lesson in the saying: “the difference between theory and practice is greater in practice than it is in theory”. You might think that all the points on a given row on a breadboard are “the same” but they are not: there is quite a lot of stray capacitance, inductance, and resistance lurking in the connections beneath the alluring abstraction of the breadboard, and it matters when working on things like this.

I moved the 2.2”F capacitor so that it was plugged into the point directly adjacent to pins 1 and 8 on the 555 (i.e. the Vcc pin and the ground pin). That gave me this result:


Notice how much smaller the effect on the voltage rail is now.

Just to eliminate any questions about the interpretation of values given the AC coupling, I took this capture with the blue trace on DC coupling:

Here we can see the power rail dip at the start of the transition is less than 1V.

Next, again following advice from everyone who ever writes about things like this, I added a smaller bypass capacitor again right at pin 8 on the 555. This trace show the result of adding an 0.22”F tantalum capacitor also “immediately next to” the 555 chip:

[ I changed the horizontal time scale in this one; sorry ]

This shows some slight improvement. I fiddled around with various values for the smaller capacitor but couldn’t find one that worked any significantly better than this one. The dip is substantially less than 1V at this point.

There are many write-ups where people talk about the 555 being a “nasty” chip with bad effects on power rails, and this little exercise shows some of that.

If you don’t have an oscilloscope and you don’t put in appropriate bypass capacitors, you may find other parts of your circuit designs misbehaving depending on how big the spikes on the voltage rails are and how sensitive your other circuitry is to those spikes!


SnapPower Charger – USB Outlet Installation

I installed two SnapPower usb charger outlets today:

The idea is that you just replace the faceplate of your outlet and get a built-in USB charger “without being an electrician”. It works, as far as that goes, but really it’s almost the same amount of work as installing a genuine USB outlet, e.g., one of these:

I turned off the breaker to my outlets, opened the faceplate, and found out that my outlets had been installed wrapped in electrical tape around the screws. So I had to take the outlet out of the enclosure anyway, to remove the electrical tape:

Once you are to this point, it’s not really a whole lot different to disconnect the entire old outlet and replace it with a “real” built-in USB outlet such as the ones shown above. Nevertheless, I took off the electrical tape (as mentioned in the “obstructions” section of the SnapPower installation brochure), put the outlet back into the wall, popped the SnapPower cover onto it, and everything works:

[ this picture also shows off a charger cord I repaired ]

I’d recommend these outlets if you specifically had a desire for the cable to come out flush to the wall, perhaps if you were installing this behind a piece of furniture. Otherwise I’d have to say you may as well go all the way and buy the “real” USB outlet, which has the benefit of looking at little more professional and gives you two USB connections instead of just this one.


Who Let The Blue Smoke Out?

I took apart a piece of gear to see if I could figure out why it stopped working. I found this on the power supply section of its board:

Well, understanding why that chip decided to blow up is above my pay grade, but I think we found at least one problem…

Coin Flip 555 Timer Circuit

Today I built a 50-50 coin toss circuit using a 555 timer circuit, for no particularly good reason other than just to try it.

I’ve seen several variations of these circuits that use the 555 to generate a clock signal which is then conditionally fed into a flip-flop when you push a button to “flip the coin”. The button connects the oscillating clock output of the 555 to the flip-flop clock input. The flip-flop is configured to toggle on each clock transition, so when you let go of the button the flip-flop basically has a 50% chance of being high or low. This is then usually shown to you via two different LEDs – one for heads, one for tails.

It occurred to me that there was already a flip-flop inside the 555, which then led to the idea that if I could build a 50% duty cycle astable 555 circuit and make a way to start/stop the oscillation, that the whole thing could be done with just the 555 and no other chips.

Previously I had built a fairly common configuration of an astable 555 circuit as an exercise. This is the circuit that allows you to easily vary the duty cycle of the oscillation:

The duty cycle in this circuit will be 50% when the charging path, which runs through R1 and the “left half” of potentiometer R2, has the same resistance as the discharging path which runs through the “right half” of R2 (but not R1). The general idea behind picking R1 small and R2 large in this circuit is to minimize that asymmetry so that positioning the potentiometer near the middle results in nearly a 50% duty cycle.

Given that idea here is my circuit to flip a coin:


The output side of the 555 circuit is where the coin flip is displayed. If the 555 Output is high, there is insufficient voltage differential between the Output and Vcc to turn on light-emitting diode D3; conversely, the Output voltage will flow through R7/D4 and that LED will illuminate. If the 555 Output is low, the reverse is true. LED D3 will illuminate, and the current from Vcc through R6/D3 will be sunk into the 555; conversely there is insufficient (nearly zero) voltage differential between Output and ground and so D4 will remain dark.

On the left-hand side we see that when the switch is in the “run” position, the circuit is the standard astable oscillator shown before. I’ve drawn it showing fixed resistors for R2/R3 but in fact I built it using the potentiometer from the previous adjustable duty cycle circuit, so that I could experiment with the effects of different duty cycles.

If the switch is moved into the “stop” position, the Trigger and the Threshold input are disconnected from the RC network and instead are connected to a simple voltage divider. With R4 and R5 being equal value, the voltage at this point will be 1/2 Vcc which is too high to trip the Trigger and too low to trip the Threshold; consequently the 555 simply remains in whichever state it was last in at that point.

I used a push-on momentary single-pole double-throw switch, wired so the normal position is “stop” and the momentary is “run”.

In my first idea for this circuit I planned to use a double-pole switch because I thought I’d also have to toggle the Discharge pin between two connections. But that’s not really necessary; if the Discharge pin is low when the timer is stopped (50% chance of this happening) it simply continues to sink current from Vcc through R1; this will be between 5ma and 15ma depending on what voltage you use for Vcc (5V – 15V). It’s a waste of power, 50% of the time, but it works. Also, don’t forget that one of the display LEDs is also always on, so the power wasted in the Discharge is only part of the power use of the circuit and could be made somewhat insignificant. But if you cared about this wasted power you could use a double-pole double-pole switch and so that in addition to moving the Trigger/Threshold between a “run” and “stop” position you could move the Discharge in tandem (between the connection as shown above and “no connection” in the “stop” position). Alternatively you could increase R1 as the asymmetry effect R1 has on charge time versus discharge time is not really important in this application; you could choose R2 and R3 to compensate for a larger R1 such that R3 = R2 + R1 is maintained for a 50% duty cycle.

The frequency of the oscillation isn’t especially important other than you want it to be fast enough so that you can’t time your press of the button to influence the result, and slow enough that the flickering can be seen because that’s a cool effect. With the values shown above the frequency will be in the neighborhood of 25-30Hz.

So, the circuit definitely works. Here’s a movie showing that:

555 flip circuit

I had originally powered the circuit from a 5V bench supply. You can see in this movie I was trying it from a 9V battery; I probably should have increased the resistors R6/R7 for that as there is no real need to pump 90mA through the LEDs. You may wish to experiment with that if you follow this idea.

There is a pretty significant drawback to this circuit: the 50-50 fairness of the coin-flip depends on having an exact 50% duty cycle. Using my oscilloscope, and taking advantage of the fact that I had used a potentiometer for R2/R3, I was able to tune the circuit to precisely that point:

However (and “of course”) … the cheap resistors used in this circuit can drift as they warm up or cool down, and there are plenty of other variance effects that all can lead to the duty cycle drifting even after it has been adjusted to 50%.  I saw that myself just while playing with the circuit; after I had adjusted to 50% a few minutes later it was off at 49.6% as an example.

Before I built this circuit I did a lot of google searching for other examples of this idea and came up empty. I can see now why people don’t build a coin-flip circuit this way, because it’s impractical to guarantee an exact 50% duty cycle and so there is no guarantee of 50/50 heads/tails fairness.

Using an external flip-flop eliminates this problem, because the external flip-flop (assuming you have set it up this way) can toggle between high and low states only on the rising edge of the 555 output clock cycle. This makes the duty cycle irrelevant, as the amount of time the 555 output is high or low has nothing to do with how long the second flip-flop will be high or low. The second flip-flop will alternate between being high and low each for an ENTIRE clock cycle of the 555 output; only the rising edge from low to high will toggle the external flip-flop. In this way any asymmetry in the duty cycle becomes irrelevant and the coin toss is inherently fair.

Thus, this circuit I built is interesting as an exercise, but probably shouldn’t be recommended for use in any real coin-flip application. Though obviously that hasn’t stopped me from posting it — if for no other reason than other people might find it and understand why no one else builds a coin-toss 555 circuit this way! 🙂


LED Christmas Lights Project Completed

I have nearly 1100 feet of RGB LED strip lighting outlining my roof for Christmas this year. I’ve written about pieces of the project incrementally along the way; this post collects all of that information and any new updates all in one place.

Topics covered:

  • Physical attachment to house
  • LED controller boxes
  • Problem Statement: How to control 9 of these?
  • Arduino 9-way IR emitter implementation
  • Programming the light show
  • Some over-the-top study of circuit behavior
  • Future directions

This is going to be a long post … settle in!

Physical Attachment to House

The LED strips look like this:


All together it took 8 rolls (four are shown in this picture) to outline my roof and a ninth to do the observation tower.

My house has a metal roof with a metal fascia going all the way around the house. Magnets will stick to the fascia metal, so that’s how I attached the LEDs to the house. It took 500 magnets from http://www.magnetshop.com/ and 500 zip-tie mount points that had to be stuck onto each magnet by hand:



The magnets attach to the fascia and the zip ties anchor the LED strips. We prototyped this method back in September and left some LED strips up for a month or so to test it out. The only problem encountered was that some of the zip-tie mounts separated from their magnets; glue fixed those.

This attachment method also has the advantage of being fairly easy to take down at the end of the season and to redeploy again next year.

Controller Box Detail

Each LED strip comes with a controller box:


As you can see, the box has an IR receiver (the “tail” on the box) with a corresponding remote control.  The RED, GREEN, BLUE, etc buttons each command varying voltage levels on the R/G/B outputs which are hooked up to the corresponding LED colors on the strand. The buttons labeled “DIY” can be programmed for custom color blends. The other buttons (JUMP/FADE/FLASH/etc) select built-in effects; for example JUMP3 cycles the strand through a rotation of three different colors.

This works great for a simple installation but for my application there is a big problem…

Problem Statement

I have nine of these boxes, because there’s a maximum strand length (based on voltage and power requirements) a single box can drive. So, for example, to set my entire house to be RED I’d have to walk around the outside of my house, aim at each individual strand’s control box, press the RED button, and repeat that process 9 times – once for each individual strand.

That’s just impractical. Nor can I just set each strand to a built-in effect (e.g., the JUMP3 cycle), because there’s no easy way to synchronize them all. Even if I could synchronize them at the start somehow, they’d probably drift apart anyway as it’s unlikely their internal timing mechanisms are constructed to very tight electronic tolerances. You might think that the JUMP3 program is switching colors every second, but one control box might switch them every 1.0001 seconds and another might switch them every 0.9999 seconds. Even a difference that small would result in the strands being visibly out of sync after just two hours.

There are other controllers you can buy that have built-in solutions for this sort of synchronization, but being a nerd I decided to address the problem by building something myself. Basically I needed a network-addressed and computer-controlled version of the handheld remote that could also drive nine IR emitters in parallel (so as to command all the boxes at once).

9-way IR Emitter Implementation

The first step for any such implementation is to capture the IR codes from the remote control in the same way any universal-remote would.

I used an Arduino Uno for this, with a standard TSOP38238 IR decoder chip (I bought mine from Adafruit) and Ken Shiriff’s excellent IR Remote library.

Here’s what the TSOP38238 looks like:


This decoder is trivial to connect to an Arduino – connect the power input to +5V, connect the ground to Arduino ground, and the data output pin goes to any Arduino input pin (I used pin 11) so the library can read it.

Strictly speaking different IR decoders are tuned for different specific IR protocol frequencies. For example the TSOP38238 is tuned for 38KHz signals and there’s a related part TSOP38236 that operates at 36KHz.

[ In fact both of these parts are deprecated and have newer versions (different part numbers) you should probably use instead; I only picked the TSOP38238 because “that’s what they had on the web site I was surfing at the time (Adafruit).” ]

I didn’t know in advance what type of code my remotes would transmit so I just had to pick something and start somewhere and see if it worked. Fortunately the decoders only cost about $2 each so you could buy a few different ones and have them in your lab kit.  At one point it was true that many (maybe even “most”) manufacturers started using the NEC protocol at 38KHz, which makes it a popular choice and probably explains why Adafruit sells that particular decoder. You might wish to peruse this IR decoder selection guide or do some further reading if you run into problems with a particular remote you are trying to decode.

I got lucky at the start because the remotes I had do in fact transmit at 38KHz using the NEC protocol and my decoder chip received them just fine.

I used some example code from the library which simply receives IR data from the decoder and prints it out on the Arduino serial output which you can monitor from Arduino IDE. Here’s the code:

#include <IRremote.h>
IRrecv irrecv(11);  // my rcvr is on pin 11
decode_results results;

void setup() {
  irrecv.enableIRIn(); // Start the receiver

void loop() {  
  if (irrecv.decode(&results)) {
    Serial.print(" ");
    Serial.print(" ");
    Serial.print("  == 0x");
    Serial.println(results.value, HEX);
    irrecv.resume(); // Continue receiving

I pushed every button on the remote and noted the corresponding values for each. As already mentioned the remote sends using the  NEC protocol with 32-bit values. Here are all the codes I got:

    BRIGHTER = 16726725
    DIMMER = 16759365
    PLAYSTOP = 16745085
    POWER = 16712445
    RED = 16718565                              
    R1 = 16722645
    R2 = 16714485
    R3 = 16726215
    R4 = 16718055

    GREEN = 16751205
    G1 = 16755285
    G2 = 16747125
    G3 = 16758855
    G4 = 16750695
    BLUE = 16753245
    B1 = 16749165
    B2 = 16757325
    B3 = 16742535
    B4 = 16734375
    WHITE = 16720605
    W1 = 16716525
    W2 = 16724685
    W3 = 16775175
    W4 = 16767015

    RED_UP = 16722135
    RED_DOWN = 16713975

    GREEN_UP = 16754775
    GREEN_DOWN = 16746615

    BLUE_UP = 16738455
    BLUE_DOWN = 16730295

    QUICK = 16771095
    SLOW = 16762935

    DIY1 = 16724175
    DIY2 = 16756815
    DIY3 = 16740495
    DIY4 = 16716015
    DIY5 = 16748655
    DIY6 = 16732335

    AUTO = 16773135
    FLASH = 16764975

    JUMP3 = 16720095
    JUMP7 = 16752735
    FADE3 = 16736415
    FADE7 = 16769055

The RED/GREEN/BLUE/WHITE correspond to the color buttons. Names such as R1, R2, etc correspond to each of the four buttons under the RED, GREEN, BLUE, and WHITE buttons on the remote.

If you look up the details of the NEC infrared protocol system, you will find that the 32-bit codes are broken down into four eight bit fields:

  • 8 bits of Address
  • 8 bits of Inverted Address
  • 8 bits of Command
  • 8 bits of Inverted Command

The “address” field is one way to make sure that hitting the fast forward button on your DVD remote control doesn’t also accidentally turn off your TV; each manufacturer was assigned their own address value to use.

The “command” field is meant to be used for the actual command, e.g., RED, BLUE, etc., in this case.

Looking at the RED code of 16718565 for example, in hex:

16718565 = 0x00FF1AE5

We can see that the “address” used by the box is 00 (inverted address FF) and the RED command itself is 1A (hex) or 26 decimal and the inverted version of that is E5 (hex) or 229 decimal. The sum of the command and the inverted command (or the sum of the address and the inverted address) should always be 255.

None of this is necessary to know but explains why the code values look so unusual in decimal vs being something more obvious like “1”, “2”, “3”, etc.

It also tells us that there are only 256 possible codes that can be encoded for any given device using this protocol. Fortunately, humans start getting annoyed with remotes that have around 75 buttons or more so this isn’t really much of a limitation.

Armed with the codes, the next step was to figure out how to send these codes under computer control, and eventually to all 9 boxes at once.

Again using an Arduino it’s pretty trivial to control one IR emitter LED with the IR Remote library and a simple circuit. Here are two example approaches:

The IRRemote example uses the Arduino output directly and can only drive the IR emitter at less than about 50% of its theoretical power because the maximum current output of an Arduino pin is 40mA. To work around this limitation the Adafruit example uses an external transistor as an amplifier and so can drive the IR emitter at a higher power setting.

I needed to drive 9 IR emitters. There are many ways I could have done that but I decided on an approach based on some things I already had sitting around in the project bin (old wall-wart power supplies from old otherwise-dead equipment) and also based on wanting to learn about MOSFETs for other, future projects.

So while I was surfing at Adafruit I also bought some logic level N-channel power MOSFETs: International Rectifier part number IRLB8721. These can handle far more voltage and power than necessary for this purpose, but they are inexpensive and have the important property that they turn on at a “logic level” of Vgs = 4.5V at the Gate G. An Arduino output pin supplies 5V so this will work well for controlling the MOSFET.

The basic idea is simple: the MOSFET will take the low-power output signal from pin 3 of the Arduino and use that to modulate the higher power from the external wall-wart supplied to a string of 9 IR emitters all in series.  The circuit looks like this:


You may wish to click the picture to open it at full resolution.

Ignoring all the resistors for a moment, the operation of this circuit is pretty simple. When Arduino pin 3 is low (0V) the MOSFET is off and no current can flow from the Drain (D) to the Source (S). Therefore the IR emitters are off as they have no connection to circuit ground. When Arduino pin 3 is high (5V) the MOSFET turns on and current can flow from D to S, connecting the ground side of the series of IR emitters and allowing current to flow through them and turn them on. Thus, the IRRemote library modulates the output on Arduino pin 3 and in turn that pin modulates the power to the nine IR emitters and they all end up transmitting the same remote control code at the same time.

Each of the nine IR emitters is actually out on my roof somewhere connected by several hundred feet of wiring back to the central point where this circuit and the Arduino sit. Because the circuit connects all the IR emitters in series, if any of these wires breaks (or if an IR emitter burns out somehow) the whole show comes to a halt; no codes will be transmitted by any of the IR emitters unless all of them are properly connected and functioning. In my case I consider this property of the series arrangement to be an advantage. If something goes wrong electrically I will know right away because nothing will work – the entire roof will stay whatever the last commanded color was. In this case I consider that better than having eight of the nine strands work (continue to change according to the programming) with one of the strands stuck, as would happen in other parallel-wiring solutions. In practice there haven’t been any failures of any emitters or wires yet so it really hasn’t made a difference one way or the other.

If you read some of my older postings on this circuit, you’ll see that there’s been some evolution of thought as the project went along. Originally we expected to need 11 or 12 strands, so I was originally trying to figure out how to power 16 (four extra on general principles) emitters. When it turned out we only needed 9 things got a little simpler and this circuit is the final result.

I’ve played around with different values for R1 and the bottom line is it really makes no difference. We taped the IR emitters directly onto the corresponding receivers (the “tail” on the control boxes). As long as the emitter is receiving at least 20mA (the minimum) and no more than 100mA (the maximum recommended) it will work just fine. I picked an R1 value of 33Ω because that value will keep the current flow between those two limits whether I have 8 or 9 IR emitters hooked up; sometimes for debugging it has been handy to take one of the emitters out of the circuit and this value allows for that.

There is some empirical measurement necessary to figure these values out because the voltage drop (“Vf”) across an individual IR emitter depends somewhat on the current flow, and the current flow in this circuit depends on all the voltage drops – in other words there’s a circular dependency so the easiest way to figure it out is to measure it rather than figure it out. So what I did to measure a few key parameters was to take a close-enough guess for the values and then measure the circuit with the MOSFET gate connected to the +5V output of the Arduino instead of pin 3. This allowed me to use a voltmeter to measure key parameters like the total voltage drop across all nine emitters.

Similarly the voltage provided by my wall wart, Vx, varied depending on load because it is an unregulated power supply. Again I just iteratively measured the reality of its output with the MOSFET gate statically fed 5V to turn the circuit on. My detailed write-up on figuring all that out is in this earlier note and won’t be repeated here. The thing I did learn from that exercise is that in the next project it would probably be smarter to use a regulated power source!

Resistor Rg protects the Arduino output pin from excessive current draw when the MOSFET transitions from off to on. When the MOSFET is off and Arduino pin first rises to 5V, the Gate input G acts somewhat like a capacitor between G and S. This is just inherent in how MOSFETs work. This means DC current will flow for a brief instant between G and S until the MOSFET accumulates enough charge and blocks further DC current flow “somewhat like a capacitor between G and S“. This is all part of the transition of the MOSFET from the OFF state (very high resistance between D and S) to the ON state (very low resistance D to S). To keep that brief current spike below the Arduino max pin output of 40mA, I choose Rg at 330Ω which leads to this calculation for the current draw when G and S are momentarily (effectively) shorted:

Ig = 5V / 330Ω = 15mA

That 15mA (which is within the 40mA limit) will only be drawn for a brief fraction of a second as the MOSFET charges. During the instant of time the 15mA is flowing the resistor will dissipate:

W = I^2 * R = (0.015 * 0.015) * 330 = 75mW

of power; I’m using a 1/4W resistor which is more than enough to tolerate this.

Resistor Rgs is there for the “Good Housekeeping Seal of Approval”. If the Arduino is powered off and pin3 is in an unknown state we don’t want the MOSFET randomly turning on and off, so Rgs  functions as a pull-down resistor making sure that the MOSFET gate stays at zero volts unless the Arduino is actively supplying voltage on pin 3. In some designs there are other considerations for this resistor but in this simple case “it just doesn’t really matter that much” is the answer to all of those complicated questions. I picked 18000Ω somewhat arbitrarily, trying to get a relatively low value for the pull-down effect while also being aware that the two resistors Rg and Rgs form a classic voltage divider; the voltage at the MOSFET gate will be:

Vg = 5 * (Rgs / (Rg + Rgs))

This means that as Rgs gets smaller, so does the gate voltage that will appear at G. With the chosen values of 330Ω for Rg and 18000Ω for Rgs the gate voltage works out to about 4.9V when the Arduino is supplying 5V. The MOSFET will turn on at anything above 4.5V so this works out just fine.

I originally prototyped all this on a breadboard and then eventually built this soldered-together implementation:


This actually shows an earlier version of the board built back when I expected to only have eight IR emitters (and to build two of these boards). Instead I have nine emitters and I daisy-chain them on a separate terminal block rather than the screw terminals shown in the picture (and I also changed the resistor R1 from 56Ω which you sort of can’t see in this picture to the 33Ω described earlier).

Well, we can geek on about electronics forever; indeed I’ll come back later in this posting and talk about some other things I measured. In the meantime, let’s move on to programming.

Programming the Light Show

From a previous project I had some code implementing a simple JSON POST interface on an Arduino (with ethernet shield) allowing remote access to digital I/O. That code is up on github.

So I plugged an Ethernet shield onto my Arduino, hooked the whole thing up to my network, and built a server starting with that code. I modified it to accept POST requests of JSON to control sending IR codes using the IRRemote library.

The JSON it accepts looks like this:

{ "codes": [ ircode-dictionaries ], "repeat": n }

An ircode-dictionary looks like:

{ "code": 16718565, "bits": 32, "protocol": "NEC" }

POSTing this to my Arduino server will make all the LED strings RED for example.

There is an optional “delay” element specifying a delay, in microseconds, to wait after sending the code. Although the NEC protocol allows for fairly tightly-repeated IR codes, the control boxes themselves don’t always respond reliably if you send codes too quickly after each other. Empirically I  found that a delay of about 175 milliseconds between codes works reasonably well.

The server can accept multiple ircode-dictionaries in one POST; the main limitation is that there isn’t much RAM (a whopping 2K!) on an Arduino so the maximum POST size my code can accept isn’t much. At the moment I have it defined as 450 characters. Still, that’s enough to allow you to do some interesting things. Only the first ircode-dictionary has to have the protocol and the bits specified; those values become the default for subsequent ircode-dictionaries in the same POST. Similarly for delay, if it’s been specified.

Given all that, we can make the LEDs rotate through RED GREEN and BLUE like this:

{ "codes" : [
    { "code": 16718565, 
      "protocol": "NEC", "bits": 32 },
    { "code": 16751205 },
    { "code": 16753245 } ],
  "repeat": 10 }

I have to be careful with the “repeat” because the Arduino server is non-responsive to network requests during the execution of all this. I usually try to limit the “repeat” value to something that will cycle in 5-10 seconds at most. Longer cycle programming is implemented by looping over multiple POST operations rather than using “repeat” to make the server do it directly.

I wrote a python script using the Requests library to send POST requests to my Arduino.  The Requests library makes it dead-simple to do stuff like this; here’s the key portions of my python code for driving my Arduino (beware of / apologies for wordpress messing up indentation and line breaks):

def sendcodes(server, code_dicts, repn=0):
    """POST code dictionaries to the server."""
    d = {"codes": code_dicts}
    if repn > 0:
        d["repeat"] = repn
    s = json.dumps(d, separators=(',', ':'))
    if server == "debug":
        print("Would send: [{}]\n".format(s))

I squeezed out extra spaces using the “separators” argument in the JSON conversion, just because of space limitations on the Arduino and thus not wanting to waste any of the limitation on unnecessary white space. For the same reason I only send the “repeat” element if the repeat is more than just one.

I then built up a whole bunch of library routines to do various effects. So far I’ve written:

  • redgreen() alternates the roof between RED and GREEN at five second intervals
  • rotate() picks eight colors at random (different each time it is called) and an interval at random (also different each time it is called) and rotates the lights through those colors. The shortest interval is 10 seconds and the longest is four minutes.
  • heartbeat() pulses the lights on and off in what I can only describe as a “thump thump” pattern meant to be reminiscent of a heartbeat. Obviously the default color for this one is RED but the display can heartbeat() in any color.
  • rapid() cycles the lights as fast as possible through a set of colors. Used sparingly; this is pretty distracting (but amusing).
  • seizure() is really a special case of rapid and just flashes between two colors, or one color and off, rapidly.

Given all that the main loop driving the display that everyone is seeing these days looks more or less like this:

def run_normal_program():
    while True:
        seizure(c=C.PINK4, c2=C.BLUE)
        seizure(c=C.PINK4, c2=C.GREEN)
        seizure(c=C.RED, c2=C.GREEN)
        ... etc ...

Most of the special effects routines run for about a minute or so. They are eye-catching but it’s just overkill if they run for very long. The rotate() routine is where the display ends up spending the majority of its time. Going through the eight colors takes 80 seconds when the random color duration chosen is 10 seconds (the shortest duration it will pick) but takes 32 minutes when the color duration is four minutes. So on average the house is in this mode for 15 minutes at a time and therefore it spends the majority of its time in this somewhat-sedate display mode punctuated by occasional blinking craziness. Whether this whole concept is cool, impressive, or hopelessly tacky is in the eye of the beholder! I have to admit that I do get a kick out of receiving text messages:  hey did I just see your house from Mopac? (and many other locations around town where the house display is quite visible).

This picture was taken from 4.8 miles away:


One problem I ran into relates to the POWER command. There is no command to turn the strands ON and OFF; there is just the POWER command which toggles the on/off state. This is potentially a big problem because if one strand ever misses a code for any reason at all then it will be out of sync. They could also get out of sync if some of them lose power while the others do not (as happened recently when a contractor working on something else temporarily unplugged one section of the display). Because of the toggle functionality I really have no way to know for sure whether sending a POWER command is turning it on or off.

Just to be sure there was no hidden explicit ON or OFF IR command I wrote a program allowing me to send “every possible” command to the boxes. Under the normal NEC IR protocol, which these devices are using for every other code on the remote control, there are only 256 possible codes that can be sent. So I tried them all and did not find any additional POWER ON or POWER OFF codes.

This is a pretty common problem in the multimedia control system world and the way it is usually solved involves additional sensors on the target device – to either sense its power draw in one way or another or to sense some other attribute that reveals whether the device is currently on or off. I certainly could have done that here with a photosensor, or even a direct voltage sense on the output of the control box, but that would require bringing another set of 9 wires back to my Arduino controller.

Instead, I never turn the boxes off; I never send the POWER command. I programmed one of the DIY codes (more on this in a moment) to be zero RED, zero GREEN, and zero BLUE — in other words, to be OFF. Instead of turning the LED strands off with the POWER command, I accomplish virtually the same thing by setting them to display the “color” DIY number 6 which I’ve programmed to be “off”.

If there is a power glitch the units always start up in the ON state. So that’s consistent with my control methodology; the units are simply never turned off and if they reboot because of a power failure they start up in the ON state by default.

The controller boxes remember the last setting of certain parameters for each color button that was on the remote. For example if you send the RED command and then send a few DIMMER commands, you will get a lower-output RED color on the LED strands. If you switch to GREEN, the GREEN will be full intensity (assuming you also haven’t dimmed it before), and when you switch back to RED the RED will be dimmed as it was before.

In other words, each color setting – each of RED, GREEN, BLUE, but also all the R1..R4, G1..G4, etc colors – each one of those separately remembers its own brightness setting.

The DIY codes work in a similar fashion, except instead of responding to the DIMMER and BRIGHTER commands they respond to the RED_UP, RED_DOWN, GREEN_UP, GREEN_DOWN, and BLUE_UP, BLUE_DOWN commands. There are six supported DIY code buttons, each one remembers its own separate value of how much RED, GREEN, and BLUE to power. I’m not entirely sure exactly how many levels of each of R/G/B the box can produce, but empirically I’ve determined it is no more than 32 levels (for each color separately). Thus to “program” the DIY color number 6 to be off all I did was select it (send DIY6), then send 32 RED_DOWN commands, 32 GREEN_DOWN commands, and 32 BLUE_DOWN commands. After doing that, any time I send DIY6 the strands all turn “off” (provide zero power to RED, GREEN, and BLUE).

For my purposes I want all of the ordinary colors to be programmed at maximum intensity, and as already described I need to set up DIY6 to be a surrogate for “off”. It’s time consuming to send all the codes to set this up, so I don’t want to do it more often than necessary. I have a separate command I wrote that will send all these configuration codes when needed. After it has been done once it shouldn’t be necessary to do it again unless we have to replace a controller box. Truth be told during debugging of this whole installation we blew a few boxes up (rain will punish all your waterproofing mistakes) and so it is handy to have the “reprogram everything” command available when needed.

Once I had a python program running that was driving the LEDs with IR codes I was able to integrate some other fun things. For example I have a Big Red Button and connected it up so that it turns the display on and off with a simple press. I also have a web server visible only within my house network and I have a page on that server that can be used to control the lights. This means I can turn them on or off from my phone from anywhere in the house now which comes in handy sometimes, and I’m adding other features to that control page so I can put the lights into a specific pattern if I want to.

One thing I might do in the future is set up a web cam (so they can see the lights) and actually let my friends control some of the light effects over the internet!

Over the Top Circuit Analysis

I had access to an oscilloscope and decided it would be fun/interesting to look at some of the details of how the circuit itself was behaving. These pictures were obtained with an earlier version of the circuit that had R1 at 56Ω and eight IR emitters instead of R1 at 33Ω and nine emitters. As these measurements were all about the MOSFET gate behavior I don’t think those changes have any effect but I list them anyway in the name of Science and full disclosure.

First I just captured a trace of what the Arduino output looks like on pin3 when it is being modulated:


In this picture there is nothing attached to the Arduino output other than the oscilloscope probe. According to the scope the signal peaks (rings) at 6.36V and dips to -1.40V on the down transition. You always have to be careful with stuff like this because the oscilloscope probes could also be contributing to some of the effects, but my GUESS is that this is pretty close to the actual truth of what is going on.

Here’s what it looks like on a broader scale, in effect showing you the NEC IR encoding at work:


If you go look at the NEC protocol details you will appreciate this picture better. We’re seeing the initial burst (the very closely-spaced vertical traces at the start) and then we can see the zero and one bit values encoded by the different-duration gaps between subsequent (smaller) bursts. In fact you can clearly see the 8 zero bits (short gaps) being transmitted for the address (zero) and then the 8 one bits (long gaps) being transmitted for the inverted address (255), and if you cared to you could decode what the actual command (and inverted command) sent was in this trace.

Here’s what it looks like on a much smaller scale showing the details of the ringing on a downward transition:


At this scale we can start to see the chunkiness of the limitations of the scope sampling bandwidth.

Here is the corresponding waveform when this output is driving the MOSFET gate as shown in this circuit.


It’s maxing at 5.56V now and I didn’t have the scope set to explicitly read out the min but visual inspection shows the negative ringing is less than -1.0V (each vertical grid is 1V).

In this last picture the yellow trace is on the Arduino side of the resistor Rg and the blue trace is on the MOSFET gate input. We can see the difference between the Arduino output and the response of the gate which behaves somewhat like an RC circuit in this case:


I did have the scope set up to show minimum voltage in this picture so you can see the ringing on the yellow dives down to -0.64V in this case.

I was really curious to know what was going on with that “pause” in the rise of the MOSFET voltage … the plateaus that occur in the middle of the blue trace rise and fall. I did some googling and discovered the “Miller Plateau” and it’s cool to see it in reality here.

Everything of course is working exactly as one would (or should) expect here; I just thought it was interesting to see it in detail. That trace with the yellow (pin3 “as commanded”) and blue (MOSFET gate “as responding”) traces shows how the signal is getting slightly distorted by my circuit; however, the distortion clearly doesn’t matter both because it is relatively minor and (more importantly) because the way the IR protocol works the exact shape of this waveform doesn’t matter so long as the receiver recognizes the modulation of the highs and lows of the 38KHz signal, which it does (we know this because … the whole thing works!)

Future Directions

There’s lots of ways I could go with this. Expect more craziness next year but for this year I’m happy with what we’ve got working so far.

One idea is to recapture the idea of each strand being individually controllable and allow for some effects like a color that “rolls around the house” at strand granularity. It’s not entirely clear to me if this effect will be as good as that sounds, because of how the strands divide up around the roof perimeter and whether it would really have the visual effect desired. But it might be worth trying. A simpler version of this idea would be to break out the tower control from the rest of the house and allow for some multi-color effects that way. These sorts of ideas will, of course, require a completely different approach for powering the IR emitters; the simple circuit I’m using now won’t allow me to do any of those things.

People of course always ask for “sync the lights to some music”. The problem with that is the control boxes don’t respond very quickly to the IR commands. They really don’t respond quickly enough to enable any convincing music synchronization.

That observation leads to the next idea: building my own LED control boxes and getting rid of the whole idea of IR control. I’ve taken one of the LED control boxes apart (of course I have!) and it appears to be a fairly straightforward dimming control circuit that I’m guessing uses PWM and quite clearly uses MOSFETS to control the 110V that are sent down each of the RED, GREEN, and BLUE supply lines (there are two MOSFETS per line and I’m wondering if somehow they used the same 60V MOSFETS I have in pairs to control a 110V signal; I’m not really sure how this works yet and have more kitbashing and research to do on that). I’ll try not to electrocute myself while doing this research. If I can build my own LED controller then I can put each of the strands directly onto my network without the intermediary IR control connection and that will allow much faster and cooler effects.

Or, of course, I could just probably buy some different controllers that might already have network connections in them. But where’s the fun in that?

Well, that’s it — this is the longest post ever and if you are still reading it at this point let me say: Thank You and Merry Christmas!

*** Updates ***

12/08/2016: I added a second bt.tn button that puts the lights through one cycle of “crazy” mode: about ten minutes of blinking and color effects. This button was very popular at a recent party.



12/10/2016: Someone in the neighborhood left me this awesome comment. Thank you!


12/26/2016: I modified the circuit to give me independent control of the tower and the roof perimeter. I simply split the IR voltage control (Arduino pin 3) into two different AND gates (74HCT08). The other input to each AND gate is an “enable” line (two different enables). This now allows me to individually enable two different copies of the IR signal, so I can control just the tower, just the roof perimeter, or both at the same time.

The TTL specification for a “HIGH” voltage output level is 2.7V minimum. That’s too low to trigger the MOSFET “logic-level” gate input which requires 4.5V minimum. It turns out the 74HCT08 (quad-AND) chip I’m using will output at least 3.8V minimum (per the data sheet) which is better than 2.7V but still not enough. Therefore, to interface the TTL outputs to the MOSFET gate I added a TC427 MOSFET dual-driver chip (one 8-pin DIP contains two independent MOSFET drivers). These drivers accept TTL-spec inputs and convert them to “full supply voltage” outputs (sort of; see the data sheet for details as obviously it’s a bit more complex/subtle than that). These are also good chips to have in your toolkit because they do a better job of driving current quickly into the MOSFET gate to force a faster transition by charging the gate faster. That’s also another benefit of using these driver chips although it turns out to be not especially important in this particular application.

The whole thing looks like this schematically:

The 330Ω Rg resistor really should be taken out now, as the driver chip works perfectly well (best, arguably) if directly connected to the MOSFET gate input; I left it in place however because this was a last-minute retrofit/add-on and it was just easier to leave that part be for now.

I programmed one effect – the tower and roof exchanging red/green between themselves (tower red, perimeter green, then tower green, perimeter red). Expect more fun with this next year!

12/29/2016: Unfortunately a mechanical connection failure has disabled the tower, and I can’t safely get to it to fix it myself. So no more tower lights 🙁 … it’s all coming down after New Year’s anyway.

Nov 5 update on Christmas Light Project

Up until today I prototyped my circuit on a breadboard; today I moved it to a perf board and soldered everything up. It still works!

Here’s a shot of the perf board:


It’s just a reimplementation of the same circuit I had already breadboarded (and described in the prior post) except that I did go ahead and update Rg to 330Ω:


The eight infrared emitters will be remotely located out by each light strand I’m controlling. The long wires between those remote IR emitters and this board will be hooked up to the terminals as shown, generally with two wires connecting to all but the outer terminals. This is because each LED has two wires but one of them needs to be connected to the next LED in the series arrangement.

The GND goes to the Arduino ground as well as the ground of the external 12.6V power supply. The plus side of that power supply connects at the lower left and the signal from Arduino pin 3 which goes (via resistor Rg) to the MOSFET gate terminal connects at “G”.

The screw terminals I’m using come in two-terminal chunks but they can also snap together to form larger banks. They are very handy to have for projects like this.

Since this whole thing fit on one half of the perf board I can implement the second copy of this circuit on the other half in the same way.

I connected everything up and was happy to learn that my amateur soldering prowess didn’t screw anything up (and especially didn’t fry the MOSFET during soldering).


From a previous project I had some code implementing a simple JSON POST interface on an Arduino (with ethernet shield) allowing remote access to digital I/O. That code is up on github.

I took that code and modified it to accept POST requests of JSON to control sending IR codes using the IRRemote library.

The JSON it accepts looks like this:

{ "codes": [ ircode-dictionaries ], "repeat": n }

An ircode-dictionary looks like:

{ "code": 16718565, "bits": 32, "protocol": "NEC" }

The thing I’m controlling takes 32-bit IR codes via the NEC protocol; as I wrote earlier I determined this using the IRRemote library and an IR receiver/decoder in the usual way. The above code will make the LED string RED for example.

You can optionally add a “delay” element to an ircode-dictionary; it specifies a delay, in microseconds, to wait after sending the code. Although the NEC protocol allows for fairly tightly-repeated IR codes, the box I’m controlling doesn’t respond reliably unless you have about 150000usec (150 milliseconds) of delay between two consecutive IR commands. I haven’t tried to refine this number; I just know that 150 milliseconds works and 50 milliseconds doesn’t, so the true limit is presumably somewhere in between. I made the server supply a 150 millisecond delay by default unless you override that with the “delay” parameter.

You can specify multiple ircode-dictionaries in one POST; the main limitation is that there isn’t much ram (a whopping 2K!) on an Arduino so the maximum POST size my code can accept isn’t much. At the moment I have it defined as 350 characters. Still, that’s enough to allow you to do some interesting things. Only the first ircode-dictionary has to have the protocol and the bits specified; those values become the default for subsequent ircode-dictionaries in the same POST. Similarly for delay, if it’s been specified.

Given all that, we can make the LEDs rotate through RED GREEN and BLUE like this:

{ "codes" : [
    { "code": 16718565, 
      "protocol": "NEC", "bits": 32 },
    { "code": 16751205 },
    { "code": 16753245 } ],
  "repeat": 10 }

You have to be careful with the “repeat” because the Arduino server is non-responsive during the execution of all this. It’s probably best to set a “repeat” value that limits the cycle to 5-10 seconds at most (if you use the “repeat” at all even) and then use looping in your script or program driving the Arduino instead.

I wrote a python script using the Requests library to send POST requests to my Arduino.  The Requests library makes it dead-simple to do stuff like this; here’s the key portions of my python code for driving my Arduino (beware of / apologies for wordpress messing up indentation and line breaks):

def sendcodes(url, code_dicts, repn=1):
    topdict = {"codes": code_dicts}
    if repn > 1:
        topdict["repeat"] = repn
    js = json.dumps(topdict, 
                  separators=(',', ':'))
    result = requests.post(url, data=js)
    return result

# send NEC codes. Each argument should either be
# a simple code or a tuple: (code, delay)
def sendNEC(url, *codes, repn=1):
    a = []
    for x in codes:
            a.append({'code': x[0], 
                     'delay': x[1]})
        except TypeError:
            a.append({'code': x})
    return sendcodes(url, [{'protocol': 'NEC', 'bits': 32, **a[0]}] + a[1:], repn=repn)

I squeezed out extra spaces using the “separators” argument in the JSON conversion, just because of space limitations on the Arduino and thus not wanting to waste any of the limitation on unnecessary white space. For the same reason I only send the “repeat” element if the repeat is more than just one.

Here are some simple examples showing the LED colors changing under control of all this magic.

For the last one (“seizure”) I backed away far enough so the R/G/B LEDs could blend as they will when seen up on my house. The result looks a little bluish but I think that’s an artifact of the video. In any case I think my neighbors will enjoy that one.


While I’ve been working on electronics and software, we’ve also been installing the lights on the house. Don’t worry, I won’t actually light them up until after Thanksgiving, respecting proper tradition — but this year I need to prototype and check things out early.

Here’s a picture of some the LEDs running around one part of my roof line:


The LED strand is attached to the roof simply by magnets, as the fascia is metal and magnetic. This is going to make it easy to put up and take down each year, though storing it requires some finesse to prevent it from become a magnetic mess. Each magnet has a zip-tie attachment stuck onto it and then is zip-tied to the LED strand. At night this seems pretty bright, I’m looking forward to getting the whole project up and running soon!