Unterrichts- und Lernmaterial für Mikrocontroller
Unterrichts- und Lernmaterial fürMikrocontroller

1 - Taktile Navigation mit Fühlern (Whiskers)

Taktile Schalter oder auch Berührungsschalter werden häufig in der Robotik zur Materialerkennung eines Objektes eingesetzt, um in einem Produktionsprozess Objekte auszurichten oder auf verschiedene Behältnisse zu verteilen.

Wir werden den BoE-Shield Bot Arduino mit einem taktilen Schalter (whiskers) versehen, ihn testen und so programmieren, dass die verschiedenen Zustände des Schalters dargestellt werden und dann entscheiden, wie der Roboter sich verhalten soll, wenn die whiskers ein Hindernis erfühlt haben. Am Ende bewegt sich der Roboter völlig autonom durch den Raum, gesteuert über die Wahrnehmung durch seine Fühler.

 

BoE Shield Bot Arduino mit Fühlern (Whiskers)

Der Bausatz der Fühler kann über die Fa. Parallax bezogen werden.

Anschlussbelegung der Whiskers auf dem Steckbrett des BoE-Shield Bot Arduino (Courtesy of Parallax Inc.)

Wie die Schalter (Whiskers) arbeiten

Die Fühler sind auf der einen Seite über die Befestigungsschrauben direkt mit Masse verbunden und auf der anderen über einen Widerstand von 220 Ohm mit einem digitalen Eingang des Arduino und über einen 10 kOhm pull-up Widerstand mit der Spannungsversorgung von 5V (Abb. 1).  

Im Programm werden zuerst die beiden Anschlusspin auf Input-Modus gestellt

  • pinMode(pin, mode)
    

und anschließend ihr Zustand HIGH oder LOW mit der Funktion digitalRead(pin) abgefragt.

Ist der Fühler offen (er hat keinen Kontakt mit einem fremden Objekt), dann liegen am Eingang von P7 5Volt an und die Abfrage

  • digitalRead(7)
    

gibt eine 1 (HIGH) zurück. Im rechten Bild (Abb. 1) ist der Fühler geschlossen (es besteht Kontakt mit einem fremden Objekt) und

  • digitalRead(7)
    

gibt eine 0 (LOW) zurück. Die Rückgabewerte werden in Variablen wLinks und wRechts abgelegt und später genutzt um irgendwelche Aktionen auszulösen oder Entscheidungen zu treffen.

Abbildung 1 - Beschaltung der Whiskers (Courtesy of Parallax Inc.)

2  - Whiskers Testprogramm

Im folgenden Programm wird überprüft, ob die Fühler funktionieren; dazu werden im Terminal die binären Rückgabewerte der Funktionen digitalRead(7) und digitalRead(5) ausgegeben. Es genügt, wenn die metallenen Fühlerenden mit der Hand gegen einen Kontakt gedrückt werden, um die Funktion zu überprüfen.

Sind beide Fühlerkontakte offen, dann sollte im seriellen Monitor zweimal die 1 angezeigt werden (11). Wird einer der Fühlerkontakte geschlossen, dann erscheint im Monitor auf der entsprechenden rechten oder linken Seite eine Null (01) oder (10). Sind beide Fühler geschlossen, erscheint die Doppelnull (00).

Aufgaben
  • Übertrage das Programm whiskers_test.ino in den Editor, speichere es ab und starte es anschließend.
  • Öffne den seriellen Monitor über das Icon rechts oben im Editor.
  • Wird keiner der beiden Fühler gedrückt, dann sollte im Monitor 11 erscheinen.
  • Drücke mit der Hand den rechten Fühler gegen den 3-Pin-Kontakt. Im Terminal sollte jetzt 10 erscheinen. Entsprechend erscheint 01, wenn der linke Fühler gedrückt wird.
  • Drücke beide Fühler gegen die 3-Pin-Kontakte. Es sollte jetzt 00 im Terminal angezeigt werden.
  • Damit ist der Test bestanden und wir können weiter fortfahren. Sollten sich Fehler eingeschlichen haben, überprüfe den Programmcode und die Schaltkreise auf Fehler.

Programm whiskers_test.ino

Terminalausgabe des Testprogramms

Wie arbeitet das Programm whiskers_test?

In der Methode setup() werden die beiden digitalen Pin 5 und 7 als Input deklariert. Über sie wird die Spannung der beiden Fühler-Schaltkreise abgefragt.

