Software Serial

Hi. I need to do a Software Serial communication to the Roomba, as the resistor values between the hardware serial pins and the FT232 chip is to low to use with the Roomba. But the problem is that i need to make a communication at 19200? Is that possible with the Arduino and then SWread() SWwrite()?

Best Regards Thomas Jespersen

SoftSerial stops at 9600

Look at this: http://sundial.org/arduino/index.php/newsoftserial/

Then what can i do? As i can't use the hardware serial port, as the resistors between that and the FT232 is to low! Read this topic too, to see what i mean with "To low" http://www.robotreviews.com/chat/viewtopic.php?f=4&t=11269&p=63143

Stick a buffer between them and see if that helps.

A TTL buffer of some flavor would work, or run it through an inverter twice, or make a buffer out of some logic (AND, NAND, OR, etc) or go the long way around and use both sides of a MAX232 to go up to RS232 levels then back down on the same chip (a MAX232 is really just a quad inverter with different voltage levels on each side). Any of these would buffer the signal - I threw them all out in case you have one of the devices on hand.

-j

I have some HEX Inverters, NAND gates for sure, but how should that work?
Have you read the post on the Roomba Hacking forum?

I skimmed the thread over there.

What a buffer would do is provide the same logic signal, but provide more current to drive the receiver (which seems to be the issue). IIRC the roomba's output driver is weak and the Arduino is pulling the signal, so you feed the weak roomba signal to a buffer of some flavor which can then provide enough current to overcome the pullup/down on the arduino side.

If all you have is an inverter: take the weak signal, feed it to the input of an inverter, feed that inverter's output to another inverter (to uninvert it) and feed the second inverter's output to the receiver that isn't receiving. Symbolically, this would look something like

roomba TX --|>o--|>o-- arduino RX

-j

Thanks, i will try that!
But also, have you read the post about the code i’ve used (found in a Hacking Roomba Book)
This is the code, and it doesn’t work properly - as it just makes the Roomba go backwards!

int ddPin = 2;
int ledPin = 9;
char sensorbytes[10];
#define bumpright (sensorbytes[0] & 0x01)
#define bumpleft (sensorbytes[0] & 0x02)
void setup() {
  pinMode(ddPin, OUTPUT); // sets the pin as output
pinMode(ledPin, OUTPUT); // sets the pin as output
Serial.begin(57600);
digitalWrite(ledPin, HIGH); // say we're alive
// wake up the robot
digitalWrite(ddPin, LOW);
delay(100);
digitalWrite(ddPin, HIGH);
delay(2000);
// set up ROI to receive commands
Serial.print(128, BYTE); // START
delay(50);
Serial.print(130, BYTE); // CONTROL
delay(50);
digitalWrite(ledPin, LOW); // say we've finished setup
}
void loop() {
digitalWrite(ledPin, HIGH); // say we're starting loop
updateSensors();
digitalWrite(ledPin, LOW); // say we're after updateSensors
if( bumpleft ) {
spinRight();
delay(1000); // spinning @ 200 for 1 sec == ~90 degrees
}
else if( bumpright ) {
spinLeft();
delay(1000);
}
goBackward();
}
void goForward() {
char c[] = {137, 0x00,0xc8, 0x80,0x00}; // 0x00c8 == 200
Serial.print( c );
}
void goBackward() {
char c[] = {137, 0xff,0x38, 0x80,0x00}; // 0xff38 == -200
Serial.print( c );
}
void spinLeft() {
char c[] = {137, 0x00,0xc8, 0x00,0x01};
Serial.print( c );
}
void spinRight() {
char c[] = {137, 0x00,0xc8, 0xff,0xff};
Serial.print( c );
}

void updateSensors() {
Serial.print(142, BYTE);
Serial.print(1, BYTE); // sensor packet 1, 10 bytes
delay(100); // wait for sensors
char i = 0;
while( Serial.available() ) {
int c = serialRead();
if( c==-1 ) { // error
for( int i=0; i<5; i ++ ) { // blink 5 times on error
digitalWrite(ledPin, HIGH); delay(50);
digitalWrite(ledPin, LOW); delay(50);
}
}
sensorbytes[i++] = c;
}
}

sorry, I don't know anything about roombas. I was trying to contribute to the "serial communication" part of the problem, as I've had to deal with a few of those problems myself...

-j

I have some good news!
I’ve got the Arduino Duemillanove board to control and recieve sensor data from the Roomba.
I have tried with and without a buffer (2x Inverter) - and it works, also without!
The problem with the Arduino was the code, it was wrong…

So it is working now, without any modifications to anything, just connected directly to the hardware TX and RX lines on the Arduino.

Here is the working code:

