PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Arduino meets Roomba



mike10
18.05.2012, 14:51
Hallo zusammen

Bin ein Neuling und ersuche euch um Rat
Es geht um die Kommunikation zwischen Arduino Uno und einem iRobot Roomba
Das Forum habe ich schon durchsucht, leider keine Infos gefunden.

Folgender Stand meiner Arbeit.
> Die Hardware steht und das Serielle Kabel, ist mit der DIN Buchse des Roomba aud die PINs 0(RX), 1(TX) und 2(Baud) überführt.
> Da dies alles neu für mich ist, habe ich mal gegoogelt und folgendes Demoprogramm auf hackingroomba.com gefunden:


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);
pinMode(ledPin, OUTPUT);
Serial.begin(57600);

digitalWrite(ledPin, HIGH);

// startet den Roboter
digitalWrite(ddPin, HIGH);
delay(100);
digitalWrite(ddPin, LOW);
delay(500);
digitalWrite(ddPin, HIGH);
delay(2000);
// das ROI, Befehle zu empfangen
Serial.print(128, BYTE);
delay(50);
Serial.print(130, BYTE);
delay(50);
digitalWrite(ledPin, LOW);
}

void loop() {
digitalWrite(ledPin, HIGH);
updateSensors();
digitalWrite(ledPin, LOW);
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);
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 ++ ) {
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
}
}
sensorbytes[i++] = c;
}
}



Da aber die Bibliothek nicht mehr unterstützt wird, musste „ serial.print (var, BYTE);“ zu „serial.write (var);“ geändert werden. Zudem habe ich statt den Protokollen, Variabeln eingesetzt, das der Datentyp keine „=“ zulässt.
Hier die geänderte Version:


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);
pinMode(ledPin, OUTPUT);
Serial.begin(57600);

digitalWrite(ledPin, HIGH);

// startet den Roboter
digitalWrite(ddPin, HIGH);
delay(100);
digitalWrite(ddPin, LOW);
delay(500);
digitalWrite(ddPin, HIGH);
delay(2000);
// das ROI, Befehle zu empfangen
Serial.write (128);
delay(50);
Serial.write(130);
delay(50);
digitalWrite(ledPin, LOW);
}

void loop() {
digitalWrite(ledPin, HIGH);
updateSensors();
digitalWrite(ledPin, LOW);
if(bumpleft) {
spinRight();
delay(1000);
}
else if(bumpright) {
spinLeft();
delay(1000);
}
goForward();
}

void goForward() {
int a=0x00;
int b=0xc8;
int c=0x80;
int d=0xff;
int e=0x38;
int f=0x01;

Serial.write(137); // DRIVE
Serial.write(a); // 0x00c8 == 200
Serial.write(b);
Serial.write(c);
Serial.write(a);
}
void goBackward() {
int a=0x00;
int b=0xc8;
int c=0x80;
int d=0xff;
int e=0x38;
int f=0x01;

Serial.write(137); // DRIVE
Serial.write(d); // 0xff38 == -200
Serial.write(e);
Serial.write(c);
Serial.write(a);
}
void spinLeft() {
int a=0x00;
int b=0xc8;
int c=0x80;
int d=0xff;
int e=0x38;
int f=0x01;

Serial.write(137); // DRIVE
Serial.write(a); // 0x00c8 == 200
Serial.write(b);
Serial.write(a);
Serial.write(f); // 0x0001 == spin left
}
void spinRight() {
int a=0x00;
int b=0xc8;
int c=0x80;
int d=0xff;
int e=0x38;
int f=0x01;

Serial.write(137); // DRIVE
Serial.write(a); // 0x00c8 == 200
Serial.write(b);
Serial.write(d);
Serial.write(d); // 0xffff == -1 == spin right
}
void updateSensors() {
Serial.write(142);
Serial.write(1); // 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 ++ ) {
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
}
}
sensorbytes[i++] = c;
}
}


Leider habe ich noch keinen Erfolg damit
Kann mir da jemand Weiterhelfen?

Vielen Dank

Mike10

5Volt-Junkie
18.05.2012, 18:22
Kannst Du Dein Problem etwas genauer schildern? Kein Erfolg kann vieles bedeuten ;)

mike10
18.05.2012, 23:14
Hallo 5Volt-Junkie

Also mit diesen einfachen Befehlen sollte der Roomba geradeaus fahren und Hinternisse vermeiden. Das Problem ist, dass sich nach dem Arduino Upload nichts tut.

