Arexx RP6-BASE, RP6v2-BASE User guide [de]

RP6 ROBOT BASE
RP6-BASE
RP6v2-BASE
©2007 - 2012 AREXX Engineering
www.arexx.com
RP6
Robot System
Bedienungsanleitung
Version RP6-BASE-DE-20120215
für RP6 und RP6v2
WICHTIGE INFORMATION! Bitte unbedingt lesen!
Bevor Sie den RP6, RP6v2 oder Zubehör in Betrieb nehmen, lesen Sie bitte diese Anleitung und ggf. die Anleitungen von Zubehörteilen voll­ständig durch! Sie erläutert Ihnen die korrekte Verwendung und weist auf mögliche Gefahren hin! Weiterhin enthält sie wichtige Informatio­nen, die für viele Anwender keineswegs offensichtlich sein dürften.
Bei Nichtbeachtung dieser Anleitung erlischt jeglicher Garantiean­spruch! Weiterhin übernimmt AREXX Engineering keinerlei Haftung für Schäden jeglicher Art, die aus Nichtbeachtung dieser Anleitung resul­tieren!
Bitte beachten Sie vor allem den Abschnitt "Sicherheitshinweise"!
Schließen Sie das USB Interface bitte erst an Ihren PC an, nachdem Sie das Kapitel 3 - „Inbetriebnahme“ gele­sen und die Software korrekt installiert haben!
Impressum ©2007 - 2012 AREXX Engineering
Nervistraat 16 8013 RS Zwolle The Netherlands
Tel.: +31 (0) 38 454 2028 Fax.: +31 (0) 38 452 4482
"RP6 Robot System" ist eingetragenes Wa­renzeichen von AREXX Engineering. Alle anderen Warenzeichen stehen im Besitz ihrer jeweiligen Eigentümer.
Diese Bedienungsanleitung ist urheberrecht­lich geschützt. Der Inhalt darf ohne vorheri­ge schriftliche Zustimmung des Herausge­bers auch nicht teilweise kopiert oder über­nommen werden!
Änderungen an Produktspezifikationen und Lieferumfang vorbehalten. Der Inhalt dieser Bedienungsanleitung kann jederzeit ohne vorherige Ankündigung geän­dert werden. Neue Versionen dieser Anleitung erhalten Sie kostenlos auf http://www.arexx.com/
Wir sind nicht verantwortlich für den Inhalt von externen Webseiten, auf die in dieser Anlei­tung verlinkt wird!
Hinweise zur beschränkten Garantie und Haftung
Die Gewährleistung von AREXX Engineering beschränkt sich auf Austausch oder Reparatur des Roboters innerhalb der gesetzlichen Gewährleistungsfrist bei nachweislichen Produkti­onsfehlern, wie mechanischer Beschädigung und fehlender oder falscher Bestückung elek­tronischer Bauteile, ausgenommen aller über Steckverbinder/Sockel angeschlossenen Kom­ponenten. Es besteht keine Haftbarkeit für Schäden, die unmittelbar durch, oder in Folge der Anwendung des Roboters entstehen. Unberührt davon bleiben Ansprüche, die auf unab­dingbaren gesetzlichen Vorschriften zur Produkthaftung beruhen.
Sobald Sie irreversible Veränderungen (z.B. Anlöten von weiteren Bauteilen, Bohren von Löchern etc.) am Roboter vornehmen oder der Roboter Schaden infolge von Nichtbeach­tung dieser Anleitung nimmt, erlischt jeglicher Garantieanspruch!
Es kann nicht garantiert werden, dass die mitgelieferte Software individuellen Ansprüchen genügt oder komplett unterbrechungs und fehlerfrei arbeiten kann. Weiterhin ist die Software beliebig veränderbar und wird vom Anwender in das Gerät gela­den. Daher trägt der Anwender das gesamte Risiko bezüglich der Qualität und der Leis­tungsfähigkeit des Gerätes inklusive aller Software. AREXX Engineering garantiert die Funktionalität der mitgelieferten Applikationsbeispiele un­ter Einhaltung der in den technischen Daten spezifizierten Bedingungen. Sollte sich der Ro­boter oder die PC-Software darüber hinaus als fehlerhaft oder unzureichend erweisen, so übernimmt der Kunde alle entstehenden Kosten für Service, Reparatur oder Korrektur. Bitte beachten Sie auch die entsprechenden Lizenzvereinbarungen auf der CD-ROM!
Symbole
Im Handbuch werden folgende Symbole verwendet:
Das "Achtung!" Symbol weist auf besonders wichtige Ab­schnitte hin, die sorgfältig beachtet werden müssen. Wenn Sie hier Fehler machen, könnte dies ggf. zur Zerstörung des Roboters oder seines Zubehörs führen und sogar Ihre eigene oder die Gesundheit anderer gefährden!
Das "Information" Symbol weist auf Abschnitte hin, die nütz­liche Tipps und Tricks oder Hintergrundinformationen enthal­ten. Hier ist es nicht immer essentiell alles zu verstehen, aber meist sehr nützlich.
Inhaltsverzeichnis
1. Einleitung ..................................................................................... 6
1.1. Technischer Support ................................................................ 7
1.2. Lieferumfang RP6 .................................................................... 7
1.3. Lieferumfang RP6v2 ................................................................ 8
1.4. Der RP6v2 und Erweiterungsmöglichkeiten ................................. 8
1.5. Features und technische Daten ............................................... 11
1.6. Was kann der RP6? ................................................................ 14
1.7. Anwendungsvorschläge und Ideen ........................................... 15
2. Der RP6 im Detail ........................................................................ 16
2.1. Steuerungssystem ................................................................. 17
2.1.1. Bootloader.......................................................................19
2.2. Stromversorgung .................................................................. 19
2.3. Sensorik .............................................................................. 20
2.3.1. Batteriespannungs-Sensor (Voltage Sensor).........................20
2.3.2. Lichtsensoren (LDRs).........................................................20
2.3.3. Anti Collision System (ACS)................................................21
2.3.4. Stoßstangensensoren (Bumper)..........................................22
2.3.5. Motorstromsensoren (Current sensing)................................22
2.3.6. Drehgeber (Encoder).........................................................23
2.4. Antriebssystem ..................................................................... 24
2.5. Erweiterungssystem .............................................................. 25
2.5.1. Der I²C Bus......................................................................26
2.5.2. Erweiterungsanschlüsse.....................................................27
3. Inbetriebnahme ........................................................................... 29
3.1. Sicherheitshinweise ............................................................... 29
3.1.1. Statische Entladungen und Kurzschlüsse..............................29
3.1.2. Umgebung des Roboters....................................................30
3.1.3. Versorgungsspannung.......................................................30
3.2. Software Installation .............................................................. 31
3.2.1. Die RP6 CD-ROM...............................................................31
3.2.2. WinAVR - für Windows.......................................................32
3.2.3. AVR-GCC, avr-libc und avr-binutils - für Linux ......................32
3.2.3.1. Automatisches Installationsskript .................................34
3.2.3.2. Manuelle Installation ..................................................35
3.2.3.3. Pfad setzen ...............................................................36
3.2.3.4. Neuere Versionen ......................................................36
3.2.4. Java 6 ............................................................................37
3.2.4.1. Windows ..................................................................37
3.2.4.2. Linux .......................................................................37
3.2.5. RobotLoader.....................................................................38
3.2.6. RP6 Library, RP6 CONTROL Library und Beispielprogramme....38
3.3. Anschluss des USB Interfaces – Windows ................................. 39
3.3.1. Überprüfen ob das Gerät richtig angeschlossen ist.................39
3.3.2. Treiber später wieder Deinstallieren.....................................40
3.4. Anschluss des USB Interfaces – Linux ...................................... 40
3.5. Software Installation abschließen ............................................ 40
3.6. Akkus einbauen .................................................................... 41
3.7. Laden der Akkus ................................................................... 43
3.8. Der erste Test ....................................................................... 43
3.8.1. USB Interface anschließen und RobotLoader starten..............44
4. Programmierung des RP6 ............................................................. 53
4.1. Einrichten des Quelltexteditors ................................................ 53
4.1.1. Menüeinträge erstellen......................................................53
4.1.2. Syntax Highlighting einstellen.............................................56
4.1.3. Beispielprojekt öffnen und kompilieren.................................58
4.2. Programme in den RP6 laden .................................................. 60
4.3. Warum ausgerechnet C? Und was bedeutet „GCC“? ................... 61
4.4. C - Crashkurs für Einsteiger .................................................... 62
4.4.1. Literatur..........................................................................62
4.4.2. Erstes Beispielprogramm....................................................63
4.4.3. C Grundlagen...................................................................66
4.4.4. Variablen.........................................................................67
4.4.5. Bedingungen ...................................................................69
4.4.6. Switch-Case.....................................................................71
4.4.7. Schleifen.........................................................................72
4.4.8. Funktionen.......................................................................74
4.4.9. Arrays, Zeichenketten, Zeiger ............................................76
4.4.10. Programmablauf und Interrupts........................................77
4.4.11. C-Präprozessor...............................................................78
4.5. Makefiles .............................................................................. 79
4.6. RP6 Funktionsbibliothek (RP6Library) ....................................... 80
4.6.1. Mikrocontroller initialisieren................................................80
4.6.2. UART Funktionen (serielle Schnittstelle)...............................81
4.6.2.1. Senden von Daten über die serielle Schnittstelle ............81
4.6.2.2. Empfangen von Daten über die serielle Schnittstelle .......83
4.6.3. Delay Funktionen (Verzögerungen und Zeitsteuerung)...........84
4.6.4. Status LEDs und Bumper...................................................87
4.6.5. ADC auslesen (Batterie-, Motorstrom- und Lichtsensoren)......92
4.6.6. ACS – Anti Collision System...............................................94
4.6.7. IRCOMM und RC5 Funktionen.............................................96
4.6.8. Stromsparfunktionen.........................................................98
4.6.9. Antriebs Funktionen..........................................................99
4.6.10. task_RP6System().........................................................105
4.6.11. I²C Bus Funktionen........................................................106
4.6.11.1. I²C Slave ..............................................................106
4.6.11.2. I²C Master ............................................................109
4.7. Beispielprogramme .............................................................. 113
5. Experimentierplatine .................................................................. 126
6. Schlusswort .............................................................................. 127
ANHANG ...................................................................................... 128
A - Fehlersuche...........................................................................128
B – Encoder Kalibrierung...............................................................136
C – Anschlussbelegungen..............................................................138
D – Entsorgungs- und Sicherheitshinweise......................................141
RP6 ROBOT SYSTEM - 1. Einleitung

1. Einleitung

Der RP6 ist ein kostengünstiger autonomer mobiler Roboter, entwickelt um sowohl Anfängern, als auch fortgeschrittenen Elektronik und Software Entwicklern einen Ein­stieg in die faszinierende Welt der Robotik zu bieten.
Der Roboter wird komplett aufgebaut geliefert und ist damit ideal für alle, die sonst eher wenig mit Löten und Basteln zu tun haben und sich hauptsächlich auf die Softwa­re konzentrieren möchten. Allerdings bedeutet dies nicht, dass man keine eigenen Schaltungen und Erweiterungen auf dem Roboter aufbauen könnte! Ganz im Gegen­teil: Der RP6 ist auf Erweiterung ausgelegt und kann als Ausgangspunkt für viele in­teressante Hardware Experimente verwendet werden!
Er trat im Jahr 2007 die Nachfolge des 2003 von der Conrad Electronic SE auf den Markt gebrachten und sehr erfolgreichen "C-Control Robby RP5" an (CCRP5, RP5 hieß dabei "Robot Project 5"), hat mit dessen Elektronik aber nur wenig gemeinsam. Der Mikrocontroller auf dem RP6 ist nicht mehr das C-Control 1 von Conrad Electronic und damit ist der Roboter auch nicht mehr direkt in Basic programmierbar. Stattdessen wird ein viel leistungsfähigerer ATMEGA32 von Atmel verwendet, der in C program­mierbar ist. Es wird demnächst aber auch ein Erweiterungsmodul geben, mit dem neuere C-Control Varianten auf dem Roboter verwendet werden können. Damit kann der Roboter dann auch in der einfacheren Sprache Basic programmiert werden und gleichzeitig um viele weitere Schnittstellen und sehr viel zusätzlichen Speicher erwei­tert werden.
Weitere Neuerungen sind das direkt im Lieferumfang enthaltene USB Interface, ein sehr viel flexibleres Erweiterungssystem mit besseren Montagemöglichkeiten, stark verbesserte Drehgeber (150 fach höhere Auflösung im Vergleich zum Vorgänger), eine präzise Spannungsstabilisierung (beim Vorgänger war dazu noch ein Erweiterungsmo­dul notwendig), eine Stoßstange mit zwei Tastsensoren und vieles andere mehr.
Die Mechanik ist zwar grundsätzlich vom RP5 übernommen worden, wurde aber auf viel leiseren Betrieb optimiert und es wurden einige zusätzliche Bohrungen zur Monta­ge von mechanischen Erweiterungen hinzugefügt.
Der RP6 ist vom Prozessor her kompatibel mit den Robotern ASURO und YETI, die bei­de den kleineren ATMEGA8 und dieselben Entwicklungswerkzeuge (WinAVR, avr-gcc) verwenden. ASURO und YETI kommen aber im Gegensatz zum RP6 als Bausätze und müssen vom Anwender aufgebaut werden. Der RP6 ist für etwas anspruchsvollere An­wender gedacht, die sehr gute Erweiterungsmöglichkeiten, bessere Mikrocontroller und mehr Sensoren benötigen.
Anfang 2012 wurde der RP6 von der leicht verbesserten Version RP6v2 abgelöst. Ziel war es nicht den Roboter grundlegend neu zu entwickeln, sondern nur ein paar Details zu verbessern. Mehr Informationen über die Änderungen sind in Kapitel 1.4 zu finden!
Es sind bereits einige Erweiterungsmodule erhältlich, mit denen Sie die Fähigkeiten des Roboters ausbauen können. Dies ist u.a. die oben genannte C-Control Erweite­rung, ein Erweiterungsmodul mit einem weiteren MEGA32 und natürlich das Lochras­ter Experimentierboard für eigene Schaltungen. Bald gibt es auch ein Wireless LAN Er­weiterungsmodul.
Wir wünschen Ihnen nun viel Spaß und Erfolg mit dem RP6 Robot System!
- 6 -
RP6 ROBOT SYSTEM - 1. Einleitung

1.1. Technischer Support

Bei Fragen oder Problemen erreichen Sie unser Support Team wie folgt über das Internet (Bevor Sie uns kontaktieren lesen Sie aber bitte diese Bedienungsanleitung vollständig durch! Erfahrungsgemäß erledigen sich viele Fragen so bereits von selbst! Bitte beachten Sie auch insbesondere Anhang A - Fehlersuche):
- über unser Forum: http://www.arexx.com/forum/
- per E-Mail: info@arexx.nl
Unsere Postanschrift finden Sie im Impressum dieses Handbuchs. Aktu­ellere Kontaktinformation, Softwareupdates und weitere Informa-
tionen gibt es auf unserer Homepage:
http://www.arexx.com/
und auf der Homepage des Roboters:
http://www.arexx.com/rp6
Auch dem Roboternetz, der größten deutschsprachigen Robotik Com­munity, kann man auf jeden Fall mal einen Besuch abstatten:
http://www.roboternetz.de/

1.2. Lieferumfang RP6

Folgende Dinge sollten Sie in Ihrem RP6 Karton vorfinden (RP6v2 s. nächste Seite):
Fertig aufgebauter RP6 Roboter
RP6 USB Interface
USB A->B Kabel
10 poliges Flachbandkabel
RP6 CD-ROM
Kurzanleitung
RP6 Experimentierplatine
4 Stück 25mm M3 Distanzbolzen
4 Stück M3 Schrauben
4 Stück M3 Muttern
4 Stück 14 pol Wannenstecker
2 Stück 14 pol Flachbandkabel
- 7 -
RP6 ROBOT SYSTEM - 1. Einleitung

1.3. Lieferumfang RP6v2

Folgende Dinge sollten Sie in Ihrem RP6v2 Karton vorfinden:
Fertig aufgebauter RP6 Roboter
RP6 USB Interface
USB A->B Kabel
10 poliges Flachbandkabel
RP6 CD-ROM
Kurzanleitung
Experimentierplatine NICHT
mehr im Lieferumfang!

1.4. Der RP6v2 und Erweiterungsmöglichkeiten

Der RP6v2 ist eine leicht überarbeitete Version des RP6. Die wichtigsten Änderungen betreffen die Drehgeber und zusätzliche Steckverbinder.
Die Drehgeber erforderten beim ursprünglichen RP6 eine Justa­ge damit ein korrektes Signal geliefert wird. Das wurde zwar schon in der Fabrik erledigt, musste nach dem Versand aber oft nochmals vom Anwender wiederholt werden. Dies ist bei den neuen Drehgebern nun dank neuer Sensorelektronik nicht mehr erforderlich (nur noch in Ausnahmefällen, es wurde jedoch auch dafür stark vereinfacht, durch leichter zu­gängliche und deutlich größere Potentiometer). Die Musterauf­kleber sind nun aus einem ro­busteren Material gefertigt und haben einen höheren Kontrast, was die Signalqualität zusätz­lich verbessert und größere To­leranzen bei der Justage zu­lässt.
Beim RP6 waren die Kabel vom Mainboard zu den Drehgebern und den Motoren fest mit Zugentlastung angelötet. Diese wurden nun mit Steckverbindern ausgestattet, so lässt sich das Mainboard sehr leicht vom Chassis abkoppeln und beides getrennt ein­setzen (wurde auch schon beim RP6 ab etwa Anfang 2010 so verbaut). Das erleichtert es eigene Schaltungen auf dem Mainboard aufzulöten, da es ohne angeschlossenes Chassis leichter zu handhaben ist. Bei eventuellen Defekten lässt es sich nun auch ohne Lötarbeiten austauschen und leichter reparieren. Auf dem Mainboard selbst sind 9 zusätzliche Steckverbinder / Stiftleisten hinzugekommen, die sich für diverse Erwei­terungen einsetzen lassen (s. Anhang). Vier davon waren zwar schon beim RP6 vorge­sehen, wurden bislang aber nicht bestückt geliefert.
- 8 -
RP6 ROBOT SYSTEM - 1. Einleitung
Die Hauptsicherung wurde von 2.5A auf 3.15A erhöht, da zusätzliche Stromversor­gungsanschlüsse hinzugekommen sind und die Stromversorgung etwas optimiert wur­de. Dies erlaubt es, größere Verbraucher als bislang zu verwenden. Ebenfalls verbes­sert wurden die Motortreiber, dort werden nun etwas leistungsfähigere und robustere MOSFETs verwendet was die ohnehin schon geringen Verluste weiter reduziert.
Die Kosten für all diese Modifikationen und allgemeine Steigerungen der Produktions­kosten erlauben es leider nicht länger die Experimentierplatine kostenlos mitzuliefern. Diese muss nun separat erworben werden. Der Rest des Roboters wurde unverändert beibehalten um Softwarekompatibilität zu gewährleisten. Wenn mehr Rechenleistung benötigt wird, gibt es neben der Experimentierplatine die RP6-M32, RP6-CC128 und RP6v2-M256-WIFI Erweiterungsmodule. Diese erlauben es den Roboter mit zusätzli­cher Rechenleistung und zahlreichen Schnittstellen für Sensorik und Kommunikation auszustatten. Das RP6-M32 Modul ist die günstigste Erweiterung und bietet einen wei­teren ATMEGA32, jedoch mit doppeltem Takt und vielen freien I/O Ports. Es eignet sich auch gut als Ergänzung zu den beiden größeren Modulen, falls die Rechenleistung des großen Moduls allein für bestimmte Sensoren mal nicht ausreicht.
Das RP6-CC128 Modul erlaubt die C-Control PRO MEGA128 Unit zusammen mit 64KB SRAM auf dem RP6 zu verwenden. Die Programmierumgebung ist eine komfortable IDE die sowohl CompactC als auch BASIC als Programmiersprache zulässt und Debug­ging über die serielle Schnittstelle unterstützt.
Das leistungsstärkste Erweiterungsmodul ist das RP6v2-M256-WIFI. Es enthält neben einem ATMEGA2560 (16MHz, 256KB Flash, 8K SRAM, ...) auch ein 2.4GHz 802.11g WLAN Funkmodul, mit dem der RP6 über ein drahtloses Computernetzwerk über­wacht, gesteuert und neu programmiert werden kann. Die insgesamt 60 freien I/O Ports mit zahlreichen ADC, PWM, SPI und UART Kanälen lassen Spielraum für nahezu beliebige Sensorik und Aktorik Erweiterungen. Über eine microSD Karte kön­nen große Datenmengen >2GByte gespeichert werden (für Datenlogging, Kartenmaterial, Webseiten, o.ä.).
Auf den zwei Bildern auf dieser Seite sind der RP6 mit zwei Erweiterungsmodulen (Ex­perimentier Platine und RP6-M32 mit LCD) und der neue RP6v2 mit RP6v2-M256-WIFI Modul (das RP6v2-M256 kann selbstverständlich auch auf dem alten RP6 verwendet werden!), Antenne und LCD zu sehen.
- 9 -
RP6 ROBOT SYSTEM - 1. Einleitung
Auch Kombinationen z.B. aus RP6v2-M256-WIFI, RP6-M32 und mehreren Experimen­tierplatinen sind möglich – hier hätte man also 3 AVR Prozessoren und insgesamt (inkl. Mainboard) etwa 80 I/O Ports zur Verfügung, die man über Flachbandkabel zu den Experimentierplatinen führen kann. Dort kann man dann beliebige Sensorschal­tungen aufbauen bzw. fertige Sensoren montieren (z.B. Ultraschall oder Infrarot Di­stanzsensoren, Temperatur, Kompass etc.). Der stärkste Prozessor übernimmt die Re­gie und steuert die beiden anderen als Slaves über den I2C Bus an.
Der Vollständigkeit halber sei erwähnt, dass die C-Control Unit zur Zeit nur den Master Modus unterstützt und daher nicht als Slave arbeiten kann. Bei Kombinationen mit mehreren Prozessoren muss also die CC128 Busmaster sein. Es ist daher nur bedingt sinnvoll die M256 und CC128 Boards zu kombinieren. Eine mögliche theoretische Lö­sung wäre die Kommunikation über die normale serielle Schnittstelle, der I2C Port der M128 Unit müsste dann deaktiviert werden oder alternativ als Master arbeiten und die M256 Unit als Slave – diese könnte über die serielle Schnittstelle aber dennoch die Kontrolle über die CC128 Unit übernehmen.
Weitere Informationen, Dokumentation und Software zu den Erweiterungsmodulen sind auf der RP6 Webseite zu finden.
An dieser Stelle nochmals der Hinweis auf die RP6 Webseite (wurde in der Vergangen­heit trotz des deutlichen Hinweises in Abschnitt 1.1 oft überlesen...):
Die CD-ROM kann nur sehr selten aktualisiert werden
(wenn überhaupt).
Aktualisierte Software und Dokumentation gibt es daher natür-
lich nur auf unserer Homepage:
http://www.arexx.com/
und auf der Homepage des Roboters:
http://www.arexx.com/rp6
Sie sollten vor Installation der Software von der CD prüfen ob
evtl. schon neuere Versionen im Internet verfügbar sind.
Und bitte den Hinweis vom Anfang der Anleitung beachten:
ERST den USB Treiber installieren,
DANN das USB Interface anschließen!
- 10 -
RP6 ROBOT SYSTEM - 1. Einleitung

1.5. Features und technische Daten

Dieser Abschnitt gibt einen Überblick darüber, was der Roboter zu bieten hat und dient gleichzeitig der Einführung einiger Begriffe und Bezeichnungen von Komponen­ten des Roboters, die vielen Anwendern noch nicht bekannt sein dürften. Vieles davon wird später im Handbuch noch detaillierter erläutert!
Features, Komponenten und technische Daten des RP6 und RP6v2:
Leistungsfähiger Atmel ATMEGA32 8-Bit Mikrocontroller
Geschwindigkeit 8 MIPS (=8 Millionen Instruktionen pro Sekunde) bei 8MHz TaktSpeicher: 32KB Flash ROM, 2KB SRAM, 1KB EEPROMFrei in C programmierbar (mit WinAVR / avr-gcc)!... und vieles mehr! Weitere Details folgen in Kapitel 2.
Flexibles Erweiterungssystem, basierend auf dem I²C-Bus
Nur zwei Signalleitungen erforderlich (TWI -> "Two Wire Interface")Übertragungsgeschwindigkeit von bis zu 400kBit/s Master->Slave basierendBis zu 127 Slaves können gleichzeitig am Bus angeschlossen werdenWeit verbreitetes Bussystem: Es sind sehr viele standard ICs, Sensoren und ähnli-
ches von vielen verschiedenen Herstellern verfügbar, die meist direkt daran ange­schlossen werden können.
Symmetrische Montagemöglichkeiten für Erweiterungsmodule an Front und Heck
Es können theoretisch beliebig viele Erweiterungsmodule übereinander gestapelt
werden, jedoch sind vom Energiebedarf/Gewicht/Bauhöhe her insgesamt nur etwa 6 bis 8 Module sinnvoll (--> jeweils 3 bis 4 Stück vorne und hinten).
22 freie 3.2mm Montagelöcher sind auf dem Mainboard vorhanden, weitere 16 im
Roboterchassis also insgesamt 38 Montagelöcher - und es gibt im Chassis noch sehr viel Platz für eigene Bohrungen!
USB PC Interface für den Programupload vom PC auf den Mikrocontroller Kabelgebunden für maximale Geschwindigkeit. Der Programmupload läuft norma-
lerweise mit 500kBaud - der komplette freie Programmspeicher des Mikrocontrol­lers (30KB, 2KB sind für den sog. Bootloader reserviert) wird innerhalb von weni­gen Sekunden beschrieben.
Das Interface kann zum Programmieren von allen für den RP6 erhältlichen Erwei-
terungsmodulen mit AVR Mikrocontroller verwendet werden.
Kann zur Kommunikation mit dem Roboter oder mit Erweiterungsmodulen ver-
wendet werden - dadurch erleichtert sich die Fehlersuche in Programmen erheb­lich, da man Messwerte, Textnachrichten und andere Daten darüber an den PC senden kann.
Der Treiber des Interfaces erzeugt eine virtuelle serielle Schnittstelle unter allen
- 11 -
RP6 ROBOT SYSTEM - 1. Einleitung
gängigen Betriebssystemen wie Windows XP / 7 und Linux, die mit fast allen Ter­minalprogrammen und eigener Software benutzbar ist.
Für den komfortablen Programmupload wird die Software RobotLoader (früher
war der Name der Software RP6Loader) mitgeliefert. Sie bietet auch direkt ein kleines Terminal um mit dem Roboter über Textnachrichten zu kommunizieren und läuft unter Windows und Linux.
Leistungsfähiges Raupen-Antriebssystem mit neuem Getriebe zur Minimierung der Geräuschentwicklung (im Vergleich zum Vorgänger CCRP5...)
Zwei starke 7.2V DC-MotorenMaximale Geschwindigkeit 25cm/s (30cm/s ohne Software Begrenzung). Das
hängt u.a. von Ladezustand/Qualität der Akkus und Gesamtgewicht ab!
Selbstschmierende Sinterlager an allen vier 4mm RadachsenZwei Gummi-RaupenkettenKann kleinere Hindernisse (bis ca. 2cm Höhe) wie Teppichkanten, Bodenuneben-
heiten, auf dem Boden liegende Zeitschriften, Kabel o.ä. problemlos überqueren und Rampen bis maximal etwa 30% Steigung befahren (mit der Bumper Platine ; ohne Bumper und mit maximal 2 Erweiterungsmodulen sind auch bis zu 40% Stei­gungen befahrbar – je nach Beschaffenheit des Untergrunds).
Zwei leistungsfähige MOSFET Motortreiber (H-Brücken)Drehzahl und Drehrichtung können vom Mikrocontroller gesteuert werdenZwei Stromsensoren mit Messbereich bis ca. 1.8A für beide Motoren (ideal um
schnell auf blockierte/stark belastete Motoren zu reagieren)
MOSFET Treiberstufen wurden beim RP6v2 leicht verbessert (noch etwas niedrige-
re Verluste und robustere MOSFETs)
Zwei hochauflösende Drehgeber zur Geschwindigkeits- und WegmessungAuflösung von 625 CPR ("Counts per Revolution" = Zählschritte pro Umdrehung)
d.H. es werden 625 Segmente der Radencoderscheibe pro Radumdrehung von den Drehgebern gezählt! (Beim alten RP5 waren es nur etwa 4 CPR)
Genaue und schnelle Geschwindigkeitsmessung und Regelung möglich! Hohe Wegstreckenauflösung von (etwa) 0.25 Millimetern pro Zählschritt!Beim RP6v2 deutlich verbesserte Sensorelektronik und Musteraufkleber!
Anti-Kollisions-System (Anti Collision System, ACS) das mithilfe eines Infrarot
Emfängers und zwei auf der Platine davor nach links und rechts ausgerichteten In­frarotdioden Hindernisse erkennen kann
Erkennt ob sich Objekte in der Mitte, links oder rechts vor dem Roboter befinden.Die Reichweite/Sendeleistung ist in mehreren Stufen einstellbar und so können
auch schlecht reflektierende Objekte erkannt werden.
Infrarot Kommunikationssystem (IRCOMM)Empfängt Signale von normalen Infrarot Fernbedienungen von Fernsehern oder
Videorecordern. So kann der Roboter mit einer normalen (RC5-)Fernbedienung gesteuert werden! Das Protokoll kann per Software angepasst werden, standard­mäßig ist jedoch nur das gängige RC5 Protokoll implementiert.
- 12 -
RP6 ROBOT SYSTEM - 1. Einleitung
Kann zur Kommunikation von mehreren Robotern verwendet werden (Reflektion
an Zimmerdecke bzw. Sichtverbindung) oder um Telemetriedaten zu übertragen.
Zwei Lichtsensoren - z.B. für Helligkeitsmessungen und Lichtquellenverfolgung
Zwei Stoßstangensensoren (Bumper) um Kollisionen zu erkennen
6 Status LEDs - um Sensoren und Programmzustände gut darstellen zu könnenVier der LED Ports können auch für andere Funktionen verwendet werden!
Zwei freie Analog/Digital Wandler (ADC) Kanäle für eigene Sensoren. (Diese
sind auch als normale I/O Pins benutzbar).
Präziser 5V SpannungsreglerMaximale Belastbarkeit: 1.5A Große Kupferfläche zur Kühlung auf der PlatineDer Dauerstrom sollte ohne zusätzliche Kühlung 1A nicht überschreiten! (Es wird
eine maximale Dauerlast von weniger als 900mA empfohlen)
Leicht wechselbare 2.5A Sicherung beim RP6 und 3.15A Sicherung beim RP6v2
Geringe Standby Stromaufnahme von weniger als 5mA (typ. 1mA, ca. 17 bis
40mA im Betrieb. Variiert je nachdem was alles angeschaltet ist (LEDs, Sensoren etc.). Diese Angabe bezieht sich natürlich nur auf die Elektronik, ohne die Motoren und ohne Erweiterungsmodule!)
Stromversorgung mit 6 NiMH Mignon Akkus (nicht im Lieferumfang enthalten!)Size AA, z.B. Sanyo (NiMH, 1.2V, 2500mAh, HR-3U), Sanyo Eneloop (High Capa-
city XX, 2500mAh, HR-3UWX) oder Panasonic Infinium, oder Energizer (NiMH,
1.2V, 2500mAh, NH15-AA) o.ä., mindestens 2000mAh.
Betriebszeit etwa 3 bis 6 Stunden je nach Belastung und Qualität/Kapazität der
Akkus (hängt natürlich davon ab wie oft und wie lange die Motoren laufen und wie sie belastet werden! Wenn die Motoren nur selten laufen, kann der Roboter noch viel länger arbeiten. Die Angabe oben bezieht sich nur auf den Roboter ohne Er­weiterungsmodule)
Anschluss für externe Ladegeräte - der Hauptschalter des Roboters schaltet zwi- schen "Laden/Aus" und "Betrieb/An" um.
Dies kann über einige herausgeführte Kontakte geändert werden und so können
auch externe Stromversorgungen oder zusätzliche Akkus an den Roboter ange­schlossen werden.
Passende externe Steckerladegeräte z.B. Voltcraft 1A / 2A Delta-Peak Akkupack
Schellladegerät, Ansmann ACS110, ACS410 oder AC48 ). Die Ladegeräte unter­scheiden sich in Austattung und Ladezeit von 3 bis 14h.
6 kleine Erweiterungsflächen auf dem Mainboard (und 2 sehr kleine auf der Sensorplatine) um eigene Sensorschaltungen direkt auf dem Mainboard unterzubrin­gen. Beispielsweise könnte man rings um den Roboter noch weitere IR Sensoren anbringen um besser auf Hindernisse reagieren zu können. Die Erweiterungsflächen können natürlich auch für Montagezwecke verwendet wer­den (z.B. Drähte und Halterungen anlöten).
Zahlreiche Modifikationsmöglichkeiten!
- 13 -
RP6 ROBOT SYSTEM - 1. Einleitung
Weiterhin werden einige C Beispielprogramme sowie eine sehr umfangreiche Funkti­onsbibliothek mitgeliefert, welche die Programmierung stark erleichtert.
Auf der Website zum Roboter werden demnächst evtl. weitere Programme und Upda­tes für den Roboter und seine Erweiterungsmodule zur Verfügung stehen. Sie können natürlich auch gerne Ihre eigenen Programme über das Internet mit anderen RP6 An­wendern austauschen! Die RP6Library und die Beispielprogramme stehen unter der Open Source Lizenz GPL!

1.6. Was kann der RP6?

Nun, direkt aus der Verpackung genommen noch nicht viel! Erst durch seine Programmierung kann der RP6 etwas tun - was das genau ist, liegt
komplett bei Ihnen und Ihrer Kreativität! Das macht den eigentlichen Reiz von Robo­terbausätzen und ähnlichem aus: eigene Ideen umsetzen oder vorhandenes verbes­sern und modifizieren! Sie können aber natürlich erstmal einfach nur die vorgefertig­ten Programme ausprobieren und verändern um einen Eindruck von den Werksseitig gegebenen Möglichkeiten zu bekommen.
Hier werden also nur einige wenige Beispiele genannt - es liegt ganz bei Ihnen was Sie aus dem RP6 machen - es gibt noch viel mehr Möglichkeiten (s. nächste Seite)!
Der RP6 kann von Haus aus z.B. ...:
... autonom (d.H. selbstständig ohne Fernsteuerung o.ä.) umherfahren
... Hindernissen ausweichen
... Lichtquellen suchen/verfolgen
... Kollisionen, blockierte Motoren und niedrigen Batterie-Ladezustand erkennen und
darauf reagieren
... die Fahrgeschwindigkeit messen und automatisch einregeln – nahezu unabhängig vom Ladezustand der Batterien, dem Gewicht des Roboters etc. (das ist die Haupt­anwendung der hochauflösenden Encoder)
... bestimmte Distanzen fahren, sich um bestimmte Winkel drehen und die zurück­gelegte Wegstrecke bestimmen (allerdings mit Abweichungen, s. Kapitel 2)
... bestimmte Muster und Figuren abfahren wie Kreise, bel. Vielecke, o.ä.
... mit anderen Robotern oder Geräten über das Infrarot-Kommunikationssystem
Daten austauschen oder darüber gesteuert werden. Das funktioniert mit gängigen TV/Video/HiFi Fernbedienungen! Damit kann man den Roboter z.B. ähnlich wie ein ferngesteuertes Auto bedienen.
... Sensorwerte und andere Daten über das USB Interface an den PC übertragen
... sehr gut und einfach über das Bussystem erweitert werden! Er lässt sich einfach
mit vielen weiteren Fähigkeiten ausstatten!
... modifiziert und den eigenen Vorstellungen angepasst werden. Einfach mal in die Schaltpläne auf der CD schauen und die Platine etwas genauer betrachten! Aber än­dern Sie bitte nur etwas, wenn Sie wissen was Sie da eigentlich tun! Sie sollten lie­ber zunächst mit einem der Erweiterungsboards anfangen – vor allem wenn Sie noch nie eine Schaltung zusammengelötet haben...
- 14 -
RP6 ROBOT SYSTEM - 1. Einleitung

