02.01.2013 Aufrufe

Roboterprogrammierung mit Hilfe eines ATMEL AVR-Prozessor ...

Roboterprogrammierung mit Hilfe eines ATMEL AVR-Prozessor ...

Roboterprogrammierung mit Hilfe eines ATMEL AVR-Prozessor ...

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

Besondere Lernleistung<br />

im Bereich<br />

Informatik<br />

<strong>Roboterprogrammierung</strong> <strong>mit</strong><br />

<strong>Hilfe</strong> <strong>eines</strong><br />

<strong>ATMEL</strong> <strong>AVR</strong>-<strong>Prozessor</strong><br />

von Dominik Hufnagel<br />

MSS12<br />

Informatik (Ro)<br />

2008/2009<br />

Projektname:<br />

HMMR<br />

Home Made Mapping Robot


Inhaltsverzeichnis<br />

1. Vorwort............................................................................................................................................1<br />

2. Thema Beschreibung......................................................................................................................2<br />

3. Die mechanischen Komponenten..................................................................................................4<br />

3.1 Grundplatte............................................................................................................................4<br />

3.2 Motoren.................................................................................................................................5<br />

3.3 Räder.....................................................................................................................................6<br />

3.4 Platinenbefestigung...............................................................................................................8<br />

3.5 Akkuhalterung.......................................................................................................................8<br />

3.6 Sensorenhalterung.................................................................................................................9<br />

4. Die elektrischen Komponenten...................................................................................................10<br />

4.1 Allgemein............................................................................................................................10<br />

4.1.1 Der Schrittmotor.....................................................................................................10<br />

4.1.2 Schaltplan und Layout............................................................................................11<br />

4.1.3 Erstellung von Platinen...........................................................................................11<br />

4.2 Schrittmotoransteuerung.....................................................................................................12<br />

4.3 Hauptplatine........................................................................................................................16<br />

4.4 Die Sensoren.......................................................................................................................20<br />

4.5 Die Funkmodule..................................................................................................................22<br />

5. Die Programmierung....................................................................................................................23<br />

5.1 Allgemein............................................................................................................................23<br />

5.2 Der Atmega.........................................................................................................................23<br />

5.3 Die Fusebits.........................................................................................................................24<br />

5.4 Der Bootloader....................................................................................................................24<br />

5.5 Der Erste Test......................................................................................................................25<br />

5.6 Aufbau der Firmware..........................................................................................................26<br />

5.7 Die Funktionen der „myLib“..............................................................................................27<br />

5.8 Die Funktion von fifo..........................................................................................................31<br />

5.9 Der PC als Empfänger.........................................................................................................32<br />

6 Anhang............................................................................................................................................36<br />

6.1 Quellenverzeichnis..............................................................................................................36<br />

6.2 Inhaltsverzeichnis der CD...................................................................................................36


1. Vorwort<br />

Die Idee zu diesem Projekt entstand durch bereits vollendete Projekte <strong>mit</strong> einem <strong>AVR</strong> 1<br />

Mikrocontroller. Das Interesse an elektronischen Schaltungen und an der Programmierung wird<br />

durch Projekte <strong>mit</strong> Mikrocontrollern kombiniert. Durch die Softwarefirma m<strong>eines</strong> Vaters kam es zu<br />

frühen Kontakt <strong>mit</strong> Computern und so<strong>mit</strong> wurde mein Interesse an der Programmierung geweckt.<br />

Mein Interesse an elektrischen Schaltungen wurde bereits an meinem zehnten Geburtstag durch ein<br />

gemeinsames Projekt <strong>mit</strong> meinem Vater geweckt. Ein weiterer Anstoß war der Wunsch eigene<br />

Schaltungen für den Komfort bei der PC Bedienung zu bauen, zum Beispiel ein LC-Display oder<br />

eine Lüftersteuerung. Zu den Mikrocontrollern kam ich schließlich vor ca. 3-4 Jahren, als mein<br />

Bruder <strong>mit</strong> der Idee kam, ein großes Display aus vielen LEDs aufzubauen. Im Internet fand ich<br />

jemanden, der mir bei vielen Schaltungen geholfen hatte und mir auch die<br />

Mikrocontrollerprogrammierung näher brachte. Diese scheute ich immer, da ich diese immer für<br />

sehr kompliziert hielt. Doch ich stellte fest, dass dies nicht so ist. Die ersten Schritte in der<br />

Programmierung von Mikrocontrollern machte ich <strong>mit</strong> Assembler, dem sogenannten<br />

Maschinencode. Assembler ist eine Hardwarenahe Programmiersprache, welche sich aus wenigen<br />

Befehlen zusammensetzt. Der Vorteil durch diesen Einstieg war, dass ich den Mikrocontroller <strong>mit</strong><br />

seinen einzelnen Registern gut kennen lernte. Erst für spätere, komplexere Projekte stieg ich auf die<br />

Hochsprache C um. Die Entscheidung für eine Besondere Lernleistung im Fach Informatik fiel, als<br />

ich hörte, dass in der Schule <strong>mit</strong> dem Asuro-Roboter gearbeitet wird, welcher auch durch einen<br />

<strong>AVR</strong> Mikrocontroller gesteuert wird. Zu dem endgültigen Thema der BLL kam es durch <strong>eines</strong><br />

meiner letzten Projekte, einen autonomen Rasenmäher, welcher jedoch nur per Zufall den Rasen<br />

mäht. Darum soll es dem Roboter aus diesem Projekt möglich sein eine Karte seiner Umgebung zu<br />

erstellen, um diese theoretisch für andere Zwecke nutzen zu können. Dieses Projekt dient auch dazu<br />

neue Erfahrung zu machen und mein Wissen zu erweitern.<br />

1 Laut <strong>ATMEL</strong>: Advanced Virtual RISC (Reduced Instruction Set Computing)<br />

© (2008/2009) 1


Idee:<br />

Planung:<br />

2. Thema Beschreibung<br />

Eine Roboterplattform fährt selbstständig in einem beliebigen Raum und kartographiert<br />

diesen <strong>mit</strong> <strong>Hilfe</strong> <strong>eines</strong> <strong>AVR</strong>-<strong>Prozessor</strong>s unter Zuhilfenahme verschiedener optischer<br />

Sensoren.<br />

Form: Der Roboter erhält eine runde Form. Die Räder werden <strong>mit</strong>tig gesetzt<br />

um das Drehen auf der Stelle zu ermöglichen.<br />

Sensoren: Zur Abstandsmessung werden die Infrarotsensoren GP2D120 von Sharp<br />

verwendet. Odometriesensoren werden aufgrund der Benutzung von<br />

Schrittmotoren nicht verwendet.<br />

<strong>Prozessor</strong>: Als <strong>Prozessor</strong> wird ein <strong>ATMEL</strong> Atmega644P verwendet, dieser bietet<br />

ausreichend Programmspeicher.<br />

Motoren: Als Antrieb werden 2 Schrittmotoren benutzt, welche über einen Treiber IC<br />

im Halbschrittbetrieb angesteuert werden.<br />

Verbindung: Der Roboter kann über den COM-Port <strong>mit</strong> dem Computer kommunizieren.<br />

Hier wird evtl. die Kabelverbindung durch eine Funk Verbindung ersetzt.<br />

Sonstiges: Die Platinen werden über den PC selbst entworfen und geätzt. Es werden evtl.<br />

Ideen zur Umsetzung der Kartographie<br />

SMD Halbleiter verwendet um Platz zu sparen.<br />

Die Stromversorgung erfolgt über ein Akkupack aus NiMH oder LiPo Zellen.<br />

Der Roboter startet in einem beliebigen Raum und legt diesen Punkt als P(0|0) in einem<br />

Koordinatensystem fest. Trifft er auf ein Hindernis/ eine Wand, folgt er dieser <strong>mit</strong> einem<br />

gleich bleibenden Abstand.<br />

Probleme:<br />

● Der Roboter wird nicht immer im 90° Winkeln drehen, daher muss die Schräge<br />

(Steigung im Koordinatensystem) berechnet werden.<br />

● Zum Folgen der Wand <strong>mit</strong> gleich bleibenden Abstand sind evtl. Sensoren<br />

erforderlich, um die Korrektur zu errechnen (Abstanddifferenz). Idee: Man nimmt<br />

nur ein angetriebenes Rad in der Mitte welches sich um 360° drehen kann →<br />

verworfen, da der Roboter sich sonst unkontrolliert drehen kann<br />

© (2008/2009) 2


Geplante Etappen<br />

● Es muss eine Einheit für das Koordinatensystem festgelegt werden (z.B. 1cm oder<br />

eine Radumdrehung..)<br />

● Der Speicherbedarf der einzelnen Koordinaten könnte den Speicher des <strong>AVR</strong><br />

übersteigen.<br />

● Planung und Bau der mechanischen Komponenten<br />

● Planung und Bau der elektronischen Komponenten<br />

● Programmierung der Grundriss Kartographie<br />

● Programmierung der Hindernis Kartographie<br />

Namensgebung:<br />

Am 11.03.2009 wurde der Roboter in HMMR getauft. Diese Kombination steht für Home<br />

Made Mapping Robot und drückt aus, dass dies ein selbstgebauter (home made)<br />

Kartographieroboter (mapping robot) ist.<br />

© (2008/2009) 3


3.1 Grundplatte:<br />

Überlegungen:<br />

Form:<br />

Fertigung:<br />

Material:<br />

3. Die mechanischen Komponenten<br />

Die Form des Chassis wurde rund gewählt um das Drehen auf der Stelle zu<br />

ermöglichen. Bei der Wahl des Durchmessers musste man die Breite der<br />

Motoren beachten. Ein Motor misst von der Rückplatte bis zum Ende der<br />

Motorwelle ca. 6cm. So<strong>mit</strong> musste der Durchmesser mindestens 12cm<br />

betragen. Um genug Platz für Sensoren etc. zu haben sollte der Durchmesser<br />

ca. 15cm betragen. Das Chassis wurde in mehreren Ebenen aufgebaut um den<br />

Platz bestmöglich zu nutzen.<br />

Es war zunächst geplant Aluminium oder Edelstahl zu verwenden. Da diese<br />

Materialien aber schwer zu beschaffen und zu verarbeiten sind, wurde auf<br />

Plexi-Glas als Alternative zurückgegriffen. Dies ist in jedem Baumarkt<br />

erhältlich und leicht zu verarbeiten.<br />

Als Grundplatte diente eine 4mm Plexiglasscheibe welche <strong>mit</strong>tels einer Oberfräse<br />

ausgefräst wurde. Der Durchmesser beträgt ca. 15,5cm. Da<strong>mit</strong> die Achse der<br />

Motoren <strong>mit</strong>tig im Kreis sitzt, wurde in die Mitte ein Loch für die Befestigung der<br />

Motoren gebohrt.<br />

Abbildung 1: Die Grundplatte <strong>mit</strong> der<br />

Mittelwand für die Motorbefestigung<br />

© (2008/2009) 4


3.2 Motoren:<br />

Die ersten Motoren wurden <strong>mit</strong> einem U-Aluprofil aneinander geschraubt und auf der<br />

Grundplatte befestigt. Die neuen Motoren haben die Befestigungslöcher jedoch Diagonal<br />

angeordnet, weswegen eine neue Befestigungsmöglichkeit der Motoren auf der Grundplatte<br />

notwendig wurde. Geplant war, eine 15mm dicke Aluplatte zu verwenden, jedoch war eine<br />

solche nicht beschaffbar. Die Ersatzlösung besteht aus 3 übereinander geschraubten 4-Kant<br />

Alu Profilen welche den Vorteil des geringen Gewichtes haben. In der Werkstatt der<br />

Wärmeverwertung Karlsruhe in Minderslachen, in welche ich durch meinen Nachbarn<br />

Zutritt bekam, wurden die Löcher für die Motoren in einer Standbohrmaschine gebohrt. Die<br />

Motoren wurden dann <strong>mit</strong> einer M3 Gewindestange und Muttern daran befestigt. In die<br />

Aluprofile konnte aufgrund der geringen Wandstärke kein Gewinde geschnitten werden,<br />

weswegen die Befestigung auf der Grundplatte durch Schrauben <strong>mit</strong> Muttern erfolgt.<br />

• Bei dem Versuch ein Zahnrad, welches auf den Schrittmotorwellen aufgepresst ist,<br />

abzuziehen ging ein Motor kaputt. Um einen gleichmäßigen geradeaus Lauf zu<br />

erreichen sind jedoch 2 gleiche Motoren notwendig. Da kein identischer Motor<br />

auffindbar war, wurde in einem spezialisierten Shop 2 2 neue Motoren gekauft. Auf<br />

Anfrage wurde dort ein Rabatt von 10% ausgehandelt, da es sich um ein<br />

Schulprojekt handelt.<br />

Abbildung 2: Die ersten Motoren <strong>mit</strong> dem U-<br />

Profil<br />

2 Http://www.mir-elektronik.de<br />

Abbildung 3: Die neuen Motoren an der 4-Kant<br />

Alu Konstruktion<br />

© (2008/2009) 5


3.3 Räder:<br />

Überlegungen:<br />

Die Anfangs verwendeten Schrittmotoren stammten aus einem alten Laserdrucker,<br />

weshalb es keine Datenblätter zu diesen Motoren gab. Es wurde aufgrund <strong>eines</strong><br />

Tests, bei dem durch Anlegen von Spannung an den Motor dieser um 25 Schritte<br />

bewegt wurde und sich die Achse etwa um ein 8tel drehte, angenommen, dass sie<br />

1,8°/Schritt drehen, also 200 Schritte pro Umdrehung benötigen. Die Motoren haben<br />

die Abmessungen 4,2x4,2cmx3,6cm. Aufgrund dieser Abmessungen muss der<br />

Raddurchmesser > 5cm sein. Die neuen Motoren (siehe unten) besitzen die gleichen<br />

Eigenschaften wie die alten, jedoch sind sie durch ein Datenblatt dokumentiert. Es<br />

wird ein Rad gesucht, das <strong>mit</strong> einer bestimmten Anzahl von Schritten möglichst<br />

genau 1cm zurücklegt. Dazu verwendet man einfach die Formeln zur<br />

Kreisberechnung: U =2⋅�⋅r . Um aus dem Umfang auf den Weg zu schließen,<br />

welchen der Roboter dann in einem Schritt zurücklegt, muss man den Umfang durch<br />

die Anzahl der Schritte pro Umdrehung, hier 200, teilen. Diese Formel löst man nach<br />

dem Radius auf und kann dann den Radius für die gewünschte Auflösung (Weg pro<br />

Schritt) er<strong>mit</strong>teln. r= 200⋅Weg<br />

2⋅�<br />

Verschiedene Auflösungen<br />

Auflösung: 0,1cm/Schritt Radius: 3,183cm Durchmesser: 6,366cm<br />

Auflösung: 0,125cm/Schritt Radius: 3,979cm Durchmesser: 7,958cm<br />

Auflösung: 0,2cm/Schritt Radius: 6,366cm Durchmesser: 12,732cm<br />

(Die Auflösungen wurden so gewählt, dass sie durch 1 ohne Rest Teilbar sind)<br />

Es wurde die Auflösung 0,1cm/Schritt gewählt, da der Durchmesser des Rades<br />

passend scheint. Bei dieser Auflösung werden also 10 Schritte für einen cm benötigt.<br />

© (2008/2009) 6


Fertigung:<br />

Als Lösung für die Räder wurden zunächst alte Räder <strong>eines</strong> Modellbauflugzeugs in<br />

eine Bohrmaschine gespannt und <strong>mit</strong>tels Schleifpapier abgeschliffen. Mit einer<br />

digitalen Schieblehre wurde der Durchmesser öfters geprüft. Diese<br />

Räderkonstruktion stellte sich jedoch als nicht verwendbar raus, da es keine<br />

Möglichkeit gab, sie an den Motoren zu befestigen. Deshalb wurden in der Werkstatt<br />

der Wärmeverwertung Karlsruhe Räder aus Teflon, nach eigenen Zeichnungen,<br />

gedreht. Teflon ist ein glattes Material und rutscht leicht auf dem Untergrund. Da<strong>mit</strong><br />

der Roboter nicht ständig ausrutscht wurde ein Stück alter Fahrradschlauch auf die<br />

Räder aufgezogen. Die gedrehten Räder können <strong>mit</strong> einer M3 Madenschraube an den<br />

Motorwellen befestigt werden.<br />

• Bei der Befestigung der Räder an den Motoren kam es zu einer großen<br />

Unwucht <strong>eines</strong> Rades. Der Fehler wurde in der Madenschraube gefunden,<br />

welche nicht gerade abgeschliffen war. Diese wurde ersetzt.<br />

• Der Fahrradschlauch auf den Rädern hatten ein wenig Schlupf weswegen es<br />

zu Abweichungen von den berechneten Strecken kam. Der Fahrradschlauch<br />

wurde <strong>mit</strong> doppelseitigen Klebeband befestigt.<br />

Abbildung 4: Die erste Lösung für die Räder,<br />

welche sich jedoch als nicht verwendbar<br />

herausstellte<br />

Abbildung 5: Die neuen Räder wurden an eine<br />

Drehbank entsprechend den Berechnungen<br />

gedreht<br />

© (2008/2009) 7


3.4 Platinenbefestigung:<br />

