jump to navigation

Arduino + iRobot Infrared Communication January 18, 2009

Posted by adrianlombard in arduino.
Tags: , , ,
trackback

Making the Arduino talk to the iRobot can be a bit tricky.  There isn’t really too much information out there on how to accomplish.  Fortunately, the iRobot IR operates quite similarly to some other projects that already exist out there.  What this project will allow you to do is use the Arduino as a remote control for the iRobot, letting you use your own commands to control it.  Now for the technical bits…

IR operates on a 38kHz carrier frequency.  If you want to send the signal ON, you modulate it 38,000 times per second between 0 and 1.  For OFF, you leave it be.  The bits 1 & 0 are encoded as follows:

data bit 1: 3ms ON, 1ms OFF
data bit 0: 1ms ON, 3ms OFF

The iRobot uses 8bit (byte) instructions, or sometimes 16bit (word) instructions.  The iRobot Create Open Interface Manual has a list of all the instructions you can send the iRobot.  You can find more info and work that’s been done for iRobot and IR using a PIC16F690 here.

Now for the Arduino bits.  Attach an IR LED emitter to a pin of your choice, I chose 9 on my trusty Arduino Mini 04.  The choice of IR LEDs is important.  After testing out a few types, a combination of 2 proves to work the best.  Choose an LED with a wide, short distance range, like 70deg, and then another with a narrower but longer beam, around 30deg.  Using these side by side gets a wide peripheral range while also extending the transmission distance.  I didn’t bother using a resistor in series.  I checked the current with an ammeter, and found I only got out about 15mA when pulsing the IR LEDs.  Holding the signal high with digitalWrite() will potentially destroy your LED, so don’t do that.

That’s it for hardware.  On to software…

I mashed up some code I found around the web.  Kudos to Mark Ivey, he’s done most of the work for us with his Universal Remote Arduino project. I’ve modified a bunch of the code to accommodate the IR spec for the iRobot. Here it is:

int IR_PIN = 9;
int led_pin = 13;
int bin_1 = 3000;	//Binary 1 threshold (Microseconds)
int bin_0 = 1000;	//Binary 0 threshold (Microseconds)

#define BIT_IS_SET(i, bits)  (1 << i & bits)  

const int period = 26;        // this is the period of 38kHz, in microseconds
const int PULSE_WIDTH = 10;   // time between pulses, in microseconds 

// some basic codes taken out of the manual:
const int SPOT = 132;
const int FORWARD = 130;
const int LEFT = 129;
const int RIGHT = 131;

void setup() {
  pinMode(led_pin, OUTPUT);
  pinMode(IR_PIN, OUTPUT);
  digitalWrite(led_pin, LOW);
  digitalWrite(IR_PIN, LOW);
  Serial.begin(9600);
}

void loop() {

  // continually sends the LEFT command:
  send_byte(LEFT);

  // put your own commands here

}

// oscillates at 38kHz to write "ON"
void on(int time) {

  for(time = time/period; time > 0; --time) {
    digitalWrite(IR_PIN, HIGH);
    delayMicroseconds(PULSE_WIDTH);
    digitalWrite(IR_PIN, LOW);
    delayMicroseconds(PULSE_WIDTH);
  }
}

// just write pin low to write "OFF"
void off(int time) {
    digitalWrite(IR_PIN, LOW);
    delayMicroseconds(time);
}

// write a binary 1
void WriteOne() {
  on(bin_1);    // on for 3ms
  off(bin_0);   // off for 1ms
}

// write a binary 0
void WriteZero() {
  on(bin_0);    // on for 1ms
  off(bin_1);   // off for 3ms
}

// Send a byte over the IR LED
void send_byte(int bits) {
  for (int i = 7; i >= 0; i--)
  {
    if (BIT_IS_SET(i, bits)) {
      WriteOne();
    } else {
      WriteZero();
    }
  }
  delay(4);      // leave 4ms at the end of the instruction
}

Now to test that your instructions actually work, turn on the iRobot Create and turn on the programmer switch, then hit Reset.  This puts it in debug mode.  If you point the remote at it and hit a button, it beeps in the binary sequence of that button.  Now point your IR LEDs at the iRobot to test it out.  You should hear some beeping!  If you suspect it’s your IR LEDs, point them up to a webcam or video camera, you should be able to see the IR light this way.

To do some more debugging, it’s useful to have an IR receiver hooked up on another board and using the serial connection.  Buy this $10 breakout board from Sparkfun, and use the code from the Arduino playground.  To make matters easy, copy and paste the data you get from the Serial monitor into Excel or a spreasheet app.  You can use an equation to subtract the values two cells up from the current cell to get the difference in timing.  You should be seeing values around 3000 and 1000, which correspond to 3ms and 1ms (values are in microseconds).

Enjoy!

Advertisements

Comments»

1. Home Easy -duino « Notes from a small field - February 2, 2009

[…] Building a Universal Remote with an Arduino […]

adrianlombard - May 28, 2010

please update links to http://www.adrianlombard.com, cheers

2. dougsko - February 23, 2009

How exactly did you come up with your PULSE_WIDTH variable? I’m trying to modulate a signal at 36kHz, and have the period figured out to be about 28us, but I’m not sure what the PULSE_WIDTH would be or how to systematically come up with this number. Just for the record, I’m trying to emulate the RC5 protocol as defined here, http://users.telenet.be/davshomepage/rc5.htm.

adrianlombard - February 23, 2009

Good question. This variable is discovered by using an oscilloscope. It should really be called “wait time”. You can measure the width between pulses with the oscilloscope to find the desired wait time for your IR signal. It is hard to calculate because the Arduino takes a few microseconds to carry out the digitalwrite() function. Therefore you can experiment with your wait times by incrementing/decrementing until it works. It is easiest to see it on an osciloscope, by comparing your Arduino’s signal against a real RC5 to see if it is stretching out or squishing the command.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: