Bevor Sie den RP6, RP6v2 oder Zubehör in Betrieb nehmen, lesen Sie
bitte diese Anleitung und ggf. die Anleitungen von Zubehörteilen vollständig durch! Sie erläutert Ihnen die korrekte Verwendung und weist
auf mögliche Gefahren hin! Weiterhin enthält sie wichtige Informationen, die für viele Anwender keineswegs offensichtlich sein dürften.
Bei Nichtbeachtung dieser Anleitung erlischt jeglicher Garantieanspruch! Weiterhin übernimmt AREXX Engineering keinerlei Haftung für
Schäden jeglicher Art, die aus Nichtbeachtung dieser Anleitung resultieren!
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“ gelesen und die Software korrekt installiert haben!
"RP6 Robot System" ist eingetragenes Warenzeichen von AREXX Engineering.
Alle anderen Warenzeichen stehen im Besitz
ihrer jeweiligen Eigentümer.
Diese Bedienungsanleitung ist urheberrechtlich geschützt. Der Inhalt darf ohne vorherige schriftliche Zustimmung des Herausgebers auch nicht teilweise kopiert oder übernommen werden!
Änderungen an Produktspezifikationen und
Lieferumfang vorbehalten.
Der Inhalt dieser Bedienungsanleitung kann
jederzeit ohne vorherige Ankündigung geändert 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 Anleitung 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 Produktionsfehlern, wie mechanischer Beschädigung und fehlender oder falscher Bestückung elektronischer Bauteile, ausgenommen aller über Steckverbinder/Sockel angeschlossenen Komponenten. 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 unabdingbaren 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 Nichtbeachtung 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 geladen. Daher trägt der Anwender das gesamte Risiko bezüglich der Qualität und der Leistungsfähigkeit des Gerätes inklusive aller Software.
AREXX Engineering garantiert die Funktionalität der mitgelieferten Applikationsbeispiele unter Einhaltung der in den technischen Daten spezifizierten Bedingungen. Sollte sich der Roboter 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 Abschnitte 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ützliche Tipps und Tricks oder Hintergrundinformationen enthalten. Hier ist es nicht immer essentiell alles zu verstehen, aber
meist sehr nützlich.
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 Einstieg 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 Software konzentrieren möchten. Allerdings bedeutet dies nicht, dass man keine eigenen
Schaltungen und Erweiterungen auf dem Roboter aufbauen könnte! Ganz im Gegenteil: Der RP6 ist auf Erweiterung ausgelegt und kann als Ausgangspunkt für viele interessante 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 programmierbar 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 erweitert 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 Erweiterungsmodul 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 Montage von mechanischen Erweiterungen hinzugefügt.
Der RP6 ist vom Prozessor her kompatibel mit den Robotern ASURO und YETI, die beide 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 Anwender 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 Erweiterung, ein Erweiterungsmodul mit einem weiteren MEGA32 und natürlich das Lochraster Experimentierboard für eigene Schaltungen. Bald gibt es auch ein Wireless LAN Erweiterungsmodul.
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. Aktuellere 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 Community, 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 Justage 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 zugängliche und deutlich größere
Potentiometer). Die Musteraufkleber sind nun aus einem robusteren Material gefertigt und
haben einen höheren Kontrast,
was die Signalqualität zusätzlich verbessert und größere Toleranzen bei der Justage zulä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 einsetzen (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 Erweiterungen einsetzen lassen (s. Anhang). Vier davon waren zwar schon beim RP6 vorgesehen, 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 Stromversorgungsanschlüsse hinzugekommen sind und die Stromversorgung etwas optimiert wurde. Dies erlaubt es, größere Verbraucher als bislang zu verwenden. Ebenfalls verbessert 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 Produktionskosten 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ätzlicher Rechenleistung und zahlreichen Schnittstellen für Sensorik und Kommunikation
auszustatten. Das RP6-M32 Modul ist die günstigste Erweiterung und bietet einen weiteren 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 Debugging ü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 überwacht, 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önnen 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 (Experimentier 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 Experimentierplatinen 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 Sensorschaltungen aufbauen bzw. fertige Sensoren montieren (z.B. Ultraschall oder Infrarot Distanzsensoren, Temperatur, Kompass etc.). Der stärkste Prozessor übernimmt die Regie 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 Vergangenheit 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 Komponenten 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:
◊ Geschwindigkeit 8 MIPS (=8 Millionen Instruktionen pro Sekunde) bei 8MHz Takt
◊ Speicher: 32KB Flash ROM, 2KB SRAM, 1KB EEPROM
◊ Frei 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 basierend
◊ Bis zu 127 Slaves können gleichzeitig am Bus angeschlossen werden
◊ Weit verbreitetes Bussystem: Es sind sehr viele standard ICs, Sensoren und ähnli-
ches von vielen verschiedenen Herstellern verfügbar, die meist direkt daran angeschlossen 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 Mikrocontrollers (30KB, 2KB sind für den sog. Bootloader reserviert) wird innerhalb von wenigen 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 erheblich, 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 Terminalprogrammen 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-Motoren
◊ Maximale 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 Radachsen
◊ Zwei Gummi-Raupenketten
◊ Kann 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% Steigungen befahrbar – je nach Beschaffenheit des Untergrunds).
● Zwei leistungsfähige MOSFET Motortreiber (H-Brücken)
◊ Drehzahl und Drehrichtung können vom Mikrocontroller gesteuert werden
◊ Zwei Stromsensoren mit Messbereich bis ca. 1.8Afü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 Wegmessung
◊ Auflösung von625 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 Infrarotdioden 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, standardmäß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önnen
◊ Vier 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 Spannungsregler
◊ Maximale Belastbarkeit: 1.5A
◊ Große Kupferfläche zur Kühlung auf der Platine
◊ Der 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 Erweiterungsmodule)
● 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 angeschlossen werden.
Schellladegerät, Ansmann ACS110, ACS410 oder AC48 ). Die Ladegeräte unterscheiden 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 unterzubringen. 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 werden (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 Funktionsbibliothek mitgeliefert, welche die Programmierung stark erleichtert.
Auf der Website zum Roboter werden demnächst evtl. weitere Programme und Updates 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 Anwendern 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 Roboterbausätzen und ähnlichem aus: eigene Ideen umsetzen oder vorhandenes verbessern und modifizieren! Sie können aber natürlich erstmal einfach nur die vorgefertigten 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 Hauptanwendung der hochauflösenden Encoder)
● ... bestimmte Distanzen fahren, sich um bestimmte Winkel drehen und die zurückgelegte 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 ändern Sie bitte nur etwas, wenn Sie wissen was Sie da eigentlich tun! Sie sollten lieber 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“ (einige der hier genannten Aufgaben sind schon recht kompliziert und nicht ganz so einfach 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 Beispielprogrammen kurz angesprochen mit einfachen I²C Porterweiterungen und A/D Wandlern 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 Geräte auf dem Roboter montiert werden und nicht wie eine Fernbedienung o.ä. verwendet 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 ansteuern
● 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 Roboter und der Programmierung vertraut machen. Das hier sollte nur eine kleine Motivation 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 Komponenten des RP6. Hier gehen wir auf die Funktionsweise der Elektronik und das Zusammenspiel mit der Software auf dem Mikrocontroller ein. Wenn Sie bereits Erfahrung
mit Mikrocontrollern und Elektronik haben, brauchen Sie viele der Abschnitte in diesem 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öchten, können Sie auch bei Kapitel 3 weitermachen, aber Sie sollten später noch auf dieses 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 Komponenten 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 Mikrocontroller 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 Festplatte, oder mehrere Gigabyte RAM! Ein Mikrocontroller kommt auch mit weit weit weniger aus. Der MEGA32 hat z.B. "nur" 32KB (32768 Bytes) Flash ROM - das ist quasi
seine "Festplatte". Darin werden alle Programmdaten gespeichert. Sein Arbeitsspeicher 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 Mikrocontrollers 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ührung eines bestimmten Programmteils braucht, denn man teilt sich die verfügbare Rechenleistung 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 Instruktionen 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 erhä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/Output 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 weiterverarbeiten. 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 Aufwand 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ängig 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 einmal wie gewünscht konfiguriert hat, arbeitet er anschließend ohne weiteres zutun fortlaufend 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 Service 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 werden, sie haben also keine eigenen Pins am Mikrocontroller. Welche der Funktionen aktiv 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ügbar. 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, kostenlos 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. Bootloader. Das ist ein kleines Programm, das über die serielle Schnittstelle des Mikrocontrollers neue Programme in den Programmspeicher laden kann. Der Bootloader kommuniziert mit einem Host PC über die mitgelieferte RobotLoader Software (ehemals
RP6Loader). Durch den speziell für den RP6 entwickelten Bootloader entfällt ein normalerweise 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önnen. 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. „Nennspannung", weil sich die Spannung mit der Zeit stark verändert. Voll aufgeladen können die Akkus im Leerlauf insgesamt bis zu 8.5V liefern! Diese Spannung sinkt während 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 Erweiterungsboard 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 "Sensors" zu sehen, weil sie besser in andere Bereiche passen. Trotzdem zählen natürlich
auch die Drehgeber (=“Encoder“), Motorstromsensoren und der Batteriespannungssensor 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änden. 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 Messbereich 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 etwas 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 Spannung 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 Umrechnungsverhä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 konstanten 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 Widerstände) platziert und nach links bzw. rechts ausgerichtet. Zwischen 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 Intensität des Lichteinfalls verändert und somit eine vom Lichteinfall abhängige Spannung 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-Halogenscheinwerfer: 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 bestimmen. 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 Sensorplatine links und rechts angebrachten IR LEDs. Die IR LEDs werden direkt vom Mikrocontroller angesteuert. Die Ansteuerungsroutinen können beliebig verändert und verbessert werden! Beim Vorgängermodell 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 Ausweichmanö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 natü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 Reichweite 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 Motorstromsensoren 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 Mikrocontroller 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 Sammelvorrichtung 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 Widerstand abfällt, proportional zum Strom verhält, der diesen 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 Motorkanal 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 Motoren 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 welchem 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 genau 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 Drehzahlmessung angebracht sind. Es handelt sich dabei um Reflexlichtschranken, die auf Codierscheiben mit je 18 weissen und 18 schwarzen Segmenten ausgerichtet sind, also
insgesamt 36 Segmente (s. Abb). Diese Codierscheiben
sind wiederum an je eines der Zahnräder der beiden Getriebe geklebt worden. Wenn es sich dreht, wandern die einzelnen Segmente an der Reflexlichtschranke vorbei. Die weissen 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 Wegstrecke gemessen und zusammen mit einem Timer zur Zeitmessung die Drehzahl und damit 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 Getriebes 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 Segmente, 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 rechnerisch 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 eindrücken (bzw. auch selbst eingedrückt werden) kann man aber von 0.25mm pro Zählschritt 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 beschrieben 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 Raupenantrieben 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 Vergleich 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 einregeln, 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 maximale 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 Getriebe 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 Getriebe, über das die beiden Raupenketten angetrieben werden (s. Abb. weiter oben).
Die Motoren genehmigen sich je nach Belastung einen recht hohen Strom und können
natürlich nicht direkt vom Mikrocontroller
angesteuert werden. Dazu braucht man
Leistungstreiber in Form von je einer HBrücke pro Motor. Das grundlegende Prinzip
ist in der nebenstehenden Abbildung dargestellt. 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 entgegengesetzte 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 erzeugen ein Rechtecksignal fester Frequenz, 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 niedrigere, mittlere Gleichspannung an, die dem
Tastverhältnis entspricht. In der Grafik ist
dies durch eine rote Linie (Ug) und die roten 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 Programmierung 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 nebenbei 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 genaueren Geschwindigkeitsregelung! Der RP6 kann sehr sehr langsam bei konstanter Geschwindigkeit fahren!
2.5. Erweiterungssystem
Eines der nützlichsten Features des RP6 ist das Erweiterungssystem. Man kann den RP6 damit genau so weit ausbauen, 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 Roboter 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 Sensoren, könnte man aber die Distanz ermitteln und so beispielsweise 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 Signalleitungen 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 Anforderungen. 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 entwickelt und ist seitdem zu einem sehr weit verbreiteten Bussystem geworden. Der I²C
Bus findet in sehr vielen elektronischen Geräten der Unterhaltungselektronik, wie Videorecordern 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 Ultraschallsensoren, elektronische Kompassmodule, Temperatursensoren und ähnliches mit diesem 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 bidirektional, was bedeutet, dass hier sowohl Master als auch Slave Daten anlegen können. 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 (ausser 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 Kommunikation stattfinden soll, gefolgt von einem Bit das festlegt ob Daten geschrieben
oder gelesen werden. Der Slave bestätigt dies mit einem ACK ("Acknowledge" = Bestätigung). Danach folgen beliebig viele Datenbytes wobei der Empfang jedes einzelnen Bytes vom Slave mit einem ACK quittiert wird. Abgeschlossen wird die Übertragung 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 machen, es ist aber trotzdem nützlich, das schonmal gehört zu haben.
2.5.2. Erweiterungsanschlüsse
Auf dem Mainboard des Roboters befinden sich insgesamt vier Erweiterungsanschlüsse. Zwei davon sind
mit „XBUS1“ und „XBUS2“ beschriftet. XBUS ist eine
Abkürzung für „eXpansion BUS“, also ErweiterungsBus. XBUS1 und XBUS2 sind vollstä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 Erweiterungsmodul finden sich an einer Seite zwei XBUS Anschlüsse.
Über je ein 14 poliges Flachbandkabel kann man die Erweiterungsmodule mit dem Mainboard und untereinander verbinden – dazu
gibt es auch zwei identische und miteinander verbundene Anschlüsse auf jedem Erweiterungsmodul. Der äussere Stecker muss
dabei als Verbindung nach unten genutzt werden, während der innere 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 abgebildet – diese kann man für eigene Schaltungen verwenden).
Auf den XBUS Anschlüssen sind Stromversorgung, der oben beschriebene 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ändert 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 variiert von Hersteller zu Hersteller), kann aber auch je nach Belastung, Art und Ladezustand 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 Mikrocontroller per externem Interrupt Signal mitzuteilen, dass neue Daten vorhanden
sind oder eine bestimmte Aufgabe ausgeführt worden ist und auf neue Befehle gewartet wird. Hätte man diese Leitungen nicht, müsste der Mastermikrocontroller (bei bestimmten 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 einiges 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 Erweiterungsanschlü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 „USRBUS“ was für „User-Bus“ steht, also „Anwender-Bus“. Sie können diese 14 poligen Erweiterungsstecker für alles verwenden was Sie wollen – ein eigenes Bussystem, zusätzliche Versorgungsleitungen (Achtung: Nicht zu stark belasten, die Leiterbahnen
sind nicht sonderlich breit) oder ähnliches. Man kann damit z.B. auch zwei der Erweiterungsmodule miteinander Verbinden, ohne diese an die anderen Erweiterungen anzuschließ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 ordentlicher.
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 Elchtest 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 allerdings 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 Betriebsspannung, GND bezeichnet den „Minuspol“ (GND = Ground,
also Masse), MRESET ist das Master Reset Signal, INTx
sind die Interruptletungen, SCL die Takt- und SDA die Datenleitung 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 einige Sicherheitshinweise die Sie vor allem dann beachten sollten,
wenn Kinder den RP6 betreiben werden!
Lesen Sie den folgenden Abschnitt daher bitte besonders aufmerksam 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 befinden 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 Einzugsstellen. 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 unerwartet anlaufen und es können unvorhergesehene Fahr- und Lenkbewegungen auftreten! 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 Erweiterungsmodulen befinden sich viele nicht abgedeckte Bauteile und Leiterbahnen. Verursachen
Sie keine Kurzschlüsse durch versehentlich abgelegte Metallgegenstände oder Werkzeug!
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 zerstö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 Wasserleitung 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 Versorgungsspannung 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 Absturzgefahr 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 befindlichen Flüssigkeitsbehälter wie z.B. Kaffeetassen, Flaschen oder Blumenvasen gesichert oder entfernt werden.
Die geschlossene Bodenwanne schützt die Mechanik zwar recht gut gegen grobe Umwelteinflüsse, sie ist aber weder wasser- noch staubdicht. Auch die Elektronik ist weitestgehend ungeschützt. Setzen Sie den Roboter daher nur im trockenen und sauberen 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 Funken entstehen. Betreiben Sie den Roboter daher auf gar keinen Fall in einer Umgebung mit brennbaren oder explosionsgefährdeten Flüssigkeiten, Gasen oder Stäuben!
Bei längerer Nichtverwendung sollte der Roboter nicht in Räumen mit hoher Luftfeuchtigkeit 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 niemals ü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 betrieben 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 Roboter geladen werden!
Bitte beachten Sie auch die Sicherheits- und Entsorgungshinweise für Batterien 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 beschä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 installierte Software wird für alle nachfolgenden Kapitel unbedingt benö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 durchzulesen 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 Anleitung und würde den Rahmen bei weitem sprengen! Hier geht es nur um den RP6, dessen 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 öffnen. 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 mindestens 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 Installationsprogramme direkt von der CD starten! Wenn Ihr Browser dies aufgrund der Sicherheitseinstellungen nicht erlaubt, müssen Sie die Dateien zunächst in ein Verzeichnis 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 installieren. 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 andeutet - 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 Sammlung 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 Programmentwicklung 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 AVRGCC lässt sich in AVRStudio, die Entwicklungsumgebung für AVRs von ATMEL, einbinden. 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 Neuinstallation 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ühren. 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 Probleme 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önnen 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 Programme 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 Entwicklungstools 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 Übersetzung 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 trotzdem 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 finden 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 benö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 Fehlermeldungen ansehen (auch mal in der Konsole etwas hochscrollen) – meist fehlen dann irgendwelche Programme die man vorher noch installieren muss (wie z.B. das oben erwä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 Kommandozeilenausgaben 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:
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 einspielen. Wir nehmen hier an, dass Sie alles ins Home Verzeichnis ~/RP6 kopiert haben:
Dieses Skript ermittelt, was auf Ihrem System verfügbar ist und erzeugt dementsprechend 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:
--disable-nls --disable-libssp –with-dwarf2
> make
> make install
Nach dem \ kann man einfach Enter drücken und weiterschreiben – so kann der Befehl 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:
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 unter 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 installiert 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 Abschnitt 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 Archiv „.bin“. Unter Linux ist es besser wenn Sie zunächst im Paketmanager Ihrer jeweiligen 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 neuere 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 Installationspaket zu kommen. Das RPM sollte bei vielen anderen Distributionen wie RedHat/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 Zusatzfunktionen integriert, wie z.B. ein einfaches Terminalprogramm.
Den RobotLoader selbst braucht man nicht zu installieren – das Programm kann einfach irgendwo in einen neuen Ordner auf die Festplatte kopiert werden. Der RobotLoader befindet sich in einem Zip-Archiv auf der CD-ROM:
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 Datei 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
Diese lange -D Option ist notwendig, damit die JVM auch alle verwendeten Bibliotheken 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 „RobotLoader.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-Archiv auf der CD:
Sie können diese einfach direkt in ein Verzeichnis Ihrer Wahl auf die Festplatte entpacken. Am besten entpacken Sie die Beispielprogramme in einen Ordner auf einer Daten Partition. Oder in den „Eigene Dateien“ Ordner in einem Unterordner „RP6\Examples\“ 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 BitWindows XP, Server 2003, Vista und Win7 Systeme:
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 korrekten 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 berü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 unten über der Taskleiste – die letzte Meldung sollte in etwa „Die Hardware wurde installiert 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 auswählen den Treiber manuell zu installieren und natürlich keinen Webdienst o.ä. zu suchen. Der Treiber befindet sich in unserem Fall auf der CD:
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 Windows XP, 2003 und 2000 neben dem RobotLoader auch den Gerätemanager verwenden: Rechtsklick auf den Arbeitsplatz --> Eigenschaften --> Hardware --> Gerätemanager 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 bitte 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-->Einstellungen-->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 verwenden 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 (zumindest 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 Support 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 Portliste 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 bereitstellt, 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 Installation 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 aufgeladen 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 Jahren unbenutzt im Schrank rumgelegen haben...
Wenn Sie später ein externes Steckerladegerät verwenden (empfohlen, jedoch nicht im Lieferumfang enthalten!), brauchen Sie die
Akkus nur einmalig einzubauen! Wir empfehlen dringend die Verwendung eines Mikrocontroller gesteuerten Ladegeräts um die Akkus
schonend zu laden! Verwenden Sie nur zugelassene und geprüfte Ladegerä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 Mainboards 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 Mainboard möglichst nur an den Rändern oder an größeren Kunststoffteilen an, um elektrostatische 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 - vorsichtig 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 unbedingt sicher, dass der Schalter
auf dem Mainboard des Roboters in der Position OFF steht,
also in Richtung des Textes
"OFF", bzw. in Richtung des
großen zylinderförmigen Kondensators auf dem Mainboard
zeigt (s. Abb)!
Bevor Sie den Roboter wieder einschalten, müssen Sie kontrollieren
ob die Akkus richtig herum eingelegt sind.
Jetzt können Sie 6 NiMH Mignon Akkus
POLUNGSRICHTIG in den Akkuhalter einlegen! Vorsicht: Wenn Sie die Akkus
falsch herum einlegen wird die Sicherung normalerweise durchbrennen!
Es kann aber auch passieren, dass Teile der Elektronik beschädigt werden!
Legen Sie die Akkus also besser gleich richtig herum ein, um derartige Probleme zu
vermeiden! Es sind Markierungen im Ak-kuhalterund auch auf den Akkus ((+)
und (-), der Minuspol (die flache Seite) der
Akkus muss in Richtung der Federn im Akkuhalter 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 Getriebe berühren können!
Da der Roboter nun ohnehin schon aufgeschraubt ist, können Sie auch kurz noch die
beiden Getriebe und Drehgeber begutachten 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 Mainboard 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 festschrauben, 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 weiterhin in der Position OFF stehen bleiben! Die Akkus können nur im ausgeschalteten Zustand geladen werden. Der Hauptschalter verbindet die Akkus entweder mit der Elektronik des RP6, oder mit der Ladebuchse.
Achten Sie darauf, das Ladegerät polungsrichtig an die Ladebuchse (mit „Charger“ beschriftet) 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 entnehmen 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 Roboter am besten sofort aus und notieren Sie sich genau was falsch gelaufen 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 mechanisch 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 welche Sprache Sie gewählt haben, können die Menüs natürlich etwas anders beschriftet sein. Auf den Screenshots 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 RobotLoader aber erst einmal neu starten bevor sich etwas ändert!
Port öffnen - Windows
Jetzt können Sie den USB Port auswählen. Sofern
kein anderer USB->Seriell Adapter mit FTDI Controller 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 Namens „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-->Refresh Portlist“ („RobotLoader-->Portliste aktualisieren“) die Portliste aktualisieren!
Port öffnen – Linux
Unter Linux wird der USB-Seriell Adapter wie ein
normaler Comport behandelt. Die D2XX Treiberinstallation 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 solange 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/ttyS1“ 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 Programms automatisch (generell bleiben die meisten Einstellungen und Selektionen erhalten).
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 gemessene 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 Roboter am Besten sofort aus und lesen Sie in Ruhe das Kapitel über Fehlersuche/Problemlösungen! Ist die Akkuspannung zu niedrig, erscheint eine Warnung. Spätestens jetztsollten die Akkus neu geladen werden (besser schon dann, wenn die Spannung 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 unten 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 Beispielprogrammen hinzufügen (s. Screenshot, hier wurden schon ein paar Hexdateien hinzugefügt). Der RobotLoader kann auch verschiedene Kategorien von Hexdateien verwalten. Damit lassen sich die Dateien übersichtlicher sortieren. Beispielsweise wenn
man mehrere programmierbare Erweiterungsmodule auf dem RP6 hat, oder verschiedene 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önnen danach sofort nach jedem erneuten Übersetzen des Programms, das neue Programm in den Mikrocontroller laden (auch per Tastenkombination [STRG+D] oder
[STRG+Y] um das Programm direkt nach dem Übertragen zu starten). Unter verschiedenen 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 Programm 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 Programmfenster!) „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 Programmieranschluss (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 allerdings direkt ausprobieren ob der Taster korrekt funktioniert! Es sollte zunächst eine Warnmeldung im Terminal erscheinen, 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 Antriebsketten 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ßerdem 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 unter 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 Testprogramms. 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 entsprechenden 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 bevor Sie auf die LED geschaut haben, oder es ist tatsächlich etwas defekt. Das Testprogramm 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 Stromsensoren 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 zusammen und ein paar mal einzeln. Hier können Sie sofort sehen ob alle LEDs korrekt funktionieren 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ändigkeit halber.
#####################################################################
#####################################################################
## Test #3 ##
### Voltage Sensor Test ###
Be sure that you are using good accumulators!
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 ansehen. 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 entsprechend verändern – je kleiner die Messwerte, desto weniger Licht fällt auf die Sensoren! 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 natürlich überhaupt keine reflektierenden Gegenstände bzw. die Decke über dem Roboter ist, könnte das auch mal nicht korrekt funktionieren – ist aber unwahrscheinlich).
Die Ausgaben des Tests sollten etwa wie folgt aussehen:
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 beschrieben 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 durchführen – aber vorher auch das Kapitel über Fehlerbehandlung im Anhang lesen!
Die Testroutine lässt den Antrieb nacheinander in verschiedenen Geschwindigkeitsstufen 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 beschä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 Akkueinbau 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!
Die einzelnen Messwerte die während der Tests ausgegeben werden sind (von links
nach rechts): T – aktueller Geschwindigkeitssollwert, VL/VR - gemessene Geschwindigkeit 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 Quelltexteditor 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 rudimentäre Projektverwaltung. Man kann so mehrere Quelltextdateien in Projekten organisieren 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 wissen 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üeinträ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 Einstellungen 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 Screenshot sehen.
„%d“ verweisst auf das Verzeichnis der aktuell gewählten
Datei und „%d\make_all.bat“
verweisst auf eine kleine Batchdatei, die in jedem Verzeichnis
der vorgefertigten Projekte für
den RP6 zu finden ist.
Bei „Shortcut“ können Sie Beipielsweise [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 Verzeichnis 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 „Command“ 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 abgebildeten 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ährend seiner Arbeit erzeugt hat komfortabel löschen. Die brauchen wir nämlich nach
dem Kompilieren meistens nicht mehr. Die erzeugte Hexdatei wird übrigens nicht gelö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!):
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 Beispielprojekte geöffnet hat, sollte PN2 in etwa so aussehen:
Links sind alle Beispielprojekte zu sehen, rechts der Quelltexteditor (mit dem angesprochenen 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 funktioniert 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 eigentlichen Programm gehören und nur der Beschreibung/Dokumentation dienen. Darauf gehen 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 Kommentare 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 angelegten 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 englischen „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 Kompilierung 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):
-------- end -------> Process Exit Code: 0
> Time Taken: 00:01
Wichtig ist ganz unten das „Process Exit Code: 0“. Das bedeutet, dass es beim Übersetzen 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“.
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 eigenen 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 geladen 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 Programmausführung muss dazu natürlich zunächst wieder gestartet werden, im Terminal 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 immer 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 Lauflicht und etwas Textausgabe.
Bevor Sie nun Ihre eigenen Programme schreiben können, folgt ein kleiner C Crashkurs...
- 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 Eigeninitiative! 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 Konzepte 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 Sprachen unterstützt. So kann man damit z.B. neben C auch in C++, Java, Ada und FORTRAN verfasste Quelltexte übersetzen.
Der GCC unterstützt nicht nur den AVR, sondern wurde eigentlich für viel größere Systeme 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 unbedingt die komplette Compiler Collection, sondern fast immer nur den C-Compiler. Ursprü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 werden. Diese Version des GCC nennt sich dann AVR-GCC. Dieser Compiler ist für Windows 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 Leser ü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 normalerweise 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 Mikrocontroller 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 effektivere Alternativen.
Einige C Tutorials / Online-Bücher (nur eine winzig kleine Auswahl):
Weiterhin gibt es viele Bücher auf dem Markt - einfach mal in eine gut sortierte Bibliothek 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 herumexperimentieren 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 umfangreich.
Speziell für den AVR-GCC und AVR Mikrocontroller gibt es ein sehr gutes deutschsprachiges Tutorial, und zwar hier:
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 speziellen Bereichen befasst ist hier zu finden:
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 verschiedene 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 benennen alle Funktionen und Variablen in den Beispielprogrammen mit englischen Begriffen! 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 hinzukommen, 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 entsprechenden 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öhnen...
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 kleinem 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 beachtet. Kommentare werden zur Dokumentation des Quelltextes verwendet und erleichtern 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 Anhaltspunkte um sich an die eigenen Gedankengänge besser erinnern zu können. Kommentare 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 Funktionen und vordefinierte Dinge bereit, die das Ansteuern der Hardware immens erleichtern. 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 genau ist, wird etwas später erklärt. Zunächst reicht es uns zu wissen, dass das Programm 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 '}' definiert! (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 initialisiert. Damit werden die Hardware Funktionen des AVRs konfiguriert. Ohne diesen
Aufruf arbeiten die meisten Funktionen des Mikrocontrollers nicht korrekt! Also niemals 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ückgegeben. 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-Programm 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 Leerzeichen, 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 Tabulatoren 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:
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ührungszeichen 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 Anweisungen 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 bestimmten Programmteilen, kann der Compiler übrigens gleich einen ganzen Haufen von Fehlermeldungen 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 (= „Rechtschreibfehler“)! Das ist vielleicht erstmal gewöhnungsbedürftig sich an all diese Regeln zu halten, aber das lernt man nachdem man einige Programme selbst geschrieben 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 abgearbeitet. Mehrere Befehle gleichzeitig kann ein AVR Mikrocontroller nicht ausführen!
Das macht aber nichts, denn es gibt viele Möglichkeiten, den Progammablauf zu beeinflussen 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.
unsinged long uint32_t32 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, verwenden 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 Namen). Steht noch ein „u“ davor, handelt es sich um einen „unsigned“ also vorzeichenlosen Datentyp. Sonst ist der Datentyp „signed“ also vorzeichenbehaftet.
Das wurde oben in der Tabelle aber nur bei „signed char“ hingeschrieben, 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“ genutzt da sonst wegen der Definition von uint8_t ein paar Dinge aus
der C Standard Bibliothek nicht damit kompatibel wären und es ohnehin logischer ist, hierfür den Datentyp char (=Engl. für „Zeichen“)
zu verwenden. Das wird im Kapitel über die RP6Library bei Textausgabe ü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:
autodefaultfloatlongsizeofunion
breakdoforregisterstaticunsigned
casedoublegotoreturnstructvoid
charelseifshortswitchvolatile
constenumintsignedtypedefwhile
continueextern
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. Kostet meistens zuviel Rechenzeit und Speicherplatz und man kommt oft mit normalen
ganzen Zahlen besser aus. Für den RP6 brauchen wir diese Datentypen also normalerweise 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 verwendet.
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 zugewiesen. Jetzt überprüfen wir in der nachfolgenden if-Bedingung in Zeile 2, ob die Variable 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änkungen 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 abhängig davon Programmcode ausführen. Das kann man natürlich wie oben beschrieben mit vielen if-then-else Bedingungen machen, aber es geht auch eleganter mit einer 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-elseif-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 Programm 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 Programmen für den Roboter damit z.B. verschiedene Bewegungsmuster auslösen. In einigen Anwendungsbeispielen werden switch-case Konstrukte z.B. für endliche Automaten 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 „wiederhole 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!
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 Endzustand zu versetzen, oder einfach Operationen solange auszuführen wie der Mikrocontroller 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 realisieren:
while(true) { }
bzw.
for(;;) { }
Der Anweisungsblock wird dann „unendlich oft“ ausgeführt (bzw. bis der Mikrocontroller 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 handelt 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 natü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 Funktionen „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ötigerweise 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:
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 Programm zuerst aufgerufen und MUSS somit auch immer vorhanden sein.
In unserer obigen Main Funktion wird zuerst die initRobotBase Funktion aus der RP6Library 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 Parameter haben. Man kann viele Parameter für eine Funktion definieren. Die Parameter werden 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");
[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:
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:
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 angelegt 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 Array 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 Arrays. 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 Element 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:
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 Anweisung von oben nach unten ausgeführt wird. Dann gibt es natürlich noch die normale 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 Mikrocontrollers 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 gerade 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 diese 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 errechnet 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 Infrarotsensorik 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²CBus) 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äprozessor ausgewertet. Mit #include "Datei" wird der Inhalt der angegebenen Datei an
dieser Stelle eingefügt. Im Falle unseres Beispielprogramms ist das die Datei RP6BaseLibrary.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.
Das lässt sich dann wie eine normale Funktion aufrufen ( setStopwatch1(100); ).
Eine wichtige Sache ist noch, dass man normalerweise hinter Präprozessor Definitionen 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 natü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:
In unseren Makefiles sind dazwischen noch einige Kommentarzeilen mit Erläuterungen
und Hinweisen zu finden. Kommentare fangen in Makefiles immer mit „#“ an und werden 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 RP6Library 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 angegebenen Verzeichnissen gesucht!), die Sie neben der Datei mit der Main-Funktion verwenden wollen. Auch die Dateien aus der RP6Library müssen hier angegeben werden, sofern 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 hardwarespezifischen 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 garantieren! 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 stattdessen einen Block (zwei geschweifte Klammern) einfügen in den das eigene Programm 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 verwendet, 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 interpretieren.
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 Verwendung 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!
Wenn man Texte mit einstellbarer Länge (length) und Anfangsposition (offset) ausgeben 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 Ausgabe 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
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 angegebene 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 basiert 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 verfü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
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 Zeichen 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 anpassen.
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 bestimmte 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ührung (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 Anschluss 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 Variable benutzten, ist die maximale Zeitspanne 25500µs = 25.5ms. Interrupt Ereignisse
werden trotzdem weiter behandelt – es wird nur der normale Programmablauf unterbrochen.
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.
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 unabhä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. Normalerweise schreibt man solche Timing Funktionen speziell auf das jeweilige Problem zugeschnitten, 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 Millisekunde, wie bei der mSleep Funktion. Das bedeutet, dass jede Stopwatch ihren Zählstand 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 Beispielprogramm:
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:
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 geschlossen 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. Normalerweise 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ände 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 reserviert! Sie sollten dieses Byte also nicht in Ihren eigenen Programmen 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üssen damit alles korrekt funktioniert. So z.B. das ACS. Hier müssen oft IR Impulse ausgesandt 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 Funktionen für die Bumper zu verstehen, mussten wir das hier aber schon kurz vorwegnehmen!
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 vorgehen 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.
task_Bumpers(); // ständig aus der Hauptschleife aufrufen!
}
return 0;
Im Beispielprogramm benutzen wir die Status LEDs um den Zustand der beiden Bumper anzuzeigen. Ist der linke Bumper gedrückt, wird LED 6 angeschaltet und LED4 abgeschaltet. Ist er nicht gedrückt, wird umgekehrt LED6 ausgeschaltet und LED4 angeschaltet. 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 angeschaltet.
Da man nun sowieso schon die automatische Auswertung der Bumper alle 50ms in der
Library hatte, war es naheliegend etwas einzubauen, das eine selbstdefinierte Funktion 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 RP6Library eingetragen werden, damit man diese Aufrufen kann.
So kann man eigens definierte Funktionen als sog. „Event Handler“, also für die Ereignisbehandlung 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 haben. 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:
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");
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 Bumperzustands. 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 Ausführung des Aufrufs in Zeile 24 erhält.
Der Event Handler kann natürlich noch andere Aktionen auslösen, als nur Text auszugeben – 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 Programmteilen – 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 verwenden, 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 verwendet, 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 entsprechender 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 bequemer. Ist aber eher Geschmackssache was man verwendet.
Auf der CD finden Sie übrigens noch einige ausführlichere Beispielprogramme zu diesem 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 Variablen 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ß anlö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 Abstandssensoren von Sharp ... Sie sollten dazu allerdings schon ein wenig
Löterfahrung haben! Sonst lieber ein Erweiterungsmodul verwenden!
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 normalen 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 bestimmen 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 automatisch 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 Mikrocontroller) 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:
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 ausgegeben. 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-Prozessor 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-Prozessor nicht veränderbar...
Die Reichweite bzw. die Sendeleistung der beiden IR LEDs des ACS, kann man mit folgenden 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 heraus 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.
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 eingestellt (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.
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 setzen 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 Roboter quasi „blind“ machen oder zumindest die Empfindlichkeit verringern. 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: Einfach mal diverse Gegenstände mit dem ACS testen und schauen welche NICHT sonderlich gut erkannt werden. Dann könnte man solche Objekte evtl. woanders hinstellen 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 weitestgehend 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 Fernbedienungen 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 verschiedene Gerätehersteller durchprobieren.
Wenn die Fernbedienung im RC5 Format sendet, wird dieses Signal von der ACS Hinderniserkennung 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 Fernbedienug 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 entfernt 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 „Togglebit“. 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. verschiedene 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 verwendet 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!
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 empfangen 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:
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 ausgelegt und dürfen nur eine Millisekunde am Stück eingeschaltet bleiben! 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 automatisch 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 verbessert und hinzugefügt werden!
void task_motionControl(void)
Die Funktion task_motionControl muss man ständig aus dem Hauptprogramm aufrufen – sonst funktioniert diese automatische Regelung nicht! Ständig aus dem Hauptprogramm 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 Hardwaretimer 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 Aufrufen 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 integrierender 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 dementsprechend 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 unabhä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 unterschiedlich 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 öfters 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ändert und erst dann wieder auf die Sollgeschwindigkeit beschleunigt.
Neben der Geschwindigkeitsregelung und Drehrichtungskontrolle, wird auch der Motorstrom ü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 Überstromereignissen 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 Wegstrecken 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 Parameter wie z.B. die Sollgeschwindigkeit übergeben. Das passiert über andere Funktionen, die wir nun im einzelnen erläutern werden.
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 Geschwindigkeit auf diesen Wert eingeregelt. Setzt man den Wert auf 0, werden die PWM Module 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
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 Hindernisse und fährt einfach nur geradeaus! Einzig die Geschwindigkeit wird möglichst konstant gehalten.
- 100 -
Loading...
+ hidden pages
You need points to download manuals.
1 point = 1 manual.
You can buy points or you can get point for every manual you upload.