Um die Platinen auf der Grundplatte zu befestigen wurde aus Plexiglas und Aluwinkeln eine<br />

U-Förmige Plattform gebaut, auf welcher die Schrittmotortreiber und die Hauptplatine Platz<br />

finden. Die Aluwinkel wurden <strong>mit</strong> 2 Komponenten Epoxyd Harz an das Plexiglas geklebt<br />

und <strong>mit</strong> der Grundplatte verschraubt. Die Platinen sind über Gummis an der Konstruktion<br />

befestigt.<br />

Abbildung 7: Die Plattform: Die Teile müssen<br />

während der Aushärtung des Klebers <strong>mit</strong> Druck<br />

aneinander gepresst werden<br />

3.5 Akkuhalterung:<br />

Der Akku wurde auf einer Plattform oberhalb der Hauptplatine befestigt. Dazu wurden<br />

Abstandshalter von PC Mainboards übereinander geschraubt und darauf eine Plexiglasplatte<br />

befestigt. Wie auch die Platinen wird der Akku von Gummis gehalten.<br />

Abbildung 8: Die Akkuhalterung bildet eine 2.<br />

Ebene oberhalb der Hauptplatine<br />

Abbildung 6: Die Platinen sind auf der<br />

Plattform <strong>mit</strong> Haushaltsgummis befestigt. Dies<br />

sorgt für ausreichend Halt<br />

© (2008/2009) 8


3.6 Sensorenhalterung:<br />

Vorne:<br />

Seite:<br />

Um die Sensoren vorne zu befestigen wurde ein Stück Alublech ausgeschnitten und<br />

gewinkelt. Der Abstand der Sensoren zueinander beträgt 10cm. Die Sensoren wurden<br />

an das Alublech geschraubt, welches ebenfalls <strong>mit</strong> Schrauben auf der Grundplatte<br />

befestigt ist.<br />

Abbildung 9: Die Sensoren auf dem Chassis:<br />

Die hervorstehenden Ecken der Halterung<br />

wurden nachträgich noch entfernt<br />

Die Sensoren an der Seite wurden ähnlich den Sensoren vorne befestigt. Jedoch<br />

wurde das Alublech an die Akkuplatte geschraubt. Der Abstand der Sensoren<br />

zueinander beträgt nur 9cm.<br />

Abbildung 10: Die Sensoren an der Seite hängen<br />

ca. 10cm über dem Boden<br />

© (2008/2009) 9


4.1 Allgemein:<br />

4.1.1 Der Schrittmotor:<br />

4. Die elektrischen Komponenten<br />

Ein Schrittmotoren ist ein Synchronmotor, welcher ganz anders als ein<br />

Gleichstrommotor arbeitet. Durch die spezielle Wicklung legt er, für eine bestimmte<br />

Kombination an den Wicklungen angelegten Spannungen, einen festen Winkel<br />

zurück. Dadurch eignet er sich gut zum Einsatz im Kartographie Roboter, da durch<br />

ihn Odometriesensoren entfallen können. Aufgrund der Genauigkeit von<br />

Schrittmotoren finden sie in vielen Bereichen Anwendung, wie z.B. in Drucker,<br />

CNC-Fräsen uvm. Ein Nachteil ist jedoch, dass er auch Strom benötigt, wenn er sich<br />

nicht dreht. Der sogenannte Haltestrom sorgt dafür, dass der Motor nicht von Hand<br />

oder durch zu viel Schwung weiter gedreht wird. Man kann einen Schrittmotor auf<br />

zwei verschiedenen Arten ansteuern, bipolar und unipolar. Hier wird nur auf die<br />

bipolare Ansteuerung eingegangen, da sie in diesem Projekt verwendet wird und der<br />

Motor durch sie mehr Kraft entwickelt.<br />

Webseiten: http://www.roboternetz.de/wissen/index.php/Schrittmotoren<br />

http://www.strz.uni-giessen.de/amp/pcprak/versuch6/intro6.html<br />

Zeichnung 1: Hier erkennt man gut wie ein Schrittmotor<br />

arbeitet (Zusammenhang zwischen Spannung und<br />

Drehwinkel)<br />

(Quelle: Roboternetz.de)<br />

© (2008/2009) 10


4.1.2 Schaltplan und Layout:<br />

Die Schaltpläne und Layouts für die einzelnen Platinen wurden selbst entworfen.<br />

Dabei wurde auf schon vorhandene Schaltpläne oder das Datenblatt der einzelnen<br />

ICs 3 zurückgegriffen. Zum Erstellen von Schaltplänen und Platinenlayouts wurde die<br />

Software Eagle verwendet. Die Freeware Version erlaubt eine Platinengröße von<br />

100x80mm und 2 Layer 4 und kann von der Herstellerseite 5 bezogen werden.<br />

Im Schaltplan war es wichtig darauf zu achten, dass man bei der Bauteilwahl auch<br />

auf die richtige Gehäuseform bzw. das richtige Rastermaß 6 der Bauteile achtet, sonst<br />

wäre es später bei dem Layout zu Problemen gekommen wäre. Die größte<br />

Schwierigkeit beim Layout war, die Bauteile sinnvoll zu platzieren, so dass die<br />

Leiterbahnen möglichst einfach zu verlegen sind. Eagle verfügt zwar über einen<br />

sogenannten „Autorouter“, welcher die Leiterbahnen im Layout automatisch verlegt,<br />

dieser arbeitet jedoch erst bei 2 Layern effizient. So<strong>mit</strong> wurden in den Layouts alle<br />

Leiterbahnen von „Hand“ verlegt. Dabei war darauf zu achten, dass die Abstände<br />

zwischen 2 Leiterbahnen nicht zu klein wurden und Leiterbahnen, auf welchen viel<br />

Strom fließt, die entsprechende Breite aufwiesen.<br />

4.1.3 Erstellung von Platinen:<br />

Die Platinen wurden über das Belichtungs-Ätzverfahren erstellt, für welches speziell<br />

<strong>mit</strong> Fotolack beschichtete Platinen notwendig sind. Dabei wurde zuerst das fertige<br />

Layout aus Eagle auf eine spezielle Laserdruckerfolie gedruckt und auf die Platinen<br />

aufgelegt, welche dann <strong>mit</strong>tels UV-Licht belichtet wurde. Der Abstand der UV-Röhre<br />

und die Belichtungsdauer waren aus früheren Projekten bekannt. Nach dem<br />

Belichten wurde der Fotolack der Platine in einer Natriumhydroxid Lösung<br />

entwickelt und anschließend in einem Natriumpersulfat Ätzbad das überschüssige<br />

Kupfer entfernt. Abschließend wurden in einer Standbohrmaschine die Löcher für die<br />

Pins der Bauteile gebohrt.<br />

3 Integrated Circuit - Halbleiterbaustein<br />

4 Lagen: Platinenoberseite bzw Platinenunterseite<br />

5 http://cadsoft.de/<br />

6 Abstand der Pins zueinander: Hier 2,54mm<br />

© (2008/2009) 11


4.2 Schrittmotoransteuerung:<br />

Überlegungen:<br />

Um bipolare Schrittmotoren anzusteuern sind spezielle IC Treiber nötig. In diesem<br />

Projekt wurde eine Kombination der ICs L297 und L298 verwendet. Zunächst war<br />

geplant, die Treiber ICs der Schrittmotoren aus dem Drucker auszulöten. Da die<br />

Beschaltung jedoch nicht erprobt war und es keine näheren Referenzen zu diesen ICs<br />

gab, wurde diese Idee verworfen. Der IC L297 ist der eigentliche Schrittmotortreiber,<br />

welcher den Strom an den einzelnen Phasen umkehrt und dafür sorgt, dass die<br />

Schrittreihenfolge eingehalten wird. Der IC L298 ist eine H-Brücke welche eine<br />

höhere Stromstärke liefert als der L297 alleine. Die Schrittmotortreiber sollten beide<br />

auf einer Platine untergebracht werden, was jedoch aufgrund des Platinenlayouts<br />

nicht möglich war. Beim Verlegen der Leiterbahnen wäre es zu vielen<br />

Überschneidungen gekommen, weswegen jeder Schrittmotortreiber auf einer eigenen<br />

Platine untergebracht ist.<br />

Datenblatt L297: http://www.st.com/stonline/products/literature/ds/1334.pdf<br />

Datenblatt L298: http://www.st.com/stonline/products/literature/ds/1773.pdf<br />

Zwischenüberlegungen<br />

Schaltplan:<br />

7 Elektolytkondensator<br />

Zwischendurch wurde überlegt den L298 durch einen L6205 zu ersetzen, da dieser<br />

mehr Strom verträgt und keine externen Dioden benötigt. Doch der Kostenfaktor war<br />

hier ausschlaggebend für die Entscheidung den L298 zu verwenden, welcher alle<br />

Anforderungen erfüllt.<br />

Der Schaltplan der Motorsteuerung wurde zum Großteil aus dem Datenblatt des<br />

L297 übernommen. Es wurde auch im Internet nach Schaltungen gesucht und Ideen<br />

übernommen bzw. abgeändert. Von jeder Platine führt ein 10-Poliger Pfostenstecker<br />

an die Hauptplatine, auf welcher dann gemeinsamen Verbindungen wie die<br />

Strombegrenzung, der Halb-/Vollschrittjumper und die gemeinsamen Anschlüsse<br />

zusammengeführt werden. Um Spannungseinbrüche in der Stromversorgung zu<br />

vermeiden, wurden 4700µF Elkos 7 als Puffer eingeplant.<br />

© (2008/2009) 12


© (2008/2009) 13


Erklärung des Schaltplans:<br />

Über die Klemmen X5 wird die<br />

Stromversorgung der Schrittmotoren<br />

angeschlossen. C3 (Elko) ist zur Pufferung und<br />

Ausgleich des Stroms. C4 (Kondensator) dient<br />

zur Glättung der Spannung.<br />

Das RC Glied bildet den Taktgeber für den IC<br />

L297<br />

Hier sieht man die Freilaufdioden für den L298.<br />

Diese dienen dazu den Strom der Motoren<br />

„abklingen“ zu lassen und eine Zerstörung des<br />

ICs durch Induktion zu verhindern.<br />

R2 und R3 bilden die Shunt 8 Widerstände zum<br />

Messen der aktuellen Stromstärke der<br />

Schrittmotoren.<br />

Über den 10-Poliger Pfostenstecker wird die<br />

Verbindung zu der Hauptplatine hergestellt und<br />

die Schaltung <strong>mit</strong> Spannung versorgt.<br />

8 Niederohmiger Widerstand an welchem der Spannungsabfall gemessen und daraus der fließende Strom errechnet<br />

wird: U = R * I<br />

© (2008/2009) 14


Layout und Erstellung<br />

Probleme:<br />

Bei der Erstellung des Layouts der Motortreiber kam es zu Überkreuzungen der<br />

Leiterbahnen. Diese wurde jedoch <strong>mit</strong>tels Lötbrücken, welche auf der Oberseite der<br />

Platine verlaufen, behoben. In der ersten Version wurde eine Verbindung vergessen.<br />

Da die Platine jedoch aufgrund <strong>eines</strong> Fehlers in der Herstellung noch einmal erstellt<br />

werden musste, wurde diese Verbindung hinzugefügt. Jedoch fehlten auch in der 2.<br />

Version noch zwei Widerstände welche kurzerhand über Lötbrücken auf der fertigen<br />

Platine eingesetzt wurden.<br />

• Bei der ersten Version der Platine wurde das Layout spiegelverkehrt auf die Platine<br />

aufgelegt weswegen diese unbrauchbar wurde und eine zweite Version erstellt<br />

werden musste.<br />

Abbildung 11: Das Platinenlayout, erstellt <strong>mit</strong><br />

Eagle, in der 2. Version<br />

• Durch die hohe Stromaufnahme der Motoren kam es zu einer starken Erhitzung des<br />

© (2008/2009) 15


L298. Hier wurde <strong>mit</strong> einem kleinen Kühlkörper Abhilfe geschaffen, welcher aus<br />

einem alten PC Netzteil entnommen und auf die richtige Größe angepasst wurde.<br />

• Bei einem Test kam es zu einem Kurzschluss. Bei einem Motortreiber kam es zur<br />

Ablösung zweier Leiterbahnen auf der Platine. Diese wurden durch Kabelbrücken<br />

ersetzt.<br />

4.3 Hauptplatine:<br />

Überlegungen:<br />

Schaltplan:<br />

Die Hauptplatine wurde modular geplant, das heißt es ist möglich Erweiterungen<br />

einfach über Stiftleisten anzuschließen. Auf der Hauptplatine wurden die Anschlüsse<br />

der Schrittmotortreiber über je 10-Polige Steckerleisten realisiert. Für die<br />

Schrittmotortreiber wurde ein Spannungsteiler für die Referenzspannung der<br />

Strombegrenzung und ein Jumper für die Halb-/Vollschrittwahl eingeplant. Die<br />

Haupteinheit ist ein Atmega644P <strong>mit</strong> einem 16MHZ Quarz. Zum Programmieren des<br />

<strong>AVR</strong>s ist ein InSystemProgramming Anschluss herausgeführt worden um das<br />

Programmieren in der Schaltung zu ermöglichen. Die Stromversorgung übernimmt<br />

ein L7805 Spannungsregler <strong>mit</strong> Stabilisierungskondensatoren.Dieser wandelt die<br />

Akkuspannung von 9,6V auf die Versorgungsspannung von 5V.<br />

Die Erstellung des Schaltplans stellte kein Problem dar, da die Grundbeschaltung von<br />

8-bit <strong>AVR</strong>s von früheren Projekten bekannt war. Der Schaltplan besteht im Groben<br />

aus 3 Teilen: Der Stromversorgung, dem Mikrocontroller, und den Anschlüssen<br />

sowie Einstellmöglichkeiten der Schrittmotoren.<br />

© (2008/2009) 16


© (2008/2009) 17


Erklärung des Schaltplans:<br />

Der IC 7805T stellt <strong>mit</strong> den 2 Kondensatoren<br />

und dem Elko die Stromversorgung des <strong>AVR</strong><br />

und der anderen ICs dar. Er wandelt die 9,6V<br />

Akkuspannung in 5V um.<br />

Der Potentiometer R2 ist für die<br />

Referenzspannung der Strombegrenzung<br />

verantwortlich. R3 begrenzt die Spannung auf<br />

maximal 3V.<br />

Über den Jumper JP1 wird der<br />

Schrittmodus der Schrittmotoren gewählt<br />

(Halb-/Vollschritt). SV1 und SV2 stellen die<br />

Steckerleisten für den Anschluss der<br />

Motortreiber dar.<br />

Die Kombination von C2, C3 und Q2 bildet die<br />

Taktquelle <strong>eines</strong> 8-bit <strong>AVR</strong> Mikrocontrollers.<br />

Diese ist bei den meisten identisch, die<br />

Taktfrequenz kann jedoch über den Quarz Q2<br />

verändert werden, hier 16MHZ.<br />

Mit SV4 wird die Verbindung zu einem<br />

Seriellen-ISP Programmierinterface hergestellt.<br />

ISP steht für InSystemProgramming. Da<strong>mit</strong> ist<br />

es möglich den <strong>AVR</strong> auf der Platine zu<br />

programmieren.<br />

© (2008/2009) 18


Layout und Erstellung:<br />

Bei der Erstellung des Layouts der Hauptplatine kam es lediglich zu zwei<br />

Überkreuzungen, welche, wie bei den Schrittmotorplatinen auch, über Lötbrücken<br />

behoben wurden. Um alle restlichen Leiterbahnen ohne weitere Überkreuzungen<br />

verlegen zu können, wurden mehrere Bahnen durch IC Pins durchgeführt. Dies<br />

führte bei der Erstellung der Platinen zu Kontakten zwischen den Pins und der<br />

Leiterbahn, welcher jedoch <strong>mit</strong> einem scharfen Messer getrennt wurden. Da kein<br />

externer Anschluss der Versorgungsspannung für Zusatzplatinen geplant war, wurde<br />

dies <strong>mit</strong>tels Lötbrücken nachgeholt.<br />

Abbildung 12: Das Platinenlayout der Hauptplatine. Die Lötbrücken sind hier gut<br />

zu sehen (rot)<br />

© (2008/2009) 19


4.4 Die Sensoren:<br />

Für die Abstandssensoren Sharp GP2D120 ist keine spezielle externe Beschaltung<br />

notwendig. Sie benötigen lediglich 5V und GND und geben über einen Pin den Abstand in<br />

Form einer Spannung zurück, welche zwischen 0,4V (30cm) und 2,8V (4cm) liegt. Um die<br />

Spannungsversorgung des Mikrocontrollers gegen Spannungseinbrüche durch den hohen<br />

Messstrom zu verhindern wurde eine eigene 5V Stromversorgung für die Sensoren erstellt.<br />

Diese besteht, wie auch bei der Hauptplatine, aus einem Spannungsregler L7805, zwei<br />

100nF Kondensatoren und einem 470µF Elko. Für diese Schaltung wurde weder Schaltplan<br />

noch eine Platine erstellt, da es einfacher und schneller war sie auf ein Stück<br />

Lochrasterplatine aufzubauen.<br />

Datenblatt der Sensoren:<br />

http://www.engr.ucsb.edu/~mdnip/me170c/datasheets/SHARPGP2D120.pdf<br />