1.7. Anwendungsvorschläge und Ideen

Der RP6 ist auf Erweiterung seiner Fähigkeiten ausgelegt - mit Erweiterungsmodulen und zusätzlichen Sensoren könnte man dem RP6 z.B. folgende Dinge „beibringen“ (ei­nige der hier genannten Aufgaben sind schon recht kompliziert und nicht ganz so ein­fach umzusetzen, die Themen sind grob aufsteigend nach Schwierigkeit geordnet):
Den Roboter mit weiteren Controllern und damit mit zusätzlicher Rechenleistung, Speicher, I/O Ports und A/D Wandlern etc. ausrüsten. Oder wie in den Beispielpro­grammen kurz angesprochen mit einfachen I²C Porterweiterungen und A/D Wand­lern erweitern.
Sensordaten und Texte auf einem LC-Display auf dem Roboter ausgeben
Auf Geräusche reagieren und Töne erzeugen
Mit zusätzlichen Objektsensoren, Ultraschallsensoren, Infrarotsensoren o.ä. die Di-
stanz zu Hindernissen bestimmen und diesen somit besser ausweichen
Schwarze Linien auf dem Boden verfolgen
Andere Roboter oder Gegenstände verfolgen/suchen
Den Roboter per Infrarot vom PC aus steuern (erfordert eigene Hardware – das geht
leider nicht mit normalen IRDA Schnittstellen!). Oder gleich Funkmodule einsetzen.
Den RP6 mit einem PDA oder Smartphone steuern (hier ist gemeint, dass diese Ge­räte auf dem Roboter montiert werden und nicht wie eine Fernbedienung o.ä. ver­wendet werden. Das wäre aber auch möglich!).
Gegenstände (z.B. Teelichter oder kleine Kugeln, Metallteile ...) einsammeln
Einen kleinen Roboterarm/Greifer anbauen um nach Gegenständen zu greifen
Mit einem elektronischen Kompass navigieren und zusätzlich Infrarotbaken (also
kleine Türme o.ä. mit vielen IR-LEDs deren Position genau bekannt ist) erkennen und so die eigene Position im Raum bestimmen und vorgegebene Zielpunkte an­steuern
Wenn man mehrere Roboter mit einer Schussvorrichtung/Ballführung und weiteren Sensoren ausstattet, könnte man die Roboter auch Fussball spielen lassen!
... was immer Ihnen sonst einfällt!
Erstmal müssen Sie jedoch diese Anleitung lesen und sich grundsätzlich mit dem Ro­boter und der Programmierung vertraut machen. Das hier sollte nur eine kleine Moti­vation sein.
Und wenn es mal mit der Programmierung nicht auf Anhieb klappt, bitte nicht gleich alles aus dem Fenster werfen, aller Anfang ist schwer!
- 15 -
RP6 ROBOT SYSTEM - 2. Der RP6 im Detail

2. Der RP6 im Detail

Dieses Kapitel beschäftigt sich detaillierter mit den wichtigsten Hardware Komponen­ten des RP6. Hier gehen wir auf die Funktionsweise der Elektronik und das Zusam­menspiel mit der Software auf dem Mikrocontroller ein. Wenn Sie bereits Erfahrung mit Mikrocontrollern und Elektronik haben, brauchen Sie viele der Abschnitte in die­sem Kapitel vermutlich nur kurz zu überfliegen. Allen Robotik Einsteigern empfehlen wir jedoch lieber erstmal dieses Kapitel ganz in Ruhe durchzulesen, um eine bessere Vorstellung der Funktionsweise des RP6 zu bekommen!
Wenn Sie es nicht abwarten können und lieber sofort den Roboter ausprobieren möch­ten, können Sie auch bei Kapitel 3 weitermachen, aber Sie sollten später noch auf die­ses Kapitel zurückkommen. Es ist zum Verständnis vieler Teile der Programmierung sehr hilfreich. Sie wollen doch bestimmt gern wissen, was Sie da eigentlich mit der Software ansteuern und wie das in etwa funktioniert?
Wir gehen hier nicht allzusehr in die Tiefe, aber trotzdem könnten ein paar Dinge in diesem Kapitel auf den ersten Blick nicht ganz so leicht zu verstehen sein - der Autor hat sich aber Mühe gegeben, alles so einfach wie möglich zu erklären.
Es lohnt sich, zu verschiedenen Dingen weitere Informationen im Internet oder in Bü­chern zu suchen. http://www.wikipedia.de/ ist z.B. oft ein guter Ausgangspunkt.
Bilder sagen bekanntlich mehr als Worte, also fangen wir mit einem Blockdiagramm des RP6 an, auf dem eine stark vereinfachte Darstellung der elektronischen Kompo­nenten des Roboters zu sehen ist:
- 16 -
RP6 ROBOT SYSTEM - 2. Der RP6 im Detail
Man kann den RP6 grob in 5 Funktionsgruppen unterteilen:
Steuerungssystem (Control System)
Stromversorgung (Power Supply)
Sensorik, IR Kommunikation und Anzeigen (Sensors) – alles was mit der Aussenwelt
kommunizieren kann bzw. bestimmte Werte misst.
Antriebssystem (Drive System)
Erweiterungssystem (Expansion System)

2.1. Steuerungssystem

Wie man auf dem Blockdiagramm leicht erkennen kann, ist das zentrale Element des Roboters der ATMEGA32 8-Bit Mikrocon­troller von ATMEL (s. Abb.).
Ein Mikrocontroller ist ein vollständiger kleiner Computer, der auf einem einzigen Chip integriert ist. Der Unterschied zu dem großen Computer vor dem Sie vermutlich gerade sitzen ist, dass er von allem sehr viel weniger hat bzw. einige Dinge gleich weg-
gelassen wurden. Er verfügt natürlich über keine riesige Fest­platte, oder mehrere Gigabyte RAM! Ein Mikrocontroller kommt auch mit weit weit we­niger aus. Der MEGA32 hat z.B. "nur" 32KB (32768 Bytes) Flash ROM - das ist quasi seine "Festplatte". Darin werden alle Programmdaten gespeichert. Sein Arbeitsspei­cher ist 2KB (2048 Bytes) groß und damit für unsere Zwecke mehr als ausreichend. (Zum Vergleich: Der Controller auf dem alten RP5 hatte gerade mal 240 Bytes RAM wovon fast alles vom Basic Interpreter verwendet wurde)
Und wie kann der Mikrocontroller mit so wenig Speicher auskommen? Ganz einfach: Er verarbeitet keine großen Datenmengen und braucht weder ein Betriebssystem wie Linux oder gar Windows, noch eine graphische Oberfläche oder sonstiges in der Art. Es läuft nur ein einziges Programm auf dem Controller, nämlich unser eigenes!
Das ist keineswegs ein Nachteil, sondern einer der größten Vorteile eines Mikrocon­trollers gegenüber einem großen Computer (neben Energieverbrauch, Platzbedarf und Kosten)! Er kann sehr zeitkritische Dinge erledigen, die auf die Mikrosekunde genau ausgeführt werden müssen. Man kann meist genau ermitteln, wie lange er zur Ausfüh­rung eines bestimmten Programmteils braucht, denn man teilt sich die verfügbare Re­chenleistung nicht mit vielen anderen Programmen wie auf einem normalen PC.
Der Controller auf dem RP6 wird mit 8MHz getaktet und führt so 8 Millionen Instruk­tionen pro Sekunde aus. Es wären zwar bis zu 16MHz möglich, darauf wird jedoch aus Stromspargründen verzichtet - er ist auch so schnell genug für die Aufgaben die er für gewöhnlich übernimmt! (Wieder der Vergleich mit dem alten RP5: Dieser hat bei 4MHz Takt nur ca. 1000 Basic Befehle pro Sekunde ausgeführt. Daher musste u.a. die ACS Steuerung von einem weiteren kleinen Controller übernommen werden – was nun nicht mehr notwendig ist!) Wer noch mehr Rechenleistung benötigt, kann einen oder mehrere zusätzliche Controller auf Erweiterungsmodulen anschließen. Das separat er­hältliche RP6Control bietet u.a. einen zweiten MEGA32 der mit den maximal möglichen 16MHz getaktet wird.
Mit der Aussenwelt kommuniziert der Controller über seine 32 I/O Pins ("Input/Out­put Pins" also Ein- und Ausgangs Pins). Die I/O Pins sind in sog. "Ports" zu jeweils 8 I/O Pins organisiert. Davon hat der MEGA32 also 4 Stück: PORTA bis PORTD.
- 17 -
RP6 ROBOT SYSTEM - 2. Der RP6 im Detail
Der Controller kann den logischen Zustand der Ports einlesen und in der Software wei­terverarbeiten. Genauso kann er auch logische Zustände über die Ports ausgeben und kleinere Lasten wie z.B. LEDs damit schalten (bis ca. 20mA).
Zusätzlich verfügt der Controller über viele integrierte Hardware Module, die spezielle Funktionen übernehmen können. Diese wären meist gar nicht oder nur mit viel Auf­wand in Software realisierbar und würden viel zuviel wertvolle Rechenzeit in Anspruch nehmen. So hat er z.B. drei verschiedene "Timer", die u.a. Taktzyklen zählen können und deshalb häufig für Zeitmessungen eingesetzt werden. Die Timer laufen unabhän­gig von der Programmausführung des Mikrocontrollers und dieser kann während er z.B. auf einen bestimmten Zählerstand wartet, andere Dinge tun. Einer der Timer wird beim RP6 dazu verwendet, zwei Pulsbreitenmodulierte Signale (PWM="Pulse Width Modulation") zu erzeugen, mit denen die Spannung der Motoren und damit deren Drehzahl eingestellt werden kann. Nachdem man einen der Timer im Programm ein­mal wie gewünscht konfiguriert hat, arbeitet er anschließend ohne weiteres zutun fort­laufend im Hintergrund. Mehr zum Thema PWM folgt im Abschnitt "Antriebssystem".
Einige andere Module des MEGA32 sind z.B.:
Eine serielle Schnittstelle (UART) die zur Kommunikation mit dem PC über das USB
Interface verwendet wird. Hier könnte man auch andere Mikrocontroller mit einem UART anschließen - solange das USB Interface nicht angeschlossen ist!
Das "TWI" (="Two Wire Interface", also Zweidraht Schnittstelle) Modul für den I²C
Bus des Erweiterungssystems.
Ein Analog/Digital Wandler ("Analog to Digital Converter", ADC) mit 8 Eingangs-
kanälen, der Spannungen mit 10bit Auflösung messen kann. Damit werden auf dem RP6 die Batteriespannung überwacht, die Motorstromsensoren ausgewertet und die Lichtstärke über zwei lichtabhängige Widerstände gemessen.
Drei externe Interrupt Eingänge. Diese erzeugen ein sog. Interrupt Ereignis, das den
Programmablauf im Controller unterbricht und ihn zu einer speziellen "Interrupt Ser­vice Routine" springen lässt. Er arbeitet diese dann zunächst ab und kehrt danach wieder an die Stelle im Programm zurück, an der er sich vor dem Interrupt Ereignis befand. Das wird z.B. für die Drehgeber verwendet. Aber dazu später mehr...
Diese Spezialfunktionen können alternativ zu den normalen I/O Pins geschaltet wer­den, sie haben also keine eigenen Pins am Mikrocontroller. Welche der Funktionen ak­tiv sind, kann man einstellen. Da auf dem RP6 aber fast alles fest verdrahtet ist, macht es natürlich kaum einen Sinn, die Standardbelegung zu ändern.
Der MEGA32 hat noch viele andere Dinge integriert, aber die können wir hier nicht alle explizit beschreiben. Wer mehr wissen will, kann sich im Datenblatt des Herstellers schlau machen (auf der CD).
Man muss dazu natürlich die englische Sprache beherrschen! Fast jede Dokumentation von Drittherstellern ist nur in Englisch verfüg­bar. Das ist normal, denn die englische Sprache ist Standard in der Elektronik und Computer Branche.
Tipp: Unter http://dict.leo.org/ finden Sie ein sehr gutes, kos­tenlos verwendbares online Deutsch/Englisch Wörterbuch, das auch
viele technische Begriffe kennt.
- 18 -
RP6 ROBOT SYSTEM - 2. Der RP6 im Detail

2.1.1. Bootloader

Im Mikrocontroller befindet sich in einem speziellen Speicherbereich der sog. Bootloa­der. Das ist ein kleines Programm, das über die serielle Schnittstelle des Mikrocontrol­lers neue Programme in den Programmspeicher laden kann. Der Bootloader kommuni­ziert mit einem Host PC über die mitgelieferte RobotLoader Software (ehemals RP6Loader). Durch den speziell für den RP6 entwickelten Bootloader entfällt ein nor­malerweise benötigtes Programmiergerät. Einziger kleiner Nachteil: Es sind von den 32KB Programmspeicher des MEGA32 nur 30KB für Sie nutzbar! Das macht aber nichts – auch das reicht schon für sehr komplexe Programme (zum Vergleich: der kleinere Roboter ASURO von AREXX hat nur 7KB freien Speicher und trotzdem kommt man gut damit aus)!

2.2. Stromversorgung

Natürlich benötigt ein Roboter Energie. Diese trägt der RP6 gespeichert in 6 Akkus mit sich herum. Die Laufzeit ist durch die Kapazität der Akkus eingeschränkt, denn auch wenn die Elektronik verhältnismäßig wenig Energie benötigt, schlucken die Motoren je nach Belastung doch ziemlich viel.
Damit die Akkus möglichst lange halten und der Roboter nicht ständig Pause machen muss, sollte man ihm daher etwas größere Energiespeicher mit etwa 2500mAh gön­nen. Kleinere mit 2000mAh oder mehr funktionieren aber auch. Mit guten Akkus kann man 3 bis 6 Stunden oder mehr Laufzeit erreichen, abhängig von der Betriebszeit der Motoren, deren Belastung und Qualität der Akkus. Die 6 Akkus die notwendig sind, haben insgesamt eine Nennspannung von 6x 1.2V = 7.2V. Im Blockdiagramm ist dies mit "UB" (= "U-Battery", U ist der Formelbuchstabe für Spannung) bezeichnet. „Nenn­spannung", weil sich die Spannung mit der Zeit stark verändert. Voll aufgeladen kön­nen die Akkus im Leerlauf insgesamt bis zu 8.5V liefern! Diese Spannung sinkt wäh­rend der Entladung ab und schwankt auch je nach Belastung (Motoren an oder aus, schnell langsam etc. - wie stark die Spannung schwankt, hängt auch von der Qualität der verwendeten Akkus ab. Der Innenwiderstand ist hier die kritische Größe).
Das ist für Messungen von Sensorwerten und ähnlichem natürlich nicht ohne weiteres brauchbar. Noch wichtiger ist jedoch, dass viele der verwendeten Komponenten wie z.B. der Mikrocontroller nur auf 5V oder weniger Betriebsspannung ausgelegt sind und bei so hohen Spannungen zerstört würden. Die Akku Spannung muss also auf einen definierten Wert heruntergeregelt und stabilisiert werden!
Das übernimmt ein 5V Spannungsregler, der einen Strom von
maximal 1.5A liefern kann (s. Abb.). Bei 1.5A würde er jedoch
ziemlich viel Wärme abgeben. Es gibt daher eine große Kühlflä-
che auf der Platine an die der Regler festgeschraubt ist. Über 1A
sollte der Regler trotz Kühlung besser nur kurzzeitig (also weni-
ge Sekunden) belastet werden, wenn man nicht noch einen zu-
sätzlichen großen Kühlköper draufschraubt.
Es wird empfohlen, 800mA Dauerlast nicht zu überschreiten! Bei
so einer Belastung und zusammen mit den Motoren wären die
Akkus auch recht schnell leer. Im normalen Betrieb ohne ein Er­weiterungsboard nimmt der Roboter übrigens nicht mehr als 40mA auf (ausser wenn das IRCOMM sendet), also überhaupt kein Problem für den Regler und man hat noch genug Reserven für die Erweiterungsmodule, die meistens auch nicht mehr als 50mA aufnehmen sofern keine Motoren, große LEDs o.ä. daran angeschlossen sind.
- 19 -
RP6 ROBOT SYSTEM - 2. Der RP6 im Detail
10V
1024
= 9.765625mV

2.3. Sensorik

Die meisten Sensoren über die der Roboter verfügt, haben wir ja schon in anderen Abschnitten kurz genannt, wollen diese nun aber etwas detaillierter betrachten.
In dem Blockdiagramm sind einige der Sensoren nicht in dem blauen Bereich "Sen­sors" zu sehen, weil sie besser in andere Bereiche passen. Trotzdem zählen natürlich auch die Drehgeber (=“Encoder“), Motorstromsensoren und der Batteriespannungs­sensor zu den Sensoren und werden darum in diesem Abschnitt beschrieben!

2.3.1. Batteriespannungs-Sensor (Voltage Sensor)

Dieser "Sensor" ist eigentlich nur ein einfacher Spannungsteiler aus zwei Widerstän­den. Wir gehen davon aus, dass die Batterien insgesamt maximal 10V liefern können. 6 NiMH Akkus werden immer unterhalb davon bleiben. Die Referenzspannung des ADC, also die Spannung mit der er die gemessene Spannung vergleicht, beträgt 5V. Da auch die Betriebsspannung 5V beträgt, darf diese nicht überschritten werden. Also müssen wir die zu messende Spannung um die Hälfte herabsetzen! Dies geschieht über einen Spannungsteiler aus zwei Widerständen, der die Spannung an den Messbe­reich des ADCs anpasst.
Der ADC löst mit 10 Bit auf (Wertebereich 0 bis 1023), was eine Auflösung von
ergibt. Ein Messwert von 512 entspricht hier also 5V und 1023 wä-
ren ungefähr 10V! Diese Grenzwerte sollten aber normalerweise nie erreicht werden! Das ist nicht besonders genau, da die Widerstände keineswegs Präzisionswiderstände
sind. Abweichungen von einigen Prozent nach oben und unten sind möglich. Auch die Referenzspannung von 5V ist nicht ganz genau und kann bei normaler Belastung et­was variieren. Das stört hier nicht, denn wir brauchen ohnehin nur einen ungefähren Wert um festzustellen ob die Batterien sich langsam dem Ende nähern. Wer die Span­nung genau messen will, braucht ein Multimeter um den Messfehler zu ermitteln und diesen dann in Software auszugleichen.
Wenn man mit Fehlern leben kann, kann man die Spannung dank des günstigen Um­rechnungsverhältnisses sogar direkt aus den ADC Werten ungefähr abschätzen: 720 entsprechen dann grob 7.2V, 700 etwa 7V und 650 wären etwa 6.5V. Bei einem kon­stanten Wert unter 560 kann man davon ausgehen, dass die Akkus fast leer sind.

2.3.2. Lichtsensoren (LDRs)

Vorne auf der kleinen Sensorplatine des Roboters sind zwei sog. LDRs (="Light Dependant Resistors" also lichtabhängige Wider­stände) platziert und nach links bzw. rechts ausgerichtet. Zwi­schen den beiden Sensoren ist noch eine kleine schwarze „Trennwand“ damit das Licht aus einer Richtung möglichst nur
einen der Sensoren erreicht. Sie bilden zusammen mit je einem normalen Widerstand wie beim Batteriesensor einen Spannungsteiler – hier allerdings um das Umgebungslicht zu messen. Die 5V Betriebsspannung wird auch geteilt, aber hier ist einer der Widerstände variabel! Es wird also das Teilungsverhältnis je nach In­tensität des Lichteinfalls verändert und somit eine vom Lichteinfall abhängige Span­nung an einen der A/D Wandler Kanäle geleitet!
Über den Spannungsunterschied zwischen den beiden Sensoren kann man ermitteln in welcher Richtung sich eine bzw. die hellste Lichtquelle vor dem Roboter befindet: Links, Rechts oder in der Mitte.
- 20 -
RP6 ROBOT SYSTEM - 2. Der RP6 im Detail
Mit einem entsprechenden Programm, kann man so z.B. eine starke Taschenlampe in einem abgedunkelten Zimmer verfolgen, oder den Roboter die hellste Stelle in einem Raum suchen lassen! Klappt z.B. sehr gut mit einem stärkeren Hand-Halogenschein­werfer: Wenn man damit auf den Boden leuchtet, kann der Roboter dem Lichtfleck auf dem Boden folgen.
Das geht natürlich auch umgekehrt: Der Roboter könnte z.B. auch versuchen sich vor hellem Licht zu verstecken...
Wenn man noch ein oder zwei LDRs hinten am Roboter anbringen würde, könnte man das noch verfeinern und die Richtung in der sich Lichtquellen befinden besser bestim­men. Der Roboter kann sonst nämlich oft nur schwer unterscheiden ob die Lichtquelle vor oder hinter ihm liegt. Zwei der A/D Wandler Kanäle sind noch frei...

2.3.3. Anti Collision System (ACS)

Der aus Softwaresicht komplexeste Sensor des RP6 ist das ACS - das „Anti Collision System“ (engl. für Anti Kollisions System)! Es besteht aus einem IR Empfänger (s. Abb.) und zwei vorne auf der Sensorpla­tine links und rechts angebrachten IR LEDs. Die IR LEDs werden di­rekt vom Mikrocontroller angesteuert. Die Ansteuerungsroutinen kön­nen beliebig verändert und verbessert werden! Beim Vorgängermo­dell war dafür noch ein eigener Controller nötig, dessen Programm aber nicht vom Anwender geändert werden konnte...
Mit den IR LEDs werden kurze, mit 36kHz modulierte Infrarot Impulse
ausgesandt, auf die der darauf ausgelegte IR Empfänger reagiert. Werden die IR Impule an einem Gegenstand vor dem Roboter reflektiert und vom IR Empfänger detektiert, kann der Mikrocontroller darauf reagieren und z.B. ein Aus­weichmanöver einleiten. Damit das ACS nicht zu empfindlich bzw. auf eventuelle Stö­rungen reagiert, wartet die Software bis eine bestimmte Anzahl von Impulsen in einer bestimmten Zeit empfangen worden ist. Es wird auch eine Synchronisation mit dem RC5 Empfang durchgeführt und auf die RC5 Signale von TV/Hifi Fernbedienungen wird so nicht reagiert. Bei anderen Codes kann das aber nicht garantiert werden und das ACS könnte dann Hindernisse erkennen, wo gar keine sind!
Da es je eine IR LED links und rechts gibt, kann das ACS grob unterscheiden ob sich das Objekt links, rechts oder mittig vor dem Roboter befindet.
Man kann zusätzlich noch die Stromstärke mit der die beiden IR LEDs gepulst werden in drei Stufen einstellen. Das ACS funktioniert aber auch in der höchsten Stufe nicht mit allen Objekten immer zuverlässig, denn es kommt auf die Beschaffenheit der Oberfläche des jeweiligen Objekts an! Ein schwarzes Objekt reflektiert das IR Licht na­türlich viel schlechter als ein weisses Objekt und ein kantiges und spiegelndes Objekt könnte das IR Licht hauptsächlich in eine bestimme Richtung reflektieren. Die Reich­weite ist also immer vom jeweiligen Objekt abhängig! Das ist eine prinzipielle Schwä­che von so gut wie allen IR Sensoren (jedenfalls in dieser Preisklasse).
Trotzdem werden die meisten Hindernisse zuverlässig erkannt und können umfahren werden. Falls das mal nicht klappt, gibt es noch die Stoßstange mit den Tastsensoren und falls auch die nicht richtig getroffen werden, kann der Roboter noch mit den Mo­torstromsensoren oder den Encodern erkennen, ob die Motoren blockieren (s.u.)!
Wem das nicht reicht, der könnte zusätzlich z.B. noch Ultraschallsensoren anbringen...
- 21 -
RP6 ROBOT SYSTEM - 2. Der RP6 im Detail
U = R⋅I

2.3.4. Stoßstangensensoren (Bumper)

Vorn am Roboter sind zwei Mikroschalter mit langem Schalthebel auf einer separaten Platine untergebracht, die etwas vor der anderen Sensorplatine liegt. Dadurch werden die IR LEDs auf der Sensorplatine geschützt und können nicht so leicht verbiegen wenn der Roboter mal gegen ein Hindernis fährt. Mit den zwei Schaltern kann der Mi­krocontroller einen solchen Aufprall registrieren und dann beispielsweise zurücksetzen, sich etwas drehen und weiterfahren. Die Schalter sind an zwei der Ports die schon mit den LEDs verbunden sind angeschlossen und blockieren so keine anderen Ports des Mikrocontrollers. Daher leuchten die LEDs auch immer wenn man einen der Schalter drückt! Da dies normalerweise relativ selten passiert, stört das aber nicht weiter.
Die Stoßstange kann man auch abmontieren und z.B. gegen eine Schuss- oder Sam­melvorrichtung für Bälle o.ä. ersetzen wenn man möchte.

2.3.5. Motorstromsensoren (Current sensing)

Es befinden sich zwei Leistungswiderstände in den beiden Motorstromkreisen. Aus dem Ohm'schen Gesetz
folgt, dass sich die Spannung die an einem bestimmten Wi­derstand abfällt, proportional zum Strom verhält, der die­sen durchfließt!
Damit die Spannungsabfälle an den Widerständen nicht zu groß werden, müssen die Widerstände klein gewählt wer-
den. In unserem Fall haben Sie einen Wert von 0.1 Ohm Die abfallende Spannung ist also nur sehr klein (0.1V bei einem Strom von 1A) und
muss verstärkt werden bevor sie mit dem ADC gemessen werden kann. Das erledigt jeweils ein sog. Operationsverstärker (OPV). In der Schaltung des RP6 wird je Motor­kanal ein OPV verwendet. Der Messbereich geht etwa bis 1.8A. Bei 1.8A fallen etwa
0.18V am Widerstand ab und es ergibt sich am Ausgang des OPV eine Spannung von etwa 4V. Mehr kann der verwendete OPV bei 5V Betriebsspannung nicht ausgeben.
Die Leistungswiderstände haben eine Toleranz von 10%, die Widerstände am OPV 5%, also ist das alles nur sehr ungenau (Ungenauigkeiten im Bereich von etwa 270mA sind möglich wenn man die Sensoren nicht kalibriert!). Wir brauchen allerdings auch nur den ungefähren Wert um festzustellen ob die Motoren stark oder wenig belastet werden. So kann der Roboter gut blockierte oder gar defekte Motoren bzw. Drehgeber erkennen! Die DC-Motoren benötigen mehr Strom je stärker sie belastet werden (Drehmoment) und somit steigt der Strom sehr stark an wenn die Motoren blockiert sind. Das wird von der Robotersoftware zur Notabschaltung verwendet: wenn die Mo­toren dauerhaft mit hohem Strom betrieben würden, könnten diese sehr heiß werden und dadurch Schaden nehmen! Und wenn die Encoder mal ausfallen sollten – aus wel­chem Grund auch immer – kann auch das damit erkannt werden. Man würde dann eine Drehzahl von 0 messen. Lässt man die Motoren aber auf voller Kraft laufen und der Strom bleibt trotzdem klein (also sind die Ketten nicht blockiert!), kann man ge­nau daraus schließen, dass entweder die Encoder, oder die Motoren ausgefallen sind (oder Encoder und Motorstromsensoren nicht funktionieren... das passiert z.B. wenn man vergessen hat diese vorher per Software einzuschalten).
- 22 -
RP6 ROBOT SYSTEM - 2. Der RP6 im Detail
50 12
50 12
=17
13 36
; 17
13 36
36=625

2.3.6. Drehgeber (Encoder)

Ganz anders als die letztgenannten Sensoren funktionieren die Drehgeber, die an den Getrieben der Motoren zur Dreh­zahlmessung angebracht sind. Es handelt sich dabei um Re­flexlichtschranken, die auf Codierscheiben mit je 18 weis­sen und 18 schwarzen Segmenten ausgerichtet sind, also insgesamt 36 Segmente (s. Abb). Diese Codierscheiben sind wiederum an je eines der Zahnräder der beiden Getrie­be geklebt worden. Wenn es sich dreht, wandern die einzel­nen Segmente an der Reflexlichtschranke vorbei. Die weis­sen Segmente reflektieren das Infrarotlicht, die schwarzen Segmente nur wenig. Die Drehgeber erzeugen so zwar auch
wie die anderen Sensoren ein analoges Signal, aber es wird digital interpretiert. Zunächst wird das Signal verstärkt und anschließend über einen sog. Schmitt Trigger in ein Rechtecksignal umgewandelt. Die Flanken dieses Signals, also die Wechsel von 5 auf 0V und umgekehrt, lösen jeweils ein Interrupt Ereignis aus und diese werden dann von der Software gezählt. So kann die zurückgelegte Wegstre­cke gemessen und zusammen mit einem Timer zur Zeitmessung die Drehzahl und da­mit auch die Geschwindigkeit ermittelt werden. Die Ermittlung der Drehzahl ist auch Hauptanwendung der Encoder – nur mit den Encodern kann man die Drehzahl auf den gewünschten Sollwert einregeln. Ohne Regelung wäre die Drehzahl nämlich von der Akkuspannung, Belastung der Motoren usw. abhängig. Die hohe Auflösung ermöglicht es dabei, auch niedrige Geschwindigkeiten noch relativ genau einzuregeln.
Jedes der zwei mittleren Stufenzahnräder des Ge­triebes hat 50 Zähne auf dem großen, und 12 auf dem kleineren Zahnrad (s. Abb). Die Codierscheiben befinden sich auf dem Zahnrad neben dem Motor, also rechnet man:
Daher haben die Encoderscheiben auch Ihre 36 Seg­mente, denn das gibt eine schöne runde Zahl ohne gebrochenen Anteil. Die Drehgeber erzeugen also 625 Flanken pro Radumdrehung wobei jede Flanke einem Segment entspricht.
Bei einem Raddurchmesser von ca. 50mm inkl. Raupenkette, ergibt sich rein rechne­risch ein Radumfang von ca. 157mm was 0.2512mm pro Zählschritt der Drehgeber entspricht. Da sich die Raupenketten aber fast immer etwas in den Untergrund ein­drücken (bzw. auch selbst eingedrückt werden) kann man aber von 0.25mm pro Zähl­schritt ausgehen – meist ist es sogar etwas weniger, z.B. nur 0.24 oder 0.23mm. Das muss man durch abfahren von Teststrecken ermitteln, wie es im Anhang grob be­schrieben ist. Sehr genau ist das allerdings durch Radschlupf (bzw. hier müssten wir eigentlich von „Kettenschlupf“ sprechen) und ähnlichen Dingen nicht - vor allem beim Rotieren auf der Stelle. Beim normalen Geradeausfahren ist dieser Fehler klein, aber beim Rotieren kann er schnell sehr große Werte annehmen! Abweichungen muss man evtl. durch weitere Tests ermitteln und mit einkalkulieren. Das ist bei Raupenantrie­ben leider so – auch bei viel teureren und hochwertigeren Robotern. Dafür hat man aber den Vorteil, dass der Roboter mit Raupenantrieb recht geländegängig ist im Ver­gleich zu Robotern mit normalem Differentialantrieb mit zwei Antriebsrädern und Stützrad. Kleinere Hindernisse und Rampen kann er meist problemlos überwinden.
- 23 -
RP6 ROBOT SYSTEM - 2. Der RP6 im Detail
Dabei sind die Encoder sehr nützlich, denn man kann die Geschwindigkeit gut einre­geln, egal wie der Untergrund und die Motorbelastung gerade aussieht.
Bei gemessenen 50 Segmenten pro Sekunde liegt die Geschwindigkeit bei 1.25 cm/s, sofern wir von 0.25mm pro Zählschritt ausgehen. Etwa 50 Segmente pro Sekunde ist auch die geringste gerade noch regelbare Geschwindigkeit (das variiert aber etwas von Roboter zu Roboter). Bei 1200 Segmenten pro Sekunde wären es die maximal möglichen 30 cm/s (bei 0.25mm Auflösung, bei 0.23 sind es 27.6 cm/s). Standardmä­ßig begrenzt die Funktionsbibliothek das aber auf 1000 Flanken pro Sekunde. Die ma­ximale Geschwindigkeit ist vom Ladezustand der Akkus abhängig – daher wären 30cm/s nicht besonders lange haltbar. Außerdem erhöht sich die Lebensdauer der Ge­triebe und Motoren je langsamer man fährt!
Wenn der Roboter 4000 Segmente gezählt hat, ist er übrigens etwa einen Meter weit gefahren. Aber wie schon gesagt, gilt das natürlich nur für genau 0.25mm Auflösung. Ohne Kalibrierung hat man hier immer mehr oder weniger starke Abweichungen. Wem es nicht auf jeden mm ankommt, braucht nichts zu kalibrieren und kann einfach von
0.25mm oder besser 0.24mm ausgehen! Optimal ist es, wenn man sich für Weg- und Winkelmessungen nicht auf die Encoder
Daten stützen muss, sondern externe Systeme wie Infrarotbaken oder einen genauen elektronischen Kompass dazu zur Verfügung hat.

2.4. Antriebssystem

Der Antrieb des RP6 besteht aus zwei Gleichstrom Motoren mit nachgeschaltetem Ge­triebe, über das die beiden Raupenketten angetrieben werden (s. Abb. weiter oben).
Die Motoren genehmigen sich je nach Belas­tung einen recht hohen Strom und können natürlich nicht direkt vom Mikrocontroller angesteuert werden. Dazu braucht man Leistungstreiber in Form von je einer H­Brücke pro Motor. Das grundlegende Prinzip ist in der nebenstehenden Abbildung darge­stellt. Eine H-Brücke besteht aus vier "Schaltern", die in Form eines H's um einen Motor angeordnet sind. Nehmen wir mal an, zunächst seien alle Schalter aus. Schaltet man dann S1 und S4 (Rot) an, liegt eine Spannung am Motor an und er dreht sich z.B. nach rechts. Schalten wir nun S1 und S4 wieder aus und danach S2 und S3 (Grün) an, wird die am Motor anliegende Spannung umgepolt und er dreht sich in die entge­gengesetzte Richtung, also nach links! Man muss darauf achten, nicht gleichzeitig S1 und S2, oder S3 und S4 einzuschalten, sonst entstünde ein Kurzschluss und dadurch könnten die "Schalter" zerstört werden!
Natürlich verwenden wir auf dem RP6 keine mechanischen Schalter, sondern sog. MOSFETs. Diese schalten beim Anlegen einer genügend hohen Spannung am Eingang durch. Die Schaltvorgänge können sehr schnell erfolgen, mehrere Kilohertz sind bei unserer Anwendung möglich.
- 24 -
RP6 ROBOT SYSTEM - 2. Der RP6 im Detail
So kann man also schonmal die Drehrichtung einstellen. Und wie bekommt man den Motor nun schneller bzw. langsamer? Ein Elektromotor dreht umso schneller, je höher die angelegte Spannung ist. Die Drehzahl kann also über die Spannung eingestellt werden - und genau dazu können wir die H-Brücke auch verwenden!
Die Abbildung verdeutlicht das Prinzip nach dem wir vorgehen können. Wir er­zeugen ein Rechtecksignal fester Fre­quenz, bei dem wir das sog. Tastverhältnis verändern. Mit "Tastverhältnis" ist das Verhältnis von der eingeschalteten zur ausgeschalteten Zeit des Signals gemeint.
Am Motor liegt dann effektiv eine niedrige­re, mittlere Gleichspannung an, die dem Tastverhältnis entspricht. In der Grafik ist
dies durch eine rote Linie (Ug) und die ro­ten Flächen verdeutlicht. Wenn z.B. eine Spannung von 7 Volt von den Akkus an
den Motortreibern anliegt, und diese mit einem Tastverhältnis von 50% angesteuert werden, würde die mittlere Spannung in etwa bei der Hälfte, also 3.5V liegen! Das stimmt real nicht ganz, aber so kann man es sich schon gut und einfach vorstellen.
Das Antriebssystem ist dank der hohen Untersetzung (~ 1:72) relativ stark und so kann der RP6 viel schwerere Lasten tragen als es z.B. der kleine Roboter ASURO könnte. Allerdings steigt mit zunehmendem Gewicht natürlich auch der Energiebedarf und die Akkus werden schneller leer sein ...
Im Vergleich mit einem ferngesteuerten Rennwagen o.ä. könnte man denken der RP6 sei langsam - stimmt auch - das ist jedoch absichtlich so! Der Roboter wird von einem Mikrocontroller gesteuert und wenn der Programmierer einen Fehler bei der Program­mierung gemacht hat, wäre es ungünstig mit 10km/h vor die Wand zu prallen! Bei dem eher gemächlichen Tempo des RP6 passiert aber nicht so schnell etwas und ne­benbei haben die Sensoren mehr Zeit die Umgebung auf Hindernisse zu untersuchen. Und da wäre natürlich noch der Vorteil der höheren Belastbarkeit und der viel genaue­ren Geschwindigkeitsregelung! Der RP6 kann sehr sehr langsam bei konstanter Ge­schwindigkeit fahren!