In der Methode loop() liefert jeder Programmzeilenaufruf von digitalRead eine Null zurück, wenn die Whiskers geschlossen und eine 1, wenn sie offen sind. Die Werte legt das Programm in den Variablen wLinks und wRechts vom Typ byte ab.

Mit Serial.print werden die Werte der beiden Variablen im Terminalfenster angezeigt. Der abschließende delay(100) Befehl verzögert die Textausgabe etwas.

3 - Navigation mit Fühlern verbessern

Bisher haben wir den Roboter nur irgendwelche vordefinierten Bewegungen ausführen lassen. Jetzt gehen wir daran Programme zu entwickeln, die den BoE-Shield Bot Arduino intelligent reagieren lassen, sobald er mit seinen Fühlern ein Hindernis ertastet hat. Es ist ein erstes Beispiel einer selbstständigen Roboter Navigation.

Der Roboter soll geradeaus laufen, während die Pin 5 und 7, die mit den Fühlern verbunden sind, ständig auf Hindernisse abgefragt werden (tatsächlich werden dort Spannungswerte abgefragt).

 

Sobald ein elektrischer Kontakt zustande kommt, wird über eine if ...else if ... else Entscheidung das weitere Vorgehen bestimmt. Der Entscheidungscode überprüft die verschiedenen Kombinationen der taktilen Sensoren und ruft dann Funktionen auf, die den Roboter in eine Bewegung zurück mit anschließender Drehung bringen. Die Fahrt wird dann wieder mit einer Vorwärtsbewegung fortgesetzt bis zum nächsten Hindernis.

Aufgaben
  • Bringe den Power-Schalter auf dem BoE-Shield in Position 1.
  • Verbinde die Batteriehalterung mit dem Arduino.
  • Übertrage das Programm whiskers_felderkundung.ino in den Editor und speichere es ab. Starte das Programm.
  • Trenne das USB-Kabel vom BoE-Shield Bot Arduino und schiebe den Power-Schalter in Position 2.
  • Stelle den Roboter auf den Boden und lasse ihn die Umgebung erkunden. Sobald er mit seinen Fühlern Hindernisse erkennt, sollte er zurücksetzen, eine Drehung ausführen und den Raum neu erkunden.

Das Programm whiskers_Felderkundung.ino

Wie arbeitet das Programm whiskers_felderkundung?

Mit der if ... else if ... else Anweisung in der Methode loop() werden alle möglichen Zustände der Fühler erfasst. Es beginnt mit

  • if((wLinks == 0) && (wRechts == 0)).
    

Wenn die Variable wLinks UND die Variable wRechts beide Null sind (dann haben beide whiskers ein Hindernis erfasst und die Taster sind geschlossen), dann fahre 1 Sekunde lang rückwärts und mache eine Linksdrehung.

 

Innerhalb einer if ... else if ... else Anweisung werden die Programmblöcke übersprungen, für die eine if-Anweisung nicht zutrifft. Es könnte zum Beispiel der linke Fühler gegen ein Hindernis stoßen und den Taster schließen, dann wird innerhalb der if ... else if ... else Anweisung der Programmblock abgearbeitet, für den diese Bedingung zutrifft. Das wäre dann die Bedingung

  • else if(wLinks == 0)
    

Der nachfolgende Programmblock wird ausgeführt

  • {
    rueckwaerts(1000);
    drehungRechts(400);
    }
    

und der Rest der if ... else if ... else Anweisung übersprungen. Das Programm geht dann weiter nach dem letzten else-Statement.

 

Hat nur der rechte Fühler ein Hindernis erfasst, werden die beiden ersten Programmblöcke übersprungen und der auf

  • else if(wRechts == 0)
    

folgende Programmblock ausgeführt.

  • {
    rueckwaerts(1000);
    drehungLinks(400);
    }
    

Mit der letzten else-Anweisung werden sozusagen alle restlichen Möglichkeiten erfasst. Sie ist nicht notwendig aber trotzdem ganz nützlich. Wenn dieser Fall eintritt, rollt der Roboter 20ms vorwärts; das ermöglicht ihm eine schnelle Reaktion auf Fühlerkontakte.

4 - Künstliche Intelligenz und die Eckenfalle

Du wirst feststellen, dass der Roboter in Ecken seine Probleme bekommt und häufig nicht mehr aus diesem Bereich herausfindet. Wenn der linke Fühler eine Wand erfasst, setzt der Roboter zurück und macht eine Rechtsdrehung. Anschließend bewegt er sich vorwärts, berührt jetzt mit dem rechten Fühler die andere Wand, setzt zurück und macht eine Linksdrehung. Und so geht es jetzt munter weiter, der Roboter hat sich damit festgefahren.

Solche Situationen kann man vermeiden, wenn man geschachtelte if-Statements anwendet. Das Programm überprüft eine Bedingung und wenn sie wahr ist überprüft sie eine weitere Bedingung innerhalb des ersten Programmblocks.

Im folgenden Programm wird der Roboter angewiesen eine Rückwärtsbewegung mit einem U-Turn einzuleiten, wenn die Whiskers vier oder fünfmal hintereinander rechts und links ein Hindernis detektiert haben.

Aufgaben
  • Stelle den Power-Schalter in Stellung 1.
  • Speicher das Programm whiskers_felderkundung.ino unter dem neuen Namen whiskers_eckenfalle.ino ab und übertrage die neuen Programmzeilen in den Editor.
  • speichere das Programm ab und starte es.
  • Teste das Programm, indem nacheinander der rechte und linke Whisker mit der Hand berührt werden. Es sollte nach dem vierten oder fünften Kontakt vom Roboter eine Rückwärtsbewegung mit einem U-Turn eingeleitet werden.

Programm whiskers_eckenfalle.ino

Wie arbeitet das Programm whiskers_eckenfalle?

Da es nur wenige zusätzliche Programmzeilen zum bereits bekannten Programm whiskers_felderkundung gibt, beschränken wir uns auf die Kommentierung der neuen Programmzeilen, die sich mit der Eckenfalle befassen.

Es werden drei neue Variablen vom Typ byte eingeführt

  • wLinksAlt,
    
  • wRechtsAlt
    
  • zaehler.
    

Die ersten beiden Variablen speichern den letzten Berührstatus der Whiskers und vergleichen ihn mit dem aktuellen Status. Die Variable zaehler enthält die Anzahl aufeinanderfolgender alternierender Kontakte der Fühler.

Alle drei Variablen werden in der Methode setup() initialisiert. Bis auf eine Variable werden sie alle auf 0 gesetzt.

Im nächsten Schritt wird geprüft, ob einer der beiden Fühler Berührung mit einem Objekt hatte. Dazu wird der ungleich-Operator in der if-Anweisung benutzt.

Wenn(wLinks ungleich wRechts) 

ist, bedeutet, wenn einer der beiden Taster eine Berührung mit einem Objekt hatte ...sind die Variablen nicht gleich und das Programm muss herausfinden, ob es ein sich wiederholendes Muster gibt. Um das herauszufinden, wird eine eingebettete zweite if-Anweisung aufgerufen, die überprüft, ob sich der aktuelle wLinks Wert vom wLinksAlt-Wert und der aktuelle wRechts-Wert vom wRechtsAlt-Wert unterscheidet. Treffen beide Bedingungen zu, dann wird die Variable zaehler um 1 erhöht.

  • if((wLinks != wLinksAlt) && (wRechts != wRechtsAlt))
    

und die Zustände in den beiden Variablen wRechtsAlt und wLinksAlt werden aktualisiert

  • zaehler++;
    
  • wLinksAlt  = wLinks;
    
  • wRechtsAlt= wRechts;
    

Wenn hintereinander vier dieser Berührkontakte gezählt worden sind, wird die Variable zaehler zurück auf 0 gestellt und ein U-Turn des Roboters eingeleitet. Dadurch, dass im Programmblock der if-Anweisung die beiden Variablen wLinks und wRechts auf 0 gestellt werden, interpretiert das Programm das mit einem U-Turn.

  • if(zaehler == 4)
    {
      wLinks  = 0;
      wRechts= 0;
      zaehler = 0;
    }
    

Ist die Bedingung if((wLinks != wLinksAlt) && (wRechts != wRechtsAlt)) nicht wahr, dass heißt, dass es keine aufeinanderfolgenden Berührungen des linken und rechten Whiskers mit einem Hindernis gegeben hat, dann wird sich der Roboter wohl nicht in einer Eckenfalle befinden, die Variable zaehler wird auf 0 zurückgesetzt und das Spiel kann von vorne beginnen.

 

Bemerkung

Etwas unübersichtlich sind die vielen geschweiften Klammern der verschiedenen Programmblöcke, die häufig nicht korrekt geschlossen werden und dann zu Fehlermeldungen führen. Hilfreich ist, zusammengehörende Programmblöcke und die entsprechenden Klammern einzurücken und darauf zu achten, dass die öffnende und die schließende Klammer gleich weit eingerückt werden.

Druckversion | Sitemap
© Reinhard Rahner - Gettorf