Slow Communication - Ditch The Master-Slave?

I have a problem that has to do with speed. I have a robot that has a Baisic Stamp II model ‘e’ (BS2e), that communicates with an Arduino to get sensor information. I like the capabilities of the BS2e that the Arduino does not have, and vice versa for the Arduino, so that’s why I used two micros. Another reason why I used two in a master-slave configuration is because I thought that it would make my robot (mentally) faster. And the last reason why I did so is because I have NO IDEA how to interface an external A/D chip to the BS2e, and the Arduino is easy to use for A/D. So, this robot is actually a hacked Roomba Red vaccum robot, so to drive it, you must send it commands via serial, at select baud rates. So the BS2e is:
-communicating to the Roomba (receiving LOOTS of sensor data, and sending some commands)
-receiving servo position and IR data (the IR module is a GP2D12 from Sharp) from the Arduino
-making decisions based on sensor data
And the Arduino is:
-making calculations for panning the servo at a certain speed, and a certain angle
-reading the GP2D12 IR sensor, and doing the A/D conversion between every pulse to the servo (FYI this is a standard hobby servo)
-sending the data (the IR value which is a 3-digit #, and the current PWM width for the servo, which is a 4-digit #)
But this robot reacts to sensor input from the Arduino REALLLY slowly. An object has to be WELL ahead of the robot in order for it to see it, make the calculation, and turn in time. The code I made makes the BS2e look at the IR value when the servo is at one of the 5 (or so) positions. Once again, the BS2e knows the position of the servo because the Arduino sends the current pulse width. But the problem is, the BS2e isn’t fast enough for the Arduino, that is, it isn’t getting the IR data, and PWM data fast enough. By the time the BS2e polls the serial input from the Arduino for the data, the servo has usually already moved 1/4 of the turn! So, it rarely detects the obstacles in front of it. I REALLY don’t want to have to get an external A/D converter for the BS2e and try to molly-coddle it until it gives me the desired setup. So am I wasting my time by using the BS2e? But the thing is, I am really accustomed to the PBASIC language for the BS2e, and if I tried to make an equivalent program as complex as some of the ones I can make with the BS2e, in the code Arduino uses, it would take me weeks to figure it out. So what should I do? Is the Arduino fast enough to do all of the above that I listed at once? :-/

The Ardiuno environment is compiled C, an order of magnitude (or two or three) faster than the BASIC stamp.

The two have differences, but IMO the Arduino is a much better platform. Just bite the bullet and learn enough C to do it all on the Arduino.

-j

Ok. Here’s the code; I haven’t tested it yet, but I’ll test it tomorrow. Part of this code comes from the ‘Hacking Roomba’ website. I give partial credit to Tod E. Kurt for the code; I added onto it for the servo/IR sensor part.

/*
 * 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 servoPin = 3;
int irPin = 0;
int ledPin = 13;
char sensorbytes[10];
int irval;
int pulses; 

#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
  pinMode(servoPin, 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);
  }
  if(pulses > 1300 && pulses < 1500) {
    if(irval > 200) 
      spinRight();
      delay(1000);
  }
  else if(pulses > 1500 && pulses < 1700) {
    if(irval > 200)
      spinRight();
      delay(1000);
  }
  else if(pulses > 1700 && pulses < 1900) {
    if(irval > 200)
      spinRight();
      delay(1000);
  }
  else if(pulses > 1900 && pulses < 2100) {
    if(irval > 200)
      spinLeft();
      delay(1000);
  }
  else if(pulses > 2100 && pulses < 2300) {
    if(irval > 200)
      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() {
  readIr();
  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;
  }    
}
void readIr() {   // do the logic for the servo, and read the GP2D12 IR module                                      
  if(pulses >= 2300) {  
    pulses = 2300;
    do            // decrement 
    {
      pulses = pulses - 50;
      digitalWrite(servoPin, HIGH);
      delayMicroseconds(pulses);
      digitalWrite(servoPin, LOW);
      delay(20);
      irval = analogRead(irPin);
     } while(pulses >= 1300);
} 
  else if(pulses <= 1300) {  
    pulses = 1300;
      do          // increment 
      {
        pulses = pulses + 50;   
        digitalWrite(servoPin, HIGH);
        delayMicroseconds(pulses);
        digitalWrite(servoPin, LOW);
        delay(20);
        irval = analogRead(irPin); 
      } while(pulses <= 2300);
}
}

The Ardiuno environment is compiled C, an order of magnitude (or two or three) faster than the BASIC stamp.

I believe its actually closer to a hundred times faster.
The AVR does one instruction per clock cycle. The BASIC stamp does significantly less.

The Ardiuno environment is compiled C, an order of magnitude (or two or three) faster than the BASIC stamp.

I believe its actually closer to a hundred times faster.
The AVR does one instruction per clock cycle. The BASIC stamp does significantly less.

An order of maginitude faster is generally regarded as ten times faster; two orders of magnitude is 100 times faster; three orders of magnitude is 1000 times faster etc.

Andrew