Shop OBEX P1 Docs P2 Docs Learn Events
Serial Communication - Too Slow?? — Parallax Forums

Serial Communication - Too Slow??

NoBo780NoBo780 Posts: 94
edited 2008-03-03 15:38 in BASIC Stamp
I have a relatively sophisticated setup with a BS2e and an Arduino (ATmega168). The BS2e is communicating to a hacked Roomba, while receiving data from the Arduino regarding servo position, and readings from an IR sensor, and then making decisions based on the data. The robot that I have put together with this setup, so far, is extremely (mentally) slow. The BS2e can't catch up, it seems, to obtain the servo and IR sensor data, fast enough so that it get get the full resolution of the revolutions of the servo (yes, you may need to read that again), and every IR reading between one pule of the servo (this is a standard hobby servo). So, the data that the BS2e sees is a little 'late', meaning that data was from a couple milliseconds ago, and that's too slow. So, if there's an object really far in front of the IR sensor, then the robot will see it and turn, but if it's too close, then it will trigger the bumper switch on the Roomba. The robot will then act a few milliseconds later, but not fast enough so that right when the bumper touches the wall/plany/etc., it turns away; even then it will still be pushing against the object for a reasonable amount of time. The reason why I have a BS2e and an Arduino together is for ease of use. The Arduino has an A/D converter, and can do tasks that the BS2e can't, and the BS2e has features that the Arduino can't muster. So I thought I'd combine them; it's easier. But how can I speed this robot up? I know Parallax does not support the Arduino, but maybe someone that knows about C code can help? I mean, all these programming languages have SOMETHING in common. Below is the BS2e code.

' {$STAMP BS2e}
' {$PBASIC 2.5}

DD       PIN  13                ' blue
RXD      PIN  14                ' orange
TXD      PIN  15                ' green
LED      PIN  8
LSRB     PIN  2
LSRF     PIN  1
INPUT TXD

ARX      PIN  1                 ' data in from Arduino

BAUDFAST    CON   32            ' 19,200 bps
BAUDMED     CON   84            ' 9,600 bps
BAUDSLOW    CON   396           ' 2,400 bps

R_START     CON   128
R_BAUD      CON   129
R_CONTROL   CON   130
R_FULL      CON   132
R_POWER     CON   133
R_SPOT      CON   134
R_CLEAN     CON   135
R_DRIVE     CON   137
R_MOTORS    CON   138
R_SONG      CON   140
R_PLAY      CON   141
R_SENSORS   CON   142

SENS_BUMPWHEEL    VAR   Byte
SENS_WALL         VAR   Bit
SENS_CLIFF_L      VAR   Bit
SENS_CLIFF_FL     VAR   Bit
SENS_CLIFF_FR     VAR   Bit
SENS_CLIFF_R      VAR   Bit
SENS_VWALL        VAR   Bit
SENS_MOTOROVER    VAR   Byte
SENS_DIRT_L       VAR   Byte
SENS_DIRT_R       VAR   Byte
i                 VAR   Byte

BUMP_RIGHT        VAR   SENS_BUMPWHEEL.BIT0
BUMP_LEFT         VAR   SENS_BUMPWHEEL.BIT1
WHEELDROP_C       VAR   SENS_BUMPWHEEL.BIT4
WHEELDROP_L       VAR   SENS_BUMPWHEEL.BIT3
WHEELDROP_R       VAR   SENS_BUMPWHEEL.BIT2
MOTOROVER_L       VAR   SENS_MOTOROVER.BIT4
MOTOROVER_R       VAR   SENS_MOTOROVER.BIT3

IRVAL             VAR   Byte(3)

PULSES            VAR   Word

LOW DD
PAUSE 100
HIGH DD
PAUSE 2000

FOR i = 1 TO 3
    LOW DD
    LOW LED
    PAUSE 250
    HIGH DD
    HIGH LED
    PAUSE 250
NEXT

SEROUT RXD, BAUDFAST, [noparse][[/noparse]R_START]
PAUSE 100
SEROUT RXD, BAUDFAST, [noparse][[/noparse]R_BAUD, 3] ' 3 == 2400 bps
PAUSE 100
SEROUT RXD, BAUDSLOW, [noparse][[/noparse]R_START]
PAUSE 100
SEROUT RXD, BAUDSLOW, [noparse][[/noparse]R_CONTROL]
PAUSE 100

Main:
    DEBUG "at the top", CR
    GOSUB Update_Sensors

    IF BUMP_RIGHT THEN
        GOSUB Spin_Left
        PAUSE 1000
    ELSEIF BUMP_LEFT THEN
        GOSUB Spin_Right
        PAUSE 1000
    ENDIF

    GOSUB Go_Forward
    PAUSE 100

    GOTO Main

Update_Sensors:
    DEBUG "update sensors",CR

    SEROUT RXD, BAUDSLOW, [noparse][[/noparse]R_SENSORS, 1]
    SERIN TXD, BAUDSLOW, 2000, No_Data,
        [noparse][[/noparse]SENS_BUMPWHEEL,SENS_WALL,

        SENS_CLIFF_L,SENS_CLIFF_FL,SENS_CLIFF_FR,SENS_CLIFF_R,
        SENS_VWALL,SENS_MOTOROVER,SENS_DIRT_L,SENS_DIRT_R]

