Monday, 30 September 2013

Shelf Lighting Project

In my first post I briefly discussed a bedroom shelf lighting project that I was working on.  I have now completed the programming, wiring and installation of all the electronics that control the lights, so it's time to share some insights with the world.

Shortly after my last post I ran into one final challenge, I fried both the Arudino Uno and the Digispark that I was using.  I never quite figured out how that happened, but I am pretty sure that I put 12V power to the 5V power rail somehow. I used silicone to hold various PCB together to reduce the overall size of the assembly, and I suspect that I was a little bit too conservative between the 12V board that ran the lights and the 5V hub that powered the sensors.  

When I went to fire it up the first time the PIR motion sensor/Photoresistor, night light combination worked properly, but the IR remote system that I just finished, didn't do a thing.  After double checking the wiring, I ripped everything apart again and started to troubleshoot.  

I proceed to un-comment all the Serial.write() commands that I had left in the code, but when I hit the upload button the dreaded avrdude stk500_getsync() not in sync resp=0x00 error flashed up in red in the debug window.  I followed all the instructions that I could find.  Nothing worked.

The Digispark had a similar problem.  The computer/IDE wouldn't recognize it when it was plugged in.  It wouldn't send commands via serial like it did before.  The power LED would turn on, but that's it.

I gave up and loaded the working sketches on to a spare set of micro controllers.  After double checking all the solder joints and testing for connectivity between every possible combination of 12V and 5V leads, I decided it was safe to plug it back in.  Luckily it worked just fine.

Here's the final sketch.


Video and pictures to follow tomorrow.

Thursday, 5 September 2013

Digispark IR Remote Receiver


Background (skip to solution for the meat and potatoes)

I am working on the last phases of a bedroom shelving project that I started years ago.  The wooden parts of the shelf have been finished for some time, but I am still working on the Arduino controlled lighting system.  The key features of the system are as follows:

  • Remote controlled
  • Customizable lighting programs (using the HSV color space)  
  • Motion sensing night light that only activates if the room is sufficiently dark

The initial prototype took about two days to build and code.  The PIR sensor, photo resistor combination worked well for the night light and I built a simple lighting program to show off to friends.  I ran into problems when I tried to integrate the remote control into the system though.  The interrupt subroutine from the IRremote library wasn't able to reliably decode the signal from the remote when the Arduino Uno was outputing six PWM signals.  Everything worked fine with five PWM signals, but things came to a grinding halt when that sixth analog write was uncommented.

I never really figured out what was causing the problem, but it must be related to how efficiently my code was processed by the 16MHz Atmega microcontrollers, as I tested both the Uno and the Mega.  I loaded the sketch onto my brand new ARM based Arduino Due and everything worked perfectly, but I couldn't justify wasting such a powerful piece of technology on some silly lights.  

Last year I backed the Digispark Kickstarter when I had a plan to use a few of the little chips for a project at work.  The work project fell through when I came up with a better idea, so I had a few spare microprocessors collecting dust in my drawer.  Naturally offloading the "sit and wait for input" task to a separate brain was the answer.

Solution

Figuring out how to use the Digispark was no simple task.  The documentation is rather limited and the simple hurdles like installing the IDE and downloading a program almost broke me due to my hatred of reading manuals.  

Once I had an LED blinking, a quick search brought up a the following web page:
http://www.ediy.com.my/index.php/blog/item/74-digispark-infrared-receiver

It's a very thorough explanation about how to decode NEC IR remotes.  I worked through the examples a few times to fully understand how the code worked.  I ran into one issue with my remote from Abra Electronics (the best Canadian supplier for hobby electronics) the first button output a 0 in the 8-bit command section of the signal, which was ignored later in the program.

I also had to make an addition to the code to handle the NEC repeat signal.  This confused me at first.  I will explain a few things that I learned /made up to justify my perception of the universe, in the process.

First thing, the IR receiver I had, and likely all IR receivers, inverts the IR signal being transmitted by the remote which basically means that we are analyzing the
the gaps in between the pulses instead of the pulses themselves.


This information is useful when trying to catch the repeat bit instead of a normal command.  The difference between the two is that the repeat signal has a 2.5 ms start bit whereas a regular command has a 4.5 ms start bit.  The following two diagrams compare the signal output from the remote control to the signal output from the IR Receiver.
Regular NEC Command and Corresponding IR Receiver Output

NEC Repeat Command and Corresponding IR Receiver Output

For more information about the NEC protocol check out the following site:
http://www.sbprojects.com/knowledge/ir/nec.php

My final Arduino code is shown below.  I used the DigiKeyboard library for trouble shooting the code.  I have commented all of the DigiKeyboard code out as it seems to cause a error when the code is compiled with I am using the latest version of the Digispark IDE (1.0.4) which has the ability to use the standard SoftwareSerial library, common to anyone who has worked with any other Arduino boards.


One thing I might note, Serial.write(key) might eliminate the whole switch-case block.  I didn't happen upon it until after I had soldered up the finished product.  I tried to update the code, but the bootloader decided to quit working and I couldn't figure out how to fix it in 20 min so I gave up.

Here are a couple of schematics of the final project (Fritzing is a beautiful thing).