Der Sensor GP2D120 arbeitet <strong>mit</strong> <strong>Hilfe</strong> der Triangulation. Dabei wird vom Sender ein IR<br />

Lichtstrahl ausgesandt. Je nach Entfernung trifft dieser an unterschiedlichen Stellen beim<br />

Empfänger auf.<br />

Abbildung 13: Das Schema des Infrarot<br />

Entfernungssensor, Quelle: roboternetz.de<br />

© (2008/2009) 20


Das folgende Diagramm, entnommen aus dem Datenblatt des Sharp GP2D120 zeigt die Relation<br />

zwischen Spannung und Entfernung. Es ist zu sehen, dass das Verhältnis nicht linear ist. So<strong>mit</strong> muss<br />

man für das Errechnen der Entfernung eine Formel verwenden, welche sich an die Kurve des<br />

Diagramms annähert. Eine solche Formel findet man im Wissensbereich der Webseite<br />

A<br />

Roboternetz.de: Entferunung=<br />

gemessenerSpannung− B<br />

In der Formel sind A und B Konstanten, welche man durch Testmessungen bestimmen muss.<br />

Dazu wählt man 2 Entfernungen und misst die anliegende Spannung an den Sensoren.<br />

Hierbei wurden die Entfernungen 5cm und 10cm gewählt. Für A und B ergeben sich dann<br />

folgende Formeln:<br />

� X1− X2�⋅D1⋅D2<br />

1) A=<br />

D1− D2<br />

2) B= X2⋅D2−X1⋅D1<br />

D2− D1<br />

Bei der Testmessung wurden die folgenden Werte er<strong>mit</strong>telt. Dabei wurde die Messung für<br />

jeden Sensor einzeln durchgeführt, da es bei der Herstellung der Sensoren vom Hersteller zu<br />

Abweichungen in kommen kann.<br />

© (2008/2009) 21


Wertetabelle:<br />

Sensor Entfernung 1<br />

(D1)<br />

Spannung 1<br />

(X1)<br />

Entfernung 2<br />

(D2)<br />

Spannung 2<br />

(X2)<br />

A B<br />

Vorne Links 5 2,28V 10 1,29V 9,9 0,3<br />

Vorne Rechts 5 2,28V 10 1,28V 9,9 0,3<br />

Seite Vorne 5 2,34V 10 1,29V 10,5 0,24<br />

Seite Hinten 5 2,24V 10 1,19V 10,5 0,14<br />

4.5 Die Funkmodule:<br />

Die Funkmodule HM-T868 und HM-R868 ersetzen zusammen die RS232 Schnittstelle über<br />

Funk. Das Modul HM-T868 ist der Sender. Dieser ist an GND, 5V und an TXD des ersten<br />

UART 9 am Mikrocontroller angeschlossen. HM-R868, der Empfänger ist an GND, 5V, RXD<br />

und noch zusätzlich an einem freien Pin angeschlossen, um den Empfänger während des<br />

Sendens abschalten zu können. Die Module besitzen eine Stiftleiste und so<strong>mit</strong> mussten nur<br />

entsprechende Kabel zu den jeweiligen Pins gelötet werden. Die Anschlussbelegung wurde<br />

dem Datenblatt entnommen:<br />

http://www.hoperf.com/pdf/HM-T_EN.pdf<br />

http://www.hoperf.com/pdf/HM-R_EN.pdf<br />

9 Universal Synchronous and Asynchronous serial Receiver and Trans<strong>mit</strong>ter<br />

© (2008/2009) 22


5.1 Allgemein:<br />

5. Die Programmierung<br />

Die Programmierung des Mikrocontrollers erfolgte in der Programmier-Hochsprache C. Als<br />

Programmieroberfläche wurde anfangs das <strong>AVR</strong> Studio verwendet, welches die Firma Atmel<br />

kostenlos auf ihrer Webseite 10 anbietet. Das <strong>AVR</strong> Studio beinhaltet einen Simulator, um vor<br />

der Programmierung des Mikrocontroller den Code testen zu können. Des weiteren bietet es<br />

die direkte Programmiermöglichkeiten des <strong>AVR</strong>s <strong>mit</strong> spezieller Hardware. Da diese<br />

Hardware in diesem Projekt fehlte, wurde der Mikrocontroller über das Programm PonyProg<br />

programmiert. Diese unterstützt „minimal Programmieradapter“ welche aus wenigen<br />

Bauteilen bestehen. PonyProg ist ebenfalls kostenlos und kann auf der Webseite des<br />

Herstellers Lancos 11 bezogen werden. Im späteren Teil der Programmierung wurde <strong>mit</strong><br />

Eclipse 12 inklusive dem dafür notwendigen <strong>AVR</strong> Plugin 13 gearbeitet. Da für Mikrocontroller<br />

ein eigener C Compiler notwendig ist, wurde zusätzlich Win<strong>AVR</strong> 14 installiert. Dies ist ein<br />

Komplettpaket welches den Compiler und zusätzliche Tools beinhaltet. Mit diesen<br />

Komponenten ist es möglich fast jeden <strong>AVR</strong> Mikrocontroller zu programmieren.<br />

5.2 Der Atmega:<br />

Der Atmega644P verfügt über einige Funktionen und Eigenschaften:<br />

• 64kByte Flash Programmspeicher, 2kByte EEPROM, 4kByte SRAM<br />

• bis zu 20MIPS (20 Millionen Instruktionen pro Sekunde)<br />

• JTAG On Chip Debug Interface, InSystemProgramming (ISP)<br />

• 3 Timer (2x 8bit; 1x 16bit), 6 PWM Kanäle, RealTimeClock<br />

• 10-bit AD-Wandler (Analog-Digital)<br />

• 2 USART Schnittstellen, Two-Wire Interface, SPI-Interface<br />

• uvm...<br />

Für dieses Projekt verwenden wir nur die Leistung von 16MIPS (16MHZ). Eine wichtige<br />

Funktion ist der Analog-Digitalwandler, welcher die Spannungen der Sensoren in digitale<br />

Werte umwandelt. Ein USART wird für die Funkverbindung zum PC verwendet. Das<br />

InSystemProgramming Interface erlaubt es, den <strong>AVR</strong> auf der Hauptplatine zu<br />

programmieren.<br />

10 http://www.atmel.com/dyn/products/tools.asp?family_id=607#798<br />

11 http://www.lancos.com/prog.html<br />

12 http://www.eclipse.org/<br />

13 http://sourceforge.net/projects/avr-eclipse/<br />

14 http://winavr.sourceforge.net/<br />

© (2008/2009) 23


5.3 Die Fusebits:<br />

Ein <strong>AVR</strong> Mikrocontroller besitzt sogenannte Fusebits. Mit ihnen können Features aktiviert<br />

und deaktiviert werden, die Frequenz des Quarzes eingestellt werden oder der Code gegen<br />

auslesen gesichert werden. Mit Setzen dieser Fusebits kann man den Mikrocontroller jedoch<br />

auch unbrauchbar machen. Für dieses Projekt musste die Debugschnittstelle JTAG<br />

deaktiviert werden, die Frequenz auf 16MHZ extern gesetzt werden, und der Bootloader<br />

aktiviert werden.<br />

5.4 Der Bootloader:<br />

Der ausgesuchte Mikrocontroller bietet 64kBytes Flash Speicher für das Programm. Durch<br />

diesen großen Speicher dauert jedoch auch das Programmieren über die<br />

InSystemProgramming Schnittstelle sehr lange, weswegen eine besondere Eigenschaft des<br />

<strong>AVR</strong>s genutzt wurde. Viele <strong>AVR</strong>-Mikrocontroller sind in der Lage sich selbst neu zu<br />

programmieren. Dazu wird einfach das Programm in einen Speicherteil übertragen, welcher<br />

nicht programmiert werden kann. Anschließend programmiert sich der <strong>AVR</strong> neu.<br />

Ein Bootloader ist nun ein Programm, welches beim Initialisieren des <strong>AVR</strong>s ausgeführt wird,<br />

über die serielle Schnittstelle das neue Programm überträgt und den <strong>AVR</strong> neu programmiert.<br />

In diesem Projekt wurde auf einen fertigen Bootloader zurückgegriffen, da das<br />

Programmieren <strong>eines</strong> Bootloaders eine komplexe Aufgabe ist. Der Bootloader besteht aus 2<br />

Teilen, einem Programm auf dem <strong>AVR</strong>, welches beim Initialisieren ausgeführt wird, und<br />

einem Gegenstück auf dem PC, welches dem Programm auf dem <strong>AVR</strong> das zu<br />

programmierende Programm sendet. Der Bootloader wurde aus der Codesammlung <strong>eines</strong><br />