2.5. Erweiterungssystem

Eines der nützlichsten Features des RP6 ist das Erweite­rungssystem. Man kann den RP6 damit genau so weit aus­bauen, wie man es benötigt. Aus Kostengründen bietet das Basissystem schließlich nur realtiv wenig Sensoren. Es sind zwar schon mehr als bei vielen anderen Robotern in dieser Preisklasse, aber erst mit weiteren Sensoren macht ein Ro­boter so richtig Spaß. Das ACS kann beispielsweise nur grob erkennen ob sich ein Hindernis vor dem Roboter befindet. Mit Ultraschallsensoren oder besseren zusätzlichen IR Senso­ren, könnte man aber die Distanz ermitteln und so beispiels­weise bessere Ausweichmanöver fahren!
- 25 -
RP6 ROBOT SYSTEM - 2. Der RP6 im Detail
Neben Sensoren macht es auch sehr viel Sinn, zusätzliche Controller einzubauen um die anfallenden Aufgaben aufteilen zu können. Beispielsweise das RP6 CONTROL M32 mit einem weiteren MEGA32 Mikrocontroller.
Das Erweiterungssystem muss natürlich in der Lage sein, viele Erweiterungsmodule miteinander zu verbinden (engl. Expansion Modules, s. Abb.), dabei mit wenigen Si­gnalleitungen auskommen und eine ausreichend hohe Geschwindigkeit bieten.

2.5.1. Der I²C Bus

Der I²C Bus (sprich: „I quadrat C Bus“ --> IIC = „Inter IC Bus“), erfüllt diese Anforde­rungen. Er braucht nur 2 Signalleitungen, kann bis zu 127 Teilnehmer miteinander verbinden und hat eine maximale Übertragungsrate von 400kBit/s.
Der I²C Bus wurde in den 1980er und 90er Jahren von Philips Semiconductors entwi­ckelt und ist seitdem zu einem sehr weit verbreiteten Bussystem geworden. Der I²C Bus findet in sehr vielen elektronischen Geräten der Unterhaltungselektronik, wie Vi­deorecordern und Fernsehern Verwendung, aber auch in industriellen Geräten und Systemen. In den meisten moderneren PCs und Notebooks ist er in Form des SMBus zu finden und wird dort u.a. zur Kommunikation der Lüftersteuerung und Temperatur­überwachung verwendet. Auf vielen anderen Robotern wird er ebenfalls eingesetzt und so ist es nicht verwunderlich, dass es auch diverse Sensormodule wie Ultraschall­sensoren, elektronische Kompassmodule, Temperatursensoren und ähnliches mit die­sem Interface gibt.
Es handelt sich um einen Master-Slave orientierten Bus. Ein oder mehrere Master steuern den Datenverkehr von und zu bis zu 127 Slaves. Wir beschreiben aber nur die Verwendung des Busses mit einem Master, auch wenn der Bus Multimaster fähig wäre! Das würde die Sache nur verkomplizieren.
Die beiden Signalleitungen werden mit SDA und SCL bezeichnet. SDA steht für "Serial Data" und SCL für "Serial Clock" - also eine Daten- und eine Taktleitung. SDA ist bidi­rektional, was bedeutet, dass hier sowohl Master als auch Slave Daten anlegen kön­nen. Der Takt auf SCL wird immer vom Master erzeugt.
Der Bus überträgt die Datenbits stets synchron zum Taktsignal, das von einem Master vorgegeben wird. Der Pegel von SDA darf sich nur ändern während SCL low ist (aus­ser bei Start und Stopbedingung, s.u.). Die Übertragungsgeschwindigkeit kann auch während einer laufenden Übertragung beliebig zwischen 0 und 400kBit/s variieren.
Zwei typische Übertragungsabläufe sind in den obigen Abbildungen dargestellt. Die erste Abbildung zeigt eine Datenübertragung vom Master zu einem Slave. Die weissen Kästchen deuten auf Datenverkehr vom Master zum Slave hin, die dunklen sind die Antworten des Slaves.
Jede Übertragung muss mit einer Startbedingung eingeleitet werden und mit einer Stopbedingung beendet werden. Die Starbedingung tritt ein, wenn bei high Pegel auf SCL die Datenleitung SDA von high auf low Pegel gezogen wird. Umgekehrt gilt dies für die Stopbedingung, also wenn während SCL high Pegel führt, SDA von low auf high gezogen wird.
- 26 -
RP6 ROBOT SYSTEM - 2. Der RP6 im Detail
Nach der Startbedingung folgt die 7Bit lange Adresse des Slaves, mit dem die Kom­munikation stattfinden soll, gefolgt von einem Bit das festlegt ob Daten geschrieben oder gelesen werden. Der Slave bestätigt dies mit einem ACK ("Acknowledge" = Be­stätigung). Danach folgen beliebig viele Datenbytes wobei der Empfang jedes einzel­nen Bytes vom Slave mit einem ACK quittiert wird. Abgeschlossen wird die Übertra­gung mit der Stopbedingung.
Das war hier nur eine sehr kurze Beschreibung des I²C Busses. Mehr dazu finden Sie in der I²C Bus Spezifikation von Philips. Auch im Datenblatt des MEGA32 findet sich einiges dazu!
In den Beispielprogrammen können Sie sehen, wie man das verwenden kann. In der RP6 Funktionsbibliothek sind die Funktionen zum Ansteuern des I²C Busses bereits vorhanden. Um das genaue Protokoll muss man sich also keine Gedanken mehr ma­chen, es ist aber trotzdem nützlich, das schonmal gehört zu haben.

2.5.2. Erweiterungsanschlüsse

Auf dem Mainboard des Roboters befinden sich insge­samt vier Erweiterungsanschlüsse. Zwei davon sind mit „XBUS1“ und „XBUS2“ beschriftet. XBUS ist eine Abkürzung für „eXpansion BUS“, also Erweiterungs­Bus. XBUS1 und XBUS2 sind voll­ständig miteinander verbunden und
symmetrisch auf dem Mainboard angeordnet. Deshalb kann man die Erweiterungsmodule sowohl vorne, als auch hinten auf dem Roboter montieren. Auf jedem Er­weiterungsmodul finden sich an einer Seite zwei XBUS Anschlüsse. Über je ein 14 poliges Flachbandkabel kann man die Erweiterungs­module mit dem Mainboard und untereinander verbinden – dazu gibt es auch zwei identische und miteinander verbundene An­schlüsse auf jedem Erweiterungsmodul. Der äussere Stecker muss dabei als Verbindung nach unten genutzt werden, während der in­nere für die Verbindung nach oben gedacht ist. So kann man (theoretisch) beliebig viele Module übereinander stapeln (s. Abb. - hier sind drei RP6 Lochraster Erweiterungsmodule abge­bildet – diese kann man für eigene Schaltungen verwenden).
Auf den XBUS Anschlüssen sind Stromversorgung, der oben be­schriebene I²C-Bus, Master Reset und Interrupt Signale vorhanden.
Zur Stromversorgung stehen zwei Spannungen an den Anschlüssen bereit, natürlich die stabilisierten 5V vom Spannungsregler, aber auch die Akkuspannung. Diese verän­dert sich mit der Zeit und schwankt je nach Belastung – sie liegt normalerweise im Bereich von etwa 5.5 (Akkus leer) bis etwa 8.5V (frisch aufgeladene Akkus – das vari­iert von Hersteller zu Hersteller), kann aber auch je nach Belastung, Art und Ladezu­stand der Batterien zeitweilig ausserhalb dieses Bereichs liegen.
Das Master Reset Signal ist wichtig um alle Mikrocontroller beim Druck auf den Start/Stop Taster bzw. beim Programmieren zurückzusetzen. Die Bootloader in den Controllern starten ihre Programme übrigens bei einem low Puls (high-low-high) auf der SDA Leitung – so starten die Programme auf allen (AVR) Controllern gleichzeitig nachdem man den Start/Stop Taster gedrückt hat oder das Programm über die Boot-
- 27 -
RP6 ROBOT SYSTEM - 2. Der RP6 im Detail
loader Software startet... (der Bootloader generiert zum Starten allerdings nicht nur einen low Puls, sondern einen kompletten I²C General Call mit 0 als Datenbyte.)
Die Interruptleitungen werden von einigen Modulen dazu verwendet, dem Master Mi­krocontroller per externem Interrupt Signal mitzuteilen, dass neue Daten vorhanden sind oder eine bestimmte Aufgabe ausgeführt worden ist und auf neue Befehle gewar­tet wird. Hätte man diese Leitungen nicht, müsste der Mastermikrocontroller (bei be­stimmten Erweiterungsmodulen) ständig die Slaves auf neue Daten abfragen. Das ist natürlich auch möglich, aber mit zusätzlichen Interrupt Leitungen spart man sich eini­ges an Buslast und Rechenzeit. Da es insgesamt nur 3 Interruptleitungen und eine vom Anwender frei verwendbare Leitung gibt, müssen sich ggf. gleiche Module wie z.B. Ultraschallsensoren eine der Leitungen teilen und ggf. alle abgefragt werden.
Die beiden anderen mit „USRBUS1“ und „USRBUS2“ beschrifteten Erweiterungsan­schlüsse auf dem Mainboard, sind NICHT miteineinander verbunden. Die einzelnen Leitungen sind auf allen Erweiterungsmodulen auf Lötpads herausgeführt, so dass man eigene Signale an diese Steckverbinder legen kann. Daher auch der Name „USR­BUS“ was für „User-Bus“ steht, also „Anwender-Bus“. Sie können diese 14 poligen Er­weiterungsstecker für alles verwenden was Sie wollen – ein eigenes Bussystem, zu­sätzliche Versorgungsleitungen (Achtung: Nicht zu stark belasten, die Leiterbahnen sind nicht sonderlich breit) oder ähnliches. Man kann damit z.B. auch zwei der Erwei­terungsmodule miteinander Verbinden, ohne diese an die anderen Erweiterungen an­zuschließen. Das ist nützlich für aufwendigere Schaltungen oder Sensoren die nicht auf eines der Erweiterungsmodule passen würden... und so bleibt die Verkabelung or­dentlicher.
Sie können natürlich nicht beliebig viele Erweiterungsmodule anschließen – spätestens bei 6 vorne oder hinten übereinander gestapelten Modulen dürfte der RP6 keinen Elch­test mehr bestehen. Und außerdem muss man auch auf den Energiebedarf achten! Wird dieser zu hoch, werden die Akkus sehr schnell leer sein. Pauschal kann man al­lerdings sagen, das insgesamt maximal bis zu 8 Erweiterungsmodule auf dem RP6 Platz finden, also jeweils 4 vorne und 4 hinten.
In der Grafik sehen Sie die Anschlussbelegung der beiden Erweiterungsstecker. Pin 1 liegt auf dem Mainboard immer auf der Seite auf der sich die weisse Beschriftung XBUS1 bzw. XBUS2 befindet bzw. ist mit „1“ neben dem Stecker beschriftet .
+UB ist die Batteriespannung, VDD die +5V Betriebsspan­nung, GND bezeichnet den „Minuspol“ (GND = Ground, also Masse), MRESET ist das Master Reset Signal, INTx sind die Interruptletungen, SCL die Takt- und SDA die Da­tenleitung vom I²C Bus.
Alles andere was Sie evtl. noch brauchen sollten, müssen Sie selbst an die USRBUS Anschlüsse löten.
Wichtiger Hinweis: Belasten Sie die Versorgungsleitungen VDD und +UB
der Erweiterungsanschlüsse nicht mehr als bis jeweils maximal 1A (gilt für beide Pins ZUSAMMEN! Also jeweils die Pins 4+6 (+UB) und 3+5 (VDD))!
- 28 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme

3. Inbetriebnahme

Bevor Sie mit dem RP6 oder seinem Zubehör loslegen, folgen nun ei­nige Sicherheitshinweise die Sie vor allem dann beachten sollten, wenn Kinder den RP6 betreiben werden!
Lesen Sie den folgenden Abschnitt daher bitte besonders auf­merksam durch!

3.1. Sicherheitshinweise

Bedingt durch die offene Bauform gibt es beim RP6 einige spitze Ecken und scharfe Kanten. Er darf daher nicht als Spielzeug für Kinder unter 8 Jahren eingesetzt wer-
den. Beaufsichtigen Sie kleine Kinder, die sich beim Betrieb des Roboters im Raum be­finden und weisen Sie Ihre Kinder auch auf die hier aufgeführten Gefahren hin! Betreiben Sie den Roboter nicht, wenn sich freilaufende Kleintiere wie z.B. Hamster im Raum befinden, ansonsten besteht Verletzungsgefahr für die Kleintiere. (Umgekehrt könnte der Roboter aber natürlich auch von einem größeren Tier, wie einem Hund oder einer Katze beschädigt werden...)
Bei dem Raupenantrieb gibt es zwischen Rad und Raupenband Einzugsstel­len. Diese Bereiche sind beim RP6 weitgehend durch die Radkästen zwischen den Rä-
dern ausgefüllt und dadurch gesichert. Achten Sie beim Betrieb trotzdem darauf, dass Sie nicht mit den Fingern zwischen Rad und Raupenband geraten. Die Motoren sind ziemlich kräftig und Sie könnten sich leicht verletzen! Auch zwischen Platine und Raupenband müssen Sie sehr vorsichtig sein!
Achtung: Die Motoren können bereits mit der standard Software die Motorleistung automatisch erhöhen! Je nach Programmierung des Roboters können die Motoren un­erwartet anlaufen und es können unvorhergesehene Fahr- und Lenkbewegungen auf­treten! Betreiben Sie den Roboter niemals unbeaufsichtigt!

3.1.1. Statische Entladungen und Kurzschlüsse

Auf der Oberfläche der Hauptplatine, dem USB Interface und allen Erweiterungsmodu­len befinden sich viele nicht abgedeckte Bauteile und Leiterbahnen. Verursachen
Sie keine Kurzschlüsse durch versehentlich abgelegte Metallgegenstände oder Werk­zeug!
Die Betriebsspannung ist sehr niedrig und damit für den Menschen ungefährlich. Viele
der Bauelemente sind allerdings elektrostatisch gefährdet und daher sollten Sie die Komponenten auf den Platinen NICHT berühren wenn es sich vermeiden
lässt! Besonders bei trockener Luft (und vor allem wenn man synthetische Kleidung, o.ä. trägt) kann sich der menschliche Körper elektrostatisch aufladen. Das gilt auch für den Roboter selbst - hier ist die Beschaffenheit des Bodenbelags wesentlich. Beim Kontakt mit leitenden Gegenständen baut sich diese Ladung mit einem kleinen Funken ab. Solche Entladungen beim Berühren elektronischer Bauelemente können diese zer­stören. Vor dem Hantieren mit dem Roboter oder seinem Zubehör sollten Sie einen großen, geerdeten Gegenstand berühren (z.B. ein PC-Metallgehäuse, eine Wasserlei­tung oder ein Heizungsrohr), um eventuelle Aufladungen abzubauen. Eine Entladung des Roboters selbst gegen geerdete Gegenstände ist ungefährlich, kann jedoch zu
- 29 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
Programmabstürzen oder unkontrollierter Funktion des Roboters führen.
Alle elektrischen Verbindungen von und zum Gerät sind stets vor Anschluss der Ver­sorgungsspannung herzustellen. Das Aufstecken oder Abziehen von Verbindungskabeln/Modulen oder das Herstellen oder Lösen von Verbindungen können sonst zur Zerstörung von Teilen des Roboters oder seinem Zubehör führen.

3.1.2. Umgebung des Roboters

Betreiben Sie den Roboter nicht auf Tischflächen oder Bereichen, auf denen Absturz­gefahr besteht. Denken Sie hierbei auch an die Kletterfähigkeit des Raupenantriebs! Kleine Hindernisse kann der Roboter problemlos überqueren und leichte Gegenstände wegschieben! Vor Inbetriebnahme des Roboters müssen alle im Erfassungsbereich be­findlichen Flüssigkeitsbehälter wie z.B. Kaffeetassen, Flaschen oder Blumenvasen ge­sichert oder entfernt werden.
Die geschlossene Bodenwanne schützt die Mechanik zwar recht gut gegen grobe Um­welteinflüsse, sie ist aber weder wasser- noch staubdicht. Auch die Elektronik ist wei­testgehend ungeschützt. Setzen Sie den Roboter daher nur im trockenen und saube­ren Innenbereich ein. Schmutz, Fremdkörper und Feuchtigkeit können die Mechanik und Elektronik beschädigen oder zerstören. Die Umgebungstemperatur darf während des Betriebs 0°C und 40°C nicht unter- bzw. überschreiten.
Es können vor allem innerhalb der Elektromotoren während des Betriebs kleine Fun­ken entstehen. Betreiben Sie den Roboter daher auf gar keinen Fall in einer Umge­bung mit brennbaren oder explosionsgefährdeten Flüssigkeiten, Gasen oder Stäuben!
Bei längerer Nichtverwendung sollte der Roboter nicht in Räumen mit hoher Luftfeuch­tigkeit gelagert werden! Weiterhin müssen Sie die Akkus entnehmen, da sie sonst nach einiger Zeit auslaufen könnten!

3.1.3. Versorgungsspannung

Zur Versorgung des Roboters ist eine Gleichspannung von 7.2V vorgesehen, die mit 6 NiMH Akkus erzeugt wird. Die maximale Betriebsspannung beträgt 10V und sollte nie­mals überschritten werden. Verwenden Sie zum Laden der Akkus nur auf Einhaltung der geltenden Sicherheitsvorschriften geprüfte Ladegeräte! Behelfsweise kann der Roboter auch mit 6 hochwertigen Alkali-Mangan Batterien be­trieben werden. Da normale Batterien schnell leer sein werden und damit hohe Kosten und Umweltbelastung verursachen, sollten Sie aber besser Akkus verwenden! Akkus haben außerdem eine höhere Strombelastbarkeit und können auch bequem im Robo­ter geladen werden!
Bitte beachten Sie auch die Sicherheits- und Entsorgungshinweise für Batte­rien und Akkus im Anhang!
Modifikationen am Roboter sollten Sie nur dann selbst durchführen, wenn Sie genau wissen was Sie tun. Sie könnten damit den Roboter irreversibel be­schädigen oder sogar sich selbst und andere damit in Gefahr bringen
(Es sei nur Zimmerbrand durch überlastete Bauelemente als Beispiel genannt ...)!
- 30 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme

3.2. Software Installation

Als nächstes kommen wir zur Software Installation. Die korrekt in­stallierte Software wird für alle nachfolgenden Kapitel unbedingt be­nötigt.
Es sind Administrator-Rechte erforderlich, also melden Sie sich ggf. vorher als Administrator an Ihrem System an!
Wir empfehlen Ihnen erstmal das gesamte Kapitel in Ruhe durchzu­lesen und erst dann Schritt für Schritt die Installationsanleitung durchzugehen!
Grundlegende Kenntnis der Bedienung von Computern mit Windows oder Linux Betriebssystem und den gängigen Programmen wie Dateimanager, Webbrow- ser, Texteditor, Packer (WinZip, WinRAR, unzip o.ä.) und ggf. Linux-Shell etc. muss vorrausgesetzt werden! Wenn Sie sich also nur wenig mit Computern auskennen,
sollten Sie sich auf jeden Fall gut damit vertraut machen bevor Sie den RP6 in Betrieb nehmen! Eine Einführung in die Bedienung von Computern ist nicht Ziel dieser Anlei­tung und würde den Rahmen bei weitem sprengen! Hier geht es nur um den RP6, des­sen Programmierung und die speziell dafür benötigte Software.

3.2.1. Die RP6 CD-ROM

Sie haben vermutlich die RP6 CD-ROM im Laufwerk Ihres Computers – falls doch nicht, legen Sie diese nun bitte ein! Es sollte unter Windows kurz darauf per Autostart das CD Menü erscheinen. Andernfalls können Sie über einen Dateimanager die Datei "start.htm" im Hauptverzeichnis der CD mit einem Webbrowser wie z.B. Firefox öff­nen. Die Installationsdateien für Firefox finden Sie übrigens auf der CD im Ordner
<CD-ROM-Laufwerk>:\Software\Firefox
sofern Sie noch keinen aktuellen Webbrowser installiert haben sollten. (Es sollte min­destens Firefox 1.x oder der Internet Explorer 6 sein...)
Nach Auswahl der Sprache finden Sie im CD Menü neben dieser Anleitung (die es auch zum Download auf unserer Homepage gibt), vielen Informationen, Datenblättern und Fotos auch den Menüpunkt "Software". Hier sind alle Software Tools, der USB Treiber und die Beispielprogramme mit Quellcode für den RP6 zu finden.
Abhängig von den Sicherheitseinstellungen Ihres Webbrowsers können Sie die Instal­lationsprogramme direkt von der CD starten! Wenn Ihr Browser dies aufgrund der Si­cherheitseinstellungen nicht erlaubt, müssen Sie die Dateien zunächst in ein Verzeich­nis auf Ihrer Festplatte speichern und dann von dort starten. Genaueres dazu steht auf der Software Seite des CD Menüs. Alternativ können Sie natürlich auch direkt in einem Dateimanager auf das CD-Laufwerk wechseln und die Software von dort instal­lieren. Die Verzeichnisnamen sind so gewählt, dass sie eindeutig den entsprechenden Softwarepaketen und Betriebssystemen zugeordnet werden können.
Bitte prüfen Sie VOR der Installation ob evtl. schon neuere Versionen auf der RP6 Webseite verfügbar sind:
http://www.arexx.com/rp6
Neuere Versionen können Fehlerkorrekturen und neue Funktionen enthalten.
- 31 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme

3.2.2. WinAVR - für Windows

Als erstes werden wir WinAVR installieren. WinAVR ist aber - wie der Name schon an­deutet - nur für Win dows verfügbar !
Linux Anwender müssen beim nächsten Abschnitt weiterlesen.
WinAVR (das wird wie das englische Wort "whenever" ausgesprochen) ist eine Samm­lung von vielen nützlichen und notwendigen Programmen für die Software Entwicklung für AVR Mikrocontroller in der Sprache C. WinAVR enthält neben dem GCC für AVR (das nennt sich dann insgesamt "AVR-GCC", mehr Infos dazu folgen später) auch den komfortablen Quelltexteditor "Programmers Notepad 2", den wir auch für die Pro­grammentwicklung für den RP6 einsetzen werden! WinAVR ist ein privat organisiertes Projekt, hinter dem keine Firma o.ä. steht - es ist kostenlos im Internet verfügbar. Neuere Versionen und weitere Informationen finden Sie hier:
http://winavr.sourceforge.net/
Inzwischen wird das Projekt aber auch offiziell von ATMEL unterstützt, und der AVR­GCC lässt sich in AVRStudio, die Entwicklungsumgebung für AVRs von ATMEL, einbin­den. Das werden wir in diesem Handbuch aber nicht beschreiben, für unsere Zwecke ist Programmers Notepad besser geeignet.
Die WinAVR Installationsdatei finden Sie auf der CD im Ordner:
<CD-ROM-Laufwerk>:\Software\AVR-GCC\Windows\
Die Installation von WinAVR ist sehr einfach und selbsterklärend - normalerweise brauchen keinerlei Einstellungen geändert werden – also einfach immer auf "Weiter" klicken!
Wenn Sie Windows 7 nutzen, müssen Sie auf jeden Fall die neueste Version 20100110 von WinAVR verwenden! Auch mit Windows XP sollte es problemlos klappen. Falls nicht, können Sie eine der zahlreichen älteren Versionen ausprobieren (vor Neuinstal­lation immer bereits installierte WinAVR Versionen wieder deinstallieren!).

3.2.3. AVR-GCC, avr-libc und avr-binutils - für Linux

Windows Anwender können diesen Abschnitt überspringen!
Unter Linux kann es schon ein wenig aufwändiger werden. Bei einigen Distributionen sind die benötigten Pakete zwar schon vorhanden, aber meist nur veraltete Versionen.
Deshalb müssen Sie neuere Versionen kompilieren und einrichten. Wir können hier nicht im Detail auf jede der zahlreichen Linux Distributionen wie
SuSE, Ubuntu, RedHat/Fedora, Debian, Gentoo, Slackware, Mandriva etc. pp. in zig verschiedenen Versionen mit ihren jeweiligen Eigenheiten eingehen und beschreiben das daher nur allgemein.
Das gilt auch für alle anderen Linux Abschnitte in diesem Kapitel!
Das hier beschriebene Vorgehen muss also bei Ihnen nicht unbedingt zum Erfolg füh­ren. Oft kann es hilfreich sein, wenn Sie im Internet z.B. nach "<LinuxDistribution> avr gcc" o.ä. suchen (Verschiedene Schreibweisen ausprobieren). Auch das gilt für alle anderen Linux Abschnitte - natürlich mit angepassen Suchbegriffen! Falls Sie Proble­me bei der Installation des AVR-GCC haben, können Sie auch mal in unserem oder im Roboternetz Forum nachschauen bzw. in einem der zahlreichen Linux Foren.
- 32 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
Zunächst müssen Sie evtl. schon installierte Versionen des avr-gcc, der avr-binutils und der avr-libc deinstallieren – wie schon gesagt sind diese meist veraltet. Das kön­nen Sie mit dem jeweiligen Paketmanager ihrer Distribution tun indem Sie nach „avr“ suchen und die drei oben genannten Pakete deinstallieren – sofern diese überhaupt vorhanden sind.
Ob der avr-gcc schon installiert ist oder nicht und wenn ja wo, können Sie über eine Konsole z.B. leicht mit
> which avr-gcc
herausfinden. Sollte hier ein Pfad angezeigt werden, ist schon eine Version installiert. Geben Sie in diesem Fall einfach mal:
> avr-gcc --version
ein und schauen Sie sich die Ausgabe an. Sollte eine Versionsnummer kleiner 3.4.6 angezeigt werden, müssen Sie diese alte Version auf jeden Fall deinstallieren. Wenn die Versionsnummer 3.4.6 oder höher ist, können Sie erstmal versuchen ob Sie Pro­gramme kompilieren können (s. nachfolgende Kapitel) und erst wenn das fehlschlägt, die neuen Tools installieren. Wir installieren im Folgenden die Version 4.1.1 (Stand von März 2007) mit einigen wichtigen Patches.
Achtung: Sie müssen unbedingt sicherstellen, dass die normalen Linux Entwicklungs­tools wie GCC, make, binutils, libc, etc. installiert sind bevor Sie mit dem Übersetzen und der Installation beginnen können! Das tun Sie am besten über den Paketmanager Ihrer Distribution. Jede Linux Distribution sollte die benötigten Pakete schon auf der Installations CD mitliefern bzw. aktuelle Pakete über das Internet bereitstellen.
Stellen Sie sicher, dass das Programm „texinfo“ installiert ist. Installieren Sie bitte ggf. das entsprechende Paket bevor Sie weitermachen – sonst klappt es nicht!
Ist das erledigt, kann mit der eigentlichen Installation begonnen werden. Es gibt nun drei Möglichkeiten, alles von Hand kompilieren und einrichten, ein einfach
anzuwendendes Installationsskript verwenden, oder fertige vorkompilierte .deb
Pakete verwenden. Die vorkompilierten Pakete sind auf der CD zu finden und können auf Debian / Ubuntu basierten Systemen verwendet werden!
(Für neuere Versionen: http://www.wrightflyer.co.uk/avr-gcc/ ) Wir empfehlen es zunächst mit den .debs oder mit dem Skript zu versuchen, wenn
das nicht klappt kann man immer noch den Compiler von Hand einrichten! Achtung: Sie sollten für die Installation noch genug freien Speicherplatz auf der Fest-
platte zur Verfügung haben! Temporär werden mehr als 400MB benötigt. Über 300MB davon können nach der Installation wieder gelöscht werden, aber während der Über­setzung braucht man den Platz.
Viele der nachfolgenden Installationsschritte erfordern ROOT RECHTE, also loggen Sie sich ggf. mit „su“ als root ein oder führen Sie die kritischen Befehle mit „sudo“ o.ä. aus, wie man es z.B. bei Ubuntu machen muss (das Installationsskript, mkdir in /usr/local Verzeichnissen und make install brauchen root Rechte).
Achten Sie im Folgenden bitte auf EXAKTE Schreibweise aller Befehle! Jedes Zeichen ist wichtig und auch wenn einige Befehle evtl. etwas seltsam aussehen – das ist alles richtig so und kein Tippfehler! ( <CD-ROM-Laufwerk> muss man natürlich trotz­dem mit dem Pfad des CD-ROM-Laufwerks ersetzen!)
- 33 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
Alle für uns relevanten Installationsdateien für den avr-gcc, avr-libc und binutils fin­den Sie auf der CD im Ordner:
<CD-ROM-Laufwerk>:\Software\avr-gcc\Linux
Zunächst müssen Sie alle Installationsdateien in ein Verzeichnis auf Ihrer Festplatte kopieren – das gilt für beide Installationsvarianten! Hier nutzen wir das Home Verzeichnis (übliche Abkürzung für das aktuelle Home Verzeichnis ist die Tilde: „~“):
> mkdir ~/RP6 > cd <CD-ROM-Laufwerk>/Software/avr-gcc/Linux > cp * ~/RP6
Die Dateien können Sie nach der erfolgreichen Installation natürlich wieder löschen um Platz zu sparen!
3.2.3.1. Automatisches Installationsskript
Wenn man das Skript mit chmod ausführbar gemacht hat, kann es sofort losgehen:
> cd ~/RP6 > chmod -x avrgcc_build_and_install.sh > ./avrgcc_build_and_install.sh
Die Nachfrage ob man mit dieser Konfiguration installieren möchte oder nicht, können Sie mit „y“ beantworten.
ACHTUNG: Das Übersetzen und Installieren wird dann je nach Rechenleistung Ihres Systems einige Zeit in Anspruch nehmen. (z.B. etwa 15 min auf einem 2GHz CoreDuo Notebook – bei langsameren Systemen evtl. entsprechend länger)
Das Skript spielt auch einige Patches ein – das sind diese ganzen .diff Dateien die in dem Verzeichnis liegen.
Wenn alles klappt, sollte ganz zum Schluss folgendes erscheinen:
(./avrgcc_build_and_install.sh) (./avrgcc_build_and_install.sh) installation of avr GNU tools complete (./avrgcc_build_and_install.sh) add /usr/local/avr/bin to your path to use the avr GNU tools (./avrgcc_build_and_install.sh) you might want to run the following to save disk space: (./avrgcc_build_and_install.sh) (./avrgcc_build_and_install.sh) rm -rf /usr/local/avr/source /usr/local/avr/build
Dann können Sie wie es dort vorgeschlagen wird
rm -rf /usr/local/avr/source /usr/local/avr/build
ausführen! Das löscht alle temporären Dateien die Sie normalerweise nicht mehr be­nötigen.
Jetzt können Sie den nächsten Abschnitt überspringen und noch den Pfad auf die avr tools setzen.
Sollte die Ausführung des Skriptes fehlschlagen, müssen Sie sich genau die Fehlermel­dungen ansehen (auch mal in der Konsole etwas hochscrollen) – meist fehlen dann ir­gendwelche Programme die man vorher noch installieren muss (wie z.B. das oben er­wähnte texinfo). Bevor Sie nach einem Fehler weitermachen, sollten Sie die bereits erzeugten Dateien im standard Installationsverzeichnis „/usr/local/avr“ vorsichtshalber löschen – am besten das ganze Verzeichnis.
Wenn Sie nicht wissen, was da genau falsch gelaufen ist, bitte alle Kommandozeilen­ausgaben in einer Datei speichern und damit an den Support wenden. Bitte immer so viele Informationen wie möglich mitsenden! Dann wird es einfacher, Ihnen zu helfen.
- 34 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
3.2.3.2. Manuelle Installation
Wenn Sie den Compiler lieber von Hand einrichten wollen oder die Installation mit dem Skript nicht klappt, können Sie nach den Anweisungen im folgenden Abschnitt vorgehen.
Die Beschreibung hier orientiert sich an diesem Artikel:
http://www.nongnu.org/avr-libc/user-manual/install_tools.html
der auch in der AVR Libc Dokumentation im PDF Format auf der CD zu finden ist:
<CD-ROM-Laufwerk>:\Software\Documentation\avr-libc-user-manual-1.6.7.pdf
ab PDF Seite 90. Wir fassen uns hier zwar kürzer, spielen aber gleich noch ein paar wichtige Patches
ein – ohne diese funktionieren einige Dinge nicht richtig. Zunächst müssen wir uns ein Verzeichnis erstellen, in das wir alle Tools installieren
werden. Das sollte /usr/local/avr sein. Also in einer Konsole ALS ROOT folgendes eingeben:
> mkdir /usr/local/avr > mkdir /usr/local/avr/bin
Es muss nicht unbedingt dieses Verzeichnis sein. Wir legen dafür einfach die Variable
$PREFIX für dieses Verzeichnis an:
> PREFIX=/usr/local/avr > export PREFIX
Das muss nun noch unbedingt der PATH Variable hinzugefügt werden:
> PATH=$PATH:$PREFIX/bin > export PATH
Binutils für AVR
Nun müssen Sie den Quellcode der Binutils entpacken und ein paar Patches einspie­len. Wir nehmen hier an, dass Sie alles ins Home Verzeichnis ~/RP6 kopiert haben:
> cd ~/RP6 > bunzip2 -c binutils-2.17.tar.bz2 | tar xf ­> cd binutils-2.17 > patch -p0 < ../binutils-patch-aa.diff > patch -p0 < ../binutils-patch-atmega256x.diff > patch -p0 < ../binutils-patch-coff-avr.diff > patch -p0 < ../binutils-patch-newdevices.diff > patch -p0 < ../binutils-patch-avr-size.diff > mkdir obj-avr > cd obj-avr
Nun wird das configure Skript ausgeführt:
> ../configure --prefix=$PREFIX --target=avr --disable-nls
Dieses Skript ermittelt, was auf Ihrem System verfügbar ist und erzeugt dementspre­chend passende Makefiles. Jetzt können die Binutils übersetzt und installiert werden:
> make > make install
Das kann je nach Rechenleistung Ihres Systems schon ein paar Minuten dauern – das gilt auch für die beiden nächsten Abschnitte – vor allem für den GCC!
- 35 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
GCC für den AVR
Der GCC wird ähnlich wie die Binutils gepatcht, übersetzt und installiert:
> cd ~/RP6 > bunzip2 -c gcc-4.1.1.tar.bz2 | tar xf ­> cd gcc-4.1.1 > patch -p0 < ../gcc-patch-0b-constants.diff > patch -p0 < ../gcc-patch-attribute_alias.diff > patch -p0 < ../gcc-patch-bug25672.diff > patch -p0 < ../gcc-patch-dwarf.diff > patch -p0 < ../gcc-patch-libiberty-Makefile.in.diff > patch -p0 < ../gcc-patch-newdevices.diff > patch -p0 < ../gcc-patch-zz-atmega256x.diff > mkdir obj-avr > cd obj-avr > ../configure --prefix=$PREFIX --target=avr --enable-languages=c,c++ \
--disable-nls --disable-libssp –with-dwarf2 > make > make install
Nach dem \ kann man einfach Enter drücken und weiterschreiben – so kann der Be­fehl auf mehrere Zeilen aufgeteilt werden. Kann man aber auch ganz weglassen.
AVR Libc
Und schließlich noch die AVR libc:
> cd ~/RP6 > bunzip2 -c avr-libc-1.4.5.tar.bz2 | tar xf ­> cd avr-libc-1.4.5 > ./configure --prefix=$PREFIX --build=`./config.guess` --host=avr > make > make install
Achtung: bei –build=`./config.guess` darauf achten auch den „Accent grave“ (à <-- den Strich da auf dem a! Neben der Backspace Taste – rechts oben auf der Tastatur, einmal mit Shift diese Taste drücken und danach die Leertaste) und kein normales Hochkomma oder Anführungszeichen zu benutzen, sonst klappt es nicht.
3.2.3.3. Pfad setzen
Sie müssen jetzt dafür sorgen, dass das Verzeichnis /usr/local/avr/bin auch in der Pfad Variablen eingetragen ist – sonst kann man den avr-gcc nicht aus der Konsole bzw. aus Makefiles heraus aufrufen. Dazu müssen Sie den Pfad in die Datei /etc/pro- file bzw. /etc/environment o.ä. (variiert von Distribution zu Distribution) eintragen – mit einem Doppelpunkt „:“ getrennt von den anderen schon vorhandenen Einträgen. In der Datei könnte das dann in etwa so aussehen:
PATH="/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/local/avr/bin"
Jetzt in einer beliebigen Konsole „avr-gcc -–version“ eingeben wie weiter oben beschrieben – wenn das funktioniert, ist die Installation gelungen!
3.2.3.4. Neuere Versionen
Die Tools werden ständig weiterentwickelt. Sie können also auch neuere Versionen als die auf der CD testen! Das ist evtl. sowieso erforderlich da die älteren Versionen sich auf neueren System evtl. nicht mehr ohne Änderungen übersetzen lassen.
- 36 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme

3.2.4. Java 6

Der RobotLoader (Infos dazu s.u.) wurde für die Java Plattform entwickelt und ist un­ter Windows und Linux verwendbar (theoretisch auch andere Betriebsysteme wie OS X, aber hier kann AREXX Engineering leider noch keinen offiziellen Support leisten). Damit das funktioniert, ist es notwendig, ein aktuelles Java Runtime Environment (JRE) zu installieren. Oft haben Sie dies bereits auf dem Rechner, allerdings muss es mindestens Version 1.6 (= Java 6) sein! Falls Sie also noch kein JRE oder JDK instal­liert haben, müssen Sie zunächst das auf der CD mitgelieferte JRE 1.6 der Firma SUN Microsystems (jetzt Oracle) installieren, oder alternativ eine neuere Version von http://www.java.com oder http://java.sun.com downloaden.
Oder neuerdings von Oracle: http://www.oracle.com/technetwork/java/
3.2.4.1. Windows
Das JRE 1.6 befindet sich für Windows in folgendem Ordner:
<CD-ROM-Laufwerk>:\Software\Java\JRE6\Windows\
Unter Windows ist die Installation von Java sehr einfach - Sie müssen nur den Setup starten und den Anweisungen auf dem Bildschirm folgen - fertig. Den nächsten Ab­schnitt können Sie überspringen.
3.2.4.2. Linux
Unter Linux ist die Installation meistens auch relativ problemlos möglich, bei einigen Distributionen kann es aber ein wenig Handarbeit erfordern.
In diesem Ordner:
<CD-ROM-Laufwerk>:\Software\Java\JRE6\
finden Sie das JRE1.6 als RPM (SuSE, RedHat etc.) und als selbstextrahierendes Ar­chiv „.bin“. Unter Linux ist es besser wenn Sie zunächst im Paketmanager Ihrer je­weiligen Distribution nach Java Paketen suchen (Suchbegriffe z.B. „java“, „sun“, „jre“, „java6“ ...) und dann diese Distributionseigenen Pakete verwenden und nicht die auf dieser CD-ROM! Achten Sie aber unbedingt darauf Java 6 (= 1.6) oder ggf. eine neue­re Version zu installieren und keine ältere Version!
Unter Ubuntu oder Debian funktioniert das RPM Archiv nicht direkt – hier müssen Sie die Paketmanager Ihrer jeweiligen Distribution bemühen um an ein passendes Instal­lationspaket zu kommen. Das RPM sollte bei vielen anderen Distributionen wie Red­Hat/Fedora und SuSE aber problemlos funktionieren. Falls nicht, bleibt noch der Weg das JRE aus dem selbstextrahierenden Archiv (.bin) zu entpacken (z.B. nach /usr/lib/Java6) und dann manuell die Pfade zum JRE zu setzen (PATH und JAVA_HOME etc.).
Bitte beachten Sie hier auch die Installationsanweisungen von Sun – die ebenfalls im oben genannten Verzeichnis und auf der Java Website (s.o.) zu finden sind! Ob Java korrekt installiert wurde, können Sie in einer Konsole überprüfen indem Sie den Befehl
„java -version“ ausführen. Es sollte in etwa folgende Ausgabe erscheinen:
java version "1.6.0" Java(TM) SE Runtime Environment (build 1.6.0-b105) Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)
Steht dort etwas ganz anderes, haben Sie entweder die falsche Version installiert, oder auf Ihrem System ist noch eine andere Java VM installiert.
- 37 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme

3.2.5. RobotLoader

Der RobotLoader wurde entwickelt, um komfortabel neue Programme in den RP6 und alle Erweiterungsmodule laden zu können (sofern diese über einen Mikrocontroller mit kompatiblem Bootloader verfügen). Weiterhin sind ein paar nützliche Zusatzfunktio­nen integriert, wie z.B. ein einfaches Terminalprogramm.
Den RobotLoader selbst braucht man nicht zu installieren – das Programm kann ein­fach irgendwo in einen neuen Ordner auf die Festplatte kopiert werden. Der RobotLoa­der befindet sich in einem Zip-Archiv auf der CD-ROM:
<CD-ROM-Laufwerk>:\Software\RobotLoader\RobotLoader_20110616.zip
Dieses müssen Sie nur irgendwo auf die Festplatte entpacken – z.B. in einen neuen Ordner C:\Programme\RobotLoader (o.ä.). In diesem Ordner finden Sie dann die Da­tei RobotLoader_start.exe und können sie mit einem Doppelklick starten.
Das eigentliche RobotLoader Programm liegt im Java Archive (JAR) RobotLoader_lib.jar. Dieses können Sie alternativ auch von der Kommandozeile aus starten.
Unter Windows: java -Djava.library.path=".\lib" -jar RobotLoader_lib.jar
Linux:
java -Djava.library.path="./lib" -jar RobotLoader_lib.jar
Diese lange -D Option ist notwendig, damit die JVM auch alle verwendeten Bibliothe­ken finden kann. Unter Windows braucht man das aber nicht und kann einfach die .exe Datei zum Starten verwenden und für Linux gibt es ein Shell Skript „RobotLoa­der.sh“. Das Skript muss evtl. zunächst noch ausführbar gemacht werden (chmod
-x ./RobotLoader.sh). Danach kann man es in einer Konsole mit „./RobotLoader.sh“
starten. Es empfiehlt sich eine Verknüpfung auf dem Desktop oder im Startmenü anzulegen,
um den RobotLoader bequem starten zu können. Unter Windows geht das z.B. einfach indem man rechts auf die Datei RobotLoader.exe klickt und dann im Menü „Senden an“ auf „Desktop (Verknüpfung erstellen)“ klickt.

3.2.6. RP6 Library, RP6 CONTROL Library und Beispielprogramme

Die RP6Library und die zugehörigen Beispielprogramme befinden sich in einem Zip-Ar­chiv auf der CD:
<CD-ROM-Laufwerk>:\Software\RP6Examples\RP6Examples.zip
Sie können diese einfach direkt in ein Verzeichnis Ihrer Wahl auf die Festplatte entpa­cken. Am besten entpacken Sie die Beispielprogramme in einen Ordner auf einer Da­ten Partition. Oder in den „Eigene Dateien“ Ordner in einem Unterordner „RP6\Examp­les\“ bzw. unter Linux ins Home Verzeichnis. Das steht Ihnen aber völlig frei.
Die einzelnen Beispielprogramme werden noch später im Softwarekapitel besprochen! In dem Archiv sind auch schon die Beispiele für das RP6 CONTROL M32 Erweiterungs-
modul und die entsprechenden Library Dateien enthalten!
- 38 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme

3.3. Anschluss des USB Interfaces – Windows

Linux Anwender können beim nächsten Abschnitt weiterlesen!
Zur Installation des USB Interfaces gibt es mehrere Möglichkeiten. Die einfachste Möglichkeit ist es, den Treiber VOR dem ersten Anschließen des Geräts zu in- stallieren. Auf der CD befindet sich ein Installationsprogramm für den Treiber.
Für 32 und 64 Bit Windows XP, Server 2003, Vista und Win7 Systeme:
<CD-ROM-Laufwerk>:\Software\USB_DRIVER\CDM20814_Setup.exe
Alte Win98SE/Me und 2k Systeme werden leider nicht mehr unterstützt.
Das CDM Installationsprogramm müssen Sie einfach nur ausführen – es gibt nur eine kurze Rückmeldung, sobald der Treiber installiert wurde, sonst passiert nichts weiter.
ACHTUNG: Windows 7 / Vista installieren ohne den zuvor installierten kor­rekten Treiber einen standard Microsoft Treiber der nicht über alle benötigen Funktionen verfügt! In diesem Fall müssen Sie den Treiber manuell im Windows Ge-
rätemanager aktualisieren (es sind ZWEI Einträge beide separat zu aktualisieren! Ein „USB Serial Converter“ unter USB und ein „USB Serialport“ in „Ports (COM & LPT)“)
Wenn der Treiber installiert wurde, können Sie das USB Interface an den PC anschlie­ßen. BITTE NOCH NICHT MIT DEM ROBOTER VERBINDEN! Einfach nur über das USB Kabel mit dem PC verbinden! Dabei darauf achten, die Platine des USB Interfaces nur am Rand oder am USB Stecker bzw. an der Kunststoffwanne des Programmiersteckers anzufassen (s. Sicherheitshinweise zu statischen Entladungen)! Sie sollten besser kei- ne der Bauteile auf der Platine, Lötstellen oder die Kontakte des Wannensteckers be­rühren wenn nicht unbedingt nötig, um statische Entladungen zu vermeiden!
Der zuvor installierte Treiber wird nun automatisch für das Gerät verwendet ohne das Sie noch etwas tun brauchen. Es erscheinen bei Windows XP kleine Sprechblasen un­ten über der Taskleiste – die letzte Meldung sollte in etwa „Die Hardware wurde instal­liert und kann nun verwendet werden!“ lauten!
Wenn Sie das USB Interface doch schon vor der Installation angeschlossen haben, werden Sie von Windows nach einem Treiber gefragt. Auch diese Installati-
onsvariante ist möglich, der Treiber befindet sich auch in entpackter Form auf der CD! Wenn dies bei Ihnen der Fall ist, erscheint (unter Windows) für gewöhnlich ein Dialog
zum Installieren eines neuen Gerätetreibers. Sie müssen dem System dann den Pfad angeben unter dem es den Treiber finden kann. Bei Windows XP muss man erst aus­wählen den Treiber manuell zu installieren und natürlich keinen Webdienst o.ä. zu su­chen. Der Treiber befindet sich in unserem Fall auf der CD:
<CD-ROM-Laufwerk>:\Software\USB_DRIVER\CDM20814_WHQL_Certified\

3.3.1. Überprüfen ob das Gerät richtig angeschlossen ist

Um zu überprüfen ob das Gerät korrekt installiert worden ist, kann man unter Win­dows XP, 2003 und 2000 neben dem RobotLoader auch den Gerätemanager verwen­den: Rechtsklick auf den Arbeitsplatz --> Eigenschaften --> Hardware --> Gerätema­nager ODER alternativ: Start --> Einstellungen --> Systemsteuerung --> Leistung und Wartung --> System --> Hardware --> Gerätemanager und dort in der Baumansicht unter "Anschlüsse (COM und LPT)" nachsehen ob ein "USB-Serial Port (COMX)" zu sehen ist - wobei das X für die Portnummer steht oder unter „USB-Controller“ nach einem „USB Serial Converter“ suchen!
- 39 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme

3.3.2. Treiber später wieder Deinstallieren

Sollten Sie den Treiber jemals wieder deinstallieren wollen (Nein, das tun Sie jetzt bit­te nicht - ist nur ein Hinweis falls Sie das jemals brauchen sollten): Wenn Sie das CDM
Installationsprogramm verwendet haben, können Sie das direkt über Start-->Einstel­lungen-->Systemsteuerung-->Software tun. In der dortigen Liste finden Sie einen Eintrag des „FTDI USB Serial Converter Drivers“ – diesen auswählen und dort dann auf deinstallieren klicken! Achtung: USB-->RS232 Adapter mit FTDI Chipsatz verwen­den meist ebenfalls diesen Treiber!

3.4. Anschluss des USB Interfaces – Linux

Windows Anwender können diesen Abschnitt überspringen!
Bei Linux mit Kernel 2.4.20 oder höher ist der benötigte Treiber schon vorhanden (zu­mindest für das kompatible Vorgängermodell FT232BM des Chips auf unserem USB Interface, dem FT232R), das Gerät wird automatisch erkannt und Sie brauchen nichts weiter zu tun. Falls es doch mal Probleme gibt, erhalten Sie Linux Treiber (und Sup­port und auch evtl. neuere Treiber) direkt von FTDI: http://www.ftdichip.com/
Unter Linux kann man nachdem man das Gerät angeschlossen hat mit:
cat /proc/tty/driver/usbserial
anzeigen lassen ob der USB-Serial Port korrekt installiert worden ist. Mehr braucht man hier normalerweise nicht zu tun. Allerdings sei noch darauf hingewiesen, dass der RobotLoader unter Windows die D2XX Treiber verwendet und dort die vollständigen USB Bezeichnungen in der Portlis­te auftauchen (z.B. „USB0 | RP6 USB Interface | serialNumber“). Unter Linux sind es stattdessen die virtuellen Comport Bezeichnungen /dev/ttyUSB0, /dev/ttyUSB1 etc.. Es werden auch die normalen Comports angezeigt, als „dev/ttyS0“ usw.. Hier müssen Sie ausprobieren welcher Port der richtige ist! Für Linux ist leider kein so einfach zu installierender Treiber verfügbar der beides be­reitstellt, von daher war es hier sinnvoller die Virtual Comport Treiber die ohnehin schon im Kernel vorhanden sind zu verwenden. Die D2XX Treiber würden bei der In­stallation auch noch einiges an Handarbeit erfordern...

3.5. Software Installation abschließen

Das war es auch schon mit der Installation der Software und des USB Interfaces! Jetzt könnten Sie noch die wichtigsten Dateien von der CD auf die Festplatte kopieren
(vor allem den kompletten Ordner „Documentation“ und falls nicht schon geschehen die Beispielprogramme). Sie können alle wichtigen Dateien wie dieses Handbuch, den RobotLoader und die Beispielprogramme auch von der AREXX Homepage downloaden. Dort finden Sie auch Links zu den anderen Softwarepaketen, die Sie benötigen.
Bitte prüfen ob bereits aktuellere Software auf der RP6 Website
http://www.arexx.com/rp6
zur Verfügung steht! Hier könnten neue Funktionen und Fehlerkorrekturen enthalten sein.
- 40 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme

3.6. Akkus einbauen

Jetzt kommen wir endlich zum Roboter selbst. Dieser benötigt natürlich noch 6 Akkus! Wir empfehlen unbedingt qualitativ hochwertige NiMH Mignon Akkus (Hersteller z.B.
Sanyo, Panasonic, o.ä. - am besten die Eneloop / Infinium Varianten!) mit einer realen Kapazität von mindestens 2000mAh (optimal sind 2500mAh) zu verwenden! Normale Batterien sollten Sie nicht verwenden. Dies wäre auf Dauer nicht nur sehr teuer, sondern würde auch unnötigerweise die Umwelt belasten.
Die Akkus sollten am besten vor dem Einbau schon vorgeladen sein! Achten Sie darauf, dass alle Akkus den gleichen Ladezustand haben (also alle frisch aufge­laden oder alle entladen) und möglichst neu sind! Akkus verlieren mit zunehmendem Alter, Zahl der Ladezyklen, Art der Ladung und Umgebungstemperatur mehr und mehr an Kapazität. Also nicht unbedingt die alten Akkus nehmen die schon seit 3 Jah­ren unbenutzt im Schrank rumgelegen haben...
Wenn Sie später ein externes Steckerladegerät verwenden (emp­fohlen, jedoch nicht im Lieferumfang enthalten!), brauchen Sie die Akkus nur einmalig einzubauen! Wir empfehlen dringend die Ver­wendung eines Mikrocontroller gesteuerten Ladegeräts um die Akkus schonend zu laden! Verwenden Sie nur zugelassene und geprüfte La­degeräte!
Wenn Sie noch kein externes Ladegerät mit passendem Anschluss haben, müssen Sie die Akkus in jeden Fall vor dem Einbau laden und auch jedesmal wieder ausbauen, neu aufladen und wieder einbauen wenn diese leer sind!
Zum Einbau der Akkus:
Als erstes müssen Sie die vier Befestigungsschrauben (s. Abb.) des Main­boards lösen!
Heben Sie dann vorsichtig das Mainboard hinten an (a. Abb.).
Den kleinen 3 poligen Stecker der Bumper Platine (s. Abb) müssen Sie NICHT unbedingt lö­sen! Bitte fassen Sie das Main­board möglichst nur an den Rän­dern oder an größeren Kunst­stoffteilen an, um elektrostati­sche Entladungen zu vermeiden!
Das Mainboard ist mit einigen fest verlöteten Kabeln mit den Motoren, den Drehgebern und dem Akkuhalter verbunden. Schieben Sie diese Kabel - je nachdem wie sie liegen - vor­sichtig beiseite.
- 41 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
Dann nehmen Sie den schwarzen in der Mitte liegenden Akkuhalter nach hinten heraus (s. Abb.).
Stellen Sie nun bitte unbe­dingt sicher, dass der Schalter auf dem Mainboard des Robo­ters in der Position OFF steht, also in Richtung des Textes "OFF", bzw. in Richtung des großen zylinderförmigen Kon­densators auf dem Mainboard zeigt (s. Abb)!
Bevor Sie den Roboter wieder ein­schalten, müssen Sie kontrollieren ob die Akkus richtig herum einge­legt sind.
Jetzt können Sie 6 NiMH Mignon Akkus POLUNGSRICHTIG in den Akkuhalter ein­legen! Vorsicht: Wenn Sie die Akkus
falsch herum einlegen wird die Siche­rung normalerweise durchbrennen!
Es kann aber auch passieren, dass Tei­le der Elektronik beschädigt werden!
Legen Sie die Akkus also besser gleich rich­tig herum ein, um derartige Probleme zu vermeiden! Es sind Markierungen im Ak- kuhalter und auch auf den Akkus ((+) und (-), der Minuspol (die flache Seite) der Akkus muss in Richtung der Federn im Ak­kuhalter zeigen...)!
Kontrollieren Sie lieber dreimal, ob die Akkus auch wirklich richtig herum in den Akkuhalter eingesetzt sind!
Legen Sie nun den Akkuhalter wieder in das Chassis und achten Sie darauf, dass alle
Kabel gut im Chassis verstaut sind und nicht die Zahnräder der beiden Getrie­be berühren können!
Da der Roboter nun ohnehin schon aufge­schraubt ist, können Sie auch kurz noch die
beiden Getriebe und Drehgeber begutach­ten und schauen, ob beim Transport nichts beschädigt wurde oder sich evtl. gelockert hat. Drehen Sie bitte einmal ganz vorsichtig und langsam an den Hinterrädern! Eine halbe Umdrehung hin und zurück sollte schon ausreichen. Es sollte zwar ein deutlicher Widerstand zu spüren sein, aber das Rad sollte sich trotzdem gut drehen lassen. Die Zahnräder müssen sich frei drehen können! Bitte Anhang A beachten!
- 42 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
Das Mainboard wird nun wieder auf das Chassis gesetzt. Eventuell zwischen Main­board und Plastikstege des Chassis geratene Kabel schieben Sie entweder mit einem Finger, oder vorsichtig mit einem langen Schraubendreher beiseite, damit das Main- board plan auf dem Chassis aufliegen kann! Bevor Sie es danach wieder fest­schrauben, sollten Sie nochmals überprüfen ob keine Kabel zwischen Mainboard und Chassis oder in die Getriebe geraten sind! Dann können Sie das Mainboard wieder mit den 4 Schrauben befestigen – Fertig!

3.7. Laden der Akkus

Sofern die Akkus nicht wie empfohlen ohnehin schon geladen sind, müssen Sie diese nun mit einem externen Ladegerät laden. Der Hauptschalter muss dazu auch weiter­hin in der Position OFF stehen bleiben! Die Akkus können nur im ausgeschalteten Zu­stand geladen werden. Der Hauptschalter verbindet die Akkus entweder mit der Elek­tronik des RP6, oder mit der Ladebuchse.
Achten Sie darauf, das Ladegerät polungsrichtig an die Ladebuchse (mit „Charger“ be­schriftet) neben dem Hauptschalter des Roboters anzuschließen! Die Polung ist auch
auf dem Mainboard vor dem Stecker aufgedruckt (s. Abb). Der Minuspol liegt AUSSEN, der Pluspol INNEN!
Die Ladezeit ist abhängig vom verwendeten Ladegerät und den Akkus (bei Mikrocontroller gesteuerten Ladegeräten wie dem Voltcraft 1A / 2A Delta Peak Schnellladegerät oder dem Ansmann ACS110 / 410 etwa 3 bis 4, bei normalen wie dem AC48 etwa 14 Stunden) - genaueres dazu entneh­men Sie bitte dem Handbuch Ihres jeweiligen Ladegeräts!
Schalten Sie den Roboter während des Ladervorgangs NICHT ein! Entfernen Sie das Ladegerät bevor Sie den Roboter wieder einschalten!

3.8. Der erste Test

ACHTUNG! Lesen Sie diesen und den folgenden Abschnitt komplett durch bevor Sie den Roboter anschalten! Sollte dann
etwas nicht so ablaufen wie hier beschrieben, schalten Sie den Robo­ter am besten sofort aus und notieren Sie sich genau was falsch ge­laufen ist! Sofern das Kapitel "Fehlersuche" keine Lösung liefert, wenden Sie sich bitte an den Support!
Jetzt kann es los gehen - der Roboter wird nun das erste Mal eingeschaltet! Schalten Sie den Roboter am Hauptschalter ein. Es sollten nun die zwei mittleren roten Status LEDs aufleuchten und kurze Zeit später eine der anderen roten LEDs (SL6) anfangen zu blinken, während eine der grünen LEDs (SL1) dauerhaft leuchtet. Dies bedeutet übrigens, dass sich kein Anwenderprogramm im Speicher des Controllers befindet. Wenn sich ein Programm im Speicher befindet, blinkt nur die grüne Status LED SL1 (kann auch im Auslieferungszustand so sein, wenn noch das Testprogramm geladen ist – das ist also auch normales Verhalten und in Ordnung).
Die gelbe PWRON LED sollte nur kurz für etwa eine Sekunde nach dem Anschalten leuchten und dann wieder ausgehen - es spart Energie die meisten nicht benötigten Sensoren wie z.B. die Drehgeber abzuschalten.
Nach etwa einer halben Minute sollte das Blinken der roten LED SL6 aufhören und alle
- 43 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
LEDs ausgehen. Der Mikrocontroller auf dem Roboter schaltet sich nun - da er ohnehin noch kein Anwenderprogramm geladen hat das er ausführen könnte - automatisch in den Standby aus dem er über das USB Interface oder einen Druck auf den Start/Stop Taster bzw. einmal aus und wieder anschalten wieder aufgeweckt werden kann. Der Roboter verbraucht auch in diesem Modus etwas Energie (bis zu 5mA) – also trotzdem immer daran denken den RP6 komplett auszuschalten, wenn er nicht verwendet wird! Wenn ein Programm geladen ist, schaltet sich der Roboter übrigens nicht von selbst in den Schlafmodus, sondern wartet immer auf Benutzereingaben bzw. den Startbefehl von der seriellen Schnittstelle (einfach ein „s“ senden) oder über den I²C Bus.

3.8.1. USB Interface anschließen und RobotLoader starten

Als nächstes testen wir den Programmupload über das USB Interface. Verbinden Sie bitte das USB Interface mit dem PC (Immer zuerst mit dem PC verbinden!) und danach über das 10pol. Flachbandkabel mit dem seitlich neben dem Start/Stop Taster angeordneten "PROG/UART" Anschluss des RP6! Das 10 pol. Flachbandkabel ist me­chanisch gegen Verpolung geschützt, sofern man es also nicht mit Gewalt behandelt, kann man es gar nicht verkehrt herum anschließen.
Starten Sie danach den RobotLoader. Je nachdem wel­che Sprache Sie gewählt haben, können die Menüs na­türlich etwas anders beschriftet sein. Auf den Screens­hots ist die englische Sprachversion dargestellt, über den Menüpunkt „Options->Preferences“ und dann bei „Language / Sprache“ kann man die Sprache anpassen (Englisch oder Deutsch) und danach auf OK klicken. Nach Änderung der Sprache muss man den RobotLoa­der aber erst einmal neu starten bevor sich etwas än­dert!
Port öffnen - Windows
Jetzt können Sie den USB Port auswählen. Sofern kein anderer USB->Seriell Adapter mit FTDI Con­troller am PC angeschlossen ist, sehen sie in der Portliste nur einen einzigen Eintrag den Sie dann bitte auswählen. Falls doch mehrere Ports vorhan-
den sind, können Sie den Port anhand des Na­mens „RP6 USB Interface“ identifizieren (oder „FT232R USB UART“). Dahinter wird noch die einprogrammierte Seriennummer angezeigt.
Sollten keine Ports angezeigt werden, können sie im Menü über „RobotLoader-->Re­fresh Portlist“ („RobotLoader-->Portliste aktualisieren“) die Portliste aktualisieren!
Port öffnen – Linux
Unter Linux wird der USB-Seriell Adapter wie ein normaler Comport behandelt. Die D2XX Treiberin­stallation von FTDI unter Linux wäre nicht ganz so einfach und die normalen Virtual Comport (VCP) Treiber sind in aktuellen Linux Kerneln sowieso
schon enthalten. Es funktioniert alles fast genauso wie unter Windows, nur muss man erst noch kurz ausprobieren welchen Namen das RP6 USB Interface hat und darauf achten, den USB Port nicht vom PC zu trennen so­lange die Verbindung noch offen ist (ansonsten muss der RobotLoader eventuell neu
- 44 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
gestartet werden damit die Verbindung wieder klappt). Die Virtual Comports heissen unter Linux „/dev/ttyUSBx“, wobei x eine Nummer ist, z.B. „/dev/ttyUSB0“ oder „/dev/ttyUSB1“. Die normalen Comports heissen unter Linux „/dev/ttyS0“, „/dev/tty­S1“ etc.. Diese tauchen ebenfalls in der Portliste auf sofern vorhanden.
Der RobotLoader merkt sich – wenn es denn überhaupt mehrere Ports gibt - welchen Port Sie zuletzt verwendet haben und selektiert diesen bei jedem Start des Pro­gramms automatisch (generell bleiben die meisten Einstellungen und Selektionen er­halten).
Nun können Sie auf den Button „Connect“ (=„Verbinden“) klicken! Der RobotLoader öffnet nun den Port und testet, ob die Kommunikation mit dem Bootloader auf dem Roboter funktioniert. Es sollte dann unten im schwarzen Feld „Status“ die Nachricht "Connected to: RP6 Robot Base ..." o.ä. zusammen mit einer Info über die aktuell ge­messene Akkuspannung erscheinen. Falls nicht, probieren Sie es nochmal! Wenn es dann immer noch nicht klappt, liegt ein Fehler vor! Schalten Sie in diesem Fall den Ro­boter am Besten sofort aus und lesen Sie in Ruhe das Kapitel über Fehlersuche/Pro­blemlösungen! Ist die Akkuspannung zu niedrig, erscheint eine Warnung. Spätestens jetzt sollten die Akkus neu geladen werden (besser schon dann, wenn die Span­nung unter etwa 5.9V gefallen ist)!
Wenn das geklappt hat, kann ein kleines Selbsttestprogramm ausgeführt werden um die Funktionsfähigkeit aller Systeme des Roboters zu überprüfen. Klicken Sie dazu un­ten im RobotLoader Fenster auf den Button „Add“ („Hinzufügen“) und wählen Sie die Datei „RP6Base_SELFTEST\RP6Base_SELFTEST.hex“ im Beispielverzeichnis aus. In dieser Datei befindet sich das Selbsttestprogramm im hexadezimalen Format – daher werden solche Programmdateien auch „Hexdateien“ genannt.
Die eben ausgewählte Datei taucht anschließend in der Liste auf. So können Sie spä-
- 45 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
ter auch noch andere Hexdateien von Ihren eigenen Programmen und den Beispiel­programmen hinzufügen (s. Screenshot, hier wurden schon ein paar Hexdateien hin­zugefügt). Der RobotLoader kann auch verschiedene Kategorien von Hexdateien ver­walten. Damit lassen sich die Dateien übersichtlicher sortieren. Beispielsweise wenn man mehrere programmierbare Erweiterungsmodule auf dem RP6 hat, oder verschie­dene Varianten von Programmen verwendet. Die Liste wird immer automatisch beim Beenden des Programms gespeichert! Es werden hier natürlich nur die Pfade zu den Hexdateien gespeichert – nicht die Hexdateien selbst. Wenn Sie an einem Programm arbeiten, brauchen Sie die Hexdatei nur einmal hinzufügen und auswählen und kön­nen danach sofort nach jedem erneuten Übersetzen des Programms, das neue Pro­gramm in den Mikrocontroller laden (auch per Tastenkombination [STRG+D] oder [STRG+Y] um das Programm direkt nach dem Übertragen zu starten). Unter verschie­denen Betriebssystemem sind die Pfadnamen natürlich komplett anders. Sie können den RobotLoader trotzdem ohne weitere Änderungen direkt unter Windows und Linux verwenden, denn es gibt für Windows und Linux jeweils eine extra Liste.
Wählen Sie jetzt die Datei „RP6Base_SELFTEST.hex“ in der Liste aus und klicken Sie dann auf den Button „Upload!“ oben rechts unter dem Fortschrittsbalken. Das Pro­gramm wird nun in den MEGA32 auf dem RP6 hochgeladen. Das sollte nicht länger als ein paar Sekunden dauern (maximal 5 Sekunden beim Selbsttest Programm).
Wechseln Sie anschließend bitte auf den Karteireiter (=„Tabs“ ganz unten im Pro­grammfenster!) „Terminal“! Alternativ geht das auch über das Menü „View“ („Ansicht“).
Starten Sie dann das Programm mit einem Druck auf den Start/Stop Taster auf dem RP6, neben dem Programmier­anschluss (s. Abb.)! Später können Sie das natürlich auch alternativ über das Menü RobotLoader-->Start Target oder die Tastenkombination [STRG]+[S] tun, so können Sie al­lerdings direkt ausprobieren ob der Taster korrekt funktio­niert! Es sollte zunächst eine Warnmeldung im Terminal er­scheinen, in der darauf hingewiesen wird, dass der RP6 während des Tests Nummer 8 die Motoren anschaltet!
ACHTUNG! Halten Sie den RP6 bitte während des Tests Nummer 8 („Motors and Encoders Test“) in den Händen oder stellen Sie einen passenden Gegenstand unter den RP6 – so dass die beiden Antriebs­ketten NICHT den Untergrund berühren können! Die Ketten dürfen während Test 8 NICHT berührt oder blockiert werden! Sonst schlägt der Test höchstwahrscheinlich fehl! Wenn der RP6 auf dem Boden stehen würde, würde sich das Verhalten des Antriebs ändern und der Test könnte dann nicht mehr korrekt funktionieren. Außer­dem würde der RP6 ein gutes Stück weit fahren und man müsste das USB Kabel hinterhertragen – sofern es übehaupt lang genug dafür ist...
Also: den RP6 in die Hand nehmen oder etwas in der Mitte un­ter den RP6 stellen (z.B. eine kleine Schachtel oder eine Fernbe-
dienung). Wenn Sie etwas unter den RP6 stellen, sollten Sie den RP6 aber trotzdem während des Tests mit einer Hand festhalten, damit er nicht wegrutscht und dann versehentlich vom Tisch fährt!
- 46 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
Die Warnmeldung erscheint auch direkt vor dem Test Nummer 8 nochmals und muss erst quittiert werden bevor es weitergeht. Genau wie jetzt, zu Beginn des Testpro­gramms. Geben Sie bitte ein kleines 'x' im Terminal ein und drücken Sie die Enter Taste (Das müssen Sie noch häufiger tun! Immer wenn so eine Meldung erscheint oder um einen Test abzubrechen...).
Jetzt sollte in etwa das Textmenü auf der linken Seite erscheinen!
Das kann sich aber noch bis zur finalen Software Version etwas verändern.
Sie können die Testprogramme durch Eingabe der entsprechen­den Zahl bzw. des Buchstabens auswählen und starten.
Wir wollen alle Standard Tests durchführen – also geben Sie bitte eine '0' ein und drücken Enter!
Es sollten folgenden Ausgaben im Teminal erscheinen:
# 0
##################################################################### ##################################################################### ## Test #1 ##
### POWER ON TEST ### Please watch the yellow PowerOn LED and verify that it lights up! (it will flash a few times!)
Schauen Sie sich jetzt die gelbe PowerON LED auf dem RP6 an! Diese sollte nun ein paar mal an und aus gehen. Tut Sie das nicht, ist entweder der Test schon vorbei be­vor Sie auf die LED geschaut haben, oder es ist tatsächlich etwas defekt. Das Testpro­gramm fährt aber trotzdem weiter fort – denn es kann nicht selbst feststellen ob die LED funktioniert oder nicht – das müssen Sie selbst überprüfen!
Die LED zeigt übrigens an, dass die Drehgeber, der IR Empfänger und die Stromsen­soren eingeschaltet sind. Zusammen mit der LED benötigen diese insgesamt immerhin knapp 10mA --> daher wird das alles zum Stromsparen nur bei Bedarf angeschaltet.
Das Programm wird nun alle Status LEDs aufleuchten lassen. Ein paar mal alle zusam­men und ein paar mal einzeln. Hier können Sie sofort sehen ob alle LEDs korrekt funk­tionieren oder evtl. beschädigt sind. Ausgabe:
## Test #2 ##
### LED Test ### Please watch the LEDs and verify that they all work! Done!
- 47 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
Jetzt folgt der Akkusensortest. Der Sensor wurde eigentlich schon getestet, weil der RobotLoader die Akkuspannung ausliest und anzeigt, aber hier nochmal der Vollstän­digkeit halber.
##################################################################### ##################################################################### ## Test #3 ##
### Voltage Sensor Test ### Be sure that you are using good accumulators!
Enter "x" and hit return when you are ready!
Bestätigen Sie bitte mit 'x'!
# x Performing 10 measurements: Measurement #1: 07.20V --> OK! Measurement #2: 07.20V --> OK! Measurement #3: 07.20V --> OK! Measurement #4: 07.20V --> OK! Measurement #5: 07.20V --> OK! Measurement #6: 07.20V --> OK! Measurement #7: 07.20V --> OK! Measurement #8: 07.20V --> OK! Measurement #9: 07.20V --> OK! Measurement #10: 07.20V --> OK! Done!
So sollte die Ausgabe in etwa aussehen – die Spannungswerte dürfen im Bereich von
5.5 bis 9.5V liegen – dann wird der Messwert als OK angesehen. Liegt der Messwert ausserhalb dieses Bereichs, wird eine Fehlermeldung angezeigt. Bitte überprüfen Sie in diesem Fall die Akkus – evtl. sind sie nicht aufgeladen oder defekt! Wenn die Akkus OK sind, kann aber auch der „Sensor“ (zwei Widerstände...) beschädigt sein.
Jetzt testen wir die Bumpersensoren. Dazu müssen Sie einfach ein wenig auf den Bumpern herumdrücken und sich die LEDs bzw. die Ausgaben auf dem Terminal anse­hen. Bei jedem Druck auf einen der Bumper und wenn dieser wieder losgelassen wird, sollte eine Ausgabe im Terminal erscheinen und sich der Zustand der LEDs ändern! Das könnte in etwa so ausschauen:
## Test #4 ##
Bumper Test Please hit both bumpers and verify that both Bumpers are working properly! The Test is running now. Enter "x" and hit return to stop this test! OBSTACLE: LEFT! FREE: LEFT! OBSTACLE: RIGHT! FREE: RIGHT! OBSTACLE: LEFT! FREE: LEFT! OBSTACLE: RIGHT! FREE: RIGHT! OBSTACLE: LEFT! OBSTACLE: RIGHT! FREE: LEFT! FREE: RIGHT!
Den Test können Sie mit 'x' + Enter abbrechen wenn alles geklappt hat! Es folgt der Lichtsensor Test. Hier müssen Sie die beiden Lichtsensoren vorne am Ro-
boter mit den Händen abdunkeln und darauf achten, dass sich die Messwerte entspre­chend verändern – je kleiner die Messwerte, desto weniger Licht fällt auf die Senso­ren! Bei normalem Tageslicht sollten die Werte etwa zwischen 200 und 900 liegen.
- 48 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
Wenn man mit einer starken Taschenlampe ganz nah herangeht und direkt auf die Sensoren leuchtet oder den Roboter in die Sonne hält, können die Werte bis etwa 1000 ansteigen. Ist es im Raum sehr dunkel, sollten die Werte unter 100 liegen.
Zu Beginn des Tests muss man wieder mit x bestätigen:
## Test #5 ##
### Light Sensor Test ### Please get yourself a small flashlight! While the test runs, move it in front of the Robot and watch if the values change accordingly!
Enter "x" and hit return when you are ready! # x The Test is running now. Enter "x" and hit return to stop this test! Performing measurements...: Left: 0510, Right: 0680 Left: 0511, Right: 0679 Left: 0512, Right: 0680 Left: 0560, Right: 0710 Left: 0630, Right: 0750 Left: 0640, Right: 0760 Left: 0644, Right: 0765
[...]
Den Test dann bitte mit Eingabe von 'x' abbrechen, wenn Sie die Sensoren getestet haben!
Dann geht es direkt weiter zum ACS Test. Hier muss nichts bestätigt werden, der Test fängt sofort an. Bewegen Sie also nun ein wenig eine Hand oder Gegenstände vor dem Roboter hin und her. Dabei sollte vor dem Roboter allerdings viel Platz sein damit die Sensoren nicht dauerhaft ein Hindernis detektieren.
Die Ausgabe sollte in etwa so aussehen:
## Test #6 ##
ACS Test Please move your hand or other obstacles in front of the Robot and verify that both ACS channels are working properly!
ACS is set to Medium power/range!
You can also send RC5 Codes with a TV Remote Control to the RP6 - it will display the Toggle Bit, Device Adress and Keycode of the RC5 Transmission! Make sure your remote control transmits in RC5 and not SIRCS or RECS80 etc.! There are several other formats that will NOT work!
The Test is running now. Enter "x" and hit return to stop this test! OBSTACLE: LEFT! FREE: LEFT! OBSTACLE: LEFT! FREE: LEFT! OBSTACLE: LEFT! OBSTACLE: RIGHT! FREE: RIGHT! FREE: LEFT! OBSTACLE: LEFT! OBSTACLE: RIGHT! FREE: RIGHT! FREE: LEFT!
Sie können während des Tests auch Codes einer RC5 kompatiblen IR Fernbedienung empfangen. Es werden dann Togglebit, Adresse und Keycode angezeigt.
- 49 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
Um den Test abzubrechen einfach x eingeben und Enter drücken. Weiter geht’s mit dem IRCOMM Test. Hier muss zunächst wieder mit x bestätigt wer-
den. Dann werden IR Datenpakete gesendet und alle empfangenen Daten im Terminal ausgegeben und automatisch überprüft (das IRCOMM empfängt normalerweise auch die von ihm selbst gesendeten Signale, da die IR Dioden recht stark sind... wenn na­türlich überhaupt keine reflektierenden Gegenstände bzw. die Decke über dem Robo­ter ist, könnte das auch mal nicht korrekt funktionieren – ist aber unwahrscheinlich).
Die Ausgaben des Tests sollten etwa wie folgt aussehen:
#### TEST #7 ####
IRCOMM Test [...]
TX RC5 Packet: 0 RX RC5 Packet --> Toggle Bit:0 | Device Address:0 | Key Code:0 --> OK! TX RC5 Packet: 3 RX RC5 Packet --> Toggle Bit:0 | Device Address:3 | Key Code:3 --> OK! TX RC5 Packet: 6 RX RC5 Packet --> Toggle Bit:0 | Device Address:6 | Key Code:6 --> OK! TX RC5 Packet: 9 RX RC5 Packet --> Toggle Bit:0 | Device Address:9 | Key Code:9 --> OK! TX RC5 Packet: 12 RX RC5 Packet --> Toggle Bit:0 | Device Address:12 | Key Code:12 --> OK! [...] TX RC5 Packet: 57 RX RC5 Packet --> Toggle Bit:1 | Device Address:25 | Key Code:57 --> OK! TX RC5 Packet: 60 RX RC5 Packet --> Toggle Bit:1 | Device Address:28 | Key Code:60 --> OK! TX RC5 Packet: 63 RX RC5 Packet --> Toggle Bit:1 | Device Address:31 | Key Code:63 --> OK!
Test finished! Done!
Der Test sollte nur etwa 5 Sekunden dauern.
Jetzt kommt der Motor und Encoder Test! Sie müssen den RP6 also unbedingt in die Hand nehmen – die Ketten dürfen den Boden oder andere Objekte nicht berühren!
Sonst wird der Test vermutlich fehlschlagen! Passen Sie auf, dass der RP6 nicht vom Tisch fällt, wenn Sie wie oben be­schrieben einen Gegenstand unter den RP6 stellen wollen.
Der Test dauert nicht besonders lange – etwa 30 Sekunden. Achten Sie unbedingt auf eventuelle Fehlermeldungen während des Tests! Es kann schonmal passieren, dass einzelne Messwerte fehlerhaft sind und der Test deswegen fehlschlägt. Also wenn die Motoren normal anlaufen und der Test erst irgendwann mittendrin abbricht, muss das noch nichts schlimmes bedeuten. In diesem Fall einfach diesen Test nochmal durch­führen – aber vorher auch das Kapitel über Fehlerbehandlung im Anhang lesen!
Die Testroutine lässt den Antrieb nacheinander in verschiedenen Geschwindigkeitsstu­fen bis etwa 50% der Maximalgeschwindigkeit laufen und wechselt später auch ein paar mal die Laufrichtung der Motoren. Dabei werden ständig die Messwerte von den Drehgebern und den Stromsensoren überwacht. Sollte z.B. beim Transport etwas be­schädigt worden sein (z.B. ein Kurzschluss in einem der Motoren oder ein verklemm-
- 50 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
tes Getriebe – das sollte man aber eigentlich schon oben beim Test vor dem Akkuein­bau bemerkt haben) wird der gemessene Strom sehr hoch sein und der Test sofort abbrechen.
So sollte das dann in etwa aussehen (etwas gekürzt):
##################################################################### ##################################################################### #### TEST #8 ####
Automatic speed speed regulation test
##################################################################### ### ATTENTION!!! DANGER!!! WARNING!!! Make sure that the RP6 can __NOT__ move! The caterpillar tracks should __NOT__ touch the ground! (hold it in your hands for example...) THE RP6 WILL START MOVING FAST! YOU CAN DAMAGE IT IF YOU DO NOT MAKE SURE THAT IT CAN __NOT__ MOVE! Make sure both crawler tracks are FREE RUNNING! DO NOT BLOCK THEM!
--> OTHERWISE THE TEST WILL FAIL! #####################################################################
Enter "x" and hit return when TO START THIS TEST! Make sure the RP6 can not move!
# x T: 000 |VL: 000 |VR: 000 |PL: 000 |PR: 000 |IL: 000 |IR: 003 |UB: 07.28V T: 000 |VL: 000 |VR: 000 |PL: 000 |PR: 000 |IL: 002 |IR: 003 |UB: 07.28V [...] Speed Left: OK Speed Right: OK T: 020 |VL: 000 |VR: 000 |PL: 000 |PR: 000 |IL: 000 |IR: 003 |UB: 07.28V T: 020 |VL: 000 |VR: 000 |PL: 000 |PR: 000 |IL: 000 |IR: 003 |UB: 07.28V T: 020 |VL: 000 |VR: 000 |PL: 000 |PR: 000 |IL: 000 |IR: 003 |UB: 07.28V T: 020 |VL: 000 |VR: 000 |PL: 020 |PR: 020 |IL: 006 |IR: 009 |UB: 07.26V T: 020 |VL: 001 |VR: 014 |PL: 039 |PR: 030 |IL: 020 |IR: 020 |UB: 07.27V [...] Speed Left: OK Speed Right: OK T: 040 |VL: 021 |VR: 019 |PL: 037 |PR: 028 |IL: 025 |IR: 021 |UB: 07.25V T: 040 |VL: 020 |VR: 020 |PL: 037 |PR: 029 |IL: 026 |IR: 022 |UB: 07.25V T: 040 |VL: 018 |VR: 020 |PL: 044 |PR: 036 |IL: 028 |IR: 023 |UB: 07.23V T: 040 |VL: 038 |VR: 038 |PL: 055 |PR: 044 |IL: 035 |IR: 029 |UB: 07.23V T: 040 |VL: 037 |VR: 042 |PL: 055 |PR: 043 |IL: 033 |IR: 028 |UB: 07.24V T: 040 |VL: 043 |VR: 041 |PL: 052 |PR: 042 |IL: 032 |IR: 026 |UB: 07.23V T: 040 |VL: 043 |VR: 041 |PL: 052 |PR: 040 |IL: 030 |IR: 024 |UB: 07.24V T: 040 |VL: 037 |VR: 041 |PL: 052 |PR: 040 |IL: 030 |IR: 023 |UB: 07.24V T: 040 |VL: 043 |VR: 040 |PL: 050 |PR: 039 |IL: 029 |IR: 022 |UB: 07.24V Speed Left: OK Speed Right: OK T: 060 |VL: 040 |VR: 039 |PL: 053 |PR: 040 |IL: 033 |IR: 024 |UB: 07.24V T: 060 |VL: 036 |VR: 040 |PL: 053 |PR: 040 |IL: 034 |IR: 026 |UB: 07.24V T: 060 |VL: 042 |VR: 039 |PL: 052 |PR: 041 |IL: 034 |IR: 027 |UB: 07.23V T: 060 |VL: 042 |VR: 040 |PL: 063 |PR: 052 |IL: 038 |IR: 032 |UB: 07.22V T: 060 |VL: 058 |VR: 060 |PL: 068 |PR: 056 |IL: 038 |IR: 032 |UB: 07.25V T: 060 |VL: 062 |VR: 062 |PL: 067 |PR: 054 |IL: 037 |IR: 029 |UB: 07.22V T: 060 |VL: 060 |VR: 062 |PL: 067 |PR: 053 |IL: 038 |IR: 028 |UB: 07.23V
[...]
Speed Left: OK Speed Right: OK T: 100 |VL: 082 |VR: 078 |PL: 080 |PR: 068 |IL: 043 |IR: 036 |UB: 07.23V T: 100 |VL: 079 |VR: 079 |PL: 081 |PR: 069 |IL: 047 |IR: 038 |UB: 07.22V T: 100 |VL: 078 |VR: 082 |PL: 092 |PR: 078 |IL: 049 |IR: 039 |UB: 07.23V T: 100 |VL: 095 |VR: 099 |PL: 101 |PR: 082 |IL: 055 |IR: 039 |UB: 07.20V T: 100 |VL: 098 |VR: 100 |PL: 109 |PR: 081 |IL: 056 |IR: 040 |UB: 07.19V T: 100 |VL: 095 |VR: 099 |PL: 111 |PR: 082 |IL: 062 |IR: 042 |UB: 07.19V T: 100 |VL: 102 |VR: 101 |PL: 111 |PR: 082 |IL: 058 |IR: 041 |UB: 07.21V T: 100 |VL: 102 |VR: 101 |PL: 109 |PR: 081 |IL: 056 |IR: 039 |UB: 07.20V T: 100 |VL: 093 |VR: 100 |PL: 113 |PR: 081 |IL: 063 |IR: 038 |UB: 07.20V
- 51 -
RP6 ROBOT SYSTEM - 3. Inbetriebnahme
T: 100 |VL: 104 |VR: 099 |PL: 112 |PR: 082 |IL: 056 |IR: 042 |UB: 07.22V Speed Left: OK Speed Right: OK T: 080 |VL: 086 |VR: 071 |PL: 022 |PR: 000 |IL: 020 |IR: 012 |UB: 07.28V T: 080 |VL: 000 |VR: 000 |PL: 000 |PR: 000 |IL: 001 |IR: 003 |UB: 07.28V T: 080 |VL: 004 |VR: 011 |PL: 088 |PR: 084 |IL: 051 |IR: 045 |UB: 07.21V T: 080 |VL: 079 |VR: 101 |PL: 103 |PR: 077 |IL: 064 |IR: 039 |UB: 07.21V T: 080 |VL: 082 |VR: 076 |PL: 098 |PR: 072 |IL: 061 |IR: 041 |UB: 07.19V T: 080 |VL: 081 |VR: 081 |PL: 096 |PR: 071 |IL: 055 |IR: 040 |UB: 07.20V T: 080 |VL: 080 |VR: 082 |PL: 095 |PR: 070 |IL: 057 |IR: 038 |UB: 07.21V T: 080 |VL: 082 |VR: 080 |PL: 094 |PR: 069 |IL: 058 |IR: 036 |UB: 07.22V T: 080 |VL: 077 |VR: 080 |PL: 095 |PR: 069 |IL: 056 |IR: 036 |UB: 07.23V Speed Left: OK Speed Right: OK T: 060 |VL: 082 |VR: 079 |PL: 095 |PR: 069 |IL: 054 |IR: 038 |UB: 07.22V T: 060 |VL: 079 |VR: 079 |PL: 095 |PR: 071 |IL: 058 |IR: 040 |UB: 07.21V T: 060 |VL: 082 |VR: 081 |PL: 093 |PR: 070 |IL: 056 |IR: 039 |UB: 07.19V T: 060 |VL: 069 |VR: 070 |PL: 080 |PR: 054 |IL: 048 |IR: 029 |UB: 07.23V T: 060 |VL: 064 |VR: 059 |PL: 075 |PR: 054 |IL: 046 |IR: 029 |UB: 07.22V T: 060 |VL: 058 |VR: 057 |PL: 075 |PR: 055 |IL: 043 |IR: 032 |UB: 07.24V T: 060 |VL: 059 |VR: 059 |PL: 075 |PR: 056 |IL: 046 |IR: 034 |UB: 07.23V T: 060 |VL: 060 |VR: 059 |PL: 075 |PR: 056 |IL: 046 |IR: 035 |UB: 07.23V T: 060 |VL: 057 |VR: 060 |PL: 076 |PR: 056 |IL: 047 |IR: 033 |UB: 07.22V T: 060 |VL: 058 |VR: 061 |PL: 077 |PR: 055 |IL: 045 |IR: 030 |UB: 07.23V Speed Left: OK Speed Right: OK T: 040 |VL: 045 |VR: 035 |PL: 043 |PR: 023 |IL: 027 |IR: 018 |UB: 07.24V T: 040 |VL: 000 |VR: 000 |PL: 011 |PR: 000 |IL: 013 |IR: 007 |UB: 07.28V T: 040 |VL: 002 |VR: 000 |PL: 038 |PR: 038 |IL: 015 |IR: 014 |UB: 07.24V T: 040 |VL: 038 |VR: 061 |PL: 059 |PR: 052 |IL: 035 |IR: 035 |UB: 07.24V T: 040 |VL: 044 |VR: 043 |PL: 057 |PR: 044 |IL: 035 |IR: 028 |UB: 07.23V T: 040 |VL: 038 |VR: 039 |PL: 057 |PR: 044 |IL: 035 |IR: 027 |UB: 07.24V T: 040 |VL: 039 |VR: 042 |PL: 055 |PR: 043 |IL: 033 |IR: 025 |UB: 07.23V T: 040 |VL: 043 |VR: 041 |PL: 053 |PR: 041 |IL: 032 |IR: 023 |UB: 07.24V T: 040 |VL: 040 |VR: 041 |PL: 054 |PR: 041 |IL: 032 |IR: 023 |UB: 07.25V Speed Left: OK Speed Right: OK T: 020 |VL: 037 |VR: 040 |PL: 054 |PR: 041 |IL: 031 |IR: 024 |UB: 07.24V T: 020 |VL: 022 |VR: 019 |PL: 022 |PR: 012 |IL: 017 |IR: 016 |UB: 07.28V T: 020 |VL: 000 |VR: 000 |PL: 000 |PR: 000 |IL: 004 |IR: 007 |UB: 07.28V T: 020 |VL: 000 |VR: 006 |PL: 030 |PR: 027 |IL: 020 |IR: 020 |UB: 07.24V T: 020 |VL: 013 |VR: 019 |PL: 043 |PR: 030 |IL: 029 |IR: 022 |UB: 07.24V T: 020 |VL: 026 |VR: 020 |PL: 038 |PR: 029 |IL: 027 |IR: 022 |UB: 07.24V T: 020 |VL: 020 |VR: 021 |PL: 038 |PR: 029 |IL: 028 |IR: 023 |UB: 07.25V T: 020 |VL: 021 |VR: 020 |PL: 038 |PR: 029 |IL: 028 |IR: 023 |UB: 07.24V T: 020 |VL: 018 |VR: 019 |PL: 038 |PR: 030 |IL: 027 |IR: 024 |UB: 07.24V T: 020 |VL: 022 |VR: 020 |PL: 037 |PR: 029 |IL: 027 |IR: 023 |UB: 07.23V Speed Left: OK Speed Right: OK
***** MOTOR AND ENCODER TEST OK! *****
Die einzelnen Messwerte die während der Tests ausgegeben werden sind (von links nach rechts): T – aktueller Geschwindigkeitssollwert, VL/VR - gemessene Geschwin­digkeit links/rechts, PL/PR – PWM Wert links/rechts, IL/IR – Motorstrom links/rechts, UB – Akkuspannung.
Wenn die Ausgaben ähnlich wie oben aussehen – ist alles OK. Wenn etwas nicht korrekt funktionieren sollte und Fehlermeldungen erscheinen, lesen
Sie bitte den Abschnitt zur Fehlerbehandlung im Anhang!
Das war es auch schon mit dem Testprogramm. Wenn alles wie erwartet geklappt hat, können Sie direkt mit dem nächsten Abschnitt weitermachen.
- 52 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4. Programmierung des RP6

Nun kommen wir endlich zur Programmierung des Roboters.

4.1. Einrichten des Quelltexteditors

Erstmal müssen wir uns eine kleine Entwicklungsumgebung einrichten. Der sog. „Quelltext“ (auch Quellcode oder engl. Sourcecode genannt) für unsere C Programme muss ja irgendwie in den Computer eingegeben werden!
Dazu werden wir natürlich auf gar keinen Fall Programme wie OpenOffice oder Word verwenden! Vielleicht ist das nicht für jeden offensichtlich, deshalb wird es hier explizit betont. Damit kann man zwar gut Handbücher wie dieses hier schreiben, aber zum Programmieren ist das absolut ungeeignet. Quelltext ist reiner Text – ohne jegliche Formatierung. Schriftgröße oder Farbe interessieren den Compiler nicht...
Für einen Menschen ist es natürlich übersichtlicher wenn bestimmte Schlüsselwörter oder Arten von Text automatisch farbig hervorgehoben werden. Das und noch einiges mehr bietet Programmers Notepad 2 (im folgenden kurz „PN2“ genannt), der Quell­texteditor den wir verwenden werden (ACHTUNG: Unter Linux müssen Sie einen an-
deren Editor verwenden, der ähnliches wie PN2 bietet. Es sind für gewöhnlich mehrere bereits vorinstalliert! (z.B. kate, gedit, exmacs o.ä.)). Neben dem Hervorheben von
Schlüsselwörtern und ähnlichem (sog. „Syntax Highlighting“) gibt es auch eine rudi­mentäre Projektverwaltung. Man kann so mehrere Quelltextdateien in Projekten orga­nisieren und in einer Liste alle zu einem Projekt gehörenden Dateien anzeigen lassen. Weiterhin kann man aus PN2 komfortabel Programme wie den AVR-GCC aufrufen und so die Programme bequem über einen Menüeintrag übersetzen lassen. Der AVR-GCC ist ja normalerweise ein reines Kommandozeilenprogramm ohne graphische Oberflä­che...
Neuere Versionen von Programmers Notepad finden Sie auf der Projekthomepage:
http://www.pnotepad.org/

4.1.1. Menüeinträge erstellen

HINWEIS: Diesen Abschnitt können Sie überspringen wenn in PN2 die Menüeinträge schon vorhanden sind (die Menüeinträge heis-
sen dann „[WinAVR] Make All“, etc.. einfach mal in dem Menü nachschauen).
Da dies aber nicht bei allen Versionen der Fall ist und es außerdem nützlich ist zu wis­sen wie man das macht (Sie können ja auch andere Programme wie den RobotLoader in dieses Menü einfügen!), beschreiben wir hier noch kurz wie man eigene Menüein­träge hinzufügen kann.
Starten Sie PN2 und wählen Sie dann im Menü „Tools“ den Menüpunkt „Add Tools...“ aus (s. Screenshot).
- 53 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Es erscheint der Optionen Dialog. Hier können Sie diverse Einstel­lungen von PN2 verändern, wir wollen aber erstmal nur neue Menüeinträge zum Tools Menü hinzufügen.
Wählen Sie dazu in der „Scheme:“ Dropdown Liste „C/C++“ aus!
Klicken Sie dann auf den Button „Add“!
Es erscheint der nebenstehende Dialog.
Hier geben Sie bitte genau das ein, was Sie auf dem Screens­hot sehen.
„%d“ verweisst auf das Ver­zeichnis der aktuell gewählten Datei und „%d\make_all.bat“ verweisst auf eine kleine Batch­datei, die in jedem Verzeichnis der vorgefertigten Projekte für den RP6 zu finden ist.
Bei „Shortcut“ können Sie Bei­pielsweise [STRG] + [M] auf der Tastatur drücken! Das ist aber optional!
Dieser Eintrag ruft das Tool „make“ über die „make_all.bat“ Batchdatei auf und leitet so das Kompilieren der Dateien im Ver­zeichnis der aktuell gewählten Datei ein. Aber dazu später mehr.
- 54 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Alternativ zu „%d/make_all.bat“ kann man auch einfach nur „make“ ins Feld „Com­mand“ schreiben und bei Parameters „all“. Die Batch Datei führt eigentlich auch nur diese Befehle aus (ist aber nützlich um das Programm einfach so aus dem Windows Explorer heraus zu kompilieren).
Jetzt auf OK klicken – es erscheint ein neuer Eintrag in der Liste:
...und nochmal auf „Add“ klicken!
Im selben Dialog wie oben nun die abgebilde­ten Eingaben vornehmen und auf OK klicken.
Es erscheint dann ein weiterer Eintrag in der Liste:
„[RP6] MAKE CLEAN“
Mit diesem Eintrag kann man die ganzen temporären Dateien die der Compiler wäh­rend seiner Arbeit erzeugt hat komfortabel löschen. Die brauchen wir nämlich nach dem Kompilieren meistens nicht mehr. Die erzeugte Hexdatei wird übrigens nicht ge­löscht und kann noch immer in den Roboter geladen werden.
Wie oben kann man alternativ zu „%d/make_clean.bat“ auch einfach nur „make“ ins Feld „Command“ schreiben und bei Parameters „clean“.
Abschließend müssen Sie noch die Änderungen im „Options“ Dialog mit einem Klick auf „OK“ bestätigen!
- 55 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.1.2. Syntax Highlighting einstellen

Eine weitere Einstellung die Sie verändern sollten betrifft das Syntax Highlighting. Es gibt einige „Keywords“ (=Schlüsselwörter) die dem normalen C/C++ Schema noch hinzugefügt werden sollten.
Das sind folgende Keywords (können Sie hier direkt per Copy & Paste ([STRG]+[C] = kopieren, [STRG]+[V] = einfügen) in das Dialogfeld kopieren!):
int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t
Dann einmal auf „Sort“ (Sortieren) klicken und den Dialog mit OK bestätigen!
Achtung: Bei neueren WinAVR und Programmers Notepad Versionen (WinAVR-20070525 oder neuer) sind diese Keywords bereits in Programmers Notepad eingetragen! Dann brauchen Sie hier nichts mehr zu ändern! In dieser Version sieht Programmers Notepad auch ein wenig anders aus als hier auf den Screenshots.
- 56 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Fertig eingerichtet und nachdem man wie im nächsten Abschnitt beschrieben die Bei­spielprojekte geöffnet hat, sollte PN2 in etwa so aussehen:
Links sind alle Beispielprojekte zu sehen, rechts der Quelltexteditor (mit dem ange­sprochenen Syntax Highlighting) und unten die Ausgabe der Tools (in diesem Fall die Ausgabe des Compilers).
Sie können noch viele andere Sachen in PN2 umstellen und es gibt viele nützliche Funktionen.
- 57 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.1.3. Beispielprojekt öffnen und kompilieren

Jetzt probieren wir gleich mal aus, ob auch alles richtig funktio­niert und öffnen die Beispielprojekte:
Im Menü „File“ den Menüpunkt „Open Project(s)“ wählen. Es erscheint ein normaler Dateiauswahl Dialog. Hier suchen Sie
bitte den Ordner „RP6Base_Examples\“ im Ordner in dem Sie die Beispielprogramme gespeichert haben.
Öffnen Sie nun bitte die Datei „RP6BaseExamples.ppg“. Das ist eine Projektgruppe für PN2, die alle Beispielprogramme sowie die RP6Library in die Projektliste („Projects“) lädt. So hat man immer alle Beispielprogramme bequem zur Verfügung und kann sich zu Beginn besser an diesen orientieren oder Funktionen in der RP6Library nachschlagen etc.
Öffnen Sie nun das erste Beispielprogramm ganz oben in der Liste („Example_01_LEDs“ und die Datei „RP6Base_LEDs.c“ selektieren) die am linken Rand des Programmfensters zu sehen ist aus! Dazu einfach doppelt auf „RP6Base_LEDs.c“ klicken! Es erscheint ein Quelltexteditor in einem Fenster innerhalb des Programms.
Unten im Programmfenster von PN2 sollte ein Ausgabebereich zu sehen sein – falls nicht, müssen Sie diesen Bereich im Menü mit View->Output aktivieren ODER falls er zu klein ist durch „ziehen“ mit der Maus vergrößern (der Mauscursor verändert sich unten im Programmfenster am oberen Rand des grauen Bereichs in dem „Output“ steht in einem recht schmalen Bereich in einen Doppelpfeil...).
Sie können sich das Programm in dem gerade geöffneten Quelltexteditor schonmal kurz anschauen, allerdings müssen Sie hier noch nicht verstehen, was da genau gemacht wird. Das wird weiter unten noch genauer erklärt. Schonmal vorweg: Bei dem grün eingefärbten Text handelt es sich um Kommentare die nicht zum eigentli­chen Programm gehören und nur der Beschreibung/Dokumentation dienen. Darauf ge­hen wird später noch genauer ein (es gibt auch eine Version dieses Programms OHNE Kommentare – damit man mal sieht, wie kurz das Programm eigentlich ist. Die Kom­mentare blähen das schon ziemlich auf, sind aber zur Erklärung notwendig. Die unkommentierte Version ist auch praktisch um den Code in eigene Programme zu kopieren!).
Zunächst wollen wir nur ausprobieren, ob das Übersetzen von Programmen korrekt funktioniert.
Es sollten oben im Tools Menü die beiden eben angeleg­ten Menüeinträge (s. Abb.) vorhanden sein (oder die standardmäßig in PN vorhandenen [WinAVR] Einträge, das ist egal, es funktioniert normalerweise mit beiden).
Klicken Sie jetzt bitte auf „MAKE ALL“! PN2 ruft nun die oben angesprochene „make_all.bat“
Batch Datei auf. Diese wiederum ruft das Programm „make“ auf. Mehr zu „make“ folgt noch später.
- 58 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Das Beispielprogramm wird nun übersetzt (das nennt man „kompilieren“ vom engli­schen „to complile“ bzw. „Compiler“=„Übersetzer“) und eine Hexdatei erzeugt. Diese enthält das Programm in der für den Mikrocontroller übersetzten Form und kann dann später in diesen geladen und ausgeführt werden! Es werden während der Kompilie­rung noch viele temporäre Dateien erzeugt (Endungen wie „.o, .lss, .map, .sym, .elf, .dep“). Die brauchen sie alle nicht weiter zu beachten! Mit dem eben angelegten Tool „make clean“ kann man diese bequem löschen. Davon ist nur die Hexdatei für Sie interessant! Die Hexdatei wird beim Aufruf von „make clean“ übrigens nicht gelöscht.
Es sollte nach dem Aufruf des MAKE ALL Menüpunktes folgende Ausgabe erscheinen (hier jedoch stark gekürzt! Einiges kann natürlich etwas anders aussehen):
> "make" all
-------- begin --------
[...]
Compiling: RP6Base_LEDs.c
avr-gcc -c -mmcu=atmega32 -I. -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct
-fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=RP6Base_LEDs.lst -I../../RP6lib
-I../../RP6lib/RP6base -I../../RP6lib/RP6common -std=gnu99 -MD -MP -MF .dep/RP6Base_LEDs.o.d RP6Ba­se_LEDs.c -o RP6Base_LEDs.o
Compiling: ../../RP6lib/RP6base/RP6RobotBaseLib.c
[...]
Creating load file for Flash: RP6Base_LEDs.hex avr-objcopy -O ihex -R .eeprom RP6Base_LEDs.elf RP6Base_LEDs.hex
[...]
Size after: AVR Memory Usage
----------------
Device: atmega32
Program: 6858 bytes (20.9% Full) (.text + .data + .bootloader)
Data: 148 bytes (7.2% Full) (.data + .bss + .noinit)
-------- end -------­> Process Exit Code: 0 > Time Taken: 00:01
Wichtig ist ganz unten das „Process Exit Code: 0“. Das bedeutet, dass es beim Überset­zen keinen Fehler gegeben hat. Steht dort ein anderer Code, gibt es einen Fehler im Quellcode, den man korrigieren muss bevor es klappt. Der Compiler gibt in diesem Fall weiter oben diverse Fehlermeldungen aus, in denen man mehr Infos dazu findet.
Aber bitte beachten Sie, dass „Process Exit Code: 0“ nicht auf ein komplett fehlerfreies Programm hinweist! Denkfehler in Ihrem Programm findet der Compiler natürlich nicht und er kann auch nicht verhindern, dass der Roboter vor die Wand fährt ;-)
WICHTIG: Weiter oben können auch noch Warnungen u.ä. stehen – diese sind oft sehr sehr hilfreich und weisen fast immer auf wichtige Probleme hin! Daher sollten diese immer beseitigt werden! PN2 hebt Warnungen und Fehler farbig hervor, so dass man diese leicht identifizieren kann. Es wird auch die Zeilennummer angegeben, die
- 59 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
der Compiler bemängelt. Wenn man auf diese farbig hervorgehobene Meldung klickt, springt PN2 im entsprechenden Editor direkt zu der jew. Zeile.
Auch sehr hilfreich ist die Angabe zum Schluss „AVR Memory Usage“.
Size after: AVR Memory Usage
----------------
Device: atmega32
Program: 6858 bytes (20.9% Full) (.text + .data + .bootloader)
Data: 148 bytes (7.2% Full) (.data + .bss + .noinit)
Das bedeutet hier, dass unser Programm 6858 Bytes groß ist und 148 Bytes RAM für statische Variablen reserviert sind (dazu kommen noch die dynamischen Bereiche für Heap und Stack, das würde an dieser Stelle aber zu weit führen... halten Sie einfach immer mindestens ein paar hundert Bytes Speicher frei). Wir haben insgesamt 32KB (32768 Bytes) an Flash ROM und 2KB (2048 Bytes) an RAM. Von den 32KB sind 2K mit dem Bootloader belegt – also können wir nur 30KB nutzen. Immer darauf achten, dass das Programm auch noch in den verfügbaren Speicher passt! (Der RobotLoader überträgt das Programm nicht wenn es zu groß ist!)
Bei dem Beispielprogramm oben sind also noch 23682 Bytes frei. Das eigentlich recht kurze Beispielprogramm RP6Base_LEDs.c ist übrigens nur deshalb schon so groß, weil die RP6Library mit eingebunden wird! Also keine Sorge, es ist genug Platz für Ihre Programme vorhanden und so kleine Programme brauchen normalerweise nicht so viel Speicher. Die Funktionsbibliothek benötigt alleine nämlich schon über 6.5KB vom Flashspeicher, nimmt Ihnen aber auch sehr viel Arbeit ab und daher werden Ihre eige­nen Programme meist relativ klein sein im Vergleich zur RP6Library.

4.2. Programme in den RP6 laden

Das eben kompilierte Programm, kann nun mit dem RobotLoader in den Roboter gela­den werden.
Dazu fügen Sie die eben erzeugte Hexdatei in die Liste im RobotLoader mit „Add“ bzw. „Hinzufügen“ ein, selektieren diese und klicken auf den „Upload!“ Button, genau wie Sie es auch schon beim Selbsttestprogramm getan haben. Danach können Sie wieder auf das Terminal wechseln und sich die Ausgabe des Programms anschauen. Die Pro­grammausführung muss dazu natürlich zunächst wieder gestartet werden, im Termi­nal ist es am bequemsten [STRG]+[S] auf der Tastatur zu drücken oder das Menü zu benutzen (oder einfach ein „s“ senden – nach einem Reset müssen Sie allerdings im­mer etwas warten bis die Meldung „[READY]“ im Terminal erscheint!). Auch [STRG]+ [Y] ist eine sehr nützliche Tastenkombination, denn damit wird das aktuell selektierte Programm in den RP6 geladen und direkt danach gestartet! Man muss also nicht extra vom Terminal aus wieder auf den Karteireiter „Flash Loader“ wechseln oder das Menü benutzen.
Das Beispielprogramm ist sehr einfach und besteht nur aus einem kleinen LED Lauf­licht und etwas Textausgabe.
Bevor Sie nun Ihre eigenen Programme schreiben können, folgt ein kleiner C Crash­kurs...
- 60 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.3. Warum ausgerechnet C? Und was bedeutet „GCC“?

