RASPBERRY PI MODEL B 700Mhz; 512Mb RAMParrot AR.Drone QuadricopterXBee Explorer Dongle

iRobot RoombaA couple of days ago, I was digging around SparkFun.com looking for some parts for a small side project I’ve been working on. While I was there, I stumbled across the RooTooth – Bluetooth Wireless Roomba Connection. I’ve seen plenty of sites before that show you how to build your own Bluetooth device for communicating with the Roomba. But, I decided to go ahead and purchase one since I really didn’t have any kinds of plans for it anyways and didn’t really plan on spending a whole lot of time tinkering with my Roomba. Earlier today, I got a knock at my door. It was FedEx and they had my parts from SparkFun.com which included my Rootooth. Being more excited about getting the parts for my other project, I set the Rootooth to the side and got busy soldering in the parts for my project. About an hour ago, I decided to checkout the Rootooth and see what I could accomplish with it. After downloading and reading thru some documentation about communicating with the Roomba, I felt that I had 2 options. The first option would be to head over to Google and see how many different apps I could find that were available. The second option would be to fire up an IDE and write my own application. Of course, being the geek that I am, I went with option 2 and I’m now at a point that I would like to share the code with you.

Before I jump into showing you how to hookup the Rootooth to your Roomba and before jumping into any code, I need to first let you know that I have the 560 model Roomba. Having said that, I haven’t tested this application with any other model. So, things might change depending on what model you have. But, hopefully, this will still give you enough information to get you moving in the right direction. Let’s begin.

The first thing you will need to do is to connect your Rootooth to your Roomba. This is actually quite simple. First, you will need to remove the dust pan from the Roomba (again, I’m using the 560, so this step might not be required for other models). With the dust pan removed, you will need to pop off the grey cover from the rest of the Roomba. It’s just a big piece of plastic that has a few clips holding it down. With the dust pan removed, you can easily get a grasp of the cover. After you’ve removed the cover, go ahead and put the dust pan back in. On top of the Roomba, you will see a port just to the right side of where it says “DIRT DETECT”. This is where you will need to connect your Rootooth.

iRobot Roomba ROI Port

Once you have your Rootooth connected to your Roomba, you will need to pair it with your computer. To do that in Windows 7, you will need to go into Control Panel and click on “Add a device” under “Hardware and Sound”. If your Roomba is powered up and Bluetooth is enabled on your computer, your Rootooth should automatically appear. It will be listed as something like “FireFly-AD00″ as shown here.

Windows 7 Add Bluetooth Device

If the Rootooth appears in the window, select it and click the “Next” button. On the next page, select “Pair without using a code”. Windows will automatically install the drivers for you and will notify you in the system tray when that is complete. After you have added the Rootooth, go back into Control Panel > Hardware and Sound > Devices and Printers > Bluetooth Devices. There you should see the newly added FireFly-AD00. Right-click on the device and select Properties. Go to the Hardware tab and make a note of the port number that Windows assigned to the device. In my case, Windows assigned “COM5″ as the port number. This port will be very important later on. So, make sure you remember it.

At this point, you should have your Rootooth connected to Windows and are now ready for some coding. The first thing you will need to do is to create a new Windows Form Application. On the form, add a new Serial Port object, a combo box for listing the available ports, buttons to connect and disconnect from your Roomba, another combo box for listing your supported commands, a button for submitting your commands to your Roomba, and an optional output Richtextbox for displaying some feedback. For this example, I am only showing you how to play sounds from your Roomba, drive it straight forward, and turn left & right. You will have to implement other commands such as controlling the LEDs and working with the sensors. There are all kinds of other cool things you can do with your Roomba, but I’m keeping this tutorial simple and sticking with the basics. With that said, go ahead and add the following items to your list of commands.

Play Notes
Drive
Turn Left
Turn Right
Stop

You will need to click on the Serial Port and change the baud rate to “115200″. You can leave the rest of the settings as default. If you have everything on your form, it should look something like shown below. However, you won’t see anything in your  Richtextbox as shown here until you have ran each of the commands which we will get to in just a minute.

Roomba#

If so, you are ready to begin adding some code. Since it is getting late and I have other things to do, I’m not going to walk you thru every line of code in the app like I normally do. Instead, I’m just going to post all of the code here and it will be up to you to add all of the corresponding pieces to your application. For those of you that are lazy, you can download my entire Visual Studio project from http://www.prodigyproductionsllc.com/downloads/RoombaSharp.zip. But don’t run off just yet. Before you can use the app, there are still a couple of things you will need to do to get your Roomba ready for action. Since the Rootooth operates at a baud rate of 115200, you will need to tell your Roomba to do the same. To do that, you will need an app that can communicate with serial devices. Since I already had PuTTY installed, I decided to use it. When you first launch PuTTY, you will need to switch the Connection Type to “Serial”. Then, you will need to enter the port name you got earlier (mine was COM5). Change the Speed setting to “115200″ and click the “Open” button.

PuTTY Serial Configuration

