Shop OBEX P1 Docs P2 Docs Learn Events
iRobot roomba 500 series C program — Parallax Forums

iRobot roomba 500 series C program

This is just a basic manual control program for the Roomba/Create 500 series robot. Control it with an Activity Board, using IR remote, and/or XBee.

I was testing a few of my Roomba 500 series robots that have not been used in a while, so I put together a PropGCC program using SimpleIDE and an Activity Board with the XBee, and an IR demodulator installed.

In IR mode you can use a remote control to drive it around, basic stuff, forward, backward, left and right turn, plus the all important STOP the robot.

In XBee mode, using an external terminal program, you can do the usual movement control, plus I have a 'crcharge' command that checks the battery voltage. The voltage was the important one, because I wanted to check the basic status of the battery.

I have one Roomba that works just fine, I have two that I am evaluating to see if I can make one fully functional. After that I will try to get one that has a manualy IR controlled, and XBee controlled using an Activity Board, to go deeper in using the Roomba 500 Open Interface (OI) specification commands.

Ray
/*
  crBad1_ab.c

  December 3,2016
  
  iRobot Roomba 500 series with Activity Board, XBee, and IR demodulator.
   
*/
#include "simpletools.h"
#include "simpletext.h"
#include "fdserial.h"
#include "sirc.h"

serial *xbee;
serial *create;

static volatile int highbyte,lowbyte;
static volatile float newbyte;

/* COGed Functions */
void irrem();

/*******************/

void menu();

/* Create control commands. */
static volatile int speed_right = 75;
static volatile int speed_left = 75;
static volatile int turn_left = 35;
static volatile int turn_right = 35;
static volatile int highbyte,lowbyte;
static volatile float newbyte;

void CRstop();
void CRfore();
void CRback();
void CRleft();
void CRrite();
void CRsafe();
void CRstart();

void BattChrg();

int main()
{
  // Add startup code here.
/*                     Rx  Tx     BAUD   */
  xbee = fdserial_open(11, 10, 0, 9600);
  pause(250);
  create = fdserial_open(13, 12, 0, 115200);
  pause(250);

  cog_run(irrem,128);
  
  /* XBee intro message. */  
  writeStr(xbee,"iRobot Roomba/Create Robot Control System.\n");
  menu();
  
  char inBuff[40];

 
  while(1)
  {
    // Add main loop code here.
    // Add main loop code here.
    writeStr(xbee,">");
    readStr(xbee,inBuff,40);
    if(!strcmp(inBuff, "help")) menu();
    else if(!strcmp(inBuff, "crstop")) CRstop();
    else if(!strcmp(inBuff, "crfore")) CRfore();
    else if(!strcmp(inBuff, "crback")) CRback();
    else if(!strcmp(inBuff, "crrite")) CRrite();
    else if(!strcmp(inBuff, "crleft")) CRleft();
    else if(!strcmp(inBuff, "crsafe")) CRsafe();
    else if(!strcmp(inBuff, "crstart")) CRstart();
    else if(!strcmp(inBuff, "crcharge"))
    {
      BattChrg();
      writeFloat(xbee,newbyte/1000);
      writeStr(xbee," Create Volts\n");
    }      
    else
    {
      writeLine(xbee,"Invalid Command");
    }        
  }  
}

/* COGed functions */
void irrem()
{
  
  int button = 0;  
  while(1)
  {

    button = sirc_button(9);
    if(button < 100) CRstop();
    {
    switch(button)
    {
      case 21:    // Pwr
        CRstop();  
        break;
      case 27:    // << 
        CRsafe();
        break;
      case 26:    // > 
        CRstart();
        break;
      case 16:    // Ch+ 
        CRfore();
        break;
      case 17:    // Ch- 
        CRback();
        break;
      case 18:    // Vol+
        CRrite();
        break;
      case 19:
        CRleft(); // Vol-
        break;
      
      //default: CRstop();
    }
    }    
    button = 0;      
  }  
}
 
/*********************************************/