Die Programmiersprache C ist sehr weit verbreitet – es ist die standard Sprache die eigentlich jeder der sich für Softwareentwicklung interessiert mal verwendet haben sollte (oder zumindest von der Syntax her ähnliche Sprachen). Für so gut wie jeden derzeit verfügbaren Mikrocontroller existiert mindestens ein C Compiler. Aus diesem Grund können alle neueren Roboter von AREXX Engineering (zur Zeit ASURO, YETI und der RP6) in C programmiert werden.
Da C sehr weit verbreitet ist, gibt es sehr viel Dokumentation dazu im Internet und in Büchern. Das macht es Einsteigern natürlich einfacher, auch wenn C schon eine relativ komplexe Sprache ist, die man ohne Vorkenntnisse normalerweise nicht mal eben so innerhalb von zwei drei Tagen erlernen kann... (also bitte nicht gleich den Roboter aus dem Fenster werfen, wenn es mal nicht auf Anhieb klappen sollte ;-) )
Die Grundlagen sind zum Glück einfach zu verstehen und man kann seine Fähigkeiten kontinuierlich ausbauen und verbessern. Das erfordert aber schon etwas Eigeninitiati­ve! Von alleine lernt sich C nicht – das ist ähnlich wie mit normalen Fremdsprachen!
Wenn man C aber erstmal einigermaßen beherrscht, ist der Einstieg in viele andere Programmiersprachen auch kein allzugroßes Problem mehr, da oft sehr ähnliche Kon­zepte verwendet werden.
Für den RP6 kommt wie auch bei unseren anderen Robotern eine spezielle Version des C Compilers aus der GNU Compiler Collection oder kurz GCC zum Einsatz. Es handelt sich beim GCC um ein universelles Compiler System, welches verschiedenste Spra­chen unterstützt. So kann man damit z.B. neben C auch in C++, Java, Ada und FORT­RAN verfasste Quelltexte übersetzen.
Der GCC unterstützt nicht nur den AVR, sondern wurde eigentlich für viel größere Sys­teme entwickelt und kennt einige dutzend verschiedene Zielsysteme.
Prominentestes Projekt, für das der GCC verwendet wird, ist natürlich Linux. Auch fast alle Anwendungsprogramme die unter Linux laufen, wurden ebenfalls mit dem GCC übersetzt. Es handelt sich hier also um ein sehr ausgereiftes und professionelles Werkzeug, das auch in vielen großen Firmen zum Einsatz kommt.
Übrigens: Wenn wir von „GCC“ sprechen, meinen wir in diesem Handbuch nicht unbe­dingt die komplette Compiler Collection, sondern fast immer nur den C-Compiler. Ur­sprünglich stand GCC sogar nur für „GNU C Compiler“ - die neuere Bedeutung wurde notwendig, als auch andere Sprachen hinzukamen.
Wenn Sie mehr über den GCC erfahren möchten, können Sie die offizielle Homepage besuchen: http://gcc.gnu.org/
Der GCC unterstützt den AVR nicht sofort von sich aus und muss erst angepasst wer­den. Diese Version des GCC nennt sich dann AVR-GCC. Dieser Compiler ist für Win­dows Benutzer fertig eingerichtet in WinAVR enthalten. Bei Linux muss man sich diesen meist noch selbst übersetzen, was Sie ja hoffentlich schon erledigt haben.
- 61 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.4. C - Crashkurs für Einsteiger

Dieses Kapitel gibt Ihnen nur eine ganz kurze Einführung in die C Programmierung. Wir besprechen hier nur die absolut notwendigen Dinge die man für den RP6 unbedingt braucht. Dieser Abschnitt und viele der Beispielprogramme verstehen sich eher als Kurzübersicht: „Was es so alles gibt und was man alles machen kann“. Es werden Beispiele gegeben und die Grundlagen erklärt, aber es wird dem Le­ser überlassen sich dann ausführlicher damit zu befassen!
Es ist also nicht mehr als ein kleiner Crashkurs! Eine vollständige Einführung würde den Rahmen dieser Bedienungsanleitung bei weitem sprengen und füllt normaler­weise dicke Fachbücher! Davon gibt es aber glücklicherweise sehr viele! Einige1 davon sind sogar kostenlos im Internet verfügbar - hier folgt nur eine kleine Übersicht...

4.4.1. Literatur

Die folgenden Bücher und Tutorials beschäftigen sich mit der C Programmierung hauptsächlich für den PC und andere "große" Rechner. Vieles was in diesen Büchern
steht, gibt es nicht für AVR Mikrocontroller - die Sprache ist zwar gleich, aber die meisten Bibliotheken die man auf normalen PCs verwenden kann, sind für einen Mi­krocontroller schlicht zu groß. Bestes Beispiel sind Funktionen wie „printf“ - auf dem PC eine Selbstverständlichkeit! Diese Funktion gibt es zwar auch für Mikrocontroller, jedoch braucht sie ziemlich viel Speicher und Rechenzeit und sollte daher besser nicht verwendet werden. Wir besprechen später noch genügend für unsere Zwecke effekti­vere Alternativen.
Einige C Tutorials / Online-Bücher (nur eine winzig kleine Auswahl):
http://www.galileocomputing.de/openbook/c_von_a_bis_z/
http://de.wikibooks.org/wiki/C-Programmierung
http://suparum.rz.uni-mannheim.de/manuals/c/cde.htm
http://www.roboternetz.de/wissen/index.php/C-Tutorial
http://www.its.strath.ac.uk/courses/c/
Weiterhin gibt es viele Bücher auf dem Markt - einfach mal in eine gut sortierte Biblio­thek gehen oder bei Buchhändlern stöbern! Da findet sich meist eine ganze Menge.
Sie müssen sich kein Buch kaufen wenn Sie nur ein wenig mit dem Roboter herumex­perimentieren wollen - vieles muss man sich ohnehin "Learning by doing" beibringen! Alle benötigten Informationen finden sich auch auf den genannten Seiten im Internet und die auf der CD mitgelieferten Beispielprogramme sind auch schon recht umfang­reich.
Speziell für den AVR-GCC und AVR Mikrocontroller gibt es ein sehr gutes deutschspra­chiges Tutorial, und zwar hier:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
Dort werden einige Dinge genannt (Programmiergeräte etc.) die man für den RP6 aber nicht braucht. Das meiste davon ist jedoch sehr nützlich und es lohnt sich auf jeden Fall dort mal reinzuschauen!
1 Eine Suche bei einer bekannten Suchmaschine nach „c tutorial“ liefert viele Millionen Treffer! Es gibt
natürlich nicht wirklich so viele – aber es werden trotzdem so einige sein.
- 62 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Ein weiterer Artikel, der sich aber eher mit dem Compiler an sich und einigen speziel­len Bereichen befasst ist hier zu finden:
http://www.roboternetz.de/wissen/index.php/Avr-gcc
Dann gibt es auch noch die WinAVR Homepage und Dokumentation:
http://winavr.sourceforge.net/
http://winavr.sourceforge.net/install_config_WinAVR.pdf
sowie die AVR-LibC Dokumentation:
http://www.nongnu.org/avr-libc/user-manual/index.html
Sie müssen natürlich nicht alle diese Tutorials/Bücher lesen! Diese Liste hier versteht sich zur Auswahl! Aber nicht alle Tutorials sind gleichermaßen ausführlich und viele behandeln sehr unterschiedliche Themen. Es lohnt sich also schon, mehrere verschie­dene zu lesen.

4.4.2. Erstes Beispielprogramm

Wie gesagt - learning by doing ist der beste Weg um die Sprache C zu lernen. Wenn Sie also etwas in diesem Crashkurs gelesen und soweit verstanden haben, sollten Sie es auch ausprobieren! Probieren geht hier wirklich über Studieren!
Natürlich müssen noch ein paar Gundlagen besprochen werden, aber damit Sie direkt einen Eindruck davon bekommen, worüber wir hier eigentlich die ganze Zeit reden, schauen wir uns jetzt mal an, wie ein kleines C Programm für den RP6 typischerweise ausschaut:
1
/*
2
* Ein kleines "Hallo Welt" C Programm für den RP6!
3
*/
4 5
#include "RP6RobotBaseLib.h"
6 7
int main(void)
8
{
9 10 11
return 0;
12
}
initRobotBase(); writeString("Hallo Welt!\n");
Wenn Sie noch nie zuvor in C programmiert haben, sieht das wahrscheinlich auf den ersten Blick aus wie eine Fremdsprache (und das ist es ja auch!), aber die Grundlagen sind wirklich sehr einfach zu verstehen. C wurde im englischsprachigen Raum entwi-
ckelt2 und deshalb sind auch alle Befehle an die englische Sprache angelehnt. Das ist aber nicht nur bei C so, sondern bei so gut wie allen Programmiersprachen.
2 ...genauer gesagt zu Beginn der 1970er Jahre in den USA, wo es dann als Entwicklungsgrundlage des UNIX Betriebssystems gedient hat – es folgten später noch viele Verbesserungen und Ergänzungen...
- 63 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Wir halten uns bei den größeren Beispielprogrammen auch konsequent daran und be­nennen alle Funktionen und Variablen in den Beispielprogrammen mit englischen Be­griffen! Hier im Handbuch und diesem C Crashkurs wird jedoch ab und an auch mal eine Ausnahme gemacht.
Bei den Programmen dieses Crashkurses sind die Kommentare auf Deutsch verfasst, aber bei den richtigen Beispielprogrammen und der RP6Library sind sie komplett auf Englisch.
Das hat den einfachen Grund, dass man ansonsten zwei Versionen des Quellcodes pflegen müsste und jedesmal wenn etwas geändert wird oder neue Funktionen hinzu­kommen, alles in zweifacher Ausführung ändern und in zwei Sprachen kommentieren müsste. Das macht nicht nur viel Arbeit, sondern verzögert auch die Freigabe von Verbesserungen und neuen Versionen.
Wer C lernen will bzw. sich detaillierter mit Mikrocontrollern, Elektronik und Robotik befasst, kommt ohnehin nur schwer um Englisch herum.
Allerdings wird die Funktionsweise der Beispielprogramme auch noch im entsprechen­den Kapitel auf Deutsch erläutert!
Nun aber zurück zum Beispiel. Dieses kleine Programm oben ist zwar funktionsfähig, tut aber nichts weiter als den Mikrocontroller zu initialisieren und den Text:
"Hallo Welt!" + Zeilenvorschub / Neue Zeile
über die serielle Schnittstelle auszugeben! Ein typisches Programm, das in so gut wie jedem Buch zu finden ist.
Das kleine Beispielprogramm können Sie natürlich auch ausprobieren. Es kann sehr sinnvoll sein das einfach mal abzutippen um ein Gefühl für die Sprache zu bekommen! Vor allem an die vielen Semikolons und Sonderzeichen muss man sich erstmal gewöh­nen...
Wem das obige Programm aber schon zu langweilig ist: Auf der CD findet sich bei den Beispielprogrammen noch ein etwas interessanteres "Hallo Welt" Programm mit klei­nem LED-Lauflicht und ein paar mehr Textausgaben!
Wir werden nun das Programm in Listing 1, Zeile für Zeile durchgehen und erklären! Zeile 1 - 3: /* Ein kleines "Hallo Welt" C Programm für den RP6! */
Das ist ein Kommentar. Dieser Teil des Quelltextes wird vom Compiler nicht weiter be­achtet. Kommentare werden zur Dokumentation des Quelltextes verwendet und er­leichtern das Verständnis fremder (und eigener!) Quelltexte. Bei fremden Quelltexten kann man damit besser nachvollziehen, was sich der Programmierer dabei gedacht hat und bei eigenen Quelltexten hat man auch nach ein paar Jahren noch gute An­haltspunkte um sich an die eigenen Gedankengänge besser erinnern zu können. Kom­mentare beginnen mit /* und enden mit */
Sie können dazwischen beliebig lange Kommentare verfassen, oder auch Teile Ihres Quellcodes „auskommentieren“ um z.B. eine andere Variante zu testen ohne den alten Quellcode zu löschen. Neben diesem mehrzeilen Kommentaren unterstützt der GCC auch einzeilige Kommentare, die mit einem „//“ eingeleitet werden. Alles in einer Zeile nach einem „//“ wird vom Compiler als Kommentar interpretiert.
- 64 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Zeile 5: #include "RP6RobotBaseLib.h"
Hier binden wir die RP6 Funktionsbibliothek ein. Diese stellt sehr viele nützliche Funk­tionen und vordefinierte Dinge bereit, die das Ansteuern der Hardware immens er­leichtern. Das müssen wir über eine sog. Headerdatei (Endung „*.h“) einbinden, da der Compiler sonst nicht weiss, wo er die ganzen Funktionen finden kann. Header braucht man für alle Dinge, die in externen C-Dateien liegen. Wenn Sie sich mal den Inhalt von der RP6RobotBaseLib.h und dann noch der RP6RobotBaseLib.c ansehen, werden Sie das Prinzip wahrscheinlich besser verstehen. Mehr zu „#include“ folgt im Kapitel über den Präprozessor.
Zeile 7: int main(void)
Das Wichtigste an dem Beispielprogramm: Die Main Funktion. Was eine Funktion ge­nau ist, wird etwas später erklärt. Zunächst reicht es uns zu wissen, dass das Pro­gramm hier anfängt (engl. „Main Function“ bedeutet zu deutsch „Haupt-Funktion“).
Zeile 8 und Zeile 12: { }
In C werden sogenannte "Blöcke" mit geschweiften Klammern - also '{' und '}' defi­niert! (Auf der Tastatur sind das [AltGr] + [7] für '{' und [AltGr] + [0] für '}' ).
Blöcke fassen mehrere Befehle zusammen. Zeile 9: initRobotBase();
Hier wird eine Funktion aus der RP6Library aufgerufen, die den AVR Mikrocontroller in­itialisiert. Damit werden die Hardware Funktionen des AVRs konfiguriert. Ohne diesen Aufruf arbeiten die meisten Funktionen des Mikrocontrollers nicht korrekt! Also nie­mals vergessen das als erstes aufzurufen!
Zeile 10: writeString("Hello World!\n");
Hier wird die Funktion "writeString" aus der RP6 Library mit dem Text "Hello World!\n" als Parameter aufgerufen. Der Text wird dann von dieser Funktion über die serielle Schnittstelle ausgegeben.
Zeile 11: return 0;
Hier endet das Programm – die Main Funktion wird verlassen und der Wert 0 zurück­gegeben. Das wird auf großen Computern meist für Fehlercodes oder ähnliches benutzt. Auf dem Mikrocontroller braucht man das aber eigentlich gar nicht und es ist nur da weil es der C Standard so will.
Jetzt haben Sie schonmal einen kleinen Eindruck davon bekommen wie so ein C-Pro­gramm ausschaut. Nun müssen wir aber erstmal noch ein paar Grundlagen besprechen, bevor es weitergeht.
- 65 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.4.3. C Grundlagen Wie schon zu Beginn gesagt, besteht ein C Programm aus reinem ASCII (American

Standard Code for Information Interchage) Text. Es wird dabei strikt zwischen Groß-
und Kleinschreibung unterschieden. Das heisst sie müssen eine Funktion die "ichBinEineFunktion" heisst, auch immer genau so aufrufen! Der Aufruf: "IcHbInEiNeFuNkTIoN();" würde so nämlich nicht funktionieren!
Man kann zwischen den einzelnen Befehlen und Anweisungen beliebig viele Leerzei­chen, Tabulatoren und Zeilenumbrüche einfügen ohne das sich die Bedeutung des Programms ändert.
Sie haben ja schon bei dem Beispielprogramm gesehen, dass die Befehle mit Tabula­toren eingerückt worden sind, um das Programm besser lesbar zu machen. Notwendig ist das aber nicht! Den Teil ab Zeile 7 vom Listing oben könnte man z.B. auch so schreiben:
1 int main(void){initRobotBase();writeString("Hallo Welt!\n");return 0;}
Das ist von der Bedeutung her identisch – aber etwas unübersichtlich. Hier wurden nur die Zeilenumbrüche und Einrückungen entfernt! Dem Compiler ist das völlig egal! (Einige Leerzeichen z.B. zwischen „int“ und „main“ sind natürlich immer notwendig um einzelne Schlüsselwörter und Bezeichner zu trennen und innerhalb von Anführungszei­chen darf man auch nicht einfach so einen Zeilenumbruch einfügen!)
Mehrere Anweisungen werden mit den oben angesprochenen geschweiften Klammern { } zu sog. Blöcken zusammengefasst. Das brauchen wir bei Funktionen, Bedingungen und Schleifen.
Jede Anweisung wird mit einem Semikolon ';' beendet, so kann der Compiler die An­weisungen auseinanderhalten.
Ein wichtiger Hinweis gleich zu Beginn, wenn Sie die Programme in diesem Tutorial abtippen wollen: Man vergisst sehr leicht die Befehle jeweils mit einem Semikolon zu beenden – oder setzt eins an eine falsche Stelle und wundert sich dann, warum das Programm nicht das tut was es soll! Vergisst man ein einziges Semikolon in bestimm­ten Programmteilen, kann der Compiler übrigens gleich einen ganzen Haufen von Feh­lermeldungen erzeugen – auch wenn es eigentlich nur ein einziger Fehler ist. Meist zeigt schon die erste Fehlermeldung den tatsächlichen Fehler an.
Auch vergisst man gern eine der vielen Klammern zu schließen oder vertut sich mit der Schreibweise von Befehlen. Der Compiler verzeiht keine Syntax Fehler (= „Recht­schreibfehler“)! Das ist vielleicht erstmal gewöhnungsbedürftig sich an all diese Re­geln zu halten, aber das lernt man nachdem man einige Programme selbst geschrie­ben hat relativ schnell.
Jedes C Programm beginnt in der Main Funktion. Die dann folgenden Befehle werden grundsätzlich sequentiell, Anweisung nach Anweisung von oben nach unten abgear­beitet. Mehrere Befehle gleichzeitig kann ein AVR Mikrocontroller nicht ausführen!
Das macht aber nichts, denn es gibt viele Möglichkeiten, den Progammablauf zu be­einflussen und an andere Stellen im Programm zu springen (mit sog. Flusssteuerung, dazu kommen wir später).
- 66 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.4.4. Variablen

Erstmal fangen wir aber damit an, wie wir denn überhaupt Daten im Arbeitsspeicher ablegen und auslesen können. Das geht mit Variablen. Es gibt in C verschiedene Arten von Variablen - sog. Datentypen. Grundsätzlich sind dies 8, 16 oder 32Bit große, ganzzahlige Datentypen, die entweder mit oder ohne Vorzeichen verwendet werden können. Wieviel "Bit" eine Variable haben muss, hängt davon ab wie groß die Zahlen sind (Wertebereich), die darin gespeichert werden sollen.
Beim RP6 verwenden wir folgende Datentypen:
Typ Alternative Wertebereich Bemerkung
signed char int8_t 8 Bit: -128 ... +127 1 Byte
char uint8_t 8 Bit: 0 ... 255 '' vorzeichenlos
int int16_t 16 Bit: -32768 ... +32767 2 Bytes
unsigned int uint16_t 16 Bit: 0 ... 65535 '' vorzeichenlos
long int32_t 32 Bit: –2147483648 ... +2147483647 4 Bytes
unsinged long uint32_t 32 Bit: 0 ... 4294967295 '' vorzeichenlos
Da insbesondere der Datentyp „int“ auf verschiedenen Plattformen nicht standardisiert ist und z.B. auf unserem Mikrocontroller 16 bit, auf PCs aber 32 bit groß ist, verwen­den wir die neuere standardisierte Bezeichnung: int16_t
Diese Datentypen ist immer so aufgebaut: [u] int N _t
u : unsigned (kein Vorzeichen) int : Integer (ganze Zahl) N : Anzahl der Bits, z.B. 8, 16, 32 oder 64 _t : t wie „type“ um Verwechslungen mit anderen Bezeichnern auszuschließen.
Auf einem Mikrocontroller kommt es oft auf jedes Byte Speicherplatz an, daher behält man mit dieser Bezeichnung auch besser den Überblick. Man sieht der Bezeichnung sofort an, dass es sich um einen 16bit Datentyp handeln muss (wegen der 16 im Na­men). Steht noch ein „u“ davor, handelt es sich um einen „unsigned“ also vorzeichen­losen Datentyp. Sonst ist der Datentyp „signed“ also vorzeichenbehaftet.
Das wurde oben in der Tabelle aber nur bei „signed char“ hinge­schrieben, denn int und long sind standardmäßig vorzeichenbehaftet und nur char ist standardmäßig vorzeichenlos - auch wenn man es nicht explizit hinschreibt. Das resultiert aus einer Compileroption die wir verwenden und die auch fast immer beim AVR-GCC aktiviert ist.
Bei Strings (=Engl. für Zeichenketten) wird auch weiterhin „char“ ge­nutzt da sonst wegen der Definition von uint8_t ein paar Dinge aus der C Standard Bibliothek nicht damit kompatibel wären und es oh­nehin logischer ist, hierfür den Datentyp char (=Engl. für „Zeichen“) zu verwenden. Das wird im Kapitel über die RP6Library bei Textaus­gabe über die serielle Schnittstelle noch etwas genauer behandelt.
Also merken wir uns einfach: Bei Zeichen und Zeichenketten immer „char“ verwenden, bei Zahlenwerten immer uintN_t oder intN_t!
- 67 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Um eine Variable nutzen zu können, muss sie zunächst deklariert werden. Hierbei wird festgelegt welchen Datentyp, Namen und evtl. noch welchen Anfangswert die Variable erhalten soll. Der Name einer Variablen muss dabei mit einem Buchstaben beginnen (Der Unterstrich also “_” zählt ebenfalls als Buchstabe) und darf auch Zahlen, aber keine Sonderzeichen wie z.B. „äöüß#'[]²³|*+-.,<>%&/(){}$§=´°?!^“ o.ä. enthalten.
Groß- und Kleinschreibung werden wie immer unterschieden. Also sind aBc und abC verschiedene Variablen! Traditionellerweise werden immer Kleinbuchstaben zumindest für den Anfangsbuchstaben von Variablennamen verwendet.
Folgende Bezeichnungen sind bereits für andere Dinge reserviert und können NICHT als Variablennamen, Funktionsnamen oder jegliche anderen Bezeichner verwendet werden:
auto default float long sizeof union
break do for register static unsigned
case double goto return struct void
char else if short switch volatile
const enum int signed typedef while
continue extern
Es gibt weiterhin noch Fließkommazahlen der Typen float und double. Man sollte auf einem kleinen AVR Mikrocontroller aber möglichst vermeiden damit zu arbeiten. Kos­tet meistens zuviel Rechenzeit und Speicherplatz und man kommt oft mit normalen ganzen Zahlen besser aus. Für den RP6 brauchen wir diese Datentypen also normaler­weise nicht.
Eine Variable zu deklarieren ist sehr einfach, hier z.B. ein char mit dem Namen x:
char x;
Nach dieser Deklaration ist die Variable x im danach folgenden Programmcode gültig und kann verwendet werden.
Man kann ihr z.B. mit
x = 10;
den Wert 10 zuweisen. Man kann der Variablen auch gleich bei der Deklaration einen Wert zuweisen:
char y = 53;
Die normalen Grundrechenarten können ganz normal verwendet werden:
signed char z; // Char mit Vorzeichen! z = x + y; // z hat nun den Wert z = x + y = 10 + 53 = 63 z = x – y; // z hat nun den Wert z = 10 – 53 = -43 z = 10 + 1 + 2 – 5; // z = 8 z = 2 * x; // z = 2 * 10 = 20 z = x / 2; // z = 10 / 2 = 5
- 68 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Es gibt dann noch ein paar nützliche Abkürzungen:
z += 10; // entspricht: z = z + 10; also ist z = 15 z *= 2; // z = z * 2 = 30 z -= 6; // z = z - 6 = 24 z /= 4; // z = z / 4 = 8
z++; // Abkürzung für z = z + 1; Also ist z hier 9 z++; // z = 10 // z++ nennt man auch „z inkrementieren“ z++; // z = 11 ... z--; // z = 10 // z-- nennt man auch „z dekrementieren“ z--; // z = 9 z--; // z = 8 ...
Oben haben wir noch den Datentyp „char“ verwendet. Wie aber schon gesagt, werden in allen anderen Programmen des RP6 (fast) nur standardisierte Datentypen verwen­det.
So z.B. wäre folgendes: int8_t x; identisch zu: signed char x; Und: uint8_t x; identisch zu: unsigned char x; // bzw. bei uns eigentlich auch einfach nur
„char“ da dieser Datentyp standardmäßig „unsigned“ ist.

4.4.5. Bedingungen

Bedingungen mit „if-else“ Konstrukten sind sehr sehr wichtig um den Programmablauf zu steuern. Man kann mit ihnen überprüfen, ob eine gegebene Bedingung wahr oder falsch ist und je nachdem bestimmten Programmcode ausführen oder nicht.
Direkt ein kleines Beispiel:
1
uint8_t x = 10;
2
if(x == 10)
3
{
4 5
}
writeString("x ist gleich 10!\n");
Hier wird in Zeile 1 zunächst die 8-Bit Variable x deklariert und ihr der Wert 10 zuge­wiesen. Jetzt überprüfen wir in der nachfolgenden if-Bedingung in Zeile 2, ob die Va­riable x den Wert 10 hat. Das ist hier natürlich immer der Fall und somit wird der Block unter der Bedingung ausgeführt und „x ist gleich 10!“ ausgegeben. Hätten wir x stattdessen mit 231 initialisiert, wäre an dieser Stelle nichts ausgegeben worden!
Allgemein hat eine if-Bedingung immer folgende Syntax:
if ( <Bedingung X> )
<Anweisungsblock Y>
else
<Anweisungsblock Z>
Ins Deutsche übersetzt heisst das übrigens soviel wie: „wenn X dann Y sonst Z“.
- 69 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Ein weiteres Beispiel dazu:
1
uint16_t tolleVariable = 16447;
2 3
if(tolleVariable < 16000) // Wenn tolleVariable < 16000
4
{ // Dann: 5 6
}
7
else // Sonst:
8
{
9 10
}
writeString("tolleVariable ist kleiner als 16000!\n");
writeString("tolleVariable ist größer oder gleich 16000!\n");
Hier wäre die Ausgabe „tolleVariable ist größer oder gleich 16000!“, denn tolleVariable ist hier 16447 und somit größer als 16000. Die Bedingung ist also nicht erfüllt und der else Teil wird ausgeführt. Wie man am Namen „tolleVariable“ erkennen kann, hat man bei der Namensgebung von Variablen (und allem anderen) keine anderen Einschrän­kungen als die weiter oben genannten.
Man kann auch mehrere If-then-else-Bedingungen hintereinander verwenden um mehrere alternative Fälle abzufragen:
1
if(x == 1) { writeString("x ist 1!\n"); }
2
else if(x == 5) { writeString("x ist 5!\n"); }
3
else if(x == 244) { writeString("x ist 244!\n"); }
4
else { writeString("x ist hat einen anderen Wert!\n");}
Innerhalb der Bedingungen kann man folgende Vergleichsoperatoren verwenden:
x == y logischer Vergleich auf Gleichheit
x != y logischer Vergleich auf Ungleichheit
x < y logischer Vergleich auf „kleiner“
x <= y logischer Vergleich auf „kleiner oder gleich“
x > y logischer Vergleich auf „größer“
x >= y logischer Vergleich auf „größer oder gleich“
Dann gibt es noch logische Verknüpfungsoperatoren:
x && y wahr, wenn x wahr und y wahr sind
x || y wahr, wenn x wahr und/oder y wahr
!x wahr, wenn x nicht wahr ist
Das kann man alles beliebig miteinander Verknüpfen und verschachteln und beliebig viele Klammern setzen:
1
if( ((x != 0) && (!(x > 10))) || (y >= 200)) {
2 3
}
writeString("OK!\n");
Die obige if Bedingung wird wahr, wenn x ungleich 0 (x != 0) UND x nicht größer als 10 ist (!(x > 10)) ODER wenn y größer oder gleich 200 ist (y >= 200). Dort könnte man noch beliebig viele weitere Bedingungen hinzufügen, sofern notwendig.
- 70 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.4.6. Switch-Case

Oft muss man eine Variable auf viele verschiedene Zahlenwerte überprüfen und ab­hängig davon Programmcode ausführen. Das kann man natürlich wie oben beschrie­ben mit vielen if-then-else Bedingungen machen, aber es geht auch eleganter mit ei­ner switch-Verzweigung.
Ein Beispiel:
1
uint8_t x = 3;
2 3
switch(x)
4
{
5 6 7 8 9 10 11 12 13 14 15
}
case 1: writeString("x=1\n"); break; case 2: writeString("x=2\n"); break; case 3: writeString("x=3\n"); // Hier fehlt das "break", also fährt case 4: writeString("Hallo\n"); // das Programm direkt mit dem case 5: writeString("du\n"); // nächsten und dem nächsten Fall fort, case 6: writeString("da!\n"); break; // und stoppt erst hier! case 44: writeString("x=44\n"); break;
// Hier gelangt das Programm hin, wenn keiner der obigen // Fälle gepasst hat:
default : writeString("x ist was anderes!\n"); break;
Das ist vom Resultat her ähnlich zu dem Beispiel auf der vorherigen Seite mit „if-else­if-else-if-else...“, nur eine andere Schreibweise.
Die Ausgabe wäre in diesem Fall (mit x = 3):
x=3 Hallo du da!
Wenn man x = 1 setzen würde, wäre die Ausgabe „x=1\n“ und mit x=5 wäre die Ausgabe:
du da!
Hier sieht man, dass das „break“ die Switch-Verzweigung beendet. Lässt man es weg, läuft das Programm einfach solange durch alle anderen Fälle durch bis entweder das Ende der switch-Verzweigung erreicht ist oder ein anderes „break“ ausgeführt wird. Dabei ist es egal ob die nachfolgenden Bedingungen erfüllt werden oder nicht!
Wenn x = 7 gesetzt wird, würde keiner der Fälle diesen Wert abdecken, das Pro­gramm im default Teil landen und die Ausgabe wäre: „x ist was anderes!\n“.
Diese ganzen Textausgaben sind natürlich nur Beispiele – man könnte in realen Pro­grammen für den Roboter damit z.B. verschiedene Bewegungsmuster auslösen. In ei­nigen Anwendungsbeispielen werden switch-case Konstrukte z.B. für endliche Auto­maten verwendet um verschiedene Verhalten des Roboters zu implementieren.
- 71 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.4.7. Schleifen

Schleifen werden immer dann gebraucht, wenn bestimmte Operationen mehrmals wiederholt werden müssen.
Dazu direkt ein kleines Beispiel:
1
uint8_t i = 0;
2
while(i < 10) // solange i kleiner als 10 ist...
3
{ // ... wiederhole folgenden Programmcode:
4 5 6 7 8 9
}
writeString("i="); // "i=" ausgeben, writeInteger(i, DEC); // den dezimalen (engl. "DECimal") Zahlenwert
// von i und ... writeChar('\n'); // ... einen Zeilenumbruch ausgeben. i++; // i inkrementieren.
Hier handelt es sich um eine „while“ Schleife die der Reihe nach „i=0\n“, „i=1\n“, „i=2\n“, ... „i=9\n“ ausgibt. Der Block nach dem sog. Schleifenkopf, also dem „while(i < 10)“ wird solange wiederholt, wie die Bedingung wahr ist. In diesem Fall ist die Bedingung „i ist kleiner als 10“. Auf Deutsch würde das obige also soviel wie „wie­derhole den folgenden Block, solange i kleiner als 10 ist“ heissen. Da i hier zunächst 0 ist und bei jedem Schleifendurchlauf um 1 erhöht wird, läuft die Schleife insgesamt 10 mal durch und gibt die Zahlen von 0 bis 9 aus. Die Bedingung im Schleifenkopf kann genau so aufgebaut werden wie bei den if Bedingungen.
Neben der while Schleife gibt es noch die „for“ Schleife. Die funktioniert ganz ähnlich, nur kann man hier noch etwas mehr im Schleifenkopf unterbringen.
Dazu wieder ein Beispiel:
1
uint8_t i; // wird hier NICHT initialisiert, sondern im Schleifenkopf!
2
for(i = 0; i < 10; i++)
3
{
4 5 6 7
}
writeString("i="); writeInteger(i, DEC); writeChar('\n');
Diese Schleife erzeugt exakt dieselbe Ausgabe wie die obige while Schleife. Hier ist nur noch einiges mehr im Schleifenkopf untergebracht.
Der grundsätzliche Aufbau ist folgender:
for ( <Laufvariable initialisieren> ; <Abbruchbedingung> ; <Laufvariable verändern> ) {
<Anweisungsblock>
}
Für Mikrocontroller braucht man oft Endlosschleifen, also Schleifen die „unendlich“ oft wiederholt werden. Fast jedes Mikrocontrollerprogramm hat eine Endlosschleife – sei es um das Programm nachdem es abgearbeitet worden ist in einen definierten Endzu­stand zu versetzen, oder einfach Operationen solange auszuführen wie der Mikrocon­troller läuft.
- 72 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Das kann man sowohl mit einer while als auch mit einer for Schleife ganz einfach rea­lisieren:
while(true) { }
bzw.
for(;;) { }
Der Anweisungsblock wird dann „unendlich oft“ ausgeführt (bzw. bis der Mikrocontrol­ler das Reset Signal erhält, oder man mit dem Befehl „break“ die Schleife beendet).
Der Vollständigkeit halber kann man noch die do-while Schleife erwähnen, dabei han­delt es sich um eine Variante der normalen while-Schleife. Der Unterschied ist, dass der Anweisungsblock mindestens einmal ausgeführt wird, auch wenn die Bedingung nicht erfüllt ist.
Der Aufbau ist folgender:
do {
<Anweisungsblock> } while(<Bedingung>);
Hier das Semikolon am Ende nicht vergessen! (Bei normalen Schleifen gehört da na­türlich keins hin!)
- 73 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.4.8. Funktionen

Ein sehr wichtiges Sprachelement sind Funktionen. Wir haben ja weiter oben auch schon mehrere solcher Funktionen gesehen und verwendet. Beispielsweise die Funk­tionen „writeString“ und „writeInteger“ und natürlich die Main Funktion.
Funktionen sind immer nützlich, wenn bestimmte Programmsequenzen in mehreren Teilen des Programms unverändert verwendet werden können – gute Beispiele sind z.B. die ganzen Textausgabe Funktionen die wir oben schon oft verwendet haben. Es wäre natürlich sehr umständlich wenn man diese identischen Programmteile immer an diejenigen Stellen kopieren müsste wo man sie braucht und man würde unnötigerwei­se Speicherplatz verschwenden. Nebenbei kann man mit Funktionen Änderungen an zentraler Stelle durchführen und muss das nicht an mehreren Stellen tun. Auch kann ein Programm deutlich übersichtlicher werden, wenn man es in mehrere Funktionen aufteilt.
Deshalb kann man in C Programmsequenzen zu Funktionen zusammenfassen. Diese haben immer folgenden Aufbau:
<Rückgabetyp> <Funktionsname> (<Parameter 1>, <Parameter 2>, ... <Parameter n>) {
<Programmsequenz> }
Damit man sich das besser vorstellen kann, direkt mal ein kleines Beispiel mit zwei einfachen Funktionen und der schon bekannten Main Funktion:
8
void someLittleFunction(void)
9
{
10 11
}
12 13
void someOtherFunction(void)
14
{
15 16
}
17 18
int main(void)
19
{
20 21 22 23 24 25
someLittleFunction(); 26 27
someOtherFunction(); 28
return 0;
29
}
writeString("[Funktion 1]\n");
writeString("[Funktion 2 – mal was anderes]\n");
initRobotBase(); // Beim RP6 das hier immer als erstes aufrufen!
// Ein paar Funktionsaufrufe:
someLittleFunction(); someOtherFunction();
someOtherFunction();
Die Ausgabe des Programms wäre folgende:
[Funktion 1] [Funktion 2 – mal was anderes] [Funktion 1] [Funktion 2 – mal was anderes] [Funktion 2 – mal was anderes]
- 74 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Die Main Funktion dient als Einsprungpunkt ins Programm. Sie wird in jedem C Pro­gramm zuerst aufgerufen und MUSS somit auch immer vorhanden sein.
In unserer obigen Main Funktion wird zuerst die initRobotBase Funktion aus der RP6Li­brary aufgerufen, die den Mikrocontroller initialisiert (muss man beim RP6 immer als erstes in der Main Funktion aufrufen, sonst funktionieren viele Sachen nicht richtig!). Diese ist vom Prinzip her genau so aufgebaut wie die anderen beiden Funktionen im Listing. Anschließend werden nacheinander ein paar mal die beiden gerade definierten Funktionen aufgerufen und der Programmcode in den Funktionen ausgeführt.
Nun kann man Funktionen nicht nur wie oben im Beispiel gezeigt definieren, sondern auch noch Parameter und Rückgabewerte benutzten. Im obigen Beispielprogramm wird als Parameter und Rückgabetyp „void“ angegeben, was soviel wie „leer“ heisst. Das bedeutet einfach, dass diese Funktionen keinen Rückgabewert und keine Parame­ter haben. Man kann viele Parameter für eine Funktion definieren. Die Parameter wer­den dabei durch Kommata voneinander getrennt.
Ein Beispiel:
1
void outputSomething(uint8_t something)
2
{
3 4 5 6
}
7 8
uint8_t calculate(uint8_t param1, uint8_t param2)
9
{
10 11 12
}
13 14
int main(void)
15
{
16 17 18 19 20 21 22 23
uint8_t result = calculate(10, 30); 24
outputSomething(result); 25
return 0;
26
}
writeString("[Der Funktion wurde folgender Wert übergeben: "); writeInteger(something, DEC); writeString("]\n");
writeString("[CALC]\n");
return (param1 + param2);
initRobotBase();
// Ein paar Funktionsaufrufe:
outputSomething(199); outputSomething(10); outputSomething(255);
Ausgabe:
[Der Funktion wurde folgender Wert übergeben: 199] [Der Funktion wurde folgender Wert übergeben: 10] [Der Funktion wurde folgender Wert übergeben: 255] [CALC] [Der Funktion wurde folgender Wert übergeben: 40]
Die RP6 Library enthält ebenfalls sehr viele verschiedene Funktionen. Schauen Sie sich einfach mal einige davon und die Beispielprogramme an, dann wird das Prinzip sehr schnell klar.
- 75 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.4.9. Arrays, Zeichenketten, Zeiger ...