Read_IR:

  DEBUG "reading IR",CR
  SERIN ARX,BAUDMED,[noparse][[/noparse]WAIT("PULSE"),DEC4 PULSES]

    IF PULSES > 1300 AND PULSES < 1500 THEN
      SERIN ARX,BAUDMED,[noparse][[/noparse]WAIT("IR"),DEC4 IRVAL]
        IF IRVAL > 200 THEN
          GOSUB Spin_Right
        ENDIF
    ELSEIF PULSES > 1500 AND PULSES < 1700 THEN
      SERIN ARX,BAUDMED,[noparse][[/noparse]WAIT("IR"),DEC4 IRVAL]
        IF IRVAL > 200 THEN
          GOSUB Spin_Right
        ENDIF
    ELSEIF PULSES > 1700 AND PULSES < 1900 THEN
        SERIN ARX,BAUDMED,[noparse][[/noparse]WAIT("IR"),DEC4 IRVAL]
        IF IRVAL > 200 THEN                                                       ' detected middle
          GOSUB Spin_Right
        ENDIF
    ELSEIF PULSES > 1900 AND PULSES < 2100 THEN
      SERIN ARX,BAUDMED,[noparse][[/noparse]WAIT("IR"),DEC4 IRVAL]
        IF IRVAL > 200 THEN
          GOSUB Spin_Left
        ENDIF
    ELSEIF PULSES > 2100 AND PULSES < 2300 THEN
      SERIN ARX,BAUDMED,[noparse][[/noparse]WAIT("IR"),DEC4 IRVAL]
        IF IRVAL > 200 THEN
          GOSUB Spin_Left
        ENDIF
    ENDIF
    DEBUG "pulses",CR
    DEBUG DEC4 PULSES
    DEBUG "ir",CR
    DEBUG DEC4 IRVAL
    RETURN

No_Data:
    DEBUG "no data!",CR
    RETURN

Done:
    PAUSE 1000
    SEROUT RXD, BAUDSLOW, [noparse][[/noparse]R_POWER] ' turn off
    STOP

Spin_Left:
    SEROUT RXD, BAUDSLOW, [noparse][[/noparse]R_DRIVE,$00,$c8,$00,$01]
    RETURN
Spin_Right:
  FOR i = 1 TO 10
    SEROUT RXD, BAUDSLOW, [noparse][[/noparse]R_DRIVE,$00,$c8,$ff,$ff]
  NEXT
    RETURN
Go_Forward:
    SEROUT RXD, BAUDSLOW, [noparse][[/noparse]R_DRIVE,$00,$c8,$80,$00]
    RETURN
Go_Stop:
    SEROUT RXD, BAUDSLOW, [noparse][[/noparse]R_DRIVE,$00,$00,$00,$00]
    RETURN






And here's the Arduino code:


int servoPin = 3;
int irPin = 0;
int val = 0;
int pulses;

void setup() {
  Serial.begin(9600);
  pinMode(servoPin, OUTPUT);    
}

void loop()
{
  if(pulses >= 2300)
    {  pulses = 2300;
      do 
      {
        pulses = pulses - 50;
        digitalWrite(servoPin, HIGH);
        delayMicroseconds(pulses);
        digitalWrite(servoPin, LOW);
        delay(20);
        readir();
      } while(pulses >= 1300);
    } 
  else if(pulses <= 1300)
    {  pulses = 1300;
      do 
      {
        pulses = pulses + 50;   
        digitalWrite(servoPin, HIGH);
        delayMicroseconds(pulses);
        digitalWrite(servoPin, LOW);
        delay(20);
        readir();
      } while(pulses <= 2300);
    }
}
void readir()
{
    val = analogRead(irPin);
    //delay(5);
    Serial.println("PULSE");
    delay(5);
    Serial.println(pulses); 
    delay(5);
    Serial.println("IR"); 
    delay(5);
    Serial.println(val);
}





▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Giggly Googley!

Post Edited (NoBo780) : 3/3/2008 3:15:31 AM GMT

Comments

  • NoBo780NoBo780 Posts: 94
    edited 2008-03-03 03:12
    To clarify, the reason why I have a servo is to have a panning sensor, instead of multiple. The IR sensor that I'm using is a GP2D12; I know the range isn't that good for that model, and given the angle of rotation of the servo, but I am going to get one with a better range soon.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Giggly Googley!
  • Mike GreenMike Green Posts: 23,101
    edited 2008-03-03 03:38
    I don't think you're going to do much better. The serial I/O is unbuffered and the BS2e is tied up while sending it. I suspect you could easily do away with the Arduino by using a ServoPAL and an external analog to digital converter like the ADC0831 which needs 3 I/O pins, but you really need some kind of buffered serial I/O. A MAX3100 might work. It also has an SPI interface and 8 byte transmit and receive buffers. It even comes in a PDIP package and only needs a crystal and a couple of capacitors for external parts.

    I really think you need to use a Propeller. It can do the servo(s), ADC, and multiple serial interfaces and have plenty of processing power for the actual work of navigation.
  • NoBo780NoBo780 Posts: 94
    edited 2008-03-03 12:39
    Erm...Thanks. But I don't know HOW to use an external ADC, or the MAX3100 IC, and a propeller would be nice, but I've already invested in a LOT. So, (and I am not, in any way, trying to·shun Parallax products), do you think an Atmel ATmega168 AVR chip will be fine for the job? Or do I need more power?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Giggly Googley!
  • Mike GreenMike Green Posts: 23,101
    edited 2008-03-03 15:38
    Frankly, I'm not impressed with the Arduino except as a teaching tool. If you're talking about using the ATmega168 AVR by itself with some other C compiler and (most importantly) a run-time library with functionality more "Stamp-like", that's one thing. If you're talking about moving all the functions to the Arduino platform, I'm not sure it will work. It's not the chip itself. It's the underlying assumptions in the Arduino software.
Sign In or Register to comment.