/*
 * RoombaBumpTurn 
 * --------------
 * Implement the RoombaComm BumpTurn program in Arduino
 * A simple algorithm that allows the Roomba to drive around 
 * and avoid obstacles.
 * 
 * Arduino pin 0 (RX) is connected to Roomba TXD
 * Arduino pin 1 (TX) is connected to Roomba RXD
 * Arduino pin 2      is conencted to Roomba DD
 * 
 * Updated 20 November 2006
 * - changed Serial.prints() to use single print(v,BYTE) calls instead of 
 *    character arrays until Arduino settles on a style of raw byte arrays
 *
 * Created 1 August 2006
 * copyleft 2006 Tod E. Kurt <tod@todbot.com>
 * http://hackingroomba.com/
 */

int rxPin = 0;
int txPin = 1;
int ddPin = 2;
int ledPin = 13;
char sensorbytes[10];

#define bumpright (sensorbytes[0] & 0x01)
#define bumpleft  (sensorbytes[0] & 0x02)

void setup() {
//  pinMode(txPin,  OUTPUT);
  pinMode(ddPin,  OUTPUT);   // sets the pins as output
  pinMode(ledPin, OUTPUT);   // sets the pins as output
  Serial.begin(57600);

  digitalWrite(ledPin, HIGH); // say we're alive

  // wake up the robot
  digitalWrite(ddPin, HIGH);
  delay(100);
  digitalWrite(ddPin, LOW);
  delay(500);
  digitalWrite(ddPin, HIGH);
  delay(2000);
  // set up ROI to receive commands  
  Serial.print(128, BYTE);  // START
  delay(50);
  Serial.print(130, BYTE);  // CONTROL
  delay(50);
  digitalWrite(ledPin, LOW);  // say we've finished setup
}

void loop() {
  digitalWrite(ledPin, HIGH); // say we're starting loop
  updateSensors();
  digitalWrite(ledPin, LOW);  // say we're after updateSensors
  if(bumpleft) {
    spinRight();
    delay(1000);
  }
  else if(bumpright) {
    spinLeft();
    delay(1000);
  }
  goForward();
}

void goForward() {
  Serial.print(137, BYTE);   // DRIVE
  Serial.print(0x00,BYTE);   // 0x00c8 == 200
  Serial.print(0xc8,BYTE);
  Serial.print(0x80,BYTE);
  Serial.print(0x00,BYTE);
}
void goBackward() {
  Serial.print(137, BYTE);   // DRIVE
  Serial.print(0xff,BYTE);   // 0xff38 == -200
  Serial.print(0x38,BYTE);
  Serial.print(0x80,BYTE);
  Serial.print(0x00,BYTE);
}
void spinLeft() {
  Serial.print(137, BYTE);   // DRIVE
  Serial.print(0x00,BYTE);   // 0x00c8 == 200
  Serial.print(0xc8,BYTE);
  Serial.print(0x00,BYTE);
  Serial.print(0x01,BYTE);   // 0x0001 == spin left
}
void spinRight() {
  Serial.print(137, BYTE);   // DRIVE
  Serial.print(0x00,BYTE);   // 0x00c8 == 200
  Serial.print(0xc8,BYTE);
  Serial.print(0xff,BYTE);
  Serial.print(0xff,BYTE);   // 0xffff == -1 == spin right
}
void updateSensors() {
  Serial.print(142, BYTE);
  Serial.print(1,   BYTE);  // sensor packet 1, 10 bytes
  delay(100); // wait for sensors 
  char i = 0;
  while(Serial.available()) {
    int c = Serial.read();
    if( c==-1 ) {
      for( int i=0; i<5; i ++ ) {   // say we had an error via the LED
        digitalWrite(ledPin, HIGH); 
        delay(50);
        digitalWrite(ledPin, LOW);  
        delay(50);
      }
    }
    sensorbytes[i++] = c;
  }    
}

Then what can i do? As i can't use the hardware serial port, as the resistors between that and the FT232 is to low!

The point was to use NewSoftSerial as a replacement for SoftwareSerial because it has better features and can run at higher speeds including 19200. You would then use this for your serial connection to the Roomba (on whatever digital pins you want except 0 & 1), completely avoiding the built-in UART that's connected to the FTDI chip.

As I said, i got it working, but i need to unplug it from the computer every time. So it would be nice to know how to do the NewSoftSerial at 19200!

I've found this page: http://sundial.org/arduino/?page_id=61 and downloaded the library. Then i changed the code so it uses that library instead of the original Hardware Serial, and it works at the 57600 baud rate!

If you're not already using the newly released arduino-0014, then you should. Particularly if you're using the OSX version as it fixes some nasty bugs that affect NewSoftSerial and other things. We worked around the bugs in NewSoftSerial for 0012 & 0013, but using 0014 would build better code.