When you click the “Open” button, a little bubble should appear in the lower-right corner of your screen telling you that a new device is attempting to connect over Bluetooth. Click that bubble and a window will appear asking for you to enter the pairing code for the device. If you’re working with the 550, try entering “1234″ as your pairing code and click the “Next” button. If you were able to connect successfully to your Rootooth & Roomba, you should see a window telling you “This device has been successfully added to this computer”. You should also see a blank black screen. The blank screen is your PuTTY window. With the PuTTY window selected, type “$$$” (3 dollar signs without the quotes) and press enter. This will put your Roomba into command mode and will illustrate that by returning “CMD” back to your screen. If you see “CMD”, type (again, without the quotes) “U,115k,N” and press enter. This will tell your Roomba that it too should operate at the 115200 baud rate. After you hit enter, it should reply back with “AOK”. If so, go ahead and close PuTTY, killing your session.

Before your new baud rate setting will take effect, you will need to restart your Roomba. To do that, press and hold the SPOT & DOCK buttons at the same time. You will need to hold them for about 10 seconds, until the power light turns off. When the power light goes out, release the buttons and you should hear a sound and your Roomba will immediately turn back on. Once your Roomba has restarted, you should be ready to use the application. When you run it, you will need to select the same port name you used above. With your correct port selected, click the “Connect” button. If everything worked accordingly, you should see the message “Roomba connected”. If you see that message, select any of the commands in the command list and click the “Send” button to execute that command.

That’s it! You should now have a C# application that allows you to communicate with your Roomba over Bluetooth. Make sure you come back here and tell me what kinds of cool things you do with your Roomba. And, until next time, HAPPY CODING!!!

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.IO.Ports;

namespace RoombaSharp
{
    public partial class Form1 : Form
    {
        public enum RoombaOpCode : byte
        {
            INVALID = 0,
            START = 128,    //0x80
            BAUD = 129,     //0x81
            CONTROL = 130,  //0x82
            SAFE = 131,     //0x83
            FULL = 132,     //0x84
            POWER = 133,    //0x85
            SPOT = 134,     //0x86
            CLEAN = 135,    //0x87
            MAX = 136,      //0x88
            DRIVE = 137,    //0x89
            MOTORS = 138,   //0x8A
            LEDS = 139,     //0x8B
            SONG = 140,     //0x8C
            PLAY = 141,     //0x8D
            SENSORS = 142,  //0x8E
            DOCK = 143      //0x8F
        }

        private StringBuilder recievedData = new StringBuilder();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            foreach (string portname in SerialPort.GetPortNames())
            {
                cmbCOMPort.Items.Add(portname);
            }
        }

        private void OpenPort_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = cmbCOMPort.Text;

            if (!serialPort1.IsOpen)
            {
                serialPort1.Open();
                if (serialPort1.IsOpen)
                    LogMessage("Roomba connected");
                else
                    LogMessage("Roomba could not connect");
            }
        }

        private void ClosePort_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.Close();
                LogMessage("Roomba disconnected");
            }
            else
            {
                LogMessage("Roomba was not connected");
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (serialPort1.IsOpen)
                serialPort1.Close();
        }

        private void SendData_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.Write(new byte[]{ (byte)RoombaOpCode.START }, 0, 1);
                serialPort1.BaseStream.Flush();
                serialPort1.Write(new byte[] { (byte)RoombaOpCode.CONTROL }, 0, 1);
                serialPort1.BaseStream.Flush();

                System.Threading.Thread.Sleep(20);

                switch (DataOut.Text)
                {
                    case "Play Notes":
                        LogMessage("Playing Notes");
                        PlayNotes();
                        break;
                    case "Drive":
                        LogMessage("Driving");
                        Drive(1, 0);
                        break;
                    case "Turn Left":
                        LogMessage("Turning Left");
                        Drive(1, 1);
                        break;
                    case "Turn Right":
                        LogMessage("Turning Right");
                        Drive(1, -1);
                        break;
                    case "Stop":
                        LogMessage("Stopping");
                        Drive(0, 0);
                        break;
                    default:
                        break;
                }
            }
        }

        private void LogMessage(string message)
        {
            OutputWindow.Text += (Environment.NewLine + message).Trim();
        }

        private void PlayNotes()
        {
            for (int i = 31; i <= 127; i++)
            {
                PlayNote(i);
                System.Threading.Thread.Sleep(20);
            }
        }

        private void PlayNote(int note)
        {
            byte[] cmd = { (byte)RoombaOpCode.SONG, 3, 1, (byte)note, (byte)10, (byte)RoombaOpCode.PLAY, 3 };
            serialPort1.Write(cmd, 0, cmd.Length);
        }

        private void Drive(int velocity, int radius)
        {
            byte[] cmd = { (byte)RoombaOpCode.DRIVE, (byte)velocity, (byte)(velocity & 0xff), (byte)radius, (byte)(radius & 0xff) };
            serialPort1.Write(cmd, 0, cmd.Length);
        }
    }
}

Download: RoombaSharp.zip (22KB)

If you enjoyed this post, please consider making a donation.

Related Posts

Tagged with:  

Leave a Reply