Es gäbe noch viel mehr Sprachelemente und Details zu besprechen, aber hier müssen wir auf die angegebene Literatur verweisen. (Infos zu Zeigern finden Sie z.B. hier:
http://www.galileocomputing.de/openbook/c_von_a_bis_z/c_014_000.htm )
Das meiste davon braucht man auch gar nicht um die Beispielprogramme verstehen zu können. Hier geben wir nur ein paar Beispiele und Begriffe an, um einen Überblick darüber zu geben. Eine sonderlich ausführliche Beschreibung ist das allerdings nicht.
Zunächst zu Arrays. In einem Array (=“Feld“) kann man eine vorgegebene Anzahl von Elementen eines bestimmten Datentyps speichern. So könnte man z.B. folgenderma­ßen ein Array mit 10 Bytes anlegen:
uint8_t unserTollesArray[10];
Schon hat man quasi 10 Variablen mit gleichem Datentyp deklariert, die man nun über einen Index ansprechen kann:
unserTollesArray[0] = 8; unserTollesArray[2] = 234; unserTollesArray[9] = 45;
Jedes dieser Elemente kann man wie eine normale Variable behandeln.
Achtung: Der Index startet immer bei 0 und wenn man ein Array mit n Elementen an­gelegt hat, geht der Index von 0 bis n-1 ! Also bei 10 Elementen z.B. von 0 bis 9.
Arrays ist sehr nützlich wenn man viele Werte gleichen Typs speichern muss. Man kann diese auch in einer Schleife der Reihe nach durchlaufen:
uint8_t i; for(i = 0; i < 10; i++)
writeInteger(unserTollesArray[i],DEC);
So werden der Reihe nach alle Elemente im Array ausgegeben (hier natürlich ohne Trennzeichen oder Zeilenumbrüche dazwischen). Analog dazu kann man auch ein Ar­ray in einer Schleife mit Werten beschreiben.
Ganz ähnlich sind Zeichenketten in C aufgebaut. Normale Zeichenketten sind stets im ASCII Code kodiert, wofür man pro Zeichen ein Byte benötigt. Zeichenketten sind in C nichts anderes als Arrays, die man eben als Zeichenketten interpretieren kann. Man kann z.B. folgendes Schreiben:
uint8_t eineZeichenkette[16] = "abcdefghijklmno";
Und schon hat man die in Klammern stehende Zeichenkette im Speicher abgelegt. Wir haben weiter oben auch schon ein paar UART Funktionen verwendet, die Zeichen-
ketten über die serielle Schnittstelle ausgeben. Die Zeichenketten sind dabei nur Ar­rays. Der Funktion wird allerdings kein komplettes Array übergeben, sondern nur die Adresse des ersten Elements in dem Array. Die Variable die diese Adresse enthält nennt man „Zeiger“ (engl. Pointer). Um einen Zeiger auf ein bestimmtes Array Ele­ment zu erzeugen schreibt man &unserTollesArray[x] wobei x das Element ist, auf das der Zeiger zeigen soll. Diese Schreibweise wird ab und an in den Beispielprogrammen verwendet. Beispielsweise so:
uint8_t * zeigerAufEinElement = &eineZeichenkette[4];
Das brauchen Sie aber erstmal noch nicht um die Programmbeispiele zu verstehen und eigene Programme zu schreiben. Wird hier nur der Vollständigkeit halber erwähnt.
- 76 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.4.10. Programmablauf und Interrupts

Wir hatten weiter oben schon gesagt, das ein Programm generell Anweisung nach An­weisung von oben nach unten ausgeführt wird. Dann gibt es natürlich noch die norma­le Flusssteuerung mit Bedingungen und Schleifen, sowie Funktionen.
Neben diesem normalen Programmablauf gibt es allerdings noch sog. „Interrupts“. Die verschiedenen Hardwaremodule (Timer, TWI, UART, Externe Interrupts etc.) des Mi­krocontrollers können Ereignisse auslösen, auf die der Mikrocontroller so schnell wie möglich reagieren muss. Dazu springt der Mikrocontroller – (fast) egal wo er sich ge­rade im normalen Programm befindet – in eine sog. Interrupt Service Routine (ISR), in der dann schnellstmöglich auf das Ereignis reagiert werden kann. Keine Sorge, Sie müssen sich hier nicht noch selbst drum kümmern, für alle benötigten ISRs wurde das bereits in der RP6Library erledigt. Aber damit Sie wissen worum es geht und was die­se seltsamen „Funktionen“ in der Library sollen, erwähnen wir es hier kurz.
Die ISRs sehen wie folgt aus:
ISR ( <InterruptVector> ) {
<Anweisungsblock>
}
z.B. für den linken Encoder am externen Interrupt Eingang 0:
ISR (INT0_vect) {
// Hier werden bei jeder Signalflanke zwei Zähler erhöht: mleft_dist++; // zurückgelegte Distanz mleft_counter++; // Geschwindigkeitsmessung
}
Man kann diese ISRs nicht direkt aufrufen! Das geschieht immer automatisch und meist kann man nicht vorhersagen wann es genau passiert! Es kann zu jeder Zeit in jedem beliebigen Programmteil passieren (ausser in einem Interrupt selbst oder wenn Interrupts deaktiviert sind). Dann wird die ISR ausgeführt und danach wieder an die Stelle zurückgesprungen an der das Programm unterbrochen wurde. Daher muss man, wenn man Interrupts einsetzt, alle zeitkritischen Dinge auch in den jeweiligen Interrupt Service Routinen erledigen. Pausen die man anhand von Taktzyklen errech­net hat, können sonst zu lang werden wenn sie von einem oder mehreren Interrupt Ereignissen unterbrochen werden.
In der RP6Library werden Interrupts verwendet um die 36kHz Modulation für die In­frarotsensorik und Kommunikation zu erzeugen. Außerdem für die RC5 Dekodierung, Timing und Delay Funktionen, um die Encoder auszuwerten, für das TWI Modul (I²C­Bus) und noch ein paar andere kleinere Dinge.
- 77 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.4.11. C-Präprozessor

Den C Präprozessor wollen wir auch noch kurz ansprechen. Wir haben diesen bereits oben verwendet – nämlich bei #include "RP6RobotBaseLib.h"!
Dieser Befehl wird noch vor dem eigentlichen Übersetzen durch den GCC vom Präpro­zessor ausgewertet. Mit #include "Datei" wird der Inhalt der angegebenen Datei an dieser Stelle eingefügt. Im Falle unseres Beispielprogramms ist das die Datei RP6Ba­seLibrary.h. Diese enthält Definitionen der in der RP6Library enthaltenen Funktionen. Das muss so gemacht werden damit der Compiler diese Funktionen auch findet und richtig zuordnen kann.
Aber das ist natürlich noch nicht alles was man mit dem Präprozessor machen kann. Man kann auch Konstanten (also feste nicht veränderbare Werte) definieren:
#define DAS_IST_EINE_KONSTANTE 123
Das würde die Konstante: „DAS_IST_EINE_KONSTANTE“ mit dem Wert „123“ definieren. Der Präprozessor ersetzt einfach jedes Vorkommen dieser Konstanten durch den Wert (eigentlich ist es Textersatz). Also würde z.B. hier:
writeInteger(DAS_IST_EINE_KONSTANTE,DEC);
das „DAS_IST_EINE_KONSTANTE“ durch „123“ ersetzt und wäre somit identisch zu:
writeInteger(123,DEC);
(übrigens ist auch das „DEC“ von writeInteger nur eine so definierte Konstante – hier mit dem Wert 10 – für das dezimale Zahlensystem.)
Auch einfache If-Bedingungen kennt der Präprozessor:
1
#define DEBUG
2 3
void someFunction(void)
4
{
5
// Mach irgendwas
6
#ifdef DEBUG
7
writeString_P("someFunction wurde ausgeführt!");
8 9
}
#endif
Der Text würde hier nur ausgegeben wenn DEBUG definiert wurde (es muss kein Wert zugewiesen werden – einfach nur definieren). Nützlich um z.B. diverse Ausgaben die man nur für die Fehlersuche braucht nur bei Bedarf zu aktivieren. Wenn DEBUG im obigen Beispiel nicht definiert wäre, würde der Präprozessor den Inhalt von Zeile 7 gar nicht an den Compiler weiterleiten.
In der RP6Library benötigen wir oft auch Makros – diese werden ebenfalls per #define definiert, man kann ihnen aber Parameter übergeben, ähnlich wie bei Funktionen.
z.B. so:
#define setStopwatch1(VALUE) stopwatches.watch1 = (VALUE)
Das lässt sich dann wie eine normale Funktion aufrufen ( setStopwatch1(100); ).
Eine wichtige Sache ist noch, dass man normalerweise hinter Präprozessor Definitio­nen kein Semikolon schreibt!
- 78 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.5. Makefiles

Das Tool „Make“ nimmt uns eine ganze Menge Arbeit ab, denn normalerweise müsste man so einiges in die Kommandozeile eintippen um ein C Programm zu kompilieren.
Make verarbeitet ein sog. „Makefile“, das alle Befehlssequenzen und Informationen enthält, die zum Kompilieren des jeweiligen Projekts notwendig sind. Diese Makefiles werden bei jedem der RP6 Beispielprojekte schon fertig mitgeliefert – man kann na­türlich später auch eigene Makefiles erstellen. Wie so ein Makefile im Detail aufgebaut ist, kann hier nicht beschrieben werden – das wäre zu umfangreich. Sie brauchen sich aber für alle RP6 Projekte ohnehin nur um die folgenden vier Einträge Gedanken zu machen – der Rest ist für Einsteiger erstmal uninteressant:
TARGET = programmName
RP6_LIB_PATH=../../RP6lib
RP6_LIB_PATH_OTHERS=$(RP6_LIB_PATH)/RP6base $(RP6_LIB_PATH)/RP6common
SRC += $(RP6_LIB_PATH)/RP6base/RP6RobotBaseLib.c SRC += $(RP6_LIB_PATH)/RP6common/RP6uart.c SRC += $(RP6_LIB_PATH)/RP6common/RP6I2CslaveTWI.c
In unseren Makefiles sind dazwischen noch einige Kommentarzeilen mit Erläuterungen und Hinweisen zu finden. Kommentare fangen in Makefiles immer mit „#“ an und wer­den von Make nicht weiter beachtet.
Die Beispielprojekte für den RP6 enthalten bereits fertige Makefiles mit den passenden Einträgen. Sie müssen diese also nur dann ändern, wenn Sie z.B. neue C Dateien zum Projekt hinzufügen wollen, oder Dateien umbenennen möchten.
Beim Eintrag „TARGET“ trägt man den Namen der C Datei ein, die die Main-Funktion enthält. Hier gibt man nur den Namen an, OHNE das „.c“ am Ende! Bei vielen anderen Einträgen muss diese Endung aber angegeben werden, also immer auf die gegebenen Beispiele und Hinweise in den Kommentaren achten!
Im Eintrag „RP6_LIB_PATH“ müssen Sie das Verzeichnis mit den Dateien der RP6Li­brary angeben. Das ist i.d.R. „../RP6lib“ oder „../../RP6lib“ also ein relativer Pfad. („../“ bedeutet „eine Verzeichnisebene höher“)
Bei RP6_LIB_PATH_OTHERS muss man alle sonstigen Verzeichnisse angeben die man verwendet hat. Die RP6Library ist in mehrere Verzeichnisse unterteilt, von denen man alle die man verwendet auch angeben muss.
Und schließlich bei „SRC“ müssen Sie alle C-Dateien angeben (keine Header Dateien! Also nicht die Dateien die mit „.h“ enden! Die werden automatisch in allen angegebe­nen Verzeichnissen gesucht!), die Sie neben der Datei mit der Main-Funktion verwen­den wollen. Auch die Dateien aus der RP6Library müssen hier angegeben werden, so­fern diese verwendet werden sollen.
Was bedeutet eigentlich $(RP6_LIB_PATH) ? Ganz einfach: So kann man in Makefiles Variablen verweden! Wir haben ja schon eine „Variable“ RP6_LIB_PATH definiert. Den Inhalt kann man nun mit $(<Variable>) überall nach dieser Deklaration einfügen. Ist praktisch und erspart sehr viel Tipparbeit...
Mehr brauchen Sie an den Makefiles für den RP6 normalerweise nicht zu ändern. Wenn Sie aber mehr wissen möchten, finden Sie hier ein ausführliches Handbuch:
http://www.gnu.org/software/make/manual/
- 79 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.6. RP6 Funktionsbibliothek (RP6Library)

Die RP6 Funktionsbibliothek, auch RP6Library oder kurz RP6Lib genannt, bietet viele nützliche Funktionen um die Hardware des RP6 anzusteuern. Über die meisten hard­warespezifischen Dinge muss man sich damit (eigentlich) keine Gedanken mehr machen. Sie müssen also natürlich nicht das über 300 Seiten starke Datenblatt des ATMEGA32 gelesen haben um den Roboter programmieren zu können! Es ist aber sehr nützlich, wenn man trotzdem grundlegend nachvollzieht, was die RP6Library Funktionen machen. Außerdem sind viele Funktionen in der RP6Library absichtlich nicht ganz perfekt – so bleibt für Sie auch noch etwas zu tun!
Man könnte noch so einige Zusatzfunktionen hinzufügen und vieles optimieren! Die Funktionen der RP6Library verstehen sich als Grundlage, auf der man aber sehr gut aufbauen kann.
In diesem Abschnitt beschreiben wir die wichtigsten Funktionen und geben kleine Beispiele. Wer weitere Informationen dazu benötigt, sollte die Kommentare in den Dateien der Library lesen und sich die Funktionen und Beispiele genau ansehen und nachvollziehen.

4.6.1. Mikrocontroller initialisieren

void initRobotBase(void)
Diese Funktion müssen Sie IMMER als erstes in der Main Funktion aufrufen! Sie initialisiert die Hardwaremodule des Mikrocontrollers. Nur wenn Sie diese Funktion
als erstes aufrufen, wird der Mikrocontroller so arbeiten, wie wir es für den RP6 benö­tigen! Ein Teil wird zwar schon vom Bootloader initialisiert, aber nicht alles.
Beispiel:
1
#include "RP6RobotBaseLib.h"
2 3
int main(void)
4
{
5 6 7
// [...] Programmcode...
8 9 10 11
}
12
initRobotBase(); // Initialisierung – IMMER ALS ERSTES AUFRUFEN!
while(true); // Endlosschleife return 0;
Jedes RP6 Programm muss mindestens so ausschauen! Die Endlosschleife in Zeile 9 ist notwendig, um ein definiertes Ende des Programms zu garantie­ren! Ohne diese Schleife könnte sich das Programm anders verhalten als erwartet!
Nur um das zu verdeutlichen: Normalerweise führt man in der Endlosschleife eigenen Programmcode aus, also würde man hier in Zeile 9 das Semikolon löschen und statt­dessen einen Block (zwei geschweifte Klammern) einfügen in den das eigene Pro­gramm kommt. Vor der Main Funktion (also Zeile 2) kann man eigene Funktionen definieren, die man dann aus der Hauptschleife beliebig oft aufrufen kann.
- 80 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.6.2. UART Funktionen (serielle Schnittstelle)

Wir haben im C-Crashkurs oben schon einige Funktionen aus der RP6Library verwen­det, vor allem die UART Funktionen. Mit diesen Funktionen kann man Textnachrichten über die serielle Schnittstelle des Roboters an den PC (oder andere Mikrocontroller) schicken und auch von diesem emfangen.
4.6.2.1. Senden von Daten über die serielle Schnittstelle
void writeChar(char ch)
Diese Funktion schickt ein einzelnes 8-Bit ASCII Zeichen über die serielle Schnittstelle. Die Anwendung ist sehr einfach:
writeChar('A'); writeChar('B'); writeChar('C');
Gibt „ABC“ aus. Man kann auch direkt ASCII Codes übertragen:
writeChar(65); writeChar(66); writeChar(67);
Das ergibt im Terminal ebenfalls die Ausgabe „ABC“ - jedes ASCII Zeichen ist schließ­lich einer bestimmten Nummer zugeordnet, das 'A' z.B. der 65. Mit einer angepassten Kommunikationssoftware, könnte man aber auch die reinen binären Werte interpretie­ren.
Oft braucht man auch:
writeChar('\n');
um eine neue Zeile im Terminal anzufangen.
void writeString(char *string) und writeString_P(STRING)
Diese Funktionen sind sehr wichtig für die Fehlersuche in Programmen, denn hiermit kann man beliebige Textnachrichten an den PC schicken. Für Datenübertragungen kann man sie natürlich ebenso verwenden.
Der Unterschied zwischen writeString und writeString_P besteht darin, dass bei Ver­wendung von writeString_P die Texte nur im Flash-ROM (Program Memory) abgelegt werden und auch von dort gelesen werden, bei writeString jedoch zusätzlich in den Arbeitsspeicher geladen werden und somit doppelt Speicherplatz verbraucht wird. Und vom Arbeitsspeicher haben wir nunmal nur 2KB zur Verfügung. Wenn es nur um die Ausgabe von festem und nicht veränderlichem Text geht, sollte man deshalb immer writeString_P verwenden. Wenn man dynamische Daten ausgeben will, die ohnehin im RAM vorliegen, muss man natürlich das normale writeString verwenden.
Auch hier ist die Anwendung denkbar einfach:
writeString("ABCDEFG");
Gibt „ABCDEFG“ aus, belegt aber für die Zeichenkette auch Arbeitsspeicher.
writeString_P("ABCDEFG");
Gibt ebenfalls „ABCDEFG“ aus, aber ohne dabei unnötig RAM zu belegen!
- 81 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
void writeStringLength(char *data, uint8_t length, uint8_t offset);
Wenn man Texte mit einstellbarer Länge (length) und Anfangsposition (offset) ausge­ben möchte, kann man diese Funktion verwenden.
Ein Beispiel:
writeStringLength("ABCDEFG", 3, 1);
Ausgabe: „BCD“
writeStringLength("ABCDEFG", 2, 4);
Ausgabe: „EF“ Diese Funktion belegt allerdings auch RAM Speicher und ist eigentlich nur für dynami-
sche Textausgabe gedacht (wird z.B. von writeIntegerLength verwendet...).
void writeInteger(int16_t number, uint8_t base);
Diese sehr nützliche Funktion gibt Zahlenwerte als ASCII Text aus! Wir haben ja oben schon gesehen, dass z.B. writeChar(65) ein 'A' ausgibt und nicht 65...
Daher braucht man so eine Konvertierungsfunktion. Beispiel:
writeInteger(139, DEC);
Ausgabe: „139“
writeInteger(25532, DEC);
Ausgabe: „25532“ Man kann den gesamten 16bit Wertebereich mit Vorzeichen von -32768 bis 32767
ausgeben. Wer größere Zahlen braucht, muss die Funktion anpassen oder besser eine eigene Funktion schreiben!
Was soll das „DEC“ als zweiter Parameter? Ganz einfach: Das bedeutet, das die Aus­gabe als Dezimalzahl (engl. DECimal) erfolgt. Es gibt aber noch andere Zahlensysteme als das Dezimalsystem mit Basis 10. So kann man die Werte auch binär (BIN, Basis
2), oktal (OCT, Basis 8) oder hexadezimal (HEX, Basis 16) ausgeben. Beispiele:
writeInteger(255, DEC);
Ausgabe: „255“
writeInteger(255, HEX);
Ausgabe: „FF“
writeInteger(255, OCT);
Ausgabe: „377“
writeInteger(255, BIN);
Ausgabe: „11111111“ Das kann für viele Anwendungen sehr nützlich sein – vor allem HEX und BIN, denn
hier sieht man sofort ohne Kopfrechnen wie die einzelnen Bits in dem Zahlenwert an­geordnet sind.
- 82 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
void writeIntegerLength(uint16_t number, uint8_t base, uint8_t length);
Eine Variante von writeInteger. Hier kann zusätzlich die Anzahl der Stellen (length) die ausgegeben werden soll, angegeben werden. Ist eine Zahl kürzer als die angege­bene Stellenzahl, werden führende Nullen angefügt. Ist Sie länger, werden nur die letzten Stellen dargestellt.
Beispiele:
writeIntegerLength(2340, DEC, 5);
Ausgabe: „02340“
writeIntegerLength(2340, DEC, 8);
Ausgabe: „00002340“
writeIntegerLength(2340, DEC, 2);
Ausgabe: „40“
writeIntegerLength(254, BIN, 12);
Ausgabe: „000011111110“
4.6.2.2. Empfangen von Daten über die serielle Schnittstelle
Diese Funktionen wurden in Version 1.3 der RP6Library komplett neu geschrieben und daher wurde dieser Abschnitt daran angepasst.
Der Empfang von Daten über die serielle Schnittstelle läuft nun komplett Interrupt ba­siert ab. Die empfangenen Daten werden automatisch im Hintergrund in einem sog. Ringpuffer gespeichert.
Einzelne empfangene Bytes/Zeichen kann man mit der Funktion
char readChar(void)
aus dem Ringpuffer lesen. Ruft man diese Funktion auf, wird das jeweils nächste ver­fügbare Zeichen zurückgegeben und aus dem Ringpuffer gelöscht.
Ist der Ringpuffer leer, gibt die Funktion 0 zurück. Allerdings sollte man vor jedem Aufruf mit der Funktion
uint8_t getBufferLength(void)
überprüfen wieviele neue Zeichen noch im Ringpuffer vorhanden sind. Mehrere Zeichen hintereinander können mit der Funktion
uint8_t readChars(char *buf, uint8_t numberOfChars)
aus dem Puffer abgerufen werden. Als Parameter übergibt man der Funktion einen Zeiger auf ein Array und die Anzahl der Zeichen die in dieses Array kopiert werden sollen. Die Funktion gibt die tatsächliche Anzahl kopierter Zeichen zurück. Das ist nützlich falls nicht soviele Zeichen wie angefordert im Puffer vorhanden waren.
Sollte der Puffer komplett voll sein, werden alte Daten beim Empfang von neuen Zei­chen nicht überschrieben, sondern es wird eine status Variable gesetzt (uart_status) die einen „übergelaufenen“ Puffer signalisiert (engl. „Buffer overflow“, UART_BUFFER_OVERFLOW). Sie sollten Ihre Programme so auslegen, dass es nicht dazu kommt. Meist ist in diesem Fall die Datenrate zu hoch oder das Programm wurde für längere Zeit mit mSleep o.ä. blockiert. Sie können auch die Größe des Ringpuffers
- 83 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
anpassen. Standardmäßig hat der Ringpuffer eine Größe von 32 Zeichen. In der RP6uart.h Datei können Sie dies mit der UART_RECEIVE_BUFFER_SIZE Definition an­passen.
Ein größeres Programm dazu finden Sie bei den Beispielprogrammen! Das Beispiel „Example_02_UART_02“ wurde an die neuen Funktionen angepasst.

4.6.3. Delay Funktionen (Verzögerungen und Zeitsteuerung)

Oft muss man Verzögerungen (Delays) in sein Programm einbauen, oder eine be­stimmte Zeitspanne warten bevor eine bestimmte Aktion ausgeführt wird.
Auch dafür hat die RP6Library Funktionen. Für die Verzögerungen einer der Timer des MEGA32 verwendet, um möglichst unabhängig von der sonstigen Programmausfüh­rung (Interrupts) zu sein und die Verzögerungen einigermaßen genau zu halten.
Aber man muss genau überlegen wann man diese Funktionen verwenden kann! Wenn man die automatische Geschwindigkeitsregelung und das ACS verwendet (wird später noch erläutert) könnte das sonst zu Problemen führen! Dann sollte man nur ganz ganz kurze Pausen mit wenigen Millisekunden (<10ms) einfügen! Das Problem kann aber leicht umgangen werden wenn man die Stopwatches verwendet die direkt im An­schluss beschrieben werden.
void sleep(uint8_t time)
Mit dieser Funktion hält man den normalen Programmablauf für eine gewisse Zeit an. Die Zeitspanne wird dabei in Schritten von 100µs übergeben (100µs = 0.1ms =
0.0001s also für die menschliche Wahrnehmung sehr kurz...). Da wir eine 8 bit Varia­ble benutzten, ist die maximale Zeitspanne 25500µs = 25.5ms. Interrupt Ereignisse werden trotzdem weiter behandelt – es wird nur der normale Programmablauf unter­brochen.
Beispiele:
sleep(1); // 100µs Pause sleep(10); // 1ms Pause sleep(255); // 25.5ms Pause
void mSleep(uint16_t time)
Wenn man längere Pausen benötigt, kann man mSleep verwenden, denn hier wird die Zeitspanne in Millisekunden angegeben. Die maximale Zeitspanne beträgt 65535ms, oder 65.5 Sekunden.
Beispiele:
mSleep(1); // 1ms Pause mSleep(100); // 100ms Pause mSleep(1000); // 1000ms = 1s Pause mSleep(65535); // 65.5 Sekunden Pause
Stopwatches
Das Problem bei diesen normalen Delay Funktionen ist - wie oben schon gesagt - dass sie den normalen Programmablauf komplett unterbrechen. Das ist aber nicht immer erwünscht, denn oft muss nur ein Teil des Programms für eine bestimmte Zeit warten, während andere Dinge weiterlaufen sollen...
Das ist der größte Vorteil daran, Hardwaretimer zu verwenden, denn diese laufen un­abhängig vom restlichen Programmablauf. Die RP6Library implementiert mit den Ti-
- 84 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
mern universell verwendebare „Stopwatches“. Diese Bezeichnung ist nicht allgemein üblich, der Autor fand den Namen aber passend, weil das ganz ähnlich wie reale Stoppuhren funktioniert. Die Stopwatches machen viele Aufgaben einfacher. Norma­lerweise schreibt man solche Timing Funktionen speziell auf das jeweilige Problem zu­geschnitten, die RP6Library bietet das hier etwas universeller und einfacher an, so dass man es für viele verschiedene Dinge gleichermaßen benutzen kann.
Mit den Stopwatches kann man viele Aufgaben quasi simultan erledigen – zumindest wirkt es für den Betrachter von außen so.
Es stehen acht 16bit Stopwatches (Stopwatch1 bis Stopwatch8) zur Verfügung. Diese kann man starten, stoppen, setzen und auslesen. Die Auflösung beträgt eine Millise­kunde, wie bei der mSleep Funktion. Das bedeutet, dass jede Stopwatch ihren Zähl­stand jede Millisekunde um 1 erhöht. Für sehr zeitkritische Dinge ist das aber nicht geeignet, da die Abfragen ob eine Stopwatch einen bestimmten Wert erreicht hat, meist nicht exakt zu diesem Zeitpunkt erfolgen.
Wie man diese Funktionen anwendet, sieht man gut an folgendem kleinen Beispielpro­gramm:
1
#include "RP6RobotBaseLib.h"
2 3
int main(void)
4
{
5 6
writeString_P("\nRP6 Stopwatches Demo Programm\n"); 7 8 9 10 11 12
uint8_t counter = 0;
13
uint8_t runningLight = 1;
14 15
// Hauptschleife:
16 17 18
// Ein kleines LED Lauflicht:
19 20 21 22 23 24 25 26 27 28
// Einen Zählerstand auf dem Terminal ausgeben:
29
if(getStopwatch2() > 1000) // Sind 1000ms (= 1s) vergangen?
30 31 32 33 34 35 36
} 37 38 39
}
initRobotBase(); // Mikrocontroller initialisieren
writeString_P("___________________________\n\n");
startStopwatch1(); // Stopwatch1 starten! startStopwatch2(); // Stopwatch2 starten!
while(true)
{
if(getStopwatch1() > 100) // Sind 100ms (= 0.1s) vergangen?
{
setLEDs(runningLight); // LEDs setzen runningLight <<= 1; // Nächste LED (shift Operation) if(runningLight > 32) // Letzte LED? runningLight = 1; // Ja, also wieder von vorn beginnen! setStopwatch1(0); // Stopwatch1 auf 0 zurücksetzen
}
{
writeString_P("CNT:"); writeInteger(counter, DEC); // Zählerstand ausgeben writeChar('\n'); counter++; // Zähler um 1 erhöhen setStopwatch2(0); // Stopwatch2 auf 0 zurücksetzen
}
return 0;
- 85 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Das Programm ist sehr einfach gehalten. Es wird jede Sekunde ein Zählerstand über die serielle Schnittstelle ausgegeben und inkrementiert (Zeile 29 bis 36) und nebenbei noch ein Lauflicht ausgeführt (Zeile 19 bis 26), das alle 100ms weitergeschaltet wird. Dazu werden Stopwatch1 und Stopwatch2 verwendet. In Zeile 9 und 10 werden die beiden Stopwatches gestartet und fangen danach an zu zählen. In der Endlosschleife (Zeile 16 bis 37) wird dann ständig abgefragt, ob die Stopwatches einen bestimmten Zählstand überschritten haben. In Zeile 19 beispielsweise für das Lauflicht, hier wird abgefragt ob bereits mindestens 100ms vergangen sind, seit die Stopwatch von 0 an zu Zählen begonnen hat. Ist das der Fall, wird die nächste LED angeschaltet und die Stopwatch auf 0 zurückgesetzt (Zeile 25) und es wird erneut 100ms lang gewartet. Genauso wird bei dem Zähler verfahren, nur ist das Intervall hier 1000ms also eine Sekunde.
Das Programm finden Sie etwas ausführlicher auch auf der CD. Es ist nur ein kleines Beispiel, man kann auch viel komplexere Dinge mit den Stopwatches realisieren und diese z.B. auch bedingt starten und stoppen etc...
Beim Beispielprogramm auf der CD sind deshalb das Lauflicht und der Zähler (dort sind es sogar 3 Stück...) auch jeweils in einer eigenen Funktion untergebracht, die aus der Endlosschleife aufgerufen werden. Das macht es bei komplexeren Programmen übersichtlicher und man kann viele Programmteile so später in anderen Programmen einfacher per Copy&Paste wiederverwenden – wie z.B. so ein Lauflicht.
Es stehen mehrere Makros zur Steuerung der Stopwatches zur Verfügung.
startStopwatchX()
Startet eine bestimmte Stopwatch. Die Stopwatch wird nicht zurückgesetzt, sondern läuft einfach vom letzten Zählstand aus weiter.
Beispiele:
startStopwatch1(); startStopwatch2();
stopStopwatchX()
Hält eine bestimmte Stopwatch an. Beispiel:
stopStopwatch2(); stopStopwatch1();
uint8_t isStopwatchXRunning()
Gibt zurück ob die Stopwatch X läuft. Beispiel:
if(!isStopwatch2Running) {
// Stopwatch läuft nicht, also mache irgendwas...
}
- 86 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
setStopwatchX(uint16_t preset)
Dieses Makro setzt Stopwatch X auf den übergebenen Wert. Beispiel:
setStopwatch1(2324); setStopwatch2(0); setStopwatch3(2); setStopwatch4(43456);
getStopwatchX()
Dieses Makro gibt den Wert von Stopwatch X zurück. Beispiel:
if(getStopwatch2() > 1000) { ... } if(getStopwatch6() > 12324) { ... }

4.6.4. Status LEDs und Bumper

void setLEDs(uint8_t leds)
Die 6 Status LEDs können Sie mit dieser Funktion steuern. Am übersichtlichsten ist es, der Funktion einen binären Wert zu übergeben (sieht immer so aus: 0bxxxxxx).
Beispiel:
setLEDs(0b000000); // Dieser Befehl schaltet alle LEDs aus. setLEDs(0b000001); // Und dieser schaltet StatusLED1 an und alle anderen aus. setLEDs(0b000010); // StatusLED2 setLEDs(0b000100); // StatusLED3 setLEDs(0b001010); // StatusLED4 und StatusLED2 setLEDs(0b010111); // StatusLED5, StatusLED3, StatusLED2 und StatusLED1 setLEDs(0b100000); // StatusLED6
Eine alternative Möglichkeit ist folgendes:
statusLEDs.LED5 = true; // LED5 im LED Register aktivieren statusLEDs.LED2 = false; // LED2 im LED Register deaktivieren updateStatusLEDs(); // Änderungen übernehmen!
Hier wird die StatusLED5 angeschaltet und StatusLED2 ausgeschaltet. Die anderen LEDs bleiben aber genau in dem Zustand in dem sie vorher gewesen sind! Das kann nützlich/übersichtlicher sein, wenn verschiedene LEDs aus verschiedenen Funktionen heraus geändert werden sollen o.ä..
Achtung: statusLEDs.LED5 = true; schaltet NICHT direkt LED5 an! Es wird nur ein Bit in einer Variablen gesetzt! Erst updateStatusLEDs(); schaltet LED5 dann wirklich an!
Zwei der Portpins an denen die LEDs angeschlossen sind, werden zusätzlich für die Bumper verwendet. Um die Bumper auszuwerten wird für sehr kurze Zeit der jeweilige Portpin auf Eingangsrichtung umgeschaltet und ausgewertet ob der Schalter geschlos­sen ist. Dazu gibt es zwei vorgefertigte Funktionen.
Diese Funktion
uint8_t getBumperLeft(void)
wertet den linken Bumper aus und diese
uint8_t getBumperRight(void)
den rechten Bumper.
- 87 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Da diese Funktionen sehr schnell ausgeführt werden, werden die LEDs nicht dunkel auch wenn die Funktion den Portpin auf Eingangsrichtung umschaltet. Man sollte aber zwischen den einzelnen Aufrufen ein paar Millisekunden Pause einfügen.
Die Ports sollten nur über die vorgefertigten Funktionen angesteuert werden! Die Ports an denen die Bumper angeschlossen sind, sind zwar durch Widerstände gesichert, aber wenn sie auf Masse geschaltet werden und dann ein Bumper geschlossen wird, fließt schon ein recht hoher Strom durch den Port. Das sollte also vermieden werden.
Beispiel:
if(getBumperLeft() && getBumperRight()) // Beide Bumper...
escape(); // Hier eigene Funktion definieren, z.B. zurücksetzen + drehen
else if(getBumperLeft()) // Links...
escapeLeft(); // hier ebenfalls zurücksetzen und nach rechts drehen.
else if(getBumperRight()) // Rechts...
escapeRight(); // und hier zurücksetzen und nach links drehen.
mSleep(50); // Die Bumper nur 20 mal pro Sekunde (20Hz) auswerten...
Die beiden LEDs 6 und 3 leuchten in jedem Fall wenn die Bumper gedrückt werden. Das ist absichtlich so (geht nicht anders) und keineswegs eine Fehlfunktion. Normaler­weise schalten die Bumper aber nur selten, deshalb stört das nicht weiter.
Sie können an die Ports der anderen vier LEDs auch weitere Bumper/Sensoren mit digitalem Ausgang oder auch Transistoren zum Schalten von Lasten, wie weiteren LEDs oder kleinen Motoren anschließen. Dazu sind allerdings noch keine passenden Funktionen implementiert...
Achtung: Fügen Sie auf jeden Fall mindestens 470 Ohm Widerstän­de zwischen Sensoren/Aktoren und Ports ein, um eine Beschädigung der Ports des Mikrocontrollers durch Überstrom zu vermeiden!
Mit dem RobotLoader kann man übrigens die LEDs während des Bootvorgangs deaktivieren. Das ist nützlich, wenn man die Ports mit irgend etwas anderem belegen will und nicht möchte, dass diese Ports beim Booten an und ausgeschaltet werden. Das erste Byte im internen EEPROM (also Adresse 0) ist für Einstellungen wie diese re­serviert! Sie sollten dieses Byte also nicht in Ihren eigenen Program­men verwenden! (das stört zwar sonst nichts wichtiges, aber man könnte sich wundern warum die LEDs plötzlich nicht mehr leuchten wenn man den RP6 anschaltet...)
Es gibt auf dem RP6 viele Dinge, die ständig ausgewertet und überwacht werden müs­sen damit alles korrekt funktioniert. So z.B. das ACS. Hier müssen oft IR Impulse aus­gesandt und Empfangen werden etc. pp.. Das kann man nicht alles automatisch in Interrupt Routinen erledigen, weil diese immer möglichst schnell ausgeführt werden müssen. Deshalb muss man aus dem Hauptprogramm ständig einige Funktionen aufrufen, die Aufgaben wie diese erledigen. Wenn man das eigene Programm richtig aufbaut, wirkt das aber so, als wenn das alles im Hintergrund laufen würde!
Diese Funktionen werden im Laufe dieses Kapitels alle noch vorgestellt. Um die Funk­tionen für die Bumper zu verstehen, mussten wir das hier aber schon kurz vorweg­nehmen!
Wo man nämlich ohnehin schon so einiges im Hintergrund ausführt, kann man auch
- 88 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
gleich noch kleinere Aufgaben - wie eben die Bumper auslesen - in einem Rutsch mit erledigen. Das geht sehr schnell und man müsste das sonst ohnehin fast immer noch im Hauptprogramm machen.
Damit die Bumper automatisch überwacht werden, muss man diese Funktion:
void task_Bumpers(void)
ständig aus der Hauptschleife aufrufen (s.a. Antriebs Funktionen – hier wird das vor­gehen noch ausführlicher besprochen) – sie prüft die Bumper dann automatisch alle 50ms und schreibt die Werte (gedrückt oder nicht gedrückt) in die Variablen
bumper_left und bumper_right
Diese kann man dann überall sonst im Programm ganz normal in if Bedingungen etc. verwenden und abfragen, oder anderen Variablen zuweisen.
Beispiel:
1
#include "RP6RobotBaseLib.h"
2 3
int main(void)
4
{
5 6 7
setLEDs(0b001001); // LEDs 1 und 4 (beide Grün) anschalten 8 9 10 11
// Hier setzen wir die LEDs je nachdem welcher Bumper 12
// gedrückt ist:
13
statusLEDs.LED6 = bumper_left; // Bumper links gedrückt 14
statusLEDs.LED4 = !bumper_left; // links nicht gedrückt 15
statusLEDs.LED3 = bumper_right; // Bumper rechts gedrückt 16
statusLEDs.LED1 = !bumper_right; // rechts nicht gedrückt 17
// Beide Bumper gedrückt:
18 19 20 21 22
// Bumper Status prüfen:
23 24 25 26
}
initRobotBase(); // Mikrocontroller initialisieren
while(true)
{
statusLEDs.LED2 = (bumper_left && bumper_right); statusLEDs.LED5 = statusLEDs.LED2; updateStatusLEDs(); // LEDs aktualisieren...
task_Bumpers(); // ständig aus der Hauptschleife aufrufen!
}
return 0;
Im Beispielprogramm benutzen wir die Status LEDs um den Zustand der beiden Bum­per anzuzeigen. Ist der linke Bumper gedrückt, wird LED 6 angeschaltet und LED4 ab­geschaltet. Ist er nicht gedrückt, wird umgekehrt LED6 ausgeschaltet und LED4 ange­schaltet. LED6 leuchtet zwar sowieso wenn der linke Bumper gedrückt wird – aber es könnte ja auch irgendetwas anderes mit den LEDs visualisiert werden, das soll nur ein Beispiel sein wie man das generell macht. Beim rechten Bumper wird dasselbe mit LED3 und LED1 gemacht. Sind beide Bumper gedrückt, wird LED2 und LED5 ange­schaltet. Da man nun sowieso schon die automatische Auswertung der Bumper alle 50ms in der Library hatte, war es naheliegend etwas einzubauen, das eine selbstdefinierte Funkti­on automatisch bei Zustandsänderungen der Bumper aufruft. Normalerweise werden die Bumper ja relativ selten getroffen und da ist es sinnvoll im Hauptprogramm nur
- 89 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
dann etwas abzufragen, wenn auch Bedarf dafür besteht. In C kann man auch Zeiger auf Funktionen definieren und diese dann darüber aufru-
fen ohne die Funktion in der Library selbst zu definieren. Normalerweise müsste eine Funktion schon zur Zeit der Übersetzung des Programms bekannt sein und in der RP6­Library eingetragen werden, damit man diese Aufrufen kann.
So kann man eigens definierte Funktionen als sog. „Event Handler“, also für die Ereig­nisbehandlung verwenden. Wird ein Bumper gedrückt, wird innerhalb von etwa 50ms automatisch eine Funktion aufgerufen, die man extra dafür erstellt und zuvor als Event Handler registriert hat. Die Funktion muss dabei eine bestimmte Signatur ha­ben. In diesem Fall muss es eine Funktion sein, die keinen Rückgabewert und keinen Parameter hat (beides void). Die Funktionssignatur muss also so void bumpersStateChanged(void) aussehen. Den Event Handler kann man beispielsweise zu Beginn der Main Funktion registrieren. Zum Registrieren dieses Event Handlers verwendet man folgende Funktion:
void BUMPERS_setStateChangedHandler(void (*bumperHandler)(void))
Die Notation müssen Sie nicht unbedingt genau verstehen – kurz gesagt wird hier ein Zeiger auf eine Funktion übergeben... Hier gleich ein einfaches Beispielprogramm dazu:
1
#include "RP6RobotBaseLib.h"
2 3
// Unsere „Event Handler“ Funktion für die Bumper.
4
// Die Funktion wird automatisch aus der RP6Library aufgerufen:
5
void bumpersStateChanged(void)
6
{
7 8 9 10 11 12 13 14 15 16 17
}
18 19
int main(void)
20
{
21 22 23
// Event Handler registrieren:
24 25 26 27 28 29 30 31
}
writeString_P("\nBumper Status hat sich geaendert:\n");
if(bumper_left)
writeString_P(" - Linker Bumper gedrueckt!\n");
else
writeString_P(" - Linker Bumper nicht gedrueckt.\n");
if(bumper_right)
writeString_P(" - Rechter Bumper gedrueckt!\n");
else
writeString_P(" - Rechter Bumper nicht gedrueckt.\n");
initRobotBase();
BUMPERS_setStateChangedHandler(bumpersStateChanged);
while(true)
{
task_Bumpers(); // Bumper automatisch alle 50ms auswerten
}
return 0;
Das Programm gibt bei jeder Änderung des Bumperzustands einmal den aktuellen Status beider Bumper aus.
- 90 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Drückt man z.B. den rechten Bumper wäre die Ausgabe:
Bumper Status hat sich geaendert:
- Linker Bumper nicht gedrueckt.
- Rechter Bumper gedrueckt!
Drückt man beide:
Bumper Status hat sich geaendert:
- Linker Bumper gedrueckt!
- Rechter Bumper gedrueckt!
Da man beide Bumper nicht wirklich gleichzeitig drücken kann, könnte evtl. noch eine zusätzliche Nachricht ausgegeben werden wo nur einer der beiden gedrückt gewesen ist.
Wohlgemerkt wird in dem obigen Programmcode, nirgendwo die Funktion
bumpersStateChanged direkt aufgerufen! Das passiert automatisch aus der RP6Library
heraus, nämlich aus der Funktion task_Bumpers bei jeder Änderung des Bumperzu­stands. Da task_Bumpers unsere Funktion eigentlich erstmal gar nicht kennt, geht das nur über einen Zeiger auf die entsprechende Funktion, der seinen Wert erst bei Aus­führung des Aufrufs in Zeile 24 erhält.
Der Event Handler kann natürlich noch andere Aktionen auslösen, als nur Text auszu­geben – z.B. könnte man den Roboter anhalten und zurücksetzen lassen. Das sollte man allerdings nicht direkt im Event Handler selbst tun, sondern in anderen Pro­grammteilen – z.B. im Event Handler einfach irgendeine Kommando-Variable setzen die man im Hauptprogramm abfragt und dann dementsprechend die Motoren steuert! Alle Event Handler sollten immer so kurz wie möglich gehalten werden!
Sie können in den Event Handlern zwar alle Funktionen aus der RP6Library verwen­den, seien Sie aber vorsichtig mit den „rotate“ und „move“ Funktionen die wir später noch besprechen werden! Benutzen Sie hier NICHT den blockierenden Modus (wenn man dann nämlich z.B. öfters auf die Bumper drückt, funktioniert das nicht ganz so wie man es eigentlich haben wollte ;-) )!
Dieses Prinzip mit den Event Handlern wird auch noch für andere Funktionen verwen­det, z.B. für das ACS – da ist es sogar sehr ähnlich zu den Bumpern, denn auch dort wird bei jeder Zustandsänderung der Objektsensoren ein Event Handler aufgerufen.
Auch für den Empfang von RC5 Codes über eine Fernbedienung werden Event Handler verwendet – jedesmal wenn ein neuer RC5 Code empfangen wurde, kann ein entspre­chender Event Handler aufgerufen werden.
Man muss für all diese Dinge übrigens keine Event Handler verwenden – man kann das alles auch durch einfache if Bedingungen o.ä. abfragen und dementsprechend darauf reagieren, aber mit Event Handlern werden einige Dinge einfacher und beque­mer. Ist aber eher Geschmackssache was man verwendet.
Auf der CD finden Sie übrigens noch einige ausführlichere Beispielprogramme zu die­sem Thema!
- 91 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.6.5. ADC auslesen (Batterie-, Motorstrom- und Lichtsensoren)