Forums entnommen (http://www.mikrocontroller.net/topic/73196). Bei diesem Bootloader<br />

ist es möglich die Pins, über welche der <strong>AVR</strong> <strong>mit</strong> dem PC kommuniziert, beliebig<br />

festzulegen. Dies macht es möglich, die InSystemProgramming Schnittstelle auch für den<br />

Bootloader zu verwenden. So<strong>mit</strong> ist kein eigener Stecker nötig. Für den Bootloader wurde<br />

ein kl<strong>eines</strong> Kabel gebaut, welches eine 9-polige Sub-D Buchse für den ComPort des PCs<br />

besitzt und einen 10-poligen Pfostenstecker für den ISP Anschluss, welcher nun als<br />

„Bootloader Anschluss“ verwendet wurde. Da der ComPort <strong>mit</strong> +-12V als Signal arbeitet,<br />

der <strong>AVR</strong> jedoch nur <strong>mit</strong> 5V, wurde in das Kabel ein MAX232 Schnittstellentreiber<br />

eingebaut.<br />

© (2008/2009) 24


5.5 Der Erste Test:<br />

Nachdem alle Kabelverbindung verlegt waren, wurde der Mikrocontroller zum ersten Mal<br />

programmiert. Zum ersten Test wurde nur eine einfache Ansteuerung der Schrittmotoren<br />

verwirklicht, welche die Motoren einfach in eine Richtung drehen lässt. Hierzu muss man<br />

sich auf das Datenblatt des L297 beziehen. Hier eine kleine Übersicht der Pins des L297 und<br />

deren Bedeutungen:<br />

Name Pin an L297 Pin an <strong>AVR</strong> Bedeutung<br />

CW/CCW 17 Motor1: PC1<br />

Motor2: PC2<br />

Clock 18 Motor1: PD4<br />

Motor2: PD5<br />

Enable 10 Motor1: PC0<br />

Motor2: PC0<br />

VRef 15 Potentiomete<br />

r auf der<br />

Hauptplatine<br />

Half/Full 19 Jumper auf<br />

Hauptplatine<br />

Mit diesem Pin wird die Richtung des Motors bestimmt.<br />

Durch einen Flanke von Low auf High auf diesem Pin<br />

führt der Motor einen Schritt aus<br />

Mit diesem Pin wird der Motorstrom ein- (Pin auf High)<br />

oder ausgeschaltet (Pin auf Low)<br />

Mit dem Trimmer auf der Hauptplatine kann eine<br />

Referenzspannung eingestellt werden, welche der<br />

Strombegrenzung gleich ist (Hier 0,7V → 0,7A<br />

Strombegrenzung pro Motor)<br />

Mit diesem Jumper kann zwischen Halb- und<br />

Vollschrittbetrieb der Motoren gewechselt werden<br />

Um die Motoren nun um eine Umdrehung in eine Richtung drehen zu können, muss zuerst<br />

Enable auf High, dann die Richtung der beiden Motoren gesetzt werden und schließlich 200<br />

Impulse an Clock angelegt werden. Da die Motoren entgegengesetzt eingebaut sind, müssen<br />

die Richtungspins jeweils den gegenteiligen Zustand haben um gerade aus zu fahren. Das<br />

Programm im Folgenden <strong>mit</strong> Kommentaren zu jeder Programmzeile:<br />

© (2008/2009) 25


#define F_CPU 16000000UL //Die CPU Frequenz wird als 16MHZ definiert<br />

#include //Die <strong>AVR</strong> Bibliothek wird eingebunden<br />

#include //Eine delay Bibliothek wird eingebunden<br />

int main()<br />

{<br />

uint16_t i; //i wird als Integer ohne Vorzeichen definiert<br />

DDRC=0xFF; //Die Pins des Port C werden als Ausgang definiert<br />

DDRD=0xFF; //Die Pins des Port D werden als Ausgang definiert<br />

PORTD=0x00; //Die Pins des Port D werden alle auf LOW gesetzt<br />

PORTC|=(1


Die „myLib.h“ Header Datei beinhaltet alle notwendigen Definitionen für die „myLib.c“<br />

Datei, welche die Programmierung übersichtlicher machen. Zum Beispiel steht nun in der<br />

„myLib.c“ Datei für „LEFT“ die Zahl 2 oder für FWD die Zahl 0 usw.<br />

5.7 Die Funktionen der „myLib“ :<br />

init(void):<br />

In der Funktion init werden die Ports des Atmega644P konfiguriert. Die ADC Ports werden<br />

als Eingänge gesetzt und die Ports zur Steuerung der Schrittmotoren als Ausgänge.<br />

Desweiteren wird ein Timer gestartet welcher für verschiedene Funktionen, dazu mehr in der<br />

jeweiligen Funktion, verwendet wird. Auch werden die globalen Interrupts aktiviert.<br />

funk_init(void):<br />

Die funk_init Funktion initialisiert die Funkmodule. Zur Zeit wird jedoch nur das<br />

Sendemodul verwendet, da das Empfangsmodul viel „Funkmüll“, das heißt unbrauchbare<br />

Zeichen, empfängt. Da es für die eigentliche Funktion des Roboters nicht von Nöten ist,<br />

wird dieses eventuell später einmal eingebunden. Zuerst wird ein FIFO 15 Buffer initialisiert,<br />

welcher sich hinter den Dateien „fifo.h“ und „fifo.c“ verbirgt und komplett selbst<br />

programmiert ist. Dann werden die Register des USART gesetzt und dieser aktiviert. Die<br />

Baudrate beträgt 9600baud. Aufgrund der Funkmodule ist es notwendig in gewissen<br />

Zeitabständen ein Byte zum PC zu senden, um die Funkverbindung zu erhalten. Aus diesem<br />

Grund wird der Timer, welcher in der init() Funktion angesprochen wurde, verwendet. Da<br />

dies über Interrupts geschieht, bleibt in der Zwischenzeit genug Zeit für die anderen<br />

Rechenoperationen.<br />

getCharArray( unsigned short number, unsigned char *numchar, unsigned char length)<br />

Mit der Funktion getCharArray werden Ganzzahlige Nummern (unsigned short number)<br />

in ein Char Array (unsigned char *numchar) umgewandelt, um diese über Funk zu<br />

versenden. Dabei wird die Länge der Zahl über unsigned char length übergeben, welche<br />

wiederum meist über die Funktion unsigned char getNumberLength er<strong>mit</strong>telt wird. Da<br />

unsigned char *numchar nur ein Zeiger auf ein Char Array ist, erfolgt in diesem Array die<br />

Rückgabe.<br />

15 First In First Out - Ringbuffer<br />

© (2008/2009) 27


unsigned char getNumberLength( unsigned short number)<br />

Die Funktion getNumberLength er<strong>mit</strong>telt, wie bereits oben erwähnt, die Länge einer Zahl<br />

und gibt diese als unsigned char zurück.<br />

double<br />

getSensor( unsigned char sensor)<br />

Diese Funktion ist für die Er<strong>mit</strong>tlung der Entfernung <strong>eines</strong> Sensors zuständig. Welcher<br />

Sensor gemessen werden soll wird über unsigned char sensor übergeben. In ihr wird<br />

zunächst der ADC 16 eingestellt und eine „Dummymessungen“ durchgeführt. Diese wird<br />

nicht berücksichtigt da meist die ersten Werte einer AnalogDigital Wandlung große<br />

Differenzen aufweisen. Danach werden 4 Messungen aufaddiert und durch<br />

Rechtsverschiebung durch 4 geteilt, um einen Durchschnittswert zu errechnen. Mithilfe der<br />

Formel aus Kapitel 4.4 wird nun für jeden Sensor einzeln die Entfernung errechnet. Die<br />

Entfernung wird schließlich als Gleitkommazahl zurückgegeben.<br />

double<br />

getWinkel( unsigned char dir)<br />

Mit der Funktion getWinkel lässt sich der Winkel zwischen den 2 vorderen oder 2 seitlichen<br />

Entfernungssensoren berechnen. Welche 2 Sensoren gewählt sind, wird <strong>mit</strong>tels unsigned<br />

char dir übergeben. Die Berechnung geschieht über den Arcus Tangens: �=atan� �d<br />

b � ,<br />

wobei �d gleich die Differenz der Entfernung beider Sensoren, und b gleich der Abstand<br />

beider Sensoren zueinander ist. Bei den vorderen Sensoren beträgt b=10cm und bei den<br />

seitlichen b=9cm. Da C in Bogenmaß arbeitet, wird muss noch in Grad umgerechnet<br />

werden. Der Rückgabewert ist eine Gleitkommazahl, welche auch negative Werte annehmen<br />

kann. Negative Werte werden dann benötigt, wenn �d negativ ist. Dies kann eintreten, da<br />

�d = vorneLinks<br />

vorneRechts<br />

16 Analog Digital Converter<br />

ist. Bei einem Winkel kleiner 90° wird �d dann negativ.<br />

© (2008/2009) 28


Abbildung 15: Winkel < 90° Abbildung 14: Winkel > 90°<br />

void setMotoren( unsigned char Status)<br />

Die Funktion setMotoren schaltet den Haltestrom der Schrittmotoren An/Aus. Der<br />

gewünschte Zustand wird über unsigned char Status übergeben.<br />

unsigned short setParallel()<br />

Mit dieser Funktion ist es möglich, den Roboter, wenn er vor einer Wand steht, zu dieser<br />

parallel auszurichten. Hierzu wird zunächst der Winkel der vorderen Sensoren zur Wand<br />

er<strong>mit</strong>telt, um diesen gedreht und <strong>mit</strong> <strong>Hilfe</strong> der seitlichen Sensoren korrigiert der Roboter<br />

seine Ungenauigkeiten der ersten Drehung. Die erste Drehung um den Winkel der vorderen<br />

Sensoren geschieht immer nach links, da nur rechts seitliche Sensoren angebracht sind. Bei<br />

der zweiten Drehung findet eine Unterscheidung statt, welche zwischen positiven und<br />

negativen Winkel unterscheidet (siehe Funktion getWinkel).<br />

void doCreateOutlineMap()<br />

Wird diese Funktion aufgerufen, erstellt der Roboter eine Karte der Außenwände und schickt<br />

diese an den PC. In dieser Funktion wird fast ausschließlich auf die externen Funktionen<br />

zurückgegriffen. Der Roboter kann an einem beliebigen Punkt im Raum starten. Er sucht<br />

sich dann zunächst eine Wand, an welcher er sich parallel ausrichtet. Dann fährt er zur<br />

nächsten Wand. An dieser Wand wird er zwangsweise am Anfang ankommen, weswegen er<br />

sich zunächst parallel ausrichtet und erst danach <strong>mit</strong> der eigentlichen Kartographie beginnt.<br />

In einer Schleife fährt er nun immer zur nächsten Wand und misst die Strecke. Diese schickt<br />

er dann per Funk zum PC und richtet sich parallel zur neuen Wand aus. Auch den gedrehten<br />

Winkel über<strong>mit</strong>telt er per Funk an den PC. Dies wird so lange wiederholt, bis er sich<br />

© (2008/2009) 29


insgesamt um die Winkelsumme in dem Polygonzug gedreht hat. Zum Beispiel: Dreieck:<br />

180°; Viereck: 360°; Fünfeck: 540°.. Diese Winkelsumme muss immer im Programm<br />

geändert werden.<br />

void<br />

doSendChar( unsigned char zeichen)<br />

Mit dieser Funktion wird ein Zeichen über Funk an den PC übertragen. Dazu wird das<br />

Zeichen in den FIFO Buffer geladen. Über den Timer, welcher in der Funktion init()<br />

gestartet wurde, wird in regelmäßigen Abständen geprüft, ob sich ein Zeichen im FIFO<br />

befindet und dieses gesendet.<br />

void<br />

doSendNumber( unsigned short number, unsigned char length)<br />

Die Funktion doSendNumber sendet eine Zahl über Funk an den PC. Dazu wird die Zahl<br />

über getCharArray in Zeichen umgewandelt und über doSendChar einzeln versendet.<br />

double<br />

doSearchWall( unsigned short distance, unsigned char checkAngle)<br />

Wird diese Funktion aufgerufen fährt der Roboter solange bis er auf eine Wand trifft. Dabei<br />

hält er bei einer Distanz an, welche man <strong>mit</strong> unsigned short distance übergibt. In einer<br />

Schleife fährt der Roboter immer wieder 3cm vorwärts, bis er eine Distanz von dem<br />

übergebenen Wert + 10 unterschritten hat. Danach hält er kurz an, misst über die Sensoren<br />

die geringste Entfernung zur Wand, zieht davon die gewünschte Distanz zur Wand ab und<br />

fährt die Differenz vorwärts, sodass er genau in der übergebenen Distanz vor der Wand steht.<br />

Wird über unsigned char checkAngle eine 1 übergeben testet der Roboter alle 3cm über die<br />

seitlichen Sensoren, ob er noch parallel zur Wand steht und korrigiert falls dies nicht der Fall<br />

ist. Die Strecke, die er bis dahin gefahren ist, gibt er als Fließkommazahl zurück.<br />

void<br />

doSleep( unsigned short time)<br />

Die Funktione doSleep versetzt den Roboter in einen kurzen „Schlaf“. Die Zeit, die gewartet<br />

werden soll, wird in Millisekunden über unsigned short time übergeben. Auch für diese<br />

Funktion wird der in der init Funktion gestartete Timer verwendet. Dieser ist genau so<br />

eingestellt, dass genau jede Millisekunde ein Interrupt ausgelöst wird.<br />

© (2008/2009) 30


void doSteps( unsigned char dir, unsigned short anzahl)<br />

Durch diese Funktion kann der Roboter vorwärts und rückwärts fahren, oder sich auf der<br />

Stelle nach links oder rechts drehen. Dies funktioniert theoretisch wie im ersten Versuch<br />

(Kap 5.5). Wird ein Impuls ausgegeben, drehen die Räder um einen Schritt bzw. 1,8°. Da die<br />

Räder einen entsprechenden Radius besitzen, entspricht ein Schritt 0,1cm. In der Funktion<br />

werden je nach übergebener Richtung durch unsigned char dir die Pins am Motortreiber<br />

gesetzt bzw. gelöscht. Dann wird ein weiterer Timer gestartet, welcher den Puls regelt und<br />

dafür sorgt, dass die Motoren sich um einen Schritt drehen bis die gewünschte Anzahl<br />

erreicht ist.<br />

void<br />

doTurn( double alpha, unsigned char dir)<br />

Mithilfe dieser Funktion ist es dem Roboter möglich, sich einen bestimmten Winkel um sich<br />

selbst zu drehen. Für diese Funktion ist der Abstand beider Räder zueinander von<br />

Bedeutung. Mit einer Schieblehre wurden 125,5mm gemessen von welchen noch 10mm<br />

aufgrund der Breite beider Räder abgezogen werden. Der Umfang beträgt dann<br />

U =�⋅d =361,91mm<br />

Für einen Teilwinkel gilt: U �= �⋅d⋅�<br />

360<br />

Teilt man nun noch durch den Weg, welcher ein Rad pro Schritt zurücklegt, hat man die<br />

Anzahl der benötigten Schritte.<br />

�⋅d⋅�<br />

Schritte=<br />

WegproSchritt⋅360<br />

Fasst man alle Konstanten zusammen, muss man nur den Winkel � <strong>mit</strong> einer einzigen<br />

Konstante multiplizieren. Die Funktion berechnet also die Anzahl der Schritte und ruft die<br />

Funktion doSteps auf.<br />

5.8 Die Funktion von fifo:<br />

Wie auch in der myLib.h stehen in der fifo.h Datei wieder nur Definitionen und Prototypen.<br />

Die Dateien „fifo.c“ und „fifo.h“ beinhalten den FIFO Buffer. In der „fifo.h“ befindet sich<br />

eine Typendefinition welche den Typ fifoBuffer definiert. Hinter dem fifoBuffer verbirgt<br />

sich ein Char Array, ein Leseindex und ein Schreibindex:<br />

typedef struct{<br />

unsigned char data[FIFO_BUFFER_SIZE+1];<br />

unsigned char readindex;<br />

unsigned char writeindex;<br />

}fifoBuffer;<br />

© (2008/2009) 31


void fifo_init( fifoBuffer *f)<br />

Bei Aufruf dieser Funktion wird der übergebene FIFO, fifoBuffer *, initialisiert. Das heißt<br />

Lese- und Schreibindex werden auf 0 gesetzt.<br />

unsigned char<br />

fifo_add( fifoBuffer *f, unsigned char fdata)<br />

Mit dieser Funktion wird ein Char, unsigned char fdata, dem FIFO, fifoBuffer *f,<br />

hinzugefügt. Dabei wird gleichzeitig der Schreibindex um eins erhöht. Ist der FIFO voll,<br />

gibt die Funktion eine 0 zurück, andernfalls eine 1.<br />

unsigned char<br />

fifo_read( fifoBuffer *f, unsigned char *readByte)<br />

Diese Funktion dient dem Auslesen <strong>eines</strong> Char aus dem FIFO fifoBuffer *f. Das<br />

ausgelesene Char wird durch das übergebenen unsigned char *readByte zurückgegeben.<br />

In der Funktion wird desweiteren der Leseindex erhöht. Bei einem leeren FIFO gibt die<br />

Funktion eine 0 zurück. Befinden sich jedoch noch Daten im FIFO gibt sie eine 1 zurück.<br />

unsigned char<br />

fifo_test( fifoBuffer *f)<br />

Mit dieser Funktion lässt sich überprüfen, ob der FIFO fifoBuffer *f noch Daten beinhaltet<br />

oder leer ist. Befinden sich noch Daten im FIFO gibt diese Funktion eine 1, andernfalls eine<br />

0 zurück.<br />

5.9 Der PC als Empfänger:<br />

In diesem Projekt dient der PC als Empfänger der Daten des Roboters. An den PC sind die<br />

selben Funkmodule wie auf dem Roboter an die Serielle Schnittstelle angeschlossen. Über<br />

ein Programm kann der PC dann die Informationen über Weg und Winkel, welche er vom<br />

Roboter erhält, in eine Karte umwandeln. Alle benötigten Informationen erhält der PC über<br />

eine speziell kodierte Zeichenkette vom Roboter welche wie Folgt aussehen kann:<br />

„D549A87D683A69D429A90“<br />

Durch den Buchstabe „D“ weiß der PC dass die darauf folgenden Zahlen die Distanz<br />

angeben, welche der Roboter zurückgelegt hat bis er auf eine Wand gestoßen ist. Das „A“<br />

sagt dem PC, um welchen Winkel sich der Roboter danach gedreht hat, um wieder parallel<br />

zur nächsten Wand zu stehen.<br />

Dem PC ist es nun möglich diese Daten über die Winkelfunktionen in Linien umzuwandeln<br />

und auf dem Bildschirm auszugeben. Das Programm <strong>mit</strong> dem dies alles geschieht ist<br />

© (2008/2009) 32


ebenfalls eine Eigenentwicklung und wurde in Visual Basic 6 geschrieben, da der zugriff auf<br />

die serielle Schnittstelle hier sehr einfach zu Handhaben ist. Da es, wie schon oben<br />

beschrieben, bei den Empfangsmodulen zu sehr viel Störungen kommt, sortiert das<br />

Programm direkt alle Zeichen aus, welche nicht „D“,“A“ oder eine Zahl sind. Wenn die<br />

Zeichenkette komplett übertragen wurde, spaltet das Programm die Zeichenkette so, dass sie<br />

die einzelnen Zahlen auslesen kann. Die Berechnung für die neuen Koordinaten sie wie<br />

Folgt aus:<br />

GesamtWinkel=Gesamtwinkel−�180− Angle�<br />

Hierbei ist Angle der Winkel der aktuell gedreht wurde. Dieser wird von 180 subtrahiert, da<br />

der Roboter den Innenwinkel misst, für die Berechnungen <strong>mit</strong> Sinus und Cosinus aber der<br />

Außenwinkel benötigt wird. Dieser Winkel wird von GesamtWinkel, einer Variablen die den<br />

insgesamt gedrehten Winkel speichert, abgezogen.<br />

X neu=cos� GesamtWinkel⋅2⋅�<br />

�⋅distance� X alt<br />

360<br />

Die neue X-Koordinate wird über den Cosinus des Gesamtwinkels errechnet. Hierbei muss,<br />

wie in C auch, der Winkel in das Bogenmaß umgerechnet werden. Distance steht hier für die<br />

Hypothenuse, so<strong>mit</strong> lässt sich also durch cos���∗Hypothenuse die Gegenkathete, also<br />

die „Höhe“ des Dreiecks berechnen. Dieser Punkt muss dann um den aktuellen X-Wert<br />

verschoben um den neue X-Wert zu erhalten.<br />

© (2008/2009) 33


Der Y-Wert lässt sich über den Sinus berechnen:<br />

sin���= Gegenkathete<br />

Hypothenuse<br />

yneu =sin � gesamtWinkel⋅2⋅�<br />

�⋅distance� yalt 360<br />

Start: Startet den Funkempfang<br />

Stop: Beendet den Funkempfang<br />

Print Map: Zeichnet Karte<br />

Clear Map: Löscht Karte<br />

=> Gegenkathete=Hypothenuse⋅sin ���<br />

© (2008/2009) 34


6. Fazit – Ausblick<br />

Da der Zeitraum der Besonderen Lernleistung nach einem Schuljahr nun zu Ende ist, möchte ich<br />

noch ein paar Abschließende Worte schreiben. Aus der Idee, einen Roboter sich in einem<br />

unbekannten Raum zu orientieren zu können, ist eine Projektarbeit entstanden, welche viel Nerven,<br />

Arbeit und auch Geld kostete. Nichts desto trotz war diese Arbeit sehr lehrreich und hat viel Spaß<br />

gemacht. Eine Idee zu realisieren bedarf viel Zeit und Überlegungen. Die erste Phase, der<br />

Erstellung der mechanischen Komponenten, welche sehr schnell abgeschlossen wurde, folgte die<br />

zweite Phase der elektrischen Komponenten. Hier gab es hin und wieder einige Rückschläge,<br />

welche das Budget in die Höhe trieben und mich manchmal zur Verzweiflung brachten, doch<br />

wurden diese letztendlich auch alle überwunden. Dank vieler Vorprojekte brachte auch die<br />

Programmierung, trotz mehrerer schlafloser Nächte, viel Spaß <strong>mit</strong> sich. Letztendlich reagiert der<br />

Roboter, welcher HMMR getauft wurde, wie gedacht, arbeitet zuverlässig und erstellt<br />

reproduzierbare Karten von ihm unbekannten Räumen. Sicherlich sind diese Karten noch <strong>mit</strong><br />

Ungenauigkeiten behaftet, welche sich jedoch in einem angemessenem Rahmen bewegen. Mit<br />

einem vielfach höheren Budget ist es natürlich möglich diese Ungenauigkeiten so zu minimieren,<br />

dass sie keine Rolle mehr spielen. Da es sich hierbei jedoch um ein Schulprojekt und nicht um eine<br />

Forschungsarbeit an einer Universität handelt bin ich <strong>mit</strong> den Ergebnissen überaus zufrieden. Leider<br />

konnten nicht alle Überlegungen oder Ziele in die Realität umgesetzt werden, da die Zeit gegen<br />

Ende doch knapper wurde als anfangs vermutet. So ist zum Beispiel die Kartographie von<br />

Hindernissen im Raum nicht verwirklicht. Auch kann der Roboter keine Winkel über 180° messen,<br />

was jedoch nur durch die bisherige Firmware beschränkt ist, da die Hardware, die zwei seitlichen<br />

Infrarotsensoren, vorhanden ist. Ebenfalls nicht realisiert ist die Kommunikation von PC zum<br />

Roboter, da die Funkmodule sehr viele unbrauchbare Daten empfangen. Dies ließe sich jedoch über<br />

verschiedene Verfahren in den Griff bekommen. Am Ende kam auch noch die Idee auf, die<br />

Ungenauigkeiten <strong>mit</strong>tels mehreren Kartographie-Durchgängen zu minimieren. Hierbei fährt der<br />

Roboter den Raum mehrfach ab und errechnet den Durchschnittswert aller Durchgänge.<br />

Auch in der Endphase des Projekts konnte ich viele neue Erfahrungen machen. Zum Beispiel habe<br />

ich mein Projekt in der Projektwoche der Schule drei Studenten der Hochschule Karlsruhe<br />

präsentieren können. Auch an dem Projekttag der Schule konnte ich meine Vortagsweise bei den<br />

Vorführungen im Projekt von Herr Roth, welche gut besucht waren, trainieren. Auch nach<br />

Abschluss dieser Besonderen Lernleistung werde ich mich weiter an dem Roboter versuchen und<br />

die Programmierung ausbauen um die besagten Ziele eventuell doch noch realisieren zu können.<br />

© (2008/2009) 35


6.1 Quellenverzeichnis:<br />

7. Anhang<br />

Robotikforum und Wissensbereich: http://www.roboternetz.de<br />

Elektronikforum und Wissensbereich: http://www.mikrocontroller.net<br />

Bezugsquelle der Schrittmotoren: http://www.mir-eletronik.de<br />

Bezugsquelle der Sensoren http://www.roboter-teile.de<br />

Software Eagle http://www.cadsoft.de<br />

Software PonyProg http://www.lancos.com<br />

Software <strong>AVR</strong> Studio http://www.atmel.de<br />

Software Eclipse-IDE http://www.eclipse.org/<br />

<strong>AVR</strong>-Plugin für Eclipse http://avr-eclipse.sourceforge.net<br />

Softwarepaket Win<strong>AVR</strong> http://winavr.sourceforge.net/<br />

6.2 Inhaltsverzeichnis der CD:<br />

• Präsentationsfilm<br />

• Dokumentation in digitaler Form<br />

• Diashow<br />

• Filme<br />

• Bilder<br />

• PC Software<br />

• Firmware Sourcecode<br />

• Bootloader Sourcecode<br />

• PC Software Sourcecode<br />

• Datenblätter aller ICs und Sensoren

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!