Monthly Archives: August 2012

Arduino Infrared Communications Link

I wanted a simple mechanism that would allow me to send data to some of my Arduino  (http://www.arduino.cc/) projects – I have a scrolling LED matrix display where I want to update the text message without having to hook up a keyboard and I wanted to be able to do this cheaply. Browsing through the web-site of a local electronics store gave me the idea of using infrared (IR) light – I could buy an IR LED and an NPN photo-transistor for a couple of dollars. I didn’t have a complete data sheet for the IR LED, only the information that it emitted light at 840 nm, outside of the range of visible light.

You can buy specialized IR receivers that are used in remote controls for televisions and other consumer electronics; these devices only pass through signals that are modulated on a 38.5 kHz carrier wave for purpose of minimizing interference from IR light from indoor lighting and the sun – it is extremely unlikely that a natural source of light would be modulated. Of course to use these specialized receivers, you need to transmit your signal on a 38.5 kHz carrier wave. Unfortunately the electronics store did not stock the specialized IR receivers and I would have to make do with the the simple IR photo-transistor they stocked.

My plan was to to connect two Arduinos together using a serial interface but instead of using copper wire to connect the transmit pin of one Arduino to the receive pin of the other, I would use IR light. I designed and prototyped the circuit below one January evening and I was excited to see that my receiving Arduino successfully echoed the “Hello world” message the other Arduino was transmitting.

I recorded the schematic of this circuit in my notebook and moved onto some projects. Eight months later I thought I should finish this project and write a communications protocol to ensure the successful transmission of uncorrupted data. The first step was to find the parts and breadboard the circuit, to start where I left off. Below is the schematic, prettied up by drawing it in Eagle CAD (http://www.cadsoftusa.com/) :

The photo below shows the breadboard with the two circuits. The Arduinos are out of the frame:

Breadboarded circuits, emitter on the left, detector on right

It didn’t work! I checked and rechecked my schematic against breadboard’s wiring and I couldn’t see anything wrong. At one point the the receiving Arduino did echo a “Hello world” message but only once. I was confident that the software was not the culprit – my background is software development and I knew the software logic was fairly simple. It had to be the hardware. But where to start? I know from my experience in debugging issues in software systems that you need to take a systematic approach. My only real hardware diagnostic tool was a $15 multimeter and my assumptions. I ran through the following investigation:

1. Both the IR LED and photo-transistor look identical; they are manufactured in a 5 mm clear dome packages, with a flat spot on the side of the casing to indicate the negative pin, i.e. the cathode in the case of the LED and the emitter in the case of the photo-transistor. Could I have mixed these components up? How could I tell? Both components were stored in their original labelled bags but I could have accidentally mixed them up when I tore the breadboard down six months ago. IR light is not in the range of the human eye and so I couldn’t be sure that my IR LED was really emitting light. I recalled that digital cameras can detect the wavelength of IR LEDs and when I looked at the view screen of my Sony Cybershot pointed at the breadboard, I saw the IR LED glowing with a bright purple colour. Okay, I had the correct components.(You can try this yourself – take your TV remote control and flash it towards your cell-phone or digital camera – you should see flashes of light in the view screen.)

2. Was my photo-transistor working properly? Could I have inadvertently burned it out? I connected the leads of the photo-transistor to the multimeter and selected the ohm-meter range. The photo-transistor showed a low resistance, even though I had not pointed the IR LED at it. This was my problem – I had somehow through my careless handling shorted out the photo-transistor. I covered the photo-transistor with my hand and suddenly the multimeter showed infinite resistance – the photo-transistor was working! Could I have transcribed the circuit incorrectly in my notebook?

Looking again at my notebook, I saw that the date I recorded the schematic was January 7th, 2012. I likely had created the circuit after work, after the sun had already set during the short winter days. I realized that I was trying to recreate this circuit during a bright summer morning, when I have a large IR light source shining through my window. I replaced the photo-transistor in the circuit and shielded the IR LED and photo-transistor with my cupped hand, and soon saw the “Hello world” message being successfully echoed on the serial monitor by the receiving Arduino. I made a shield out of heat-shrink tubing to block out the ambient light between the IR components and the circuit continued to communicate without my manual intervention. Below is the shielded version of the IR communications link:

For now I am going to use the heat-shrink tubing as my solution to reduce IR interference.

The code for the transmitter is shown below. I am using an ATTiny85 chip and the SoftwareSerial library with the Arduino 1.0.1 IDE:

/*
  ATTiny85_SerialDisplay
  
  Board: ATTiny85 (internal 8MHz clock)
 
 */

#include <SoftwareSerial.h>

#define rxPin 3  // DIP pin #2
#define txPin 4  // DIP pin #3

SoftwareSerial displayPort(rxPin, txPin); // Rx, Tx

void setup()  {

  // set the data rate for the SoftwareSerial port
  displayPort.begin(1200);
  delay(200);
}

void loop() 
{ 
  displayPort.println("Hello");
  delay(2000);  
}

The code for the IR receiver simply listens for a character from one serial port and echoes it to another:

/*
  Program: SerialReader
  
  Board: Arduino Uno
  Purpose: Reads from one serial port and outputs to another.
  
 */

#include <SoftwareSerial.h>

#define rxPin 2
#define txPin 3

// set up a new serial port
SoftwareSerial inputPort =  SoftwareSerial(rxPin, txPin, false);

void setup()  {
  // set the data rate for the SoftwareSerial port
  inputPort.begin(1200);
  Serial.begin(9600);
  Serial.println("nStarting to listen...n");
  delay(200);
}

void loop() 
{
  if (inputPort.available())
  {
    Serial.print((char)inputPort.read());
  }
}

Next to design the communications protocol…