Quantcast
Viewing latest article 20
Browse Latest Browse All 33

Raspberry Pi IR blaster and Roomba IR codes

When I finally bought an iRobot vacuum cleaner, I went for the Roomba 620 which is the current entry model. This version doesn't come with any accessories like the "Virtual Walls" (infrared barriers), an infrared remote control, or handy features like scheduling.

However, all of the above ought in principle to be possible by transmitting infrared (IR) signals from a DIY circuit... or a Raspberry Pi? For example, with older model Roombas people have used LIRC and an IR Blaster to tell their Roomba to start cleaning by mimicking the remote control - with the computer handling the scheduling.

Image may be NSFW.
Clik here to view.
Raspberry Pi Infrared Blaster,
using a P2N2222A NPN transistor,
and two IR LEDs in series with 3.3V

Roomba InfraRed Signals

iRobot sell simple IR remote controls which cover the basic commands (like start cleaning) and even let you steer it. The IR codes are emitted 940nm using a form of pulse-width modulation (PWM), modulated with a carrier frequency around 38KHz. Each code consists of a sequence of eight bits, encoded as:
  • Bit 0 - 1ms on, 3 ms off
  • Bit 1 - 3ms on, 1 ms off
and terminated with ~4ms off. That means in total the code and the pause is about 36ms. The IR control codes are published in the iRobot Create Open Interface v2 (PDF), and see also my last blog post on recording in the Roomba IR codes.

Raspberry Pi IR Blaster

I recently setup an infrared receiver in my Raspberry Pi, but this time I need to hook up an infrared LED under GPIO control. And if you want to mimic a Roomba docking station, you would need three separate independently controllable IR LEDs.

According to the source code (see original pull request and the lirc_rpi homepage), the default Raspberry Pi LIRC settings use GPIO18 (pin 12) for input and GPIO17 (pin 11) for output:

/* set the default GPIO input pin */
static int gpio_in_pin = 18;
/* set the default GPIO output pin */
static int gpio_out_pin = 17;

So, too make life simple, I used GPIO17 (pin 11) to connect my IR transmitter. Since I didn't have any resistors handy I improvised and uses two IR LEDs in series and the 3.3V supply (pushing the LEDs a little over the rating but it works for now in my solder-free test rig).

LIRC Codes

Some kind soul posted a LIRC configuration for the Roomba Remote Control (dated Oct 2007), with codes for clean, spot, max, power, and pause. Here's a cut down version showing just the clean button (the most important button).

# Excerpt from a config file which was automatically generated
# using lirc-0.8.2(default) on Sun Oct 7 19:28:15 2007
#
# brand: iRobot
# model no. of remote control: Standard Roomba Remote
# devices being controlled by this remote: Roomba Discovery/400 Series
#

begin remote

name iRobot_Roomba
flags RAW_CODES|CONST_LENGTH
eps 30
aeps 100

ptrail 0
repeat 0 0
gap 91790

begin raw_codes

name clean
2831 886 972 2709 944 2711
943 2710 2743 893 958 2723
931 2722 927 19304 2811 897
954 2726 927 2726 927 2726
2747 889 966 2714 942 2710
941

end raw_codes

end remote

The LIRC Configuration File Format Technical Details tells us these numbers are in micro-seconds, so we'd expect to see patterns of 3000 (3ms) and 1000 (1ms) but what was measured were on average ~2740 and ~930 instead. Was the calibration slightly off?

We expect each code to send eight bits, each either 3ms on 1ms off or the other way round (then an off pause) which would be 15 numbers (16 if you include the final off). However, all the button recordings had 31 numbers so clearly this captured double singles - with a gap of about 19000 (or 19ms) in between.

$ sudo mv /etc/lirc/lircd.conf /etc/lirc/lircd_original.conf
$ wget http://lirc.sourceforge.net/remotes/irobot/Roomba
$ sudo mv Rooma /etc/lirc/lircd.conf
$ sudo modprobe lirc_rpi
$ sudo /etc/init.d/lirc start
[ ok ] Loading LIRC modules:.
[ ok ] Starting remote control daemon(s) : LIRC :.
$ irsend LIST """"
irsend: iRobot_Roomba

$ irsend send_once iRobot_Roomba CLEAN
(watch flash via IR camera!)

A single send didn't work. Four or five (in a quick loop) do. Range 4m+ (although harder to get the line of sight).

Generating a configuration file

Using this Python script I generated a complete set of Roomba IR codes for LIRC, based on the above example entry and the documented codes:

$ python make_roomba_lirc.py > Roomba_LIRC.conf
$ sudo cp Roomba_LIRC.conf /etc/lirc/lircd.conf
$ sudo /etc/init.d/lirc restart
[ ok ] Stopping remote control daemon(s): LIRC:.
[ ok ] Loading LIRC modules:.
[ ok ] Starting remote control daemon(s) : LIRC :.
$ irsend list iRobot_Roomba ""
irsend: 0000000000000001 left
irsend: 0000000000000002 forward
irsend: 0000000000000003 right
irsend: 0000000000000004 spot
irsend: 0000000000000005 maxdock
irsend: 0000000000000006 small
irsend: 0000000000000007 medium
irsend: 0000000000000008 largeclean
irsend: 0000000000000009 pause
irsend: 000000000000000a power
irsend: 000000000000000b forwardleft
irsend: 000000000000000c forwardright
irsend: 000000000000000d stop
irsend: 000000000000000e sendall
irsend: 000000000000000f seekdock
irsend: 0000000000000010 virtualwall

It isn't very easy, but pairs of commands like this worked to drive the Roomba:

$ irsend send_start iRobot_Roomba forward
$ irsend send_stop iRobot_Roomba ""
$ irsend send_start iRobot_Roomba forwardright
$ irsend send_stop iRobot_Roomba ""
$ irsend send_start iRobot_Roomba right
$ irsend send_stop iRobot_Roomba ""
$ irsend send_start iRobot_Roomba stop
$ irsend send_stop iRobot_Roomba ""

I can see why people have hooked this up to web interfaces to control their Roombas.

Anyway, with a careful positioning, and a cron job, I could use the Raspberry Pi IR blaster to automatically trigger the Roomba to clean the house on a rota. It would be an expensive way to do it, but I think the Raspberry Pi could also mimic a Roomba Virtual Wall as well.

Viewing latest article 20
Browse Latest Browse All 33

Trending Articles