Am ADC (Analog to Digital Convertor) sind - wie in Abschnitt 2 schon beschrieben wurde - viele Sensoren des RP6 angeschlossen. Natürlich bietet die RP6Library auch hier eine Funktion, um diese auszulesen:
uint16_t readADC(uint8_t channel)
Die Funktion gibt einen 10 Bit Wert (0...1023) zurück, also benötigt man 16 Bit Varia­blen für die Sensorwerte.
Es stehen folgende Kanäle zur Verfügung:
ADC_BAT --> Batteriespannungs Sensor ADC_MCURRENT_R --> Motorstromsensor des rechten Motors ADC_MCURRENT_L --> Motorstromsensor des linken Motors ADC_LS_L --> Linker Lichtsensor ADC_LS_R --> Rechter Lichtsensor ADC_ADC0 --> Freier ADC Kanal für eigene Sensoren ADC_ADC1 --> Freier ADC Kanal für eigene Sensoren
Hinweis: Die Anschlüsse für die zwei freien ADC Kanäle sind nicht bestückt. Hier kann man eigene Stecker im 2.54mm Rastermaß an­löten und evtl. noch zwei kleine 100nF Kondensatoren und einen großen 470µF Elko hinzufügen falls man Sensoren anschließen möchte die hohe Spitzenströme benötigen wie z.B. IR Abstandssen­soren von Sharp ... Sie sollten dazu allerdings schon ein wenig Löterfahrung haben! Sonst lieber ein Erweiterungsmodul verwenden!
Beispiele:
uint16_t ubat = readADC(ADC_BAT); uint16_t iMotorR = readADC(ADC_MCURRENT_R); uint16_t iMotorL = readADC(ADC_MCURRENT_L); uint16_t lsL = readADC(ADC_LS_L); uint16_t lsR = readADC(ADC_LS_R); uint16_t adc0 = readADC(ADC_ADC0); uint16_t adc1 = readADC(ADC_ADC1);
if(ubat < 580) writeString_P("Warnung! Batterie fast leer!");
Standardmäßig wird die 5V Versorgungsspannung als Referenz verwendet. Man kann aber die Funktion auch so umschreiben, dass die interne 2.56V Referenz des ATMEGA32 verwendet wird (dazu im Datenblatt vom MEGA32 nachlesen). Für die nor­malen Sensoren des RP6 wird das allerdings normalerweise nicht benötigt.
Es ist sinnvoll mehrere ADC Werte zu messen (z.B. in einem Array speichern) und dann zunächst einmal den Mittelwert davon zu bilden oder Minimum/Maximum zu be­stimmen bevor man die Messwerte des ADCs auswertet. Ab und zu fängt man sich nämlich durch Störungen Messfehler ein. Im Falle der Akkuspannung ist es z.B. für einen automatischen Stromsparmodus absolut notwendig, ein paar Werte zu mitteln denn die Spannung kann sehr stark schwanken - vor allem wenn die Motoren laufen und wechselnd belastet werden.
Wie bei den Bumpern kann man die ADC Messungen automatisieren. Es gibt auch hier schon eine kleine Funktion, die uns das Leben etwas erleichtern kann.
- 92 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
void task_ADC(void)
In diesem Fall verkürzt sie die Zeit die zum Auslesen aller Analog/Digital Wandler Kanäle im Programm benötigt wird. Ruft man diese Funktion ständig auf, werden au­tomatisch alle ADC Kanäle der Reihe nach „im Hintergrund“ (also immer wenn gerade Zeit dazu ist) ausgelesen und die Messwerte in Variablen gespeichert.
Der ADC benötigt für jede Messung etwas Zeit und mit der readADC Funktion wäre der normale Programmablauf dann für diese Zeit unterbrochen. Da die Messung aber auch ohne unser zutun läuft (der ADC ist schließlich ein Hardwaremodul im Mikrocon­troller) können wir in dieser Zeit auch andere Dinge erledigen.
Es gibt für die einzelnen Kanäle folgende 16Bit Variablen, die man immer und überall im Programm verwenden kann:
ADC_BAT: adcBat ADC_MCURRENT_L: adcMotorCurrentLeft ADC_MCURRENT_R: adcMotorCurrentRight ADC_LS_L: adcLSL ADC_LS_R: adcLSR ADC_ADC0: adc0 ADC_ADC1: adc1
Sobald Sie die task_ADC() Funktion verwenden, sollten Sie nur noch diese Variablen benutzen und NICHT die readADC Funktion!
Beispiel:
1
#include "RP6RobotBaseLib.h"
2 3
int main(void)
4
{ 5 6 7 8 9 10 11 12
writeString_P("\nADC Lichtsensor Links: "); 13 14
writeString_P("\nADC Lichtsensor Rechts: "); 15 16 17 18 19 20 21 22 23 24 25 26
}
initRobotBase(); startStopwatch1(); writeString_P("\n\nKleines ADC Messprogramm...\n\n");
while(true)
{
if(getStopwatch1() > 300) // Alle 300ms...
{
writeInteger(adcLSL, DEC);
writeInteger(adcLSL, DEC); writeString_P("\nADC Akku: "); writeInteger(adcBat, DEC); writeChar('\n');
if(adcBat < 600)
writeString_P("Warnung! Akku ist bald leer!\n");
setStopwatch1(0); // Stopwatch1 auf 0 zurücksetzen
}
task_ADC(); // ADC Auswertung – ständig aus der Hauptschleife } // aufrufen! Dann sollte man aber readADC nicht
return 0; // mehr verwenden!
Hier werden alle 300ms die Messwerte der beiden Lichtsensoren und vom Akku ausge­geben. Unterschreitet die Akkuspannung etwa 6V, wird eine Warnung ausgegeben.
- 93 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.6.6. ACS – Anti Collision System

Das Anti Collision System wird nicht mehr wie beim RP5, von einem kleineren Co-Pro­zessor gesteuert, sondern direkt vom MEGA32. Das erfordert nun zwar etwas mehr Programmieraufwand auf dem Hauptcontroller, hat aber auch den Vorteil, dass man es beliebig verändern und verbessern kann. Beim RP5 war das Programm im Co-Pro­zessor nicht veränderbar...
Die Reichweite bzw. die Sendeleistung der beiden IR LEDs des ACS, kann man mit fol­genden Funktionen einstellen:
void setACSPwrOff(void) --> ACS IR LEDs aus
void setACSPwrLow(void) --> Geringe Reichweite
void setACSPwrMed(void) --> Mittlere Reichweite
void setACSPwrHigh(void) --> Maximale Reichweite
Wenn man das ACS auswerten möchte, muss man ständig aus der Hauptschleife her­aus die Funktion:
void task_ACS(void)
aufrufen, die das ACS komplett steuert. Der Rest sieht dann ganz ähnlich wie bei den Bumpern aus.
Es gibt zwei Variablen:
obstacle_left und obstacle_right
welche jeweils den Wert true haben, sobald ein Hindernis detektiert wurde. Sind beide true, befindet sich das Hindernis mittig vor dem Roboter.
Wenn man möchte, kann man auch hier einen Event Handler erstellen, muss man aber nicht – also genau wie bei den Bumpern.
void ACS_setStateChangedHandler(void (*acsHandler)(void))
Mit dieser Funktion registriert man den Event Handler, der folgende Signatur haben muss: void acsStateChanged(void)
Wie die Funktion genau heisst, ist dabei übrigens fast egal.
Das folgende Beispielprogramm zeigt die Anwendung. Zuerst wird der Event Handler registriert (Zeile 44), dann die Stromversorgung zum IR Empfänger eingeschaltet (Zeile 46 – ohne das funktioniert es nicht!) und die Sendestärke der ACS IR LEDs ein­gestellt (Zeile 47). Unten in der Hauptschleife wird dann die Funktion task_ACS() ständig aufgerufen.
Der Rest erfolgt automatisch – die acsStateChanged Funktion wird immer aufgerufen, wenn sich der Zustand des ACS verändert hat – also wenn z.B. ein Objekt von den Sensoren entdeckt wird und wieder verschwindet. Das Programm stellt den aktuellen Zustand des ACS als Text im Terminal und mit den LEDs dar.
- 94 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
1
#include "RP6RobotBaseLib.h"
2 3
void acsStateChanged(void)
4
{
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
writeString_P(" MITTE!"); 21 22 23
statusLEDs.LED6 = obstacle_left && obstacle_right; // Mitte? 24
statusLEDs.LED3 = statusLEDs.LED6; 25 26 27 28 29 30
}
31 32
int main(void)
33
{
34 35 36
writeString_P("\nRP6 ACS - Testprogramm\n"); 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
}
writeString_P("ACS status hat sich geändert! L: ");
if(obstacle_left) // Hindernis links
writeChar('o');
else
writeChar(' ');
writeString_P(" | R: ");
if(obstacle_right) // Hindernis rechts
writeChar('o');
else
writeChar(' ');
if(obstacle_left && obstacle_right) // Mitte?
writeChar('\n');
statusLEDs.LED5 = obstacle_left; // Hindernis links statusLEDs.LED4 = (!obstacle_left); // LED5 invertiert! statusLEDs.LED2 = obstacle_right; // Hindernis rechts statusLEDs.LED1 = (!obstacle_right); // LED2 invertiert! updateStatusLEDs();
initRobotBase();
writeString_P("_____________________\n\n");
setLEDs(0b111111); mSleep(1000); setLEDs(0b001001);
// ACS Event Handler registrieren:
ACS_setStateChangedHandler(acsStateChanged);
powerON(); // ACS Empfänger einschalten (und Encoder etc.) setACSPwrMed(); // ACS auf mittlere Sendeleistung stellen.
while(true)
{
task_ACS(); // ständig die task_ACS Funktion aufrufen!
}
return 0;
In diesem Beispiel sieht man auch nochmal sehr schön wie man die LEDs einzeln set­zen kann.
Wenn man das Programm ausführt, sollte man den RP6 natürlich am Rechner ange-
- 95 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
schlossen lassen und sich die Ausgaben auf dem Bildschirm ansehen. Bewegen Sie einfach mal die Hand oder einen Gegenstand direkt vor dem Roboter hin und her!
Das ACS kann durch Störquellen in seiner Funktion beeinträchtigt werden! Bestimmte Leuchtstoffröhren und ähnliches können den Ro­boter quasi „blind“ machen oder zumindest die Empfindlichkeit ver­ringern. Wenn Sie also Probleme damit haben, schalten Sie erstmal alle evtl. störenden Lichtquellen aus. (Tipp: Wenn Sie den Roboter direkt vor einem Flachbildschirm oder Flachbildfernseher platziert haben, kann es auch daran liegen. Meist wird dort schließlich auch eine Leuchtstoffröhre für die Hintergrundbeleuchtung verwendet... ) Die Reichweite hängt außerdem stark von den Gegenständen selbst ab, denn eine schwarze Oberfläche reflektiert das IR Licht natürlich weniger gut als eine helle weisse Oberfläche. Sehr dunkle Objekte werden vom ACS nicht immer erkannt!
So gesehen, sollte man das ACS noch mit Ultraschallsensoren oder besseren IR Sensoren unterstützen.
Was Sie unbedingt noch tun sollten, bevor Sie den Roboter herumfahren lassen: Ein­fach mal diverse Gegenstände mit dem ACS testen und schauen welche NICHT son­derlich gut erkannt werden. Dann könnte man solche Objekte evtl. woanders hinstel­len während man den Roboter herumfahren lässt... ist allerdings nicht mehr ganz so wichtig wie beim Vorgänger, denn notfalls gibt es jetzt noch die Stoßstange die wei­testgehend verhindert, dass die IR LEDs verbiegen!

4.6.7. IRCOMM und RC5 Funktionen

Mit dem IR Empfänger kann der RP6 auch IR Signale von normalen TV/Hifi Fernbedienun­gen empfangen. Das klappt allerdings nur, wenn die Fernbedienung im RC5 Code sendet! Die meisten Universalfernbedienungen (s. Abb.) können auf dieses Format eingestellt werden – wie das geht steht im Handbuch der jeweiligen Universalfernbedienung. Wenn in der Codetabelle nicht explizit der RC5 Code aufgeführt wird, kann man einfach einige ver­schiedene Gerätehersteller durchprobieren.
Wenn die Fernbedienung im RC5 Format sendet, wird dieses Signal von der ACS Hin­derniserkennung ignoriert und das ACS nur sehr wenig bis gar nicht gestört. Es kann trotzdem noch Hindernisse detektieren, möglicherweise aber etwas später da so nur die Pausen zwischen den RC5 Übertragungen genutzt werden können. Sollte die Fern­bedienug allerdings nicht im RC5 Format senden, wird natürlich der gesendete Code nicht erkannt und das ACS könnte dadurch gestört werden.
Mit einer passenden Software im Mikrocontroller, kann man den RP6 dann mit einer Fernbedienung steuern und ihm Befehle senden!
Über das IRCOMM System kann man auch IR Signale senden. Die beiden Sendedioden vorne am Roboter sind nach oben zur Decke gerichtet. Über die Reflektion an der
- 96 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Zimmerdecke und anderen Gegenständen oder bei direkter Sichtverbindung nach vorn, kann man so mit anderen Robotern oder z.B. einer Basisstation kommunizieren. Das geht zwar nur relativ langsam (ein Datenpaket braucht ca. 20ms und danach eine kleine Pause), aber einfache Kommandos und einzelne Messwerte lassen sich schon damit übertragen. Die Reichweite ist natürlich etwas eingeschränkt und es funktioniert nur im selben Raum wenn die Roboter maximal etwa 2 bis 4 Meter voneinander ent­fernt sind (je nach Lichtverhältnissen, Hindernissen, Beschaffenheit der Zimmerdecke und den Aufbauten/Erweiterungen auf den Robotern). Die Reichweite lässt sich aber steigern, wenn man z.B. noch ein paar weitere IR LEDs hinzuschaltet (z.B. mit einem weiteren MOSFET, einem großen Kondensator und kleinem Vorwiderstand).
Aufgrund der notwendigen Synchronisation mit dem ACS ist auch für diese Aufgaben die task_ACS() Funktion zuständig. Diese muss also auch deshalb ständig in der Hauptschleife aufgerufen werden, damit auf empfangene IR Daten reagiert werden kann - und außerdem um die Übertragungen mit dem IRCOMM auszuführen!
RC5 Datenpakete enthalten immer eine Geräteadresse, den „Keycode“ und ein „Togg­lebit“. Die 5 Bit Geräteadresse gibt an, welches Gerät angesteuert werden soll. Bei normaler Verwendung kann man so die Fernbedienungen für TV, Videorecorder, HiFi Anlage etc. unterscheiden. Bei unserer Anwendung kann man anstattdessen z.B. ver­schiedene Roboter adressieren. Der 6 Bit Keycode ist bei normalen Fernbedienungen der Tastencode, aber wir können damit natürlich auch Daten übertragen. Zwar nur 6 Bit, aber 8 Bit Daten könnte man auf zwei Übertragungen aufteilen, oder noch 2 der 5 Bit Geräteadresse oder das Togglebit zweckentfremden.
Das Togglebit wird normalerweise dazu verwendet, um zu unterscheiden ob eine Taste auf der Fernbedienug dauerhaft gedrückt wird oder mehrmals hintereinander. Das Togglebit kann bei Datenübertragungen von Roboter zu Roboter aber beliebig verwen­det werden.
RC5 Daten kann man mit dieser Funktion senden:
void IRCOMM_sendRC5(uint8_t adr, uint8_t data)
Wobei adr die Geräteadresse und data Keycode bzw. Daten sind. In adr kann man zusätzlich das Toggle Bit setzen, indem man das höchstwertige Bit dieses Bytes setzt. Dazu kann man die Konstante TOGGLEBIT wie folgt verwenden:
IRCOMM_sendRC5(12 | TOGGLEBIT, 40);
Dieser Befehl sendet ein RC5 Datenpaket an Adresse 12, bei gesetztem Togglebit und mit 40 als Daten.
IRCOMM_sendRC5(12, 40);
So sieht es dann aus, wenn man das Togglebit NICHT setzen will. Der Empfang von RC5 Daten funktioniert über einen Event Handler, ähnlich wie bei
den Bumpern und beim ACS. Der Event Handler wird automatisch aus der task_ACS() Funktion aufgerufen sobald neue RC5 Daten vorliegen. Beispielweise könnte man dann, wenn Tastencode 4 empfangen wurde, nach links drehen und bei Code 6 nach
rechts o.ä....
In einem der Beispielprogramme wird genau das gemacht: man kann die Bewegung des Roboters komplett über eine IR Fernbedienung steuern.
- 97 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
Der Event Handler muss folgende Signatur haben:
void receiveRC5Data(RC5data_t rc5data)
Wie die Funktion heisst, ist natürlich auch hier fast egal!
void IRCOMM_setRC5DataReadyHandler(void (*rc5Handler)(RC5data_t))
Mit dieser Funktion kann man den zuvor definierten Event Handler registrieren. z.B. so:
IRCOMM_setRC5DataReadyHandler(receiveRC5Data);
Danach wird immer diese Funktion aufgerufen sobald ein gültiger RC5 Code empfan­gen worden ist.
RC5data_t ist ein eigens definierter Datentyp, der RC5 Adressbits (Device Address), Togglebit und Keycode (bzw. die Daten) enthält. Diese sind dann ähnlich wie normale
Variablen verwendbar und haben folgende Bezeichnungen:
rc5data.device, rc5data.toggle_bit, rc5data.key_code
Auf der CD finden Sie ein größeres Beispielprogramm dazu.
Achtung: schalten Sie niemals den Pin des IRCOMM dauerhaft an! Die IR LEDs und die Steuerschaltung sind für Impulsbetrieb ausge­legt und dürfen nur eine Millisekunde am Stück eingeschaltet blei­ben! Die Stromaufnahme ist sonst bei voll aufgeladenen Akkus zu hoch. Ändern Sie die IRCOMM Funktionen nicht selbst ab, wenn Sie nicht genau wissen was Sie tun. Vor allem die Interrupt Routine die zur Ansteuerung verwendet wird, sollte nicht verändert werden!

4.6.8. Stromsparfunktionen

Weiter oben haben wir powerON() verwendet, ohne näher darauf einzugehen. Man kann beim RP6 das ACS, die Encoder, die Motorstromsensoren und die Power ON LED abschalten um Energie zu sparen (sind immerhin etwa 10mA wenn man diese Sensoren gerade nicht braucht).
Dazu gibt es die Makros:
powerON()
um die genannten Dinge einzuschalten und
powerOFF()
um das alles abzuschalten. Diese beiden Makros tun nichts weiter, als einen I/O Pin auf high oder low zu schalten.
Bevor man ACS, IRCOMM und Motorregelung verwenden kann, muss man in jedem Fall das Makro powerON() aufrufen! Sonst haben die entsprechenden Sensoren keine Energie. Die Motorregelung kann z.B. nur korrekt arbeiten, wenn ein Signal von den Drehgebern und Stromsensoren kommt. Wenn Sie mal vergessen powerON() aufzurufen, werden die Motoren nach einem kurzen Startversuch sofort wieder abgeschaltet und die vier roten Status LEDs fangen an zu blinken.
- 98 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6

4.6.9. Antriebs Funktionen

Der Antrieb des Roboters kann mit Funktionen der RP6Library sehr komfortabel gesteuert werden. Es gibt dort bereits Funktionen, die mithilfe der Drehgeber automa­tisch die Geschwindigkeit der Motoren einregeln, den Motorstrom überwachen, automatisch bestimmte Distanzen abfahren und noch einiges mehr. Das ist sehr komfortabel, aber man muss – wie bei den anderen Systemen auch - ein paar Besonderheiten beachten wenn man das benutzen will.
Und die aktuelle Fassung ist sicherlich noch nicht optimal. Da kann noch viel verbes­sert und hinzugefügt werden!
void task_motionControl(void)
Die Funktion task_motionControl muss man ständig aus dem Hauptprogramm aufru­fen – sonst funktioniert diese automatische Regelung nicht! Ständig aus dem Haupt­programm aufrufen heisst hier nichts anderes, als dass man diese Funktion in der Hauptschleife des Programms bei jedem Schleifendurchlauf einmal aufrufen muss. Es reicht, wenn die Funktion alle 10 bis 50 Millisekunden einmal aufgerufen wird. Besser ist es allerdings, die Funktion noch sehr viel öfter aufzurufen. Es schadet nicht, wenn man die Funktion noch schneller aufruft, denn das Timing wird von einem der Hard­waretimer gesteuert. Daher ist es auch egal ob man die Funktion in gleichbleibenden Intervallen aufruft, oder ob man mal 1ms und mal 10ms zwischen den einzelnen Auf­rufen benötigt. Es kostet auch nur unwesentlich mehr Rechenzeit, die Funktion oft aufzurufen. Sie wird nur komplett ausgeführt, wenn auch etwas zu tun ist.
Wird diese Funktion korrekt angewandt, kümmert sie sich darum die Motoren immer relativ genau mit den gewünschten Drehzahlen laufen zu lassen.
Das wird hier erreicht, indem bei jeder Geschwindigkeitsmessung die Abweichung ermittelt und alle gemessenen Abweichungen aufsummiert werden (also ein integrie­render Regler). Mit diesem Fehlerwert kann dann die Spannung an den Motoren über die PWM Module des Mikrocontrollers angepasst werden. Ist die Geschwindigkeit zu niedrig, sind die Fehlerwerte positiv und die Spannung an den Motoren wird dement­sprechend erhöht. Ist die Geschwindigkeit zu hoch, wird die Spannung verringert. Das pendelt sich beim RP6 dann schnell auf einen relativ konstanten PWM Wert ein (kleine Schwankungen sind normal). Durch diese Regelung wird die Geschwindigkeit unab­hängig von der Akkuspannung, der Belastung (Gewicht, Untergrund, Steigung/Abhang etc.) und Fertigungstoleranzen eingeregelt. Würde man die PWM Kanäle nur auf einen festen Wert einstellen, würde sich die Geschwindigkeit abhängig von der Belastung und Akkusspannung sehr stark verändern und wäre auch für jeden Kanal unterschied­lich aufgrund der immer vorhandenen Fertigungstoleranzen.
Auch die Drehrichtung der Motoren wird von dieser Funktion gesteuert, denn es wäre der Lebensdauer der Motoren und der Getriebe nicht gerade zuträglich, wenn man öf­ters z.B. bei 15cm/s die Drehrichtung abrupt ändert. Wenn die Drehrichtung also ge­ändert werden soll, wird automatisch auf 0cm/s abgebremst, die Drehrichtung geän­dert und erst dann wieder auf die Sollgeschwindigkeit beschleunigt.
Neben der Geschwindigkeitsregelung und Drehrichtungskontrolle, wird auch der Mo­torstrom überwacht und die Motoren automatisch abgeschaltet wenn einer von beiden zuviel Strom benötigen sollte. Das verhindert, dass die Motoren überlastet werden und
- 99 -
RP6 ROBOT SYSTEM - 4. Programmierung des RP6
heißlaufen, was auf Dauer zu Beschädigungen führen würde. Nach drei Überstromer­eignissen innerhalb von 20 Sekunden wird der Roboter komplett gestoppt und die vier roten Status LEDs fangen an zu blinken.
Ebenfalls wird überwacht ob einer der Encoder oder Motoren ausgefallen ist (kann schonmal passieren, wenn man zuviel dran rumbastelt...). Denn falls das der Fall ist, würde die motionControl Funktion den PWM Wert bis aufs Maximum erhöhen und so evtl. den Roboter ausser Kontrolle geraten lassen... und das wäre natürlich weniger schön! Auch in diesem Fall wird der Roboter komplett gestoppt.
Um es übersichtlich zu halten, wurden auch die Routinen für das Abfahren von Weg­strecken und das Drehen um bestimmte Winkel mit in diese Funktion aufgenommen.
Sie sehen also, dass diese Funktion extrem wichtig für den automatischen Betrieb des Antriebssystems ist. Der motionControl Funktion selbst, werden übrigens keine Para­meter wie z.B. die Sollgeschwindigkeit übergeben. Das passiert über andere Funktio­nen, die wir nun im einzelnen erläutern werden.
void moveAtSpeed(uint8_t desired_speed_left, uint8_t desired_speed_right)
Mit dieser Funktion wird die Sollgeschwindigkeit eingestellt. Die beiden Parameter geben die Geschwindigkeit für den linken und für den rechten Motor an. Sofern man wie oben beschrieben die motionControl Funktion ständig aufruft, wird die Geschwin­digkeit auf diesen Wert eingeregelt. Setzt man den Wert auf 0, werden die PWM Mo­dule komplett deaktiviert nachdem der Roboter abgebremst hat.
getDesSpeedLeft() und getDesSpeedRight()
Mit diesen Makros kann man die derzeit eingestellte Sollgeschwindigkeit auslesen. Die Anwendung der moveAtSpeed Funktion ist recht einfach – ein Beispiel:
1
#include "RP6RobotBaseLib.h"
2 3
int main(void)
4
{
5 6 7 8 9 10 11 12 13
// Aus der Hauptschleife ständig die motionControl Funktion
14
// aufrufen – sie regelt die Motorgeschwindigkeiten:
15 16
task_ADC(); // Wird wegen den Motorstromsensoren aufgerufen! 17 18
}
initRobotBase(); // Mikrocontroller initialisieren
powerON(); // Encoder und Motorstromsensoren anschalten (WICHTIG!!!)
moveAtSpeed(70,70); // Geschwindigkeit einstellen
while(true)
{
task_motionControl();
}
return 0;
... und schon fährt der RP6 los! Aber er reagiert natürlich überhaupt nicht auf Hinder­nisse und fährt einfach nur geradeaus! Einzig die Geschwindigkeit wird möglichst kon­stant gehalten.
- 100 -
Loading...