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).



No comments:

Post a Comment