m.a.r.v.i.n
20.05.2012, 12:22
Hast du einen iRobot Create oder einen Roomba? Der Roomba verwendet ein ähnliches Protokoll (http://irobot.lv/uploaded_files/File/iRobot_Roomba_500_Open_Interface_Spec.pdf) aber eine andere Baudrate (115.2kBaud statt 56kBaud). Das Beispiel ist demnach für den Create geschrieben.
Eine gemeinsame GND Verbindung ist zudem notwendig. Die Baud Leitung wird nur benötigt, wenn man mit 19.2kBaud arbeiten will. Sind RX,TX über Kreuz angeschlossen (RX0 Arduino an TX4 Roomba und TX1 Arduino an RX3 Roomba)?

mike10
20.05.2012, 23:58
Hallo m.a.r.v.i.n

Habe ein Roomba, also die 115,2k. Demzufolge kann ich auf die Baud Leitung verzichten. Betr. GND heisst das, dass der gemeinsame GND vom PIN 6 oder 7 des Roomba auf einen der zwei GNG-PINs des Arduino zu überführen ist?
RX und TX sind nicht gekreuzt angeschlossen, also 3(R) auf 0(A) und 4(R) auf 1(A).

Gruss mike10

m.a.r.v.i.n
21.05.2012, 10:58
Hallo mike10,
demnach mußt du dein Programm auf 115.2kBaud anpassen. Die GND Leitung (Pin 6 und 7 vom Roomba) müssen mit GND am Arduino verbunden sein. RX und TX müssen über Kreuz verdrahtet werden, sonst ist Ausgang mit Ausgang verbunden. Im schlimmsten Fall kann dadurch der Roomba und/oder das Arduino board beschädigt werden.

mike10
22.05.2012, 07:49
Hallo m.a.r.v.i.n

Alle Änderungen sind vorgenommen und der kleine läuft:) Zumindest einmal geradeaus (im loop). Der Bumper spricht als Sensor leider noch nicht an. Gemäss Programm sollte dieser doch ausgewertet werden?

Gruss mike10

m.a.r.v.i.n
22.05.2012, 10:22
Hallo mike10,
könnte sein, das der Roomba TX Pin abgeraucht ist.
Ich spreche aus eigener leidvoller Erfahrung. Damals habe ich auf die Beschriftung der Controller Platine (Jeenode board) vertraut und brav RX und TX überkreuz verdrahtet. Leider war die Beschriftung bereits gedreht, mit dem Ergebnis das beim Roomba und dem Controller jeweils der TX Pin abgeraucht sind.
Teste mal ob der Arduino überhaupt etwas empfängt (Serial.write Ausgabe der empfangenen Zeichen).

mike10
22.05.2012, 19:30
Hallo m.a.r.v.i.n

Oh nein, hoffentlich nicht...das Arduino ist noch zu verkraften, aber nicht der Roomba:(
Bin mir nicht sicher, wie ich das mit dem testen des Arduino anstellen muss. Wird das mit dem Befehl Serial.write(incomingByte) gelöst?

Gruss mike10

m.a.r.v.i.n
22.05.2012, 21:44
Hallo mike10,
So was in der Art, direkt hinter die Lese Funktion:


int c = Serial.read();
Serial.println(c, HEX);

mike10
23.05.2012, 21:14
Hallo m.a.r.v.i.n

Habe mal mit einem Code nur das Arduino getestet. Die Schnittstelle scheint zu funktionieren.
Leider komme ich mit deiner Lösung nicht weiter. Muss noch ein wenig probieren...
Sofern das Programm nicht noch ein Fehler aufweist, ist aber schon klar, dass der Roomba futsch ist:(

Gruss mike10


int ran;

void setup () {

Serial.begin(9600);

}

void loop () {
char data = Serial.read();
Serial.print(ran);

if(data == 'W'){
ran = random(1,9);
}
}

m.a.r.v.i.n
23.05.2012, 23:40
Autsch, vergiss mal schnell meine Lösung wieder. Der Arduino Uno hat ja nur eine serielle Schnittstelle. So kann das ja nicht funktionieren. Vielleicht kannst du auch einfach nur die LED blinken lassen wenn ein Zeichen empfangen wurde.

5Volt-Junkie
24.05.2012, 21:07
Wenn ich mich recht erinnere, kann man eine zweite serielle Schnittstelle erzeugen.

mike10
24.05.2012, 22:43
Kein ProblemO:)
Versuche das Ding mal zum blinken zu bringen.
Bin dann über die Pfingsten nicht online. Melde mich am Dienstag wieder.

Vielen Dank, schöne Feiertage und Gruss
mike10

mike10
31.05.2012, 20:35
Hallo zusammen
Hatte die Möglichkeit einen zweiten Roomba zu gebrauchen (Serie 555).
Nun wird es interessant, das Arduino habe ich ja schon getestet und scheint in Ordnung zu sein.
Aber auch mit dem zweiten Roomba (Seriall IO i.O.) hat der Bumber keine Funktion auf das Arduino.
Da muss doch an der Software irgendwas nicht in Ordnung sein?!

m.a.r.v.i.n
02.06.2012, 11:09
Hallo,
wie schon gesagt. Den Blinktest einbauen. Das Programm schein i.O. zu sein.

mike10
04.06.2012, 22:46
Hallo

Also mit dem Blinktest komme ich leider nicht voran.
Habe aber die Möglichkeit, ein weiteres Arduino Uno R3 zu gebrauchen.
Der Roomba und das Arduino sind also neu, aber das Problem ist das alte!
Ist einfach nur frustrierend, da ich mich eigentlich nur auf die einfache Programmierung, also Vorwärts, Links, Rechts konzentrieren möchte.
Dazu ist aber ein Standart-Programm die Voraussetzung, bei der sowohl das Senden und auch das Empfangen funktioniert.