/* Create commands */
void CRstop()
{
  fdserial_txChar(create,145);
  fdserial_txChar(create,0);
  fdserial_txChar(create,0);
  fdserial_txChar(create,0);
  fdserial_txChar(create,0);
}

void CRfore()
{
  fdserial_txChar(create,145);  
  fdserial_txChar(create,((speed_right)>>8)&0xFF);
  fdserial_txChar(create,((speed_right)&0xFF));
  fdserial_txChar(create,((speed_left)>>8)&0xFF);
  fdserial_txChar(create,((speed_left)&0xFF));
}

void CRback()
{
  fdserial_txChar(create,145);
  fdserial_txChar(create,((-speed_right)>>8)&0xFF);
  fdserial_txChar(create,((-speed_right)&0xFF));
  fdserial_txChar(create,((-speed_left)>>8)&0xFF);
  fdserial_txChar(create,((-speed_left)&0xFF));    
}

void CRleft()
{
  fdserial_txChar(create,145);  
  fdserial_txChar(create,((turn_right)>>8)&0xFF);
  fdserial_txChar(create,((turn_right)&0xFF));
  fdserial_txChar(create,((-turn_left)>>8)&0xFF);
  fdserial_txChar(create,((-turn_left)&0xFF));
}

void CRrite()
{
  fdserial_txChar(create,145);  
  fdserial_txChar(create,((-turn_right)>>8)&0xFF);
  fdserial_txChar(create,((-turn_right)&0xFF));
  fdserial_txChar(create,((turn_left)>>8)&0xFF);
  fdserial_txChar(create,((turn_left)&0xFF));
}

void CRsafe()
{
  fdserial_txChar(create,128);
  pause(400);
  fdserial_txChar(create,132);  
}

void CRstart()
{
  fdserial_txChar(create,128);
}        

void BattChrg()
{
  fdserial_txChar(create,142);
  fdserial_txChar(create,22);
  highbyte = fdserial_rxChar(create);
  pause(50);
  lowbyte = fdserial_rxChar(create);
  newbyte = ((highbyte << 8) + lowbyte);
}  
/*********************************************/


void menu()
{
  writeStr(xbee,"Menu -  help,   \n");
  writeStr(xbee,"crcharge, crstop, crfore, crback, crleft, crrite \n");
  writeStr(xbee,"crsafe, crstart, \n");
}  

