Friday, December 18, 2015

Spark Lamp Update

At the beginning of the year, I posted my Spark Lamp project. It worked fine most of the time but I noticed when I would get home from work and flip the light switch on the wall to turn the lamps on, it would take 10 to 15 seconds before the lights actually turned on. This really started to become an issue when Daylight Savings ended in November and it was dark out when I got home from work.
View post on imgur.com

Although I spent a lot of time on the original homemade optoisolator circuit, I knew it had to go. I asked on Reddit for an IC to detect when 120Vac is present and got some good responses. In my typical fashion, I decided to fix the problem using only components I had on hand. Due to this, I ran into some other issues that could have been avoided if I had gone down another route.

I wanted to use a real optoisolator, but did not have one on hand. My backup plan was a solid state relay, but I also didn't have one that worked at the required voltages, or fit into the chassis I was already using. So I was stuck with using a mechanical relay. I didn't think it would be an issue, but there are some annoyances. First off, you can hear the relay switching every time you flip the light switch. It's not much of an issue because it alerts you that it is actually working, and the relays that control the lamps are also mechanical, and you can hear them as well. The downside of this approach is the bouncing from the relay causes the interrupts on the Spark Core to fire a few times. I had to play some software tricks (which I'll describe later) to get around this issue.

I ended up wasting a lot of time replacing the old optoisolator with the new relay. I thought up a pretty smart way to reuse the old circuit and its connections, and in my rush, I ended up removing parts of that circuit by mistake. Once I realized the mistake, it was just easier to remove the entire old circuit and start fresh, than to go back to the old method. I also had to remove some of the plastic from the chassis to get the relay to fix nicely. I zip tied it into place so it shouldn't run away.

Removed some plastic around the old USB ports 

The relay squeezed into place

Once I assembled everything, I put it back in the bedroom and quickly tested it and everything seemed to be working fine. I completely installed everything and, that night, realized there was an issue with the individual buttons not working as expected. I debugged further and determined they only behaved this way when the light switch on the wall was off and the relay was off. I thought the problem was caused from installing all three inputs on adjacent pins, causing a weak short between them, so the next day I disassembled everything and separated the inputs so there was plenty of room between them on the Spark Core. I assembled everything again and realized this wasn't the cause of the issue.

I then took to debugging the Spark Core code with a lot of Serial.println()'s (isn't Arduino debugging great? I also experienced a long string of issues due to a USB cable with bad data connections, so keep that in mind when debugging a Spark Core with the included USB cable). Working through all of the states made me realize that when the light switch is off and you press a lamp switch, the relay interrupt is called (presumably from bouncing? I bet a capacitor on the pins would fix this, but I wasn't about to open the chassis again to solder some more). I ended up adding some rudimentary debouncing that really only ignores subsequent state changes for 5 runs though loop(). It's hacky, but the system works exactly like I expect, so I can't complain.

I also mentioned at the end of my last post that IFTTT support has been added to the Spark Core. I hardly use it, but I do have the IFTTT DO Button Today widget on my iPhone that allows me to easily switch the lights on remotely via wifi. It's a nice bonus feature.

Easily turn the lamps on and off