Comments

  • Very cool Ray. I dumpster dove at an old company I worked at where someone had thrown away parts to a Roomba and I had a similar idea to yours to repurpose the parts. I don't have any Xbee devices yet but was considering to use either a Red Bear bluetooth module I have or the new WX ESP8266 WiFi Module with an Prop Activity board and use MQTT to communicate with the Activity Board.

    Are you using a XStick on the other end to communicate with your Roomba?

    Thanks for sharing.

    Cheers,

    Jon
  • Are you using a XStick on the other end to communicate with your Roomba?
    I am using an XBee USB Adapter Board. I connect up to my Windows 7 box, and I use the putty serial terminal program. All parts are purchased from Parallax.

    Bluetooth vs XBee, most of the common BT devices are only good for a ~ten foot distance. While the XBee, with the small antenna is good for up to sixty feet, indoors. Also I found the pairing requirement with BT a real PIA.

    A brief history, I purchased four Roomba 515 units at a Sams Club, back about five or six years ago. At that time their was no Activity Board or Raspberry Pi or , ..., etc available. Now the stuff that is available, you can just about attach the device to the top surface of the Roomba, and with a little cover of some sort, to protect the unit, you can do some cool things. Actually, I will be seeing whether you can really implement some real cool things with that setup.

    I am also considering doing a scratch build robot, maybe using my old RB5X, which I have stripped down to the chassis, but that discussion is for another thread.

    Ray

  • Duane DegnDuane Degn Posts: 10,588
    edited 2016-12-03 22:27
    I have a bunch of XBee modules myself and I think they're great but they sure are expensive compared to other wireless options.

    I've used the cheap ($3) HC-05 Bluetooth modules in a bunch of projects. I think these cheap Bluetooth modules are great if you're going to use an Android device. These devices will usually work without any special configuration at 9600 bps but I generally use 115200 bps in my projects. I haven't had any problems pairing the HC-05 with any of my Android devices. For some reason when I pair an HC-05 with my Windows 10 PC, it generates two com ports. I can then use one of these comports with Parallax Serial Terminal. I can't program the Propeller through the BT module but otherwise the wireless connection behaves a lot like a wired connection.

    The HC-05 modules can be either master or slave so you could use two of these devices for Prop to Prop communication.

    I'm not sure, but since the Roomba's hacker port is just a serial interface, I think it would be possible to control the Roomba with only the XBee or Bluetooth device connected to the Roomba. I don't think a microcontroller on the receiving end is a requirement. Of course it's probably a good idea to use some sort of brain on the Roomba so you can implement some sort of fail safe procedure if the wireless signal is lost.

    I also like the inexpensive nRF24L01+ modules. These modules often cost less than $2 each. The only reception issues I have with these devices occurs when a major appliance (refrigerator, oven, etc.) is positioned between the two units. While the HC-05 Bluetooth modules are just about as easy to use as the XBee modules, the nRF24L01+ modules require a driver to communicate with the device over a SPI connection.

    Here's a link to my Roomba project. I used a Propeller Quickstart board on on the Roomba and a Propeller Proto Board with a Playstation 2 controller as the remote. The various buttons on the PS2 controller would turn on the various motors on the Roomba.

    As I mentioned earlier, I think XBee modules work great but I just wish I hadn't spent so much money on XBee modules. I wasn't aware there were so many inexpensive alternatives when I started learning about microcontrollers.

  • @Duane, when I looked at your project, first thing that came to mind, how is the QS board being powered? After a closer look I noticed that you have, I think, a voltage divider setup to bring down ~14.4V -> 5.0V. I use an adjustable voltage regulator, in this case too bring down ~16.0V -> 9.0V.

    Some general observations:
    First, Roomba automated power down. If you take the robot off the charging station, the 'Clean' button, which is green, is in 'Start (128) mode', and fully charged, will go blank (no color) after five minutes. In this case you have to either press the "Clean' button to start it up or put it back on the charger, lift and carry.

    The next occurrence, of an automated power down, is when the robot is in the 'Safe (131)' or 'Full (132)' mode. The 'Clean' button is now no color, and the power down occurs in about an hour, give or take a few minutes.

    These are very important occurrences, because the Activity Board cannot communicate with the robot, the connection has been broken.

    Second, you always have to beware of battery power issues. In the OI mode, the 'Clean' button is blank, no color, so you really have no idea as to what the battery state is. I am considering adding a COG to check for inactivity, avoid a power down, and maybe three LEDs, green, yellow, and red. The code could check the battery state every four minutes, and turn on the appropriate LED. This could be a quick visual as to what the battery state is.

    Probably a better solution for this would be to have a voltage divider connected to the raw battery power connectors, and use the Activity Board ADC to get some raw readings of the battery state.

    As for the XBee, which is a peer to peer setup, a better solution would be to have Zigbee units. That way, I think in an easy to implement manner, you could have a master and multiple slaves setups. Right now if I were to have another robot with an XBee, I would have a signal sent out and the two robots would be reacting to the same command.

    The other major concern, besides battery power, is availability of usable RAM, you start to run out of programming space very quickly.

    Ray
  • Interesting problem showed up with my original Activity Board. It seems like the Board just quits, after a period of time.

    Today I was running the program to see when and if the Roomba does a power down while it is in the 'Safe' (131) mode. After the program ran for ~52 minutes, the green LEDs by the Activity Board power switch began to flicker and I could no longer communicate with the Activity Board. Is this a sign that the Activity Board is FAULTY or is going FAULTY?

    This board normally, when I turn it on, both the green LEDs by the power switch are on. Not sure if I have another working Activity Board stashed somewhere. I think the new boards are closer to $80, getting on the expensive side for what I am using it for.

    Ray
  • Ray,

    How do you have the Activity Board connected to the Roomba? Also, have you tried running the Activity Board without being connected to any other device? Perhaps something is pulling the A.B. down causing it to not power on.

  • I use the raw power connection, as high as 16V when fully charged, at the DIN socket that is connected to a small adjustable DC-DC regulator which is set at 9V which is plugged into the Activity Board via a barrel plug.

    This board has been used quite extensively on other projects, so I think that it has reached its usage potential. Some time back I noticed that when you set the power switch too the '1' setting, both the LEDs are on, only one is supposed to be on. The switch is compromised, but is that doing something weird to the board?

    Yes, I have had this board up and running with a different projects, and I did not notice any power outages at that time.

    I did do an experimental run where I had the power essentially coming from the USB socket, that is the power source when you are programming the board. The same outage problem occurred under those circumstances.

    Ray
  • I modified my Roomba a bit, and changed to a Propeller DNA-RTC board. The program below should allow for minimalist control.

    I removed the brushes and the springs in the drive wheel unit, the robot is now much lighter, and you get more travel time. The only problem now is the top face of the robot, there is no large blank flat surface, therefore making it somewhat difficult to attach boards and sensors.

    Since I have an XBee and IR units attached, you can control the robot with a remote control or via an XBee external terminal program, very basic stuff.

    Since I am using the Propeller DNA-RTC board, I will have to find the RTC program that I had developed for the board. I hope it is not lost, it was a pain to write, I would hate to have too do it over again. If I am successful in finding it, then I will have to start thinking about automating the robot. Yes, I think I have a Parallax compass somewhere, also some Pings, plus the Roomba 500 series uses the lighthouse units, maybe some kind navigation system for the robot?

    The DNA-RTC board has flash memory, does anybody have a C program for setting the flash memory up to be used like a RAM drive? If the size of the program is smaller than the program that is needed to use uSD device, maybe that would work out better.

    Ray
    /*
      cr_dnartc.c
    
      December 15, 2016
      This is the iRobot Roomba/Create Control System
      using the Propeller DNA-RTC Board and Parallax 
      devices where needed.
      
    */
    #include "simpletools.h"
    #include "simpletext.h"
    #include "fdserial.h"
    #include "sirc.h"
    
    serial *xbee;
    serial *create;
    
    void menu();
    
    /* Create control commands. */
    static volatile int speed_right = 100;
    static volatile int speed_left = 100;
    static volatile int turn_left = 50;
    static volatile int turn_right = 50;
    static volatile int highbyte,lowbyte;
    static volatile float newbyte;
    
    void CRstop();
    void CRfore();
    void CRback();
    void CRleft();
    void CRrite();
    
    void CRfull();
    void CRstart();
    
    void BattChrg();
    /***************************/
    
    /* COGed Functions */
    void irrem();
    void pwrmon();
    /***************************/
    
    int main()
    {
      // Add startup code here.
      high(16);  // Turn on green LED.
    /*                     Rx  Tx     BAUD   */
      xbee = fdserial_open(17, 18, 0, 9600);
      pause(250);
      create = fdserial_open(1, 0, 0, 115200);
      pause(250);
    
    /* Start up the COG functions. */  
      cog_run(irrem,128);
      pause(100);
      cog_run(pwrmon,128);
    /*******************************/
        
      char inBuff[40];
     
      while(1)
      {
        // Add main loop code here.
        /* You are now in XBee interactive mode. */
        writeStr(xbee,">");
        readStr(xbee,inBuff,40);
        if(!strcmp(inBuff, "help")) menu();
        else if(!strcmp(inBuff, "crstop")) CRstop();
        else if(!strcmp(inBuff, "crfore")) CRfore();
        else if(!strcmp(inBuff, "crback")) CRback();
        else if(!strcmp(inBuff, "crrite")) CRrite();
        else if(!strcmp(inBuff, "crleft")) CRleft();
    
        else if(!strcmp(inBuff, "crfull")) CRfull();
        else if(!strcmp(inBuff, "crstart")) CRstart();
        else if(!strcmp(inBuff, "crcharge"))
        {
          BattChrg();
          writeFloat(xbee,newbyte/1000);
          writeStr(xbee," Roomba/Create Volts\n");
        }
        else
        {
          writeLine(xbee,"Invalid Command");
        }    
      }  
    }
    
    /* COGed functions */
    /* IR remote control system. */
    void irrem()
    {
      while(1)
      {
        int button = sirc_button(2);
        switch(button)
        {
          /* Stop robot */
          case 21:    // Pwr
            CRstop();  
            break;
          /* Forward */
          case 16:    // Ch+ 
            CRfore();
            break;
          /* Backward */
          case 17:    // Ch- 
            CRback();
            break;
          /* Right */
          case 18:    // Vol+
            CRrite();
            break;
          /* Left */
          case 19:
            CRleft(); // Vol-
            break;
          /* Roomba/Create Full control mode */
          case 27:    // << 
            CRfull();
            break;
          /* Roomba/Create Start mode */
          case 26:    // > 
            CRstart();
            break;      
        }      
      }    
    }
    
    /* Check the batter4y state. */  
    void pwrmon()
    {
      CRfull();  // Put robot in full control mode.
      while(1)
      {
        BattChrg();
        if((newbyte/1000) >= 14.4) high(16);  //Green LED on.
        if((newbyte/1000) <= 14.3)  // Battery is less than 14.4 Volts.
        {
          low(16);  // Turn off green LED.
          high(19); // Turn on red LED.
        }
        pause(2000);      
      }    
    }  
    /*********************************************/
    
    /* Create commands */
    void CRstop()
    {
      fdserial_txChar(create,145);
      fdserial_txChar(create,0);
      fdserial_txChar(create,0);
      fdserial_txChar(create,0);
      fdserial_txChar(create,0);
    }
    
    void CRfore()
    {
      fdserial_txChar(create,145);  
      fdserial_txChar(create,((speed_right)>>8)&0xFF);
      fdserial_txChar(create,((speed_right)&0xFF));
      fdserial_txChar(create,((speed_left)>>8)&0xFF);
      fdserial_txChar(create,((speed_left)&0xFF));
    }
    
    void CRback()
    {
      fdserial_txChar(create,145);
      fdserial_txChar(create,((-speed_right)>>8)&0xFF);
      fdserial_txChar(create,((-speed_right)&0xFF));
      fdserial_txChar(create,((-speed_left)>>8)&0xFF);
      fdserial_txChar(create,((-speed_left)&0xFF));    
    }
    
    void CRleft()
    {
      fdserial_txChar(create,145);  
      fdserial_txChar(create,((turn_right)>>8)&0xFF);
      fdserial_txChar(create,((turn_right)&0xFF));
      fdserial_txChar(create,((-turn_left)>>8)&0xFF);
      fdserial_txChar(create,((-turn_left)&0xFF));
    }
    
    void CRrite()
    {
      fdserial_txChar(create,145);  
      fdserial_txChar(create,((-turn_right)>>8)&0xFF);
      fdserial_txChar(create,((-turn_right)&0xFF));
      fdserial_txChar(create,((turn_left)>>8)&0xFF);
      fdserial_txChar(create,((turn_left)&0xFF));
    }
    
    /* Puts Roomba/Create in full control mode.
       You now have control of all the sensors
       and robot functions.
    */
    void CRfull()
    {
      fdserial_txChar(create,128);
      pause(400);
      fdserial_txChar(create,132);  
    }
    
    /* Takes Roomba/Create out of Full or Safe mode. */
    void CRstart()
    {
      fdserial_txChar(create,128);
    }
    
    /* Check the battery voltage. */
    void BattChrg()
    {
      fdserial_txChar(create,142);
      fdserial_txChar(create,22);
      highbyte = fdserial_rxChar(create);
      pause(50);
      lowbyte = fdserial_rxChar(create);
      newbyte = ((highbyte << 8) + lowbyte);
    }  
    /*********************************************/
    
    
    
    void menu()
    {
      writeStr(xbee,"Menu -  help,   \n");
      writeStr(xbee,"crcharge, crstop, crfore, crback, crleft, crrite \n");
      writeStr(xbee,"crfull, crstart, \n");
    }
    
Sign In or Register to comment.