Inhaltsverzeichnis - ADAM - Leonardo da Vinci Projects and

Inhaltsverzeichnis - ADAM - Leonardo da Vinci Projects and
Inhaltsverzeichnis
1
Einleitung
5
2
Mikrocontroller und Robotik
9
3
AVR Mikrocontroller
3.1
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3.9
3.10
4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Ohm’sches Gesetz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Berechnung des LED-Widerstands . . . . . . . . . . . . . . . . . . . 53
Spannungsteiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
57
Robotic HomeLab Kit
5.1
5.2
5.3
5.4
14
17
27
31
33
35
37
39
41
47
51
Elektronik
4.1
4.2
4.3
5
Einführung . . . . . . . . . . .
Register . . . . . . . . . . . . .
Architektur . . . . . . . . . . .
Taktgeber . . . . . . . . . . . .
Interrupts . . . . . . . . . . .
Digitale Inputs/Outputs . . .
Externe Interrupts . . . . . . .
Analog-zu-Digital Konverter
Counters/Timers . . . . . . .
USART . . . . . . . . . . . . .
13
Ganzheitliches Konzept der Robotik
Robotik unterrichten . . . . . . . . .
HomeLab Hardware . . . . . . . . .
HomeLab Bibliothek . . . . . . . . .
5.4.1 Bitweise Operationen . . . .
5.4.2 Pins . . . . . . . . . . . . . . .
5.4.3 Analog-Digital-Wandler . . .
5.4.4 Serielles Interface . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
59
61
67
71
73
76
79
81
Inhaltsverzeichnis
5.4.5
5.4.6
5.4.7
5.4.8
5.4.9
5.4.10
5.4.11
6
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6.2
6.3
6.4
6.5
6.6
Anfang . . . . . . . . . . . . . . . . . . . . . .
6.1.1 Installationsanweisung für Windows
6.1.2 Die Softwareumgebung für Linux . .
Digitale Input/Output Pins . . . . . . . . . .
6.2.1 Light-emitting Diode (LED) . . . . . .
6.2.2 Schalter . . . . . . . . . . . . . . . . .
6.2.3 Vermeidung von Kontaktprellung . .
Timer und Verzögerungen . . . . . . . . . . .
6.3.1 Softwareverzögerungen . . . . . . . .
6.3.2 Hardwareverzögerung . . . . . . . . .
6.3.3 Periodische Interrupts . . . . . . . . .
6.3.4 Aufgaben . . . . . . . . . . . . . . . .
Anzeigen und Displays . . . . . . . . . . . . .
6.4.1 7-Segment-LED-Anzeige . . . . . . . .
6.4.2 Alphanumerisches LCD . . . . . . . .
6.4.3 Graphisches LCD . . . . . . . . . . . .
6.4.4 Aufgaben . . . . . . . . . . . . . . . .
Sensoren . . . . . . . . . . . . . . . . . . . . .
6.5.1 Potentiometer . . . . . . . . . . . . . .
6.5.2 Thermistor . . . . . . . . . . . . . . . .
6.5.3 Fotowiderstand . . . . . . . . . . . . .
6.5.4 Infrarot-Entfernungsmesser . . . . . .
6.5.5 Ultraschall-Entfernungsmesser . . . .
6.5.6 Übungen . . . . . . . . . . . . . . . . .
Motoren . . . . . . . . . . . . . . . . . . . . .
6.6.1 Gleichstrommotor . . . . . . . . . . .
6.6.2 Servomotor . . . . . . . . . . . . . . .
6.6.3 Schrittmotor . . . . . . . . . . . . . . .
85
94
96
97
99
101
103
107
Praktische Beispiele
6.1
2
Timer . . . . . . . . . . .
Verzögerung . . . . . . .
7-Segment LED Display
Alphanumerisches LCD
Graphisches LCD . . . .
Sensoren . . . . . . . . .
Motoren . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
109
110
124
136
137
143
146
153
154
157
160
163
165
166
170
173
175
177
178
182
186
192
198
203
205
205
210
215
Inhaltsverzeichnis
6.7
7
Beispielprojekt
7.1
7.2
8
6.6.4 Aufgaben .
6.6.5 Fragen . . .
Datenschnittstellen
6.7.1 RS-232 . . .
6.7.2 ZigBee . . .
6.7.3 Aufgabe . .
6.7.4 Fragen . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
219
221
222
223
227
227
228
229
Bericht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Mobile Roboterplattform . . . . . . . . . . . . . . . . . . . . . . . . . 231
Ausblick
247
3
1
Einleitung
Dieses Buch wurde als praktisches Handbuch für Mikorcontroller und Robotik
konzipiert, in der Hoffnung, dem Leser bei der Entwicklung von „smarten“Lösungen
zu helfen. Darüber hinaus soll es auch dazu beitragen, die Begeisterung für den
Ingenieurberuf bei jungen Menschen zu wecken. In erster Linie richtet sich das
Buch an Schulen sowie Universitäten, aber auch an Bastler und Unternehmen,
die im Rahmen von Projekten mit AVR Mikrocontrollern arbeiten möchten.
Ziel ist es, sowohl Lehrende als auch Lernende dabei zu unterstützen, rasch Ergebnisse zu erzielen: so soll Schülern und Studenten neues Wissen vermittelt
und das Leben der Lehrenden erleichtert werden.
Plattform
Für die praktischen Beispiele in diesem Buch wird ein AVR ATmega128 Mikrocontrollersystem,das sogenannte HomeLab Kit, als grundlegende Plattform genutzt. Die AVR Mikrocontroller sind, neben Microchip PIC, die am weitesten
verbreiteten in der Hobby-Robotik-Community. Darüber hinaus sind siebesonders gut für Lehrzwecke geeignet.
Das Buch ist systematisch in fünf Kapitel unterteilt:
1. Das erste Kapitel gibt eine kurze Einführung in die grundlegenden elektronischen Prinzipien und Berechnungen. Die vorgestellten Beispiele und Formeln
sind sehr nützlich für viele folgende Aufgaben. Außerdem wird die Programmiersprache „C“kurz vorgestellt und ein paar grundlegende Anwendungsbeispiele werden diskutiert.
2. Im zweiten Kapitel wird am Beispiel des ATmega 128 ein Überblick über 8-bit
AVR Mikrocontroller gegeben. Dieses Kapitel basiert weitgehend auf dem Datenblatt des ATmega Mikrocontrollers, stellt die benötigten Informationen jedoch
1 Einleitung
vereinfacht und übersichtlicher dar. Hier werden allgemein die Grundfunktionen eines Mikrocontrollers erörtert.
3. Dieses Kapitel führt die Hardware- und Softwareplattform ein, welche für
Lehrzwecke entwickelt wurde und als Grundgerüst für weitere Beispiele in den
folgenden Kapiteln dient. Ferner wird an dieser Stelle auch die „HomeLab Library“, eine für das Kit entwickelte Softwarebibliothek, welche vereinfachte Methodenaufrufe für häufig genutzte Funktionalitäten bietet, vorgestellt. Dies bietet
dem Benutzer den Vorteil, dass er sich auf die Logik seiner Software konzentrieren kann, anstatt den Fokus auf das Programmieren von Registern legen zu
müssen. Dabei berücksichtigt dieses Buch sowohl Windows- als auch Linux-Betriebssysteme.
4. Im vierten Kapitel werden schließlich praktische Beispiele sowie Übungen vorgestellt. Die Beispiele sind unterteilt in „Labs“(Übungsabschnitte) und decken
die meisten elektro-mechanischen Bauteile und Funktionen ab. Jeder Abschnitt
enthält zunächst eine kurze Beschreibung des theoretischen Hintergrunds sowie praktische Beispiele. Durch einfaches Kopieren der Beispielprogramme in
den Controller hat der Nutzer direkt die Möglichkeit, die Funktionen zu nutzen.
Am Ende jedes Unterkapitels finden sich Beispielaufgaben sowie Verständnisfragen zum jeweiligen Übungsabschnitt. Sämtliche Übungen sind nach ihrem
Schwierigkeitsgrad gegliedert, damit sowohl Anfänger als auch Fortgeschrittene die für sie geeigneten Übungsaufgaben auswählen können. Darüber hinaus
werden zum besseren Verständnis der Aufgaben Bezüge zu den betreffenden
theoretischen Abschnitten dargestellt.
5. Im fünften Kapitel finden sich Tipps für die gemeinsame Arbeit an Problemstellungen. Hier wird illustriert wie man gemeinsam entwickelte Konzepte implementiert sowie präsentiert und wie Berichte verfasst werden. Dabei sind jene
Themen, welche in einem Teambericht enthalten sein sollen, besonders hervorgehoben. Weiterhin wird an dieser Stelle auch ein Beispielprojekt vorgestellt, welches als Muster zum Erstellen eines präzisen Berichts für eigene Projekte dienen
soll.
Wir hoffen, dass das Buch eine gute Hilfe sowohl für neue als auch für erfahrene
Mikrocontroller- und Robotik-Enthusiasten darstellt und vielen Menschen diese
Technologie näher bringt.
6
Bochum, im Sommer 2011
Sven Seiler
7
2
Mikrocontroller und Robotik
Mikrocontroller
Abbildung 2.1: The first microcontroller in the world: Intel 8048
Mikrocontroller sind im Wesentlichen Computer, welche auf einen einzelnen
Chip mit integriertem Schaltkreis positioniert werden und aus einer Speichereinheit, einem Prozessor sowie Input-Output Schnittstellen bestehen. Sie werden für eine bestimmte Aufgabe programmiert, was bedeutet, dass sobald eine
Änderung oder Verbesserung der Aufgabe nötig ist, ein neues Programm auf
dem Chip installiert werden muss. Eigenschaften, welche den Mikrocontroller
von anderen Computern (PC, Laptop, Server, etc.) unterscheiden sind:
Sämtliche Funktionen sind auf einem einzelnen, kleineren und kompakteren Chip gespeichert.
Er wird zur Durchführung einer bestimmte Aufgabe programmiert, um die
Funktionalität zu ändern muss neue Software installiert werden.
Er verbraucht weniger Strom, da alle physischen Komponenten kleiner
und energiesparender sind als die eines PC, Laptops oder Servers. Entwickler von Mikrocontrollern fokussieren einen geringen Energieverbrauch, sodass mobile Anwendungen länger betrieben werden können.
2 Mikrocontroller und Robotik
In- und Outputs, die auf einen bestimmten Zweck ausgelegt sind. Mikrocontroller besitzen so genannte Peripherie-Schnittstellen, welche Verbindungen zwischen mehreren Mikrocontrollern oder zwischen einem Mikrocontroller und einem Computer (z. B. USB, CAN, UART) ermöglichen
sowie dabei helfen, reale physikalische Prozesse nachzuvollziehen (z. B.
Schaltvorgänge, Temperaturmessungen, etc.) und nicht zuletzt auch die
Steuerung von Umgebungen unterstützen (z. B. Motoren steuern, Alarme
auslösen, etc.).
Mikrocontroller finden sich in diversen Gegenständen des täglichen Gebrauchs:
in Haushaltsgeräten (z. B. Mikrowelle, Fernsehgerät), Spielzeugen (Lego NXT,
sprechende Puppen), Beförderungsmitteln (Auto, Aufzug), etc. Der umfassende Einsatz von Mikrocontrollern ist möglich, da sie leicht zu programmieren
sind und eine Vielzahl von Funktionen besitzen; folglich können sehr leicht neue
Funktionen hinzugefügt sowie das Anwendungsniveau erhöht werden.
Robotik
Robotik ist die Wissenschaft, welche die Technologie und das notwendige Wissen zum Bau von Robotern miteinander kombiniert. Aufgrund des rasanten technologischen Fortschritts ist der Begriff „Roboter“, der als automatisierte Maschine den Menschen ersetzt, nicht mehr klar definiert. Roboter sind nicht länger nur
humanoide Roboter, Roboterhände in Fertigunggstraßen, Autopiloten in Flugzeugen, aus lebenden Neuronen bestehende künstliche Intelligenz oder einfache
Reinigungsroboter; der Begriff „Roboter“bezeichnet vielmehr auch Computersoftware, welche für den Menschen gedachte Aufgaben ausführt (z. B. Berichte
erstellen). Es ist allseits bekannt, dass Roboter gebaut werden, um den Menschen
bei bestimmten Aufgaben zu ersetzen. Eine Vielzahl von Gründen rechtfertigt
dieses: gefährliche Arbeitsbedingungen, günstigere Produktion, monotone Arbeit bei der Menschen zu Fehlern neigen, neue Systeme, die so komplex und
zeitkritisch sind, dass automatisierte Maschinen diese besser erledigen können
als Menschen.
10
Mikrocontroller in der Robotik
Aufgrund der Weitläufigkeit der Robotik, konzentrieren wir uns in diesem Buch
auf die Hobby-Robotik. Diese Systeme sind nicht allzu komplex und es ist möglich sie eigenständig zu implementieren. Häufig genutzte Mikrocontroller in der
Robotik sind:
Atmel AVR Mikrocontroller (ATmega, ATtiny, etc.)
Microchip Technology PIC Mikrocontroller (PIC16, PIC24, etc.)
Mikrocontroller, die auf der ARM-Technologie basieren.
Drittanbieter haben sehr häufig Entwicklungsplatinen und Umgebungen gebaut,
die auf den zuvor genannten Mikrocontrollern basieren. Zum Beispiel: Arduino
(VAR), BASICStamp (PIC) und Lego NXT (ARM). Die zur Entwicklung von HomeLab notwendigen Grundvoraussetzungen, welche in diesem Buch beschrieben werden, basieren auf dem AVR ATmega127 Mikrocontroller.Aus der Vielzahl der zur Verfügung stehenden Mikrocontroller und Entwicklungsplatinen
gilt es nun, das für den jeweiligen Bedarf am besten geeignete Produkt auszuwählen. Allgemein lassen sich die folgenden 4 Eigenschaften unterscheiden:
Preis, technische Merkmale, Entwicklungsumgebung und Kundenbetreuung. Bemerkenswerte technische Merkmale sind:
Arbeitsgeschwindigkeit des Prozessors - legt die Arbeitsgeschwindigtkeit
des Chips fest
Speicherkapazität des Programms - bestimmt die Größe des Programms,
das auf dem Chip installiert werden kann
Datenspeicherkapazität - gibt die mögliche Datenverarbeitungsmenge des
Programms an
Anzahl der Input- / Output-Schnittstellen sowie deren Funktionen - unterschiedliche Schnittstellen bieten differenzierte Möglichkeiten
Anzahl der Timer - wichtig für das Zeitverhalten der Anwendung
11
2 Mikrocontroller und Robotik
Energieverbrauch - von großer Bedeutung für mobile Anwendungen
In diesem Buch verwenden wir PC-Software als Entwicklungsumgebung, mit
der Programme erstellt und kompiliert und auf die Mikrocontroller geladen werden können sowie Zugriff auf die laufenden Programme hergestellt werden kann,
um so mögliche Fehler zu entdecken. Da diese Software während der Entwicklungsphase des Programms als primäre Entwicklungsumgebung dient, wird die
einfache und angenehme Arbeitsweise während der Nutzung deutlich. Dies führt
schließlich zur vierten Eigenschaft, der Kundenbetreuung. Hier ist es wichtig,
dass auf Hilfe und Unterstützung bezüglich diverser Problemstellungen so einfach wie möglich zugegriffen werden kann. Unter Berücksichtigung der vier
genannten Merkmale, sollte es schließlich möglich sein, die geeignete Entwicklungsplatine zu finden.
12
3
AVR Mikrocontroller
Das folgende Kapitel stellt den AVR Mikrocontroller vor, auf welchem dieses
Buch basiert. Trotz seiner geringen Größe besitzt der Mikrocontroller eine Vielzahl von Funktionen, welche von Atmel in einem fast 400 Seiten umfassenden
Handbuch dokumentiert wurden. Darüber hinaus gibt es noch einige weitere
Dokumente, die sich mit der Thematik befassen. Sämtliche Informationen werden in dem folgenden Abschnitt in komprimierter Form dargestellt, um dem
Leser so einen schnellen und einfachen Überblick über das Thema zu geben. Zugleich dient diese Übersicht dazu, ungeübten Nutzern das Verständnis des AVR
Mikrocontrollers näher zu bringen und zeigt ihnen, wie das Datenblatt zu lesen
ist.
3 AVR Mikrocontroller
3.1
Einführung
Abbildung 3.1: ATmega128 in SMT package (TQFP64, to be precise)
AVR ist eine Serie aus 8-bit RISC Microcontroller produziert von Atmel. AVR
folgt der Harcard-Architektur und hat daher separate Programm- und Datenspeicher. Für das Programm hat er einen internen überschreibbaren Flash-Speicher, für statische Daten (SRAM) und EEPROM-Speicher. Die Taktfrequenz des
Controllers liegt normalerweise bei 16MHz und schafft fast 1 MIPS pro 1MHzZyklus.
Die Produktion des AVR Microcontroller begann 1997 und heute ist AVR einer
der am beliebtesten Controller der freischaffenden Elektronik-Ingenieure. Dank
der günstigen Entwicklungstools, der diversen Peripherals in einem Paket und
des niedrigen Energiebedarfs kam der anfängliche Erfolg. Heute gibt es noch
einen anderen Grund sich für den AVR zu entscheiden: die Masse an Information
und an Tutorials die sich über die Jahre angesammelt haben. Die AVR Technologie altert natürlich, aber um konkurrenzfähig zu bleiben stellt Atmel neue AVR
Microcontroller her, mit up-to-date peripherals und 16- und 32-bit Bus, Erste aus
der 8-bit kompatiblem XMega Serie und Letztere aus der neuen AVR32 Serie.
Basierend auf den Typ der Anwendung, gibt es unterschiedliche Typen von AVR
Microcontroller, jeder mit einer unterschiedlichen Konfiguration. Die meisten
der AVRs gehören zur megaAVR Serie, sie haben einen großen Programm-Speicher. Als Gegenstück gibt es die tinyAVR Serie, mit weniger Funktionen. Zusätzlich gibt es noch unterschiedliche Microcontroller Serien speziell zum Kontrollieren von USB, CAN, LCD, ZigBee, automatics, Beleuchtung und batteriebetriebene Geräte.
14
3.1 Einführung
Der folgende Text beschreibt die Hauptfeatures der megaAVR Serie Microcontroller, am Beispiel des beliebtesten Controller dieser Serie, des ATmega128. Dieser Controller ist auch im HomeLab-Kit enthalten. Generell alle AVR Microcontroller Registernamen, Bedeutungen und Benutzungen sind in einer Weise geregelt , welche es möglich macht Beispiele auch mit anderen Controller zu nutzen, in dem man nur kleine Änderungen durchführt.Der Hautunterschied liegt
in den Peripherals.Die Codebeispiele dieser Einführung sind mit AVR LibC in
Assembler und C geschrieben .
äuÿerer Aufbau
Abbildung 3.2: ATmega32 in 40-pin DIP casing
Wie alle anderen Controller ist der AVR in einer Standarthülle gepackt. Das traditionelle Gehäuse ist DIP (bzw. DIL). DIP ist eine so genannte Casing-On-Legs.
Alle Pins treten wie Beine , ca 5mm in Länge, aus dem schwarzen Plastikgehäuse
hervor.DIP Gehäuse sind eine gute Wahl für Hobbyanwendungen und Prototypen, weil es dafür günstige Sockets gibt. Daher kann der Microcontroller einfach
ersetzt werden sollte er Ausfallen. Die Beine sind aber auch der Nachteil des DIP
Gehäuses, da man dafür Löcher in die Platine bohren muss.
Die Surface-Mount-Casings (SMT, bzw. SMD) sind viel kompakter, weil die Pins
dafür gedacht sind direkt auf die Platine gelötet zu werden ohne zu Bohren.
AMT Microchips sind dünne münzen-große rechteckige Gehäuse mit Pins von
ca. 1mm Länge. Eine ruhigere Hand und präzisere Werkzeuge werden zum löten
von SMT Chips benötigt.
AVRs gibt es als DIP und SMT Gehäuse. Das Layout der Pins ist vom Design her
so logisch und elektronisch ausgeglichen wie es nur möglich ist. Zum Beispiel
15
3 AVR Mikrocontroller
sind bei größeren Chips die Ground- und Supply-Pins auf mehreren Seiten des
Microcontrollers, die Pins für einen Externen Oszillator sind nahe des GroundPins, die Bus-Pins sind durchnummeriert, die Communication-Pins sind nebeneinander etc. AVRs digitale Pins sind kompatibel mit TTL/CMOS Voltwerten.
Bei 5V Supply-Spannung, 0 bis 1 V sind Logische Null (Zero), auch Zero, Null,
0 Low, Ground oder GND genannt. Bei Gleicher Supply-Spannung, 2 bis 5.5V
sind die logische Eins, auch one, 1, high, genannt. Dieses Typ von weiten Spannungsunterschieden gibt es nur im Input, die Outputspannung an einem Pin mit
keinem Load ist immer noch 0 V oder nahe der Supply-Spannung, je nach Status
des Pins.Die erlaubte Analogspannung an den ADC Kanälen ist 0-5.5V.
ATmega128 Um die folgenden Beispiele am ATmega 128 besser zu verstehen,
gibt es am Ende des Textes ein Pinout-Schema des ATmega128 (SMT Package).An jedem Pin ist ein Text mit der Nummer, primären Funktion und sekundären (alternativen) Funktion in Klammen. Supply Pins sind GND und VCC.AVCC
und AREG sind die analog zu digital Konverter Supply- und ReferenceVoltagePins.XTAL1 und XTAL2 sind für den Anschluss einen externen Schwingquarzes,
Resonator oder Taktgebers. Die Pins PB0 bis PG4 markieren die Bits der InputOutput Buses. Die sekundären Funktionen werden in dem entsprechenden Kapitel besprochen.
16
3.2 Register
Abbildung 3.3: ATmega128 pinout
3.2
Register
Typischerweise ist das Register eines der Bestandteile eines Mikrocontrollers, die
ein Anfänger nur mühsam versteht. Im Umgang mit Mikrocontrollern ist es jedoch unumgänglich diese Komponente zu kennen. Auch für die weitere Arbeit
mit diesem Buch ist der Leser dazu angehalten, sich das Konzept des Registers
anzueignen. Daher wird es im nun folgenden Text auf eine möglichst verständliche Weise erklärt, sodass auch ein Anfänger ein Gespür für das Register bekommt.
17
3 AVR Mikrocontroller
Essence
Abbildung 3.4: Tasten eines Kassettenrekorders
Ein Register ähnelt einem Panel von Tasten eines Haushaltsgerätes. Es verfügt
über Schalter, die ein- und ausgeschaltet werden können. Das beste Beispiel hierfür ist ein Kassettenrekorder. Zur Erinnerung, ein Kassettenrekorder verfügt über
6 Tasten von links nach rechts:
Aufnahme
Zurückspulen
Abspielen
Vorspulen
Stopp
Pause
Jede Taste führt eine Funktion aus, jedoch nur wenn sie auch korrekt verwendet
wird. So macht die Stopp-Taste solange nichts, bis die Kassette abgespielt wird.
Erst dann kann die Funktion ausgeführt werden und die Wiedergabe wird gestoppt. Dagegen können Vorlauf- und Rückspultasten zu jeder Zeit betätigt werden, denn die Kassette kann in beide Richtungen gespult werden, unabhängig
davon ob sie gerade abgespielt wird oder nicht. Die Aufnahmetaste startet nur
dann eine Aufnahme, wenn sowohl die Abspielen- als auch die Aufnahmetaste zeitgleich gedrückt werden. Eventuell hat mancher einmal versucht, mehrere
oder alle Tasten auf einmal zu betätigen. Dieses hat vermutlich eine unerwartete
Funktion des Kassettenrekorders ausgelöst oder ihn sogar beschädigt.
18
3.2 Register
Die Register von Mikrocontrollern verhalten sich wie Tasten eines Kassettenrekorders - jede Taste führt eine Funktion aus, wenn sie korrekt verwendet wird.
Werden die falschen Tasten betätigt, wird der Mikrocontroller in der Regel nicht
direkt beschädigt, aber er wird nicht funktionieren. Tatsächlich gibt es keine
Tasten im Register sondern stattdessen eine Vielzahl von Transistoren, welche
die Stromversorgung ein- und ausschalten. Einfachere Mikrocontroller haben 8
transistorbasierte Schalter in einem einzigen Register. Unter einem Register kann
man sich eine 8-Bit Zahlenfolge vorstellen, wobei jedes Bit durch den Status eines dieser Schalter gekennzeichnet wird. Zum Beispiel kann ein Bit-Wert von 1
bedeuten, dass der Schalter an ist, ein Wert von 0 hieße dann, dass er aus ist.
Abbildung 3.5: „Tasten“des Registers und Bitwerte
Da der Status eines Registerschalters einfach durch eine Nummer abgebildet
werden kann, lässt sich ein Register mit einem Speicher vergleichen, der Daten
in Form genau einer Zahl speichern kann. Durch diesen Vergleich wird deutlich,
dass Register tatsächlich Speicherslots sind. Der Unterschied zwischen einem
Register und einem Speicherslot besteht darin, dass letzterer lediglich Informationen speichert, während die Informationen in einem Register tatsächlich etwas
steuern. So sorgt zum Beispiel der Binärwert 01100001 in einem Register dafür,
dass drei imaginäre Tasten betätigt werden wodurch eine Funktion ausgelöst
wird.
Während es bei einem Kassettenrekorder möglich ist, jeden Knopf einzeln zu
betätigen, ergeben sich bei einem Register Schwierigkeiten, wenn nur der Wert
eines Schalters oder Bits geändert werden soll. Hier ist es gewöhnlich notwendig, den gesamten Inhalt der Registers zu ändern. Bevor jedoch detaillierter auf
die Thematik der Bit-Veränderung eingegangen wird, muss zunächst klargestellt
werden, dass ein Mikrocontroller mehrere Register enthält. Die Vielzahl der Register führt dazu, dass diese voneinander unterscheidbar gemacht werden müssen, was durch Kennzeichnung mit einem Namen geschieht, wie zum Beispiel
„PORTB“. Hierdurch wird dem Entwickler die Arbeit erleichtert, da jedem Namen auch eine eigene numerische Adresse zugewiesen wird.
19
3 AVR Mikrocontroller
Gebrauch
Zur Programmierung eines Registers oder auch dazu, um Werte aus diesem abzulesen muss er als Variable in C deklariert werden. Das folgende Beispiel veranschaulicht, wie ein Binärwert einem imaginären Register REG zugewiesen wird
und dann in der Variable reg abgelegt wird. Binärwerte werden an einem vorangestellten 0b (leading zero) erkannt, sodass der Compiler das binäre Zahlensystem erkennt.
REG = 0 b01100001 ;
unsigned char reg = REG ;
Die Schwierigkeit liegt nicht darin, Registerwerte zu schreiben und auszulesen,
sondern vielmehr darin, ein einzelnes Bit zu verändern. Hierzu sind Kenntnisse
der Binärmathematik sowie im Gebrauch diverser Zahlensysteme notwendig. Es
ist auch möglich, nur mit Binärzahlen zu arbeiten. Da diese aufgrund ihrer Länge die Programmierarbeit jedoch erschweren können, verwenden die meisten
Programmierer die kürzeren Hexadezimalzahlen.
Abbildung 3.6: Hexadezimalzahlen
Im Hexadezimalsystem gibt es nicht nur die Ziffern 0 und 1 wie im binären System oder 0 bis 9 gemäß dem Dezimalsystem, sondern stattdessen 0 bis F. Eine Hexadezimalzahl besteht aus vier Bits. Die Abbildung auf der rechten Seite
veranschaulicht die Binärzahlen und deren zugehörige Hexadezimalwerte. Binärzahlen werden in Hexadezimalzahlen umgewandelt indem vier Bits zugleich,
beginnend bei dem niedrigsten, gelesen werden. Die Bitfolge wird von links nach
rechts gelesen und startet bei 0. So ist zum Beispiel das niederwertigste Bit (an
Stelle 0) 0 und das mit dem höchsten Wert (an Stelle 3) 1. Im vorangehenden
20
3.2 Register
Beispiel ist der Binärwert der Registers 01100001, der im Hexadezimalsystem 61
entspricht und in C als 0x61 (leading zero) geschrieben wird.
Um einzelne Bits innerhalb einer Zahl zu verändern (Register, Variable oder ähnliches) müssen Binäroperationen angewandt werden. Binäroperationen sind Vorgänge zwischen zwei Binärzahlen, wobei jedes Bit der Zahlen durch eine eigene
logische Operation abgebildet wird. Mikrocontroller unterstützen generell vier
unterschiedliche Binäroperationen. Der folgende Abschnitt beschreibt die logische Operation hinter diesen vier Binäroperationen mit einzelnen sowie mehreren Bits.
Abbildung 3.7: Negation, logische Multiplikation, logische Addition und exklusive Disjunktion
Negation / Inversion
Eine Negation kehrt den Wert eines Bits in das jeweilige Gegenteil um. So
wird aus einer 0 eine 1 und umgekehrt. In C wird eine Negation durch
“˜“vorgenommen.
Logische Multiplikation / Konjunktion
Bei der Multiplikation zweier Bits ist das Ergebnis 1 für den Fall, dass beide
Bits den Wert 1 besitzen, ansonsten 0. Eine Logische Multiplikation wird in
C durch “&“dargestellt.
Logische Addition / Disjunktion
Eine Addition von zwei Bits ergibt 1 wenn zumindest eines der Bits den
Wert 1 hat und 0 wenn beide Bits den Wert 0 haben. In C kennzeichnet
„|“die Logische Addition.
Exklusive Disjunktion / Exklusives ODER / XOR
Das Ergebnis einer Exklusiven ODER Operation ist 1 bei zwei unterschiedlichen Bits (also wenn ein Bit den Wert 1 besitzt, das andere den Wert 0),
ansonsten 0. Eine Exklusive Disjunktion wird in C durch „ˆ “dargestellt.
21
3 AVR Mikrocontroller
Man benötigt nicht mehr als diese vier Operationen, um einzelne Bits zu ändern.
Da die Theorie allein vermutlich nicht ausreichen mag, enthalten die folgenden
Abschnitte einige Anwendungsbeispiele.
Abbildung 3.8: Ein einzelnes Bit „high“setzen
Um einzelne oder mehrere Bits in einem Register “high“zu setzen (1) muss eine logische Addition durchgeführt werden.
Hierfür muss ein Operand das Register sein und ein anderer die Binärzahl, wobei das einzige „high“Bit jenes ist, was ein einem Register „high“gesetzt werden
muss. Diese Binärzahl wird Bitmaske genannt. Nachfolgend ist der C-Code für
diese Operation abgebildet:
Ein einzelnes Bit highsetzen
// Annahme REG = 0 x0F
REG = REG | 0 x11 ; // E r s t e Methode
REG |= 0 x11 ;
// Zweite Methode
// E r g e b n i s REG = 0 x1F
Abbildung 3.9: Ein einzelnes Bit “low“setzen
Um einzelne oder mehrere Bits in einem Register
“low“zu setzen (0) ist eine logische Multiplikation nötig. Dabei muss ein Operand das Register und ein weiterer eine Bitmaske sein, in welcher das einzige
low-Bit jenes ist, welches im Register „low“gesetzt werden soll.
Ein einzelnes Bit lowsetzen
// Annahme REG = 0 x0F
REG = REG & 0xFE ; // E r s t e Methode
REG &= 0xFE ;
// Zweite Methode
// E r g e b n i s REG = 0x0E
22
3.2 Register
Abbildung 3.10: in einzelnes Bit invertieren
Zum Invertieren einzelner oder mehrerer Bits eines Registers muss eine Exklusive Disjunktion angewandt werden.
Hierzu ist ein Operand das Register, der andere muss eine Bitmaske sein, in der
das einzige high Bit jenes ist, welches invertiert werden soll. Der C-Code für diese Operation ist unten abgebildet:
Ein einzelnes Bit invertieren / umkehren
// Annahme REG = 0 x0F
REG = REG ^ 0 x11 ; // E r s t e Methode
REG ^= 0 x11 ;
// Zweite Methode ( nur e i n e pro I n v e r s i o n verwenden
)
// E r g e b n i s REG = 0x1E
Abbildung 3.11: Invertieren aller Bits
Durch die Negationsoperation werden sämtliche Bits eines Register invertiert. Diese Operation besteht aus nur einen Operanden und ist daher unär. Der hierfür benötigte C-Code ist unten abgebildet:
Das gesamte Register invertieren
// Annahme REG = 0 x0F
REG = ~REG ;
// E r g e b n i s REG = 0 xF0
Abbildung 3.12: Den Wert eines Bits auslesen
23
3 AVR Mikrocontroller
Sollen ein oder mehrere Bits aus einem
Register gelesen werden muss ebenfalls die logische Multiplikation angewandt
werden. Einer der Operanden ist das Register, der zweite eine Bitmaske, in welcher das einzige high-Bit jenes ist, welches aus dem Register gelesen werden soll.
Unten ist der C-Code für diesen Vorgang dargestellt.
Den Wert eines einzelnen Bits auslesen
// Annahme REG = 0 x0F
unsigned char x = REG & 0 x01 ;
// E r g e b n i s x = 0 x01
Ein Bit verschieben Viele Programmiersprachen verfügen mittlerweile über einige zusätzliche Bitoperationen, was die Programmierarbeit erleichtert. Hierzu
gehören die Operationen, welche die Bits einer Binärzahl nach rechts oder links
verschieben. Im Umgang mit Registern liegt der größte Vorteil dieser Operationen darin, dass Bitfolgen zu Bitmasken konvertiert werden können und umgekehrt.
Abbildung 3.13: Linksshift
Das Bild auf der rechten Seite zeigt einen Linksshift. Auch wenn ein Bitshift keine
logische Operation darstellt und kein zugehöriges Symbol hat, wird diese Operation in C mit “«“gekennzeichnet. Eine Linksshiftoperation wird genutzt, um
eine Bitfolge in eine Bitmaske umzuwandeln. Um beispielsweise die Maske für
das sechste Bit (Rang 5) zu erhalten, muss das erste Bit um fünf Stellen nach links
verschoben werden. In C wird diese Operation wie folgt geschrieben:
REG = 0 x01 << 5 ;
// E r g e b n i s REG = 0 x20
Abbildung 3.14: Rechtsshift
24
3.2 Register
Der Rechtsshift funktioniert auf die gleiche Weise und wird in C durch “»“dargestellt. Rechtsshiftoperationen dienen dazu, den logischen Wert eines Bits aus der
Bitmaske zu erhalten. An einem vorherigen Beispiel wurde bereits gezeigt, wie
der Wert eines einzelnen Bits gelesen werden konnte. Ist dieses Bit nun nicht das
niederwertigste, sondern zum Beispiel eines mit dem Rang 5, wäre das Ergebnis
entweder 0x20 oder 0x00. Allerdings wird manchmal ein Ergebnis von 1 oder 0
benötigt und genau hier kommt die Rechtsshiftoperation zur Anwendung. Der
Rechtsshift aus dem Beispiel rechts sieht in C folgendermaßen aus:
// Annahme REG = 0 x20
unsigned char x = REG >> 5 ;
// E r g e b n i s x = 0 x01 ( or simply 1 )
Wird durch diese Operationen ein Bit vom niedrigsten Rang nach rechts oder
vom höchsten Rang nach links verschoben, verschwindet es. Einige Programmiersprachen verfügen jedoch über rotierende Bitshiftoperationen, bei denen ein
Bit nicht verschwindet, sondern vom niedrigsten zum höchsten Rang wandert
oder umgekehrt. In C gibt es diese Operationen nicht, sie können jedoch bei Bedarf vom Programmierer selbst geschrieben werden.
Sämtliche Bitoperationen sind nicht nur mit Registern durchführbar, sondern
auch mit Variablen und Konstanten. Letztere können jedoch ausschließlich als
Operanden, nicht als Ergebnis genutzt werden.
AVR Register
Um tatsächlich mit dem Register eines Mikrocontrollers zu arbeiten, ist es notwendig zu wissen, wie dieser spezielle Mikrocontroller verwendet wird. Zu jedem Mikrocontroller gibt es ein oder mehrere Datenblätter, welche seine Struktur
und Funktionalität beschreiben. Dieses Datenblatt enthält auch Informationen
über die Register. Der folgende Abschnitt dient dazu, die Registerbeschreibungen der AVR Datenblätter zu verstehen.
25
3 AVR Mikrocontroller
Abbildung 3.15: Eines der AVR Register, Datenblattansicht
Die Abbildung zeigt das UCSRnA Register des ATmega128. UCSRnA bezeichnet „USART Control and Status Register A“. Dieses Register wird verwendet um
das USART Modul der AVR Mikrocontroller zu konfigurieren und deren Status
auszulesen. Sämtliche AVR Registernamen werden in Großbuchstaben geschrieben, jedoch enthält der Name auch ein kleines n, welches den Index des Moduls
kennzeichnet. Der ATmega128 verfügt über zwei nahezu identische USCART
Module, die jedoch nicht getrennt beschrieben werden, sodass der Nutzer das
n als 0 oder 1 lesen muss. Aus diesem Grund hat der ATmega128 die Register
USCR0A und UCSR1A.
Der Inhalt des Registers wird durch eine Box mit 8 Feldern und einem dicken
schwarzen Rahmen dargestellt. Jedes Feld steht hier für ein Bit. Die Bitränge sind
oberhalb der Box abgebildet - von links nach rechts ansteigend. Da der AVR ein
8-Bit Mikrocontroller ist, haben auch die meisten seiner Register 8-Bit. Es gibt
auch Ausnahmen, so sind einige Register 16-Bit groß, aber tatsächlich bestehen
sie aus zwei 8-Bit Registern. So wie jedes Register einen Namen hat, hat auch jedes Bit innerhalb des Registers einen Namen - so wie die Tasten an einem Kassettenrekorder. Jedes Bit wird im Datenblatt beschrieben. Wie Registernamen sind
Bitnamen ebenfalls Abkürzungen und das kleine n entspricht jeweils dem Modulindex. Einige Register nutzen weniger als 8 Bit, in diesem Fall ist das Feld
eines solchen Bits mit einem Trennstrich markiert.
Unterhalb der Bits des Registers finden sich im Datenblatt zwei Zeilen. Die erste gibt an, ob das Bit lesbar (R), beschreibbar (W) oder beides (R/W) ist. Kann
beispielsweise der Status eines Bits nicht überschrieben werden, so bleibt das Bit
unverändert, auch wenn das mit dem Programm versucht wurde. Durch Auslesen eines beschreibbaren Bits wird stets ein spezifischer Wert ausgegeben, der
im Datenblatt angegeben ist. In der zweiten Zeile wird der Standardwert dargestellt, den das Bit nach dem Reset des Mikrocontrollers hat.
26
3.3 Architektur
Während die AVR Registernamen auf eine tatsächliche Adresse im Speicher verweist, enthalten Bitnamen den Rang und das zugehörige Bit. Daher ist eine Transformation der Namen zu Bitmasken mit einer Shiftoperation notwendig, wenn
man mit Bits in einem Register arbeiten will. Der folgende Code zeit einige Beispielzeilen für die Nutzung des USART 0 Modul Registers.
// S e t z e TXC0 B i t high
UCSR0A |= ( 1 << TXC0 ) ;
// S e t z e U2X0 B i t low
UCSR0A &= ~(1 << U2X0 ) ;
// L i e s den Wert aus UDRE0 B i t ( Maske )
unsigned char u = (UCSR0A & ( 1 << UDRE0) ) ;
// An d i e s e r S t e l l e i s t der Wert entweder 0 oder 3 2 ,
// wodurch d i e Nutzung i n e i n e r l o g i s c h e n Operation a k t i v i e r t wird
if (u)
{
// I n v e r t i e r e MPCM0 B i t
UCSR0A ^= ( 1 << MPCM0) ;
}
// Manchmal i s t es notwendig einen s p e z i f i s c h e n 1 oder 0 Wert zu
erhalten
// Dazu muss das B i t nach r e c h t s verschoben werden
u >>= UDRE0 ;
// Nun i s t der Wert entweder 0 oder 1
3.3
Architektur
Der AVR hat einen internen 8-Bit Daten-Bus, durch den Daten zwischen der
arithmetisch-logischen Einheit (ALU), dem Status Register (SREG), dem Befehlszähler (PC), dem Random-Access-Memory (SRAM), und den Peripherieschnittstellen bewegt werden können. Das Programm, eine Reihe an Befehlen, die in
der ALU ausgeführt werden, resultiert aus einer Adresse im Flash-Speicher, spezifiziert vom Befehlszähler. Der ALU hat 32 8-bit Mehrzweckregister, welche als
Operanden genutzt werden, wenn Befehle ausgeführt werden.
27
3 AVR Mikrocontroller
Abbildung 3.16: Block diagram of ATmega128
Befehls-Pipeline
Der AVR hat eine zweistufige Befehls-Pipeline. Während ein Befehl ausgeführt
wird, wird der nächste aus dem Programmspeicher geholt. Darum sind beim
Ausführen einer „Jump-Instruction“zwei Takte notwendig, um die Bedingungen
des Jumps zu erfüllen. Neue Befehle werden immer von der nächsten Speicheradresse geholt. Dadurch ist es notwendig die vorherigen Befehle zu löschen und
28
3.3 Architektur
neue zu laden, wenn man zu einer neuen Adresse springt, da der Ort an dem der
Befehl geholt wurde nun nicht mehr stimmt.
Mehrzweckregister
Mehrzweckregister R0-R31 sind wie Buffer, um mit Speicher- und Peripheriedaten zu arbeiten und sie zu speichern. Sie vereinfachen die Architektur des Prozessors, weil sie schnellen Zugang der ALU erlauben und der Datenbus nicht immer
benutzt werden muss um Operanden aus dem Speicher zu lesen. Mehrzweckregister werden für alle datenbezogenen arithmetischen und logischen Abläufe
benutzt.
Wenn man in Assembler programmiert, ist es möglich die benötigten Daten im
Mehrzweckregister zu speichern. Programmiert man in C und muss eine Variable im Mehrzweckregister speichern, wird die Variable zusätzlich als „Register“definiert. Zum Beispiel:
r e g i s t e r char x ;
Befehlssatz
Der Befehlssatz der meisten AVRs besteht aus 90-133 verschiedenen Befehlen.
Der ATmega128 hat 133 Befehle. Befehle haben entweder ein, zwei, oder keine
Operanden. Die meisten Befehle benötigen nur einen Takt zur Ausführung, komplexere Befehle können jedoch bis zu fünf Taktzyklen benötigen. Für den XMega,
den Nachfolger des AVR, wurden viele Befehle modifiziert, damit weniger Taktzyklen genutzt werden. Die meisten Befehle im AVR werden benutzt für Jumps,
um Daten zu bewegen und zu vergleichen und um arithmetische Berechnungen
auszuführen. Ein Status-Register wird genutzt um Berechnungen und Vergleiche
auszuführen. Es speichert den Output-Status der ALU - ob das Ergebnis negativ,
positiv, null, den maximal erlaubten Wert (8 Bits) überschreitet, oder einen Bit in
die nächste Operation transferieren muss, usw. (Es gibt noch ein paar kompliziertere Fälle).
Example
29
3 AVR Mikrocontroller
Die ist ein Teil eines in Assembler geschrieben Codes, der bloße Befehle beinhaltet, welcher eine 5 zum Byte in der RAM-Adresse $ 100 (dezimal 256) hinzufügt.
Diese Befehle gibt es alle im AVR.
ldi
lds
add
sts
r1 , 5
r2 , $100
r2 , r 1
$100 , r 2
;
;
;
;
Lä dt d i e
Lä dt das
Fü g t den
Schreibt
Konstante 5 i n das Mehrzweckregister r 1
Byte aus dem S p e i c h e r i n das R e g i s t e r r 2
Wert von r 1 zu r 2 hinzu
den Wert von r 2 zurück i n den S p e i c h e r
Programmstapelspeicher (stack)
Ein Stapelspeicher (stack) ist eine Datenstruktur, bei der der letzte in den Speicher geschriebene Wert, als erstes ausgelesen wird. Die Stacks im AVR können
genutzt werden, wenn man mit Subroutinen, Interrupts und temporären Daten arbeitet. Bevor eine Subroutine oder ein Interrupt ausgeführt wird, speichert
der Stack die Adresse im Befehlszähler, bei welcher das Programm unterbrochen wurde. Wenn die Subroutine oder der Interrupt ausgeführt wurde, wird
die Adresse wieder aus dem Stack gelesen, und das Programm fährt von der
Adresse vor der Unterbrechung wieder fort. Das Speichern temporärer Daten im
Stack wird normalerweise dann genutzt, wenn man mit kleineren Stücken Code
arbeitet, welche keinen reservierten Speicher während ihrer Ausführung benötigen. Einfache Assembler Programme werden normalerweise so geschrieben,
dass es nicht notwendig ist, den Stack zu nutzen, aber wenn das Programm viele
Variablen und Funktionen enthählt, verwendet der Compiler den Stack automatisch.
Der Stack der MegaAVR-Serie ist physikalisch im Random-Access-Memory zu
finden. Einige Modelle der tinyAVR-Serie besitzen jedoch keinen Random-AccessMemory sodass der Stack hier durch eine kleine, separate und begrenzte Speichereinheit realisiert. Normalerweise gibt es keinen Compiler für Modelle ohne
Random-Access-Memory.
Um in einer hochleveligen Sprache zu programmieren (Pascal, C, C++), ist es
nicht notwendig, sich mit der inneren Arbeitsweise eine Mikrocontrollers zu beschäftigen, da der Compiler in diesem Fall Mehrzweckregister und Befehle selbst
30
3.4 Taktgeber
auswählen kann. Es kann jedoch nur von Vorteil sein, zu wissen was in einem
Mikrocontroller abläuft. Es ist notwendig die Befehle des Mikrocontrollers genau zu kennen, wenn man zeitkritische Applikationen entwickelt, bei denen die
Operationen in einer begrenzten Anzahl an Taktzyklen beendet sein müssen.
3.4
Taktgeber
Wie die meiste digitale Elektronik, arbeitet auch der AVR in einer konstanten
Frequenz. Eine konstante Frequenz versichert die Zuverlässigkeit von Datenaustausch im Gerät. Es gibt unterschiedliche Methoden um ein Taktsignal für den
AVR zu generieren.
Interner RC Oszillator
Abbildung 3.17: Using an RC oscillator
Dies ist ein interner Taktgeber, welcher keine externen Komponenten benötigt.
Seine größten Nachteile sind niedrige Taktfrequenz und Ungenauigkeit.
Externer RC Oszillator
Funktioniert nach dem gleichen Prinzip wie ein interner Taktgeber und hat keine
signifikanten Vorteile gegenüber diesem.
Schwingquarz
31
3 AVR Mikrocontroller
Abbildung 3.18: Using a crystal oscillator
Schwingquarze nutzen einen Kristall (gewöhnlich einen Quarz), welcher in einem elektrischen Feld in seiner Resonanzfrequenz vibriert. Er hat die piezoelektrische Eigenschaft bei mechanischer Deformation (Vibration) ein elektrisches
Feld zu produzieren. Schwingquarze haben eine Präzision von ca. 0.001%, welche temperaturunabhängig ist.
Keramische Resonatoren
Keramische Resonatoren ähneln den Schwingquarzen, sind aber aus günstigeren piezoelektrischen Materialien gemacht. Keramische Resonatoren sind in der
Regel kleiner als Schwingquarze, aber weniger genau (˜0.5%) und weniger stark
temperaturabhängig.
Externes Taktsignal
Abbildung 3.19: Using an external clock signal
Ein Externes Taktsignal kann mit jedem Gerät erzeugt werden, solange die Frequenz und die Amplitude (Spannung) im richtigen Bereich liegen. Zum Beispiel
kann ein externer Taktgeber benutzt werden um ein Taktsignal gleichzeitig an
mehrere Microcontroller weiterzugeben.
32
3.5 Interrupts
3.5
Interrupts
Interrupts können im AVR - je nach Controller - durch Zähler,
Kommunikations-Interfaces, Analog-zu-Digital Konverter, Komparator, spezielle Input-Output Pins und verschiedene andere Funktionen hervorgerufen werden. Jeder Interrupt kann von der Einheit die ihn generiert, entweder zugelassen werden oder nicht. Unabhängig davon, ob der Interrupt zugelassen ist oder
nicht, gibt es ein 1-Bit Feld (Interrupt Flag) in der dazugehörigen Einheit im Controller, welches mit „true“markiert wird, wenn die Interrupt-Bedingung erfüllt
ist. Wurde die Interrupt-Flag auf „true“geändert wird und der Interrupt zugelassen, dann wird der Controller den für den Interrupt gedachten Code ausführen.
Jeder Interrupt des AVR Microcontrollers ist an ein bestimmtes Ereignis gebunden. Jedes Ereignis hat einen Flag-Bit im Status-Register, welcher den Eintritt
des Ereignisses markiert. Ereignisse sind ebenfalls an die Register der InterruptMasken sowie die dazugehörigen Bits gebunden. Wenn das Interrupt-Bit des Ereignisses unmaskiert ist und ein Ereigniss stattfindet, stoppt der Prozessor die
Ausführung des laufenden Programms für einige Arbeitszyklen und führt das
Interrupt-Programm aus. Nachdem das Interrupt-Programm ausgeführt wurde,
fährt der Prozessor mit seinem pausierten Hauptprogramm fort.
Example
Um Interrupts mit der AVR LibC Bibliothek zu nutzen, ist es notwendig interrupt.h einzubinden. Der Code der ausgeführt wird, wenn der Interrupt stattfindet, wird nach einem „ISR“-Keyword geschrieben. Der Text innerhalb der Klammern nach „ISR“kennzeichnet den Namen des Interrupts. Ein Beispiel in C:
# include <avr/ i n t e r r u p t . h>
ISR ( XXX_vect )
{
// Anweisungen
}
Die generelle Erlaubnis sämtlicher Interrupts wird vom Control- und Statusregister SREG konfiguriert. Die Option, alle Interrupts sofort zu erlauben oder
zu verbieten existiert zum Schutz von Daten. Da Interrupts das Ausführen ei-
33
3 AVR Mikrocontroller
nes Programms unterbrechen, könnten einige Daten im Hauptprogramm dabei
zerstört oder beschädigt werden. Solche Situationen können einfach vermieden
werden, wenn man alle Interrupts verbietet, bevor man mit empfindlichen Daten arbeitet. Das generelle Verbot von Interrupts ist einfach, da hierzu lediglich
ein Register (SREG) geändert werden muss. Nachdem der kritische Teil des Programms ausgeführt wurde, können Interrupts einfach wieder zugelassen werden wodurch dann sämtliche Interrupts die zurückgehalten wurden, ausgeführt
werden.
Example
Angenommen, in diesem Programm wird eine 16-Bit Variable verwendet, welche sowohl von dem Hauptprogramm, als auch vom Interrupt geändert wird
und der Wert dieser Variable wird später einer anderen Variable gegeben.
# include <avr/ i n t e r r u p t . h>
// Globale 16− B i t V a r i a b l e x und y
unsigned s h o r t x , y ;
// Ein zuf ä l l i g e r I n t e r r u p t der den Wert von x ä n d e r t .
ISR ( XXX_vect )
{
x = 0 x3333 ;
}
i n t main ( )
{
// x einen Wert geben
x = 0 x1111 ;
// I n t e r r u p t s g e n e r e l l e r l a u b e n
sei () ;
// y erh ä l t Wert von x
y = x;
}
Das Programm selbst ist sehr einfach - zuerst bekommt die Variable x den Wert
0x1111 und später wird dieser an y weitergegeben. Wenn ein Interrupt zwischen
diesen beiden Operationen auftritt, bekommt x einen Wert von 0x3333. Logisch
gesehen kann y somit zwei mögliche Werte am Ende des Programms haben,
34
3.6 Digitale Inputs/Outputs
allerdings existiert bei einem 8-Bit AVR noch eine dritte Möglichkeit. Hierzu
kommt es, da die 8-Bit Architektur zur Verarbeitung von 16-Bit Daten 2 Taktzyklen braucht. Daher kann ein Interrupt durch schlechtes Timing die Integrität
dieser Daten beschädigen. Dadurch kann y am Ende des Programms den Wert
0x1111 oder 0x3333, aber auch 0x3311 haben Um den dritten und ungewollten
Wert zu verhindern, sollten alle Interrupts temporär verboten werden wenn eine
Operation mehr als einen Taktzyklus umfasst.
Im folgenden Beispiel wird eine sichere Methode benutzt um y den Wert von x
zu geben:
// I n t e r r u p t s g e n e r e l l v e r b i e t e n
cli () ;
// y erh ä l t Wert von x
y = x;
// Sä m t l i c h e I n t e r r u p t s wieder z u l a s s e n
sei () ;
3.6
Digitale Inputs/Outputs
Sämtliche Busse des AVR sind sowohl lesbar als auch beschreibbar, wenn sie im
normalen logischen Input/Output (I/O) Modus verwendet werden. AVR Busse
werden nacheinander mit lateinischen Buchstaben (A, B, C usw.) benannt. Allerdings können einige AVR zwar einen Bus B, jedoch keinen Bus A besitzen.
Jeder Bus ist ein 8-Bit Bus und jedes Bit hat normalerweise seinen eigenen Pin
am Controller. Pins werden mit Ziffern, beginnend bei Null, versehen. Für beide Richtungen im Bus gibt es ein separates Register. Zusätzlich gibt es noch ein
weiteres Register welches die tatsächliche Richtung des Bus festlegt, ein Bitwert
von 1 markiert den Bus als Output und ein Wert von 0 als Input. Damit hat der
Bus drei Register:
PORT - Zur Festsetzung des Outputwertes
35
3 AVR Mikrocontroller
PIN - Zum Auslesen des Inputs am Bus
DDR - Zur Festlegung der Richtung des Busses.
Beispiel
Aufgabe: Die Pins 0-3 von Bus B sollen Input sein, die Pins 4-7 Output, setzen
Sie Pin 5 „high“und lesen Sie die Werte der Pins 0-3 in einer Variable aus. Der CCode sieht wie folgt aus:
# include <avr/ i o . h>
i n t main ( )
{
unsigned char x ;
// P in s 0−3 a l s Input , 4−7 a l s Output
DDRB = 0 xF0 ;
// S e t z t Pin 5 " high "
PORTB |= ( 1 << PIN5 ) ;
// L i e s t den Wert der Pins 0−3
x = PINB & 0 x0F ;
}
In diesem Beispiel, wird der Input im Hi-Z (hochohmig) Modus verwendet.
Im Wesentlichen liegt an diesem Input keine Ladung an. Diese Betriebsart könnte
hilfreich sein, wenn der Pin als Datenbus genutzt wird. Es ist sinnvoll, einen PullUp-Widerstand für den Input zu nutzen, wenn der Pin als Taste, Schalter oder
anderes verwendet wird wobei er mit der Masse verbunden ist. Hierfür muss das
korrespondierende Output-Bit im Inputmodus „high“gesetzt werden. Als Folge
daraus muss zwischen Stromversorgung und Input ein Widerstand eingefügt
werden, welcher die Inputspannung hoch hält, bis irgendetwas sie heruntersetzt.
Ein solcher Pull-Up-Widerstand dient dazu, ein Floaten des Inputs aufgrund von
Reibungselektrizität oder anderen Einwirkungen zu verhindern. Nachdem der
Controller gebootet wurde, befinden sich sämtliche IO Busse standardmäßig im
hochohmigen Inputmodus.
Normalerweise werden die Pins am IO Bus, neben den logischen Anschlüssen,
auch für andere Peripherieschnittstellen genutzt. Soll eine alternative Funktion
36
3.7 Externe Interrupts
des Pins genutzt werden, kann der zugehörige IO Pin-Modus im AVR Datenblatt abgelesen werden. Wenn beispielsweise ein ADC Kanal als Input dienen
soll, sollte der Pin im Input Modus sein. Um jedoch ein ein PWM Signal zu generieren, sollte er im Output Modus betrieben werden. Es gibt jedoch auch Peripheriemodule, die den IO Pin-Modus eigenständig auswählen.
3.7
Externe Interrupts
Externe Interrupts sind eine der einfachsten Funktionen der Peripheriegeräte.
Normalerweise haben AVR’s 1 bis 8 spezielle Pins, welche benutzt werden um
Interrupts im Programm auszulösen, wenn sich entweder ihr logischer Wert ändert oder sie einen bestimmten Status erreichen. Da diese Funktion normalerweise gebraucht wird um externe logische Signale zu überwachen, werden diese
Pins auch externe Interrupt-Pins genannt.
Um einen externen Interrupt zu nutzen, muss der Pins als Standard IO Input (er
kann auch als Output genutzt werden, jedoch kann der Interrupt dann nur vom
Controller selbst ausgelöst werden) konfiguriert werden. Außerdem muss der
Empfang von Interrupts zugelassen sein und die Bedingung, welche den Interrupt auslöst, muss im externen Konfigurationsregister des Interrupts spezifiziert
werden.
Es existieren vier mögliche Bedingungen:
Logische Null (Spannung von 0 V)
Änderung des logischen Werts
Fallende Flanke - logische Änderung von 1 zu 0
Steigende Flanke - logische Änderung von 0 zu 1
Der Modus „logische Null“bewirkt, dass der Interrupt durchgehend ausgelöst
wird, solange der Pin den Wert Null hat. Während dieser Periode wird die Ausführung des Hauptprogramms gestoppt.
37
3 AVR Mikrocontroller
Prinzipiell gibt es zwei Typen von Interrupts: Mit dem Taktgeber des Controllers synchrone und asynchrone Interrupts. Synchrone Interrupts funktionieren
indem sie den Wert des Inputs behalten. Auf diese Weise können Änderungen
der logischen Werte aufgedeckt werden, indem die Werte zwischen zwei Taktzyklen verglichen werden. Erfolgen die Änderungen des Signals schneller als
der Tastzyklus des Controllers, können Interrupts falsch oder gar nicht ausgelöst
werden. Asynchrone Interrupts sind unabhängig vom Taktgeber des Controllers
und können so schnellere Änderungen im externen Signal erfassen - das logische
Level muss jedoch immer noch für mind. 50 ns konstant sein. Der ATmega128
hat 4 synchrone und 4 asynchrone externe Interrupts.
Beispiel
Aufgabe: Lassen Sie ATmega128 Pin Nummer 9 (Pin 7 an Bus E) einen Interrupt
auslösen, wenn sich sein Wert ändert. Der Pin gehört zum externen, synchronen
INT7 Interrupt.
# include <avr/ i n t e r r u p t . h>
// Der Code des e x t e r n e n I n t e r r u p t s
ISR ( INT7_vect )
{
// mache irgendetwas
}
i n t main ( )
{
// Ändere Pin 7 an Bus E zu einem Inputpin , indem B i t 7 auf 0 g e s e t z t
wird
DDRE &= ~(1 << PIN7 ) ;
// D e f i n i e r e einen P u l l −Up Widerstand f ü r Pin 7 an Bus E
// um Input F l o a t i n g zu verhindern .
PORTE |= ( 1 << PIN7 ) ;
// S e t z t den Interruptmodus auf " Logische Änderung " f ü r den I n t e r r u p t
7
// im e x t e r n e n I n t e r r u p t k o n f i g u r a t i o n s r e g i s t e r .
EICRB = ( 1 << ISC70 ) ;
// Erlaube e x t e r n e n I n t e r r u p t 7
EIMSK |= ( 1 << INT7 ) ;
38
3.8 Analog-zu-Digital Konverter
// Erlaube g l o b a l e I n t e r r u p t s
sei () ;
// E n d l o s s c h l e i f e
while ( 1 ) continue ;
}
Verfügt der AVR über ausreichend Pins, ist es möglich, zusätzlich zu einem
Interrupt der von einem einzelnen Pin ausgelöst wird, eine ganze Gruppe an
Pins zu nutzen, um Interrupts durch logische Wertänderungen auszulösen. Diese
Interrupts werden einfach „Pin change Interrupts“genannt. Sie lösen aus, sobald
mindestens der Wert von einem Pin in der Gruppe sich ändert.
3.8
Analog-zu-Digital Konverter
Analog-zu-Digital Konverter (ADC) transformieren einen analogen Spannungswert in einen digitalen Wert. Die erlaubte Spannungsreichweite am ADC-Input
eines AVR Microcontrollers liegt bei 0-5.5V. Der digitale Wert ist 10 Bit groß und
bis auf ± 2 Einheiten genau. Der Fehler kann jedoch auch noch größer sein,
wenn die Betriebsspannung nicht vor Störungen geschützt ist. Der AVR hat separate Betriebs- und Vergleichsspannungs-Pins für den ADC. Die separate Betriebsspannung trägt dazu bei, Störungen möglichst klein zu halten wobei sie
sich nicht mehr als 0.3V von der Hauptbetriebsspannung unterscheiden darf.
Die Vergleichsspannung definiert den maximalen digitalen Wert. Beträgt sie zum
Beispiel 3V beträgt, dann wird ein Input mit der gleichen Spannung mit 210 - 1
(1023) ausgelesen.
Der AVR ADC arbeitet nach dem Prinzip der schrittweisen Annäherung. Kurz
gesagt, die gemessene Spannung wird mit bestimmten Spannungslevels verglichen und die Ergebnisse werden als Bit-Array ausgegeben. Diese Methode ist
relativ langsam, da jedes Bit im Endergebnis einzeln berechnet wird. Der AVR
benötigt 13 Taktzyklen für jede Messung, für die Erste jedoch (beim Start-up )
werden, 25 Taktzyklen benötigt. Diese Taktzyklen entsprechen jedoch nicht den
Arbeitstakten des Controllers, sondern sind spezielle Taktzyklen die der ADCEinheit durch den Frequenzteiler zugewiesen wurden. Um die maximale Präzision zu erreichen, sollte die ADC-Frequenz sollte 50-200 kHz betragen, bei höheren
39
3 AVR Mikrocontroller
Frequenzen sinkt die Genauigkeit. Eine höhere Frequenz ist dann sinnvoll, wenn
viele Daten ausgelesen werden sollen wobei die Genauigkeit dieser vernachlässigt wird. Gemäß dem AVR-Handbuch dauert eine Messung 13-260 µs.
Der gemessene Wert kann als 8- oder 10-Bit Wert gelesen werden. Da der AVR
ein 8-Bit Mikrocontroller ist, verfügt er über zwei 8-Bit Register um ADC-Werte
zu speichern. In den Einstellungen kann festgelegt werden, ob die ersten oder
letzten zwei Bits in ein seperates Register sollen. Falls die zwei zuletzt ausgelesenen Bits, welche das Ergebnis weniger widergeben, separiert werden, kann das
Ergebnis als 8-Bit Wert ausgelesen werden. Eine solche Kombination nennt man
„left aligned result“. Darüber hinaus kennzeichnet „right aligned result“jene Kombination, bei der beide Register gelesen werden, und der Wert ein 10-Bit Format
hat.
Ein normaler AVR verfügt über 8 analoge Spannungs-Input-Kanäle. Die Mikrocontroller der ATtiny Serie besitzen weniger, einige ATmega haben 16, allerdings
existiert immer nur ein ADC. Um verschiedene Inputs nutzen zu können hat
das Gerät einen eingebauten Multiplexer. Der Input des Multiplexer kann durch
Nutzung eines speziellen Registers definiert werden. Die ADC Einheit weist darüber hinaus noch weitere Eigenschaften auf: Der Sleepmodus des Prozessors
wird für die Umwandlung genutzt, um Störungen zu verringern. Außerdem gibt
es die Option zur Nutzung einer internen festen Vergleichsspannung (gewöhnlich 2.65 V, bei manchen Modellen aber 1 V)
Beispiel
Aufgabe: Messen Sie die Spannung des ADC Kanals 3 eines ATmega128. Der
Spannungsbereich liegt bei 0-5 V und das Ergebnis sollte 8-Bit präzise sein.
# include <avr/ i o . h>
i n t main ( )
{
unsigned char r e s u l t ;
// Wä h l e den AREF Pin zum V e r g l e i c h der Spannung
// ( es wird angenommen , dass AREF mit der +5V Stromversorgung
verbunden i s t ) )
// Wä h l e Kanal 3 im M u l t i p l e x e r r
// ordne das E r g e b n i s l i n k s an
ADMUX = ( 1 << REFS0 ) | ( 1 << ADLAR) | ( 3 ) ;
40
3.9 Counters/Timers
// S t a r t e den ADC,
// s e t z e den Umwandlungszyklus 16 mal langsamer a l s das T a s t v e r h ä
ltnis
ADCSRA = ( 1 << ADEN) | ( 1 << ADPS2 ) | ( 1 << ADSC) ;
// Warte auf Beendigung des Messvorganges
while (ADCSRA & ( 1 << ADSC) ) continue ;
// L i e s den 8− B i t Wert aus
r e s u l t = ADCH;
}
3.9
Counters/Timers
Counter, welche man auch in einigen Fällen Taktgeber nennen kann, sind einer
der wichtigsten Unterfunktionen eines Microcontrollers. Diese ermöglichen es
Prozesse exakt zu timen, Signale zu generieren und Ereignisse zu zählen. Ein
Zähler konvertiert die Nummer der Inputzyklen in einen binären Wert mit Hilfe
eines Arrays an Triggern. Die maximale Nummer der gezählten Zyklen hängt
von der Länge des Arrays ab und diese ist markiert von der Länge des binären
Codes. Der AVR hat 8- und 16- Bit Counter. Wenn ein Timer seinen maximalen
Wert erreicht hat(255 bei 8-Bit und 65535 bei 16-Bit), generiert der nächste Zyklus
ein Overflow und der Zähler macht ein Reset auf 0. Das Taktsignal eines Counters kann vom Taktsignal des Microcontrollers kommen und in diesem Fall ist
es möglich den Wert mit einem Prescaler herunter zusetzen. Einige AVRs haben
einen internen unabhängigen Taktgeber, welcher mit einem Frequenzmultiplikator modifiziert werden kann, um schneller zu laufen.Counter unterscheiden sich
auch in Applikationsfällen und Arbeitsmodi.
Counter's default mode
Im Default-Modus macht ein Counter nichts anderes, als fortlaufend
Nummer zu zählen. Sein wert kann natürlich jederzeit ausgelesen, und von ei-
41
3 AVR Mikrocontroller
nem Programm verändert werden. Die einzige zusätzliche Funktion im DefaultModus ist, dass er ein Interrupt beim Counter-Overflow verursacht. Der DefaultModus wird normalerweise benutzt, um eine Sektion eines Programms in bestimmten Intervallen laufen zulassen.
Example
Aufgabe: Ein 8 MHz ATmega128 soll einen Interrupt alle 10ms (100 Hz) auslösen.
Dafür ist der 8-Bit Counter 0 brauchbar.
# include <avr/ i n t e r r u p t . h>
ISR ( TIMER0_OVF_vect )
{
// Gibt den Counter einen Wert ,
// dass der nä c h s t e Overflow i n 10Hz p a s s i e r t .
// Formel : 256 − 8 MHz / 1024 / 100 Hz = 1 7 7 , 7 8 5 = ~178
TCNT0 = 1 7 8 ;
}
i n t main ( )
{
// Um den e r s t e n I n t e r r u p t i n 10ms auszul ösen ,
// muss der Counter i n i t i a l i s i e r t werden .
TCNT0 = 1 7 8 ;
// P r e s c a l e r Wert 1024
TCCR0 = 0 x07 ;
// E r l a u b t Overflow I n t e r r u p t s
TIMSK |= ( 1 << TOIE0 ) ;
// E r l a u b t g l o b a l I n t e r r u p t s
sei () ;
// E n d l o s s c h l e i f e
while ( 1 ) continue ;
}
Der Counter in diesem Beispiel wird den Interrupt nicht in exakt 10 ms generieren, dafür müsste man dem Counter einen Dezimalwert geben, das ist aber
nicht möglich.Um einen präzisen Intervall zwischen den Interrupts zu verwirklichen, wird sowohl der Prescaler Wert, als auch der Wert des Counter müssen
42
3.9 Counters/Timers
so ausgesucht werden, dass ihre Division in einer exakten Nummer endet. Das
ist nicht immer möglich, vor allem mit 8-Bit Countern, da ihr Wertebereich sehr
klein ist. Um einen präziseren oder größeren Intervall zu bekommen, kann ein
16-Bit Counter gewählt werden.
Es ist auch möglich einen externen Taktgeber als das Taktsignals eines Counters zu nutzen.Der AVR hat einen Pin „Tn“
dafür. Das n ist Platzhalter für die Nummer des Counters.Das Externe Taktsignal
und die Polarität kann man im Prescaler Register auswählen.
Externer Taktgeber
Da die Counter zeitlich abgestimmte Operationen ermöglichen,
haben komplexe AVR Microcontroller eine Option auf
Hardware-Level für zeit spezifische Ereignisse.Der Teil des Counter heißt „Input
Capture Unit“. Es gibt eine Auswahl zwischen zwei Ereignissen: Die logische
Änderung eines Werts an einem speziellen Input Pins oder im Wert des analogen
Komparator Ergebnisses. Wenn das gewählte Ereignis eintritt wird der Wert des
Counters in ein spezielles Register geschrieben, welches man jederzeit auslesen
kann. Wenn das Event länger ist als die Overflowzeit des Counter, muss das
Programm die Overflow mit zählen und beim Endergebnis mitberechnen.
Timing events
Example
Aufgabe: Miss die Frequenz eines Externen 122Hz - 100kHz logischen Rechtecksignals mit einem 8MHz ATmega128. Die Messung soll mit einer 1 Hz-Präzision erfolgen. Das Programm nutzt einen 16-Bit Counter mit einer Input Capture
Unit.
# include <avr/ i n t e r r u p t . h>
unsigned long frequency ;
// I n t e r r u p t f ü r das E r e i g n i s
ISR ( TIMER1_CAPT_vect )
{
// Counter t o 0
TCNT1 = 0 ;
43
3 AVR Mikrocontroller
// Das E r g e b n i s i s t nur gü l t i g wenn der Counter
// noch kein Overflow h a t t e .
i f ( ! ( TIFR & ( 1 << TOV1) ) )
{
// Berechnen der Frequenz von der Periode
frequency = ( unsigned long ) 8000000 /
( unsigned long ) ICR1 ;
}
else
{
// Frequenz i s t weniger a l s 122Hz
frequency = 0 ;
// S e t z t d i e Counter Overflow Flagge auf 0
TIFR &= ~(1 << TOV1) ;
}
}
i n t main ( )
{
// R e g i s t r i e r t e i n e " r i s i n g f r o n t " , P r e s c a l e r Wert auf 1
TCCR1B = ( 1 << ICES1 ) | ( 1 << CS10 ) ;
// E r l a u b t E r e i g n i s − I n t e r r u p t s
TIMSK = ( 1 << TICIE1 ) ;
// E r l a u b t g l o b a l I n t e r r u p t s
sei () ;
// E n d l o s s c h l e i f e
while ( 1 ) continue ;
}
Das Programm löst jedes mal bei einer „Rising Front“im externen Signal einen
Interrupt aus.Während des Interrupts, überprüft das Programm den Counter
auf einen Overflow - dass kann passieren wenn die Frequenz des Signals unter 122Hz (8 MHz / 216 ) ist und in so einem Fall spiegelt der Wert des Counters
die echte Periode nicht mehr wieder. Die Frequenz wird berechnent indem man
mit 32-Bit Nummern die Inverse der Periode bekommt. Als erstes setzt man den
Counter auf 0, weil der Timer mit dem gleichen Taktsignal wie der Prozessors
arbeitet und jede Befehlsausführung nach dem externen Event die zu messende
Periode verkürzt und damit das Ergebnis verfälscht. Die maixmale gemessene
44
3.9 Counters/Timers
Frequenz wird durch die Zeit die das Interrupt benötigt limitiert.
Events erfassen und die Zeit registrieren die es brauchte damit das Event
auftrat kann auf Software Level abgehandelt werden. Es ist möglich einen externen oder andere Interrupts zu nutzen und den Wert des Counters während des
Events auszulesen. Das Erfassen auf Hardwarelevel wird genutzt um unabhängig vom Hauptprogramm zu arbeiten und sehr kurze (oder häufige) Events zu
timen.
Taktsignal generieren
Komplexere Counter können ein Taktsignal generieren, zusätzlich zum Timen
eines Signals. Dafür hat der Counter eine „Output Compare Unit“
und eine „Compare Match Output Unit“. Die Output-Compare-Unit hat Register
mit der gleichen Bit-Weite wie der Counter und die Werte dieser Register werden
mit den Werten des Counters verglichen während dieser läuft.Ein Interrupt kann
generiert werden und spezielle Pin Werte können geändert werden wenn der
Counter Wert gleich der des Compare Unit Registers ist. In diesem Moment kann
ein Pin entweder High oder low gesetzt oder invertiert werden. Das Signal wird
durch Änderungen im Wert des Output-Pins generiert.
In einigen Signal-generierenden Modi, kann der maximale Wert des Counters
verändert werden.Die physikalische Größe bleibt die gleiche, aber ein Vergleichsregister wird benutzt um den Counter bei einem bestimmten Wert zu resetten.Das
vorherige Beispiel kann auch mit dieser Methode gelöst werden, aber die Funktion ist eher für das Ändern der Periode des Signals gedacht. Zusätzlich kann
ein Counter so eingestellt werden, dass er mit auf- oder absteigenden Werten
arbeitet.
Der Counter und die Signal-generierenden Modi die diese nutzten sind einer
der komplexesten Peripheriemodule in einem AVR. Über jeden hier zu schreiben
würde eine große Zeitverschwendung sein, normalerweise gibt es keinen Grund
alles zu wissen, um sie zu nutzen. Der folgende Absatz beschreibt einer der üblichen PWM Signale in den Robotics. Der Rest kann den AVR Dokumentationen
entnommen werden.
45
3 AVR Mikrocontroller
Pulsweitenmodulation (PWM) ist ein Typ eines Signals, wo die Frequenz und die Periode(normalerweise) konstant sind, aber die
Länge der Halb-Periode ändert sich. PWM Signale werden benutzt um elektromechanische, optische und andere Geräte zu kontrollieren.Zum Beispiel, ein Servomotor nutzt ein ein 50Hz PWM Signal und haben einen hohe Halbperiode von
1 - 2 ms.
Pulse Width Modulation
Example
Aufgabe: Generiere mit einem 8Mhz ATmega128, zwei Geschwindigkeits-regulierende Servomotor Signale. Nutze Pin PB5 (OC1A) um eine Pulsweite von 1ms
zu generieren und Pin PB6 (OC1B) um eine Pulsweite von 2ms zu generieren.
# include <avr/ i o . h>
i n t main ( )
{
// S e t p i n s as outputs
DDRB |= ( 1 << PIN5 ) | ( 1 << PIN6 ) ;
// S e t outputs A and B low f o r comparison ,
// " F a s t PWM" mode , p r e s c a l e r value 8
TCCR1A = ( 1 << COM1A1) | ( 1 << COM1B1) | ( 1 << WGM11) ;
TCCR1B = ( 1 << WGM13) | ( 1 << WGM12) | ( 1 << CS11 ) ;
// Maximum value o f t h e c o u n t e r . Formula :
//
TOP = 8 MHz / 8 / 50 Hz
ICR1 = 2 0 0 0 0 ;
// Half −period o f t h e f i r s t motor i s 1 ms , and second 2 ms
OCR1A = 1 0 0 0 ;
OCR1B = 2 0 0 0 ;
// Endless loop
while ( 1 ) continue ;
}
46
3.10 USART
3.10
USART
USART ist ein Universal Synchrones Serielles Interface, UART ist die vereinfachte Version - Universelles Asynchrones Interface. Der Unterschied zwischen beiden liegt darin, dass das USART auch eine Taktsignalleitung nutzt um Daten
zu synchronisieren, während das UART nur Datenleitungen benutzt. Das UART
des AVR Mikrocontrollers Duplexverkehr, 5- bis 9-Bit Datenworte (8-Bit Wort
= 1 Byte), 1 oder 2 Stop Bits, 3 Paritätsmodi und eine Vielzahl an Baud-Raten
zulässt. AVR Mikrocontroller verfügen normalerweise über bis zu 2 USART Interfaces, jedoch gibt es auch einige ohne USART. Datenübertragungen werden
mit einen Wort für Wort ausgeführt - der AVR konvertiert das Wort, welches er
vom Benutzer bekommt in Bits auf Hardwareeinheiten und übermittelt es unabhängig und andersherum. Der Benutzer kann das USART mit Schreib- und
Lesekonfigurationen sowie Status- und Datenregistern kontrollieren.
Jede Einstellungsoption hat ein eigenes Register, welches recht einfach anhand
des Datenblatts konfiguriert werden kann. Die Baud-Rate ist allerdings etwas
schwieriger einzustellen. Das Taktsignal für die Datenübertragung wird vom
Taktgeber des Controllers generiert und der Nutzer kann eine Zahl von 1 bis 4096
eingeben, durch welche die Taktrate dividiert wird. Das Ergebnis wird darüber
hinaus, je nach Modus, durch 2, 8 oder 16 dividiert. Das Problem ist, dass nicht alle Taktfrequenzen so dividiert werden können, dass das Ergebnis eine StandardBaud-Rate ergibt. Bei einigen Frequenzen kann die Baud-Rate bis zu 10% vom
Standardwert abweichen. Die Datenblätter des AVR beinhalten Tabellen mit Angaben zu den typischen Taktfrequenzen, Baud-Raten, den nötigen Multiplikatoren um die Baud-Raten zu erreichen sowie den möglichen Rechenfehlern.
Da die Datenübertragung unabhängig vom Prozessor und viel langsamer geschieht, ist es nötig zu bestätigen, dass das Interface für das nächste Wort bereit
ist, bevor eine weitere Übertragung stattfindet. Das kann gewährleistet werden,
indem das Ready Bit des Sendepuffers beachtet wird, welches anzeigt ob der
Puffer bereit ist, ein neues Wort zu empfangen oder nicht. Der Controller startet
mit einen aktivierten Ready Bit. Sobald ein Wort übertragen wird und der Puffer
leer ist, wird das Ready Bit „high“gesetzt.
Der Empfang eines Wortes ist wird durch ein spezielles Status-Bit gekennzeichnet. Zusätzlich gibt es Status-Bits, welche Rahmenfehler, Paritätsfehler und Puf-
47
3 AVR Mikrocontroller
ferüberläufe anzeigen. Ein Pufferüberlauf tritt auf, wenn das letzte Wort noch
aus dem Puffer gelesen werden muss, während ein neues ankommt. Aus diesem
Grund ist es wichtig, die empfangenen Datenwörter stets so schnell wie möglich ins Programm zu lesen, z.B. mit Hilfe eines Interrupts. Es gibt drei mögliche
Gründe für Interrupts: Sendepuffer bereit, Übertragung erfolgreich, Empfang erfolgreich.
Der Sende- und Empfangspuffer sind physikalisch getrennte Register, aber sie
nutzen die gleiche Speicheradresse und den gleichen Namen. Während des Schreibens in ein gemeinsam benutztes Register, werden die Daten im Sendepuffer gespeichert, beim Auslesen werden sie aus dem Empfangspuffer gelesen. Werden
9-Bit Worte benutzt, wird das 9. Bit mit Hilfe eines Einstellungsregister übertragen und ausgelesen.
Beispiel
Aufgabe: Konfigurieren Sie die USART0 Schnittstelle eines 8 MHz ATmega128
so, dass sie ein 8-Bit-Wort asynchron überträgt, wobei die Baudrate 9600 bps beträgt, 1 Stoppbit und kein Paritätsbit genutzt werden soll. Senden Sie das Symbol
“X“.
# include <avr/ i o . h>
i n t main ( )
{
// S e t z t d i e Baud−Rate auf 9600 bps . Formel :
//
F a k t o r = Frequenz / 16 / Baudrate −1
//
UBRR = 8000000 / 16 / 9600 − 1 = ~51
UBRR0H = 0 ;
UBRR0L = 5 1 ;
// Erlaube Senden
UCSR0B = ( 1 << TXEN0) ;
// K o n f i g u r i e r e den asynchronen Modus , s e t z e d i e Wortgrö ß e auf 8 B i t
,
// 1 S t o p p b i t , kein P a r i t ä t s b i t .
UCSR0C = ( 1 << UCSZ01 ) | ( 1 << UCSZ00 ) ;
// Warte solange , b i s der Datenpuff er l e e r i s t ( das v o r h e r i g e Wort
wurde gesendet )
// In diesem B e i s p i e l i s t es je do c h n i c h t nö t i g zu warten , da nur das
48
3.10 USART
e r s t e Symbol
// gesendet wird . Es s o l l t e je do c h b e a c h t e t werden , wenn mehr
a l s e i n Symbol gesendet wird .
while ( ! ( UCSR0A & ( 1 << UDRE) ) ) continue ;
// S c h r e i b e das Symbol i n den Sendepuffer .
UDR0 = ’X ’ ;
// E n d l o s s c h l e i f e
while ( 1 ) continue ;
}
49
4
Elektronik
Verschiedene elektronische Schaltkreise werden so häufig in praktischen Beispielen verwendet, dass sie in den folgenden Kapiteln separat beschrieben werden.
Da sie das Verständnis der Beispiele sowie den Bau eigener Schaltkreise erleichtern, ist es wichtig sie zu kennen.
4 Elektronik
4.1
Ohm'sches Gesetz
Das Ohm’sche Gesetz besagt, dass die Stromstärke eines elektrischen Leiters direkt proportional zu der potenziellen Differenz oder Spannung zwischen zwei
Punkten sowie umgekehrt proportional zu dem Widerstand zwischen diesen ist,
unter der Voraussetzung, dass die Temperatur konstant bleibt.
Die Gleichung lautet wie folgt:
Abbildung 4.1: Resistance of the conductor, applied voltage and current through the resistance
I=U/R
mit:
I für die Stromstärke [in A]
U für die Spannung [in V]
R für den elektrische Widerstand [in Ω]
Viele weitere, in der Elektronik häufig verwendete Gleichungen sind vom Ohm’schen
Gesetz abgeleitet.
52
4.2 Berechnung des LED-Widerstands
4.2
Berechnung des LED-Widerstands
Für den Fall, dass die Betriebsspannung höher ist als die Spannung der LED,
muss der Widerstand in Reihe in den Stromkreislauf geschaltet werden. Er begrenzt die Spannung und erzeugt dadurch den notwendigen Spannungsabfall.
Um den korrekten Widerstand auszuwählen, wird folgende, vom Ohm’schen
Gesetz abgeleitete, Gleichung angewandt:
Abbildung 4.2: LED mit in Serie geschaltetem Widerstand
R = (Uin - U f ) / I f
Ur = Uin - U f
Pr = Ur · I f
mit:
R für den Widerstand.
Uin für die Betriebsspannung.
U f für die LED Spannung.
53
4 Elektronik
I f für die LED Stromstärke.
Ur für den Spannungsabfall am Widerstand.
Pr für die Leistung des Widerstands, welche in Wärme umgewandelt wird.
Der spannungsbegrenzende Widerstand einer LED darf nicht geringer sein als R
und muss mindestens die Leistung von Pr haben.
4.3
Spannungsteiler
Ein Spannungsteiler ist ein elektrischer Schaltkreis, der die Eingangsspannung
teilt. Die Ausgangsspannung ist ein Teil der Eingangsspannung und der Wert ist
abhängig vom Verhältnis der Widerstände im Schaltkreis. Die Abbildung rechts
zeigt ein Beispiel mit zwei Widerständen.
Die Ausgangsspannung des Schaltkreises wird mit folgender Gleichung berechnet:
Abbildung 4.3: Schaltplan eines Spannungsteilers
U2 = U1 · (R2 / (R1 + R2 ))
54
4.3 Spannungsteiler
mit:
U1 für die Eingangsspannung
U2 für die Ausgangsspannung
R1 und R2 für die Widerstände
Die Gleichung ist vom Ohm’schen Gesetz abgeleitet.
mit:
I = U1 / (R1 + R2 )
und:
U2 = I · R2
Spannungsteiler werden häufig im Zusammenhang mit Widerstandssensoren
(Fotowiderstand, temperaturgesteuerter Widerstand etc.) verwendet, wobei einer der Widerstände durch einen Widerstandssensor ersetzt wird. Dadurch wird
die Widerstandsänderung des Sensors einfach in eine Spannungsänderung transformiert, welche kompatibel zu dem analogen Input des Mikrocontrollers ist.
55
5
Robotic HomeLab Kit
5 Robotic HomeLab Kit
Das auf dem ATmega128 Mikrocontroller basierende Mechatronik und Robotik
HomeLab ist eine Zusammenstellung von Modulen in einem tragbaren Koffer.
Es ermöglicht die Durchführung diverser Mechatronik- und Robotikexperimente und -übungen, angefangen bei einem Blinklicht bis hin zur Erstellung komplexer Geräte. In erster Linie richtet sich das HomeLab an Schulen, da es zusätzlich
zur Hardware methodologisches Material sowie Übungen mit Musterlösungen
enthält. Das HomeLab wurde in eine Web-Umgebung integriert, welche Schülern und Lehrern die gegenseitige Interaktion ermöglichen soll. Kurz gefasst ist
das HomeLab kit eine Sammlung mobiler Werkzeuge mit dem Zweck zu Hause,
in der Schule oder am Arbeitsplatz lernen und üben zu können.
Das HomeLab kit wurde von der Tallinn University of Technology sowie estnischen Unternehmen in Kooperation mit europäischen Partneruniversitäten und
der Unterstützung des Leonardo da Vinci Programms entwickelt. Die HomeLab Module sind zu verschiedenen Bausätzen zusammengestellt. Die Grundausstattung, welche zum Erlernen einfacher digitaler In- und Output-Operationen
dient, nennt sich HomeLab Basic kit. Der Sensoren und Bedienteil Ergänzungsbausatz besteht aus einer Zusammenstellung von Sensoren, Motoren sowie deren Treibern. Das Advanced kit enthält sowohl das HomeLab Basic kit sowie das
Sensors and Actuators Add-on kit und darüber hinaus zusätzliche Module.
Die HomeLab Basic und Advanced kits eignen sich zur Durchführung von Experimenten, als Basisplattform für Roboter sowie andere mechatronische Regeltechniken. Das HomeLab wird ständig weiterentwickelt, daher lohnt es sich, regelmäßig nachzuschauen, ob neue Übungsaufgaben oder Modul-Updates veröffentlicht wurden. Darüber hinaus ist es lohnenswert, die Versionsnummern
der Module zu überprüfen, da einige Übungsaufgaben und Beispiele in neueren
Versionen verfügbar sind. Die Nutzung von DistanceLab erhöht den Nuten von
HomeLab maßgeblich. DistanceLab ermöglicht es, die HomeLab Hardware über
das Internet zu betreiben.
HomeLab Webseite
http://home.roboticlab.eu
DistanceLab Webseite
http://distance.roboticlab.eu
58
5.1 Ganzheitliches Konzept der Robotik
5.1
Ganzheitliches Konzept der Robotik
Die Ingenieurausbildung kann sich heutzutage nicht mehr auf einer bestimmten
Lehrmethode aufbauen, wie zum Beispiel klassische universitäre Vorlesungen
und Übungen. Lernende sind heute nicht mehr mit zeitlich festgelegten Vorlesungen und Übungen zufrieden. Viele junge Leute, aber auch Erwachsene, leben ein Leben in einer modernen Informationsgesellschaft, in welchem Sie viel
Zeit im Internet verbringen. Daher bestätigen die klassischen Lernmethoden die
Lernenden und ihre Art zu Lernen heute nicht mehr. Aufgrund dessen müssen
die Ingenieursausbildungen in eine Internetumgebung gebracht und dadurch
attraktiver werden, ohne jedoch die Qualität und die praktische Erfahrung zu
verlieren.The integrated concept of robotic and mechatronic study incorporates
the standard teaching and studying aids and novel approaches, which are integrated into one methodical unit.
Das ganzheitliche Konzept der Robotik und Mechatronik beinhaltet sowohl standardisierte Lehrmethoden und Lernhilfen, als auch neue Ansätze, welche in einer systematischen Einheit untergebracht sind.
Das folgende Beispiel kann Schulen helfen Kurse zur Robotik zu starten oder
einen Denkanstoß zu geben, wie man verschiedene Lernkonzepte in einer praktische Lerneinheit in diesem technologischen Feld anwendet.
Das Konzept beinhaltet die folgenden Lehr- und Lernhilfsmittel:
Koventionelles Lehrbuch, z.B. „Integrated Systems & Design“ISBN: 9789985-59-850-4.
Praktisches Übungsbuch
Robotic HomeLab
DistanceLab
Das Kompetenznetzwerk der Robotik- und
Mechatronikgemeinschaft http://www.roboticlab.eu.
Theoretische Lernhilfsmittel sind das konventionelle Lehrbuch und das Übungs-
59
5 Robotic HomeLab Kit
buch, welches zusätzlich zur Papierversion auf elektronisch erhältlich ist.
Der praktische Teil besteht aus dem Robotic HomeLab und dem DistanceLab,
einer internetbasierten Programmierumgebung für Roboter. Das HomeLab bildet zusammen mit dem DistanceLab eine kompakte Lösung, was bedeutet, dass
der Lernende auch einzelne Funtionen der Robotik (z.B. Sensormesswerte, Motorsteuerung, etc.) von zuhause aus ausprobieren und gleichzeitig sein erlerntes
Wissen im Robotersystem anwenden kann. Das Robotersystem kann über das
DistanceLab erreicht werden, welches aus realen Geräten besteht. Das System
selbst ist aus denselben Komponenten zusammengestellt, wie sie auch im mobilen
HomeLab-Koffer enthalten sind.
Der Ablauf von einem Lernprozess bzw. der Arbeit mit dem Lab ist auf dem
nächsten Bild beschrieben.
Das Thema beginnt mit einer Einführung, welche eine klassische Vorlesung, eine Onlinevorlesung oder eine Videovorlesung sein kann. Die Videovorlesungen
sind auch für die klassischen Vorlesungen wichtig, da sie die Möglichkeit bieten eine Vorlesung erneut zu sehen, sollte etwas unklar geblieben oder der Studierende nicht in der Lage gewesen sein, an der Vorlesung teil zu nehmen. Die
60
5.2 Robotik unterrichten
Einführungsvorlesung gibt eine Übersicht über das jeweilige Problem und mit
Hilfe eines Lehrers kann dann ein praktisches Beispiel durchgegangen werden.
Der theoretische Teil wird durch das Lehrbuch und das praktische Übungsbuch
unterstützt.
Nach der Einführungsvorlesung wird der praktische Arbeitsteil realisiert. Die
Praktische Arbeit besteht anfangs darin, die Codebeispiele auszuführen und später darin, die Beispiele entsprechend der Übung zu verändern. Daraufhin folgen
komplexere Übungen, welche durch einen Lehrer jeder Person oder jedem Team
individuell aus dem Übungsbuch zugeteilt werden.
Die Ergebnisse der praktischen Arbeit werden in einem Bericht zusammengefasst und dem Betreuer zugeschickt. Falls die Entwicklungsumgebung eine automatische Berichterstattung unterstützt, so kann diese anstatt dem Senden einer
Email genutzt werden. Zusätzlich zu den Textberichten wird außerdem die HEXDatei für die Arbeitsmaschine eingebunden. Der Bericht umfasst typischerweise die Beschreibung der Arbeit und einen vollständig kommentierten Quellcode
der Lösung.
5.2
Robotik unterrichten
Es ist allseits bekannt, dass die Informations- und Telekommunikationstechnologie (ICT) in das tägliche Leben von vielen Menschen eingetreten ist und die
Art und Weise des Lernens und der Kommunikation verändert hat. Viele junge
Leute sind es gewohnt Informationen über das Kursmaterial über verschiedene Kommunikationswege aus dem Internet zu bekommen. Bevor versucht wird
ein Problem zu lösen wird erst eine schnelle Suche nach möglichen Lösungen,
Beispielen oder Hintergrundinformationen durchgeführt. Da die tägliche Kommunikation teilweise in soziale Netzwerke verlagert wurde, ist es nur natürlich,
dass die Methodik, welche von den Schulen angewandt wird auch diesem Trend
folgen muss, um die Studierenden in ihrem täglichen Umfeld zu erreichen. Natürlich wird die traditionelle Lehrmethodik nicht komplett ersetzt, aber sich nur
auf diese zu verlassen ist heutzutage nicht mehr genug.
Robotik und Mechatronik sind sehr zukunftsreiche Gebiete, in denen es sehr
wichtig ist den neuesten Trends und Technologien zu folgen. Gleichzeitig sind
61
5 Robotic HomeLab Kit
diese Gebiete sehr praktisch veranlagt und es verlangt viel manuelle Erfahrung
Fähigkeiten und Wissen zu erlangen. Selbst verschiedene virtuelle Simulationen
können durchgeführt werden um das Systemverhalten zu verstehen. Trotzdem
ersetzten die virtuellen Simulationen nicht die praktische Erfahrung mit echter Hardware.Das Folgende ist eine praktische Anleitung wie ein Robotikkurs
eingeführt werden kann, in dem verschiedene Lehransätze genutzt werden. Die
Methodik erwartet, dass der Lehrer das HomeLab kit benutzen kann.
Aspekte die bei der Erstellung eines neuen Kursen berücksichtigt werden müssen:
1. Gruppengröße
Die optimale Anzahl der Teammitglieder ist weitgehend durch die Anzahl
der Computer Arbeitsplätze begrenzt. Das bedeutet, dass normalerweise
nicht mehr als 3 Personen zusammen an einem Arbeitsplatz arbeiten können. Wenn mehr Personen an einem Arbeitsplatz arbeiten müssen könnte
es sein, dass sie nicht in der Lage sind aktiv an der Arbeit teilzunehmen
und somit die Konzentration auf die Arbeit verloren geht.
2. Praktische Arbeit und Berichterstattung
Die Praktische Arbeit ist unterteilt in Übungseinheiten, wobei jede Übung
eine ähnliche Struktur besitzt und mit einem Bericht endet, jedoch unterschiedliche Fähigkeiten trainiert. Es ist außerdem möglich die Arbeit innerhalb der Gruppe aufzuteilen, so dass zum Beispiel ein Mitglied für die
Erstellung des Quellcodes, ein anderes Mitglied für die Erstellung des Berichts und ein Mitglied für das Anschließen der Hardware verantwortlich
ist. Zusätzlich zu dem kommentierten Quellcode sollte der Bericht auch
Algorithmen, Beschreibungen der Arbeit, Antworten auf die gestellten Fragen, ein Schema der Hardwareverbindungen und Vor- und Nachteilbeurteilungen der Übung enthalten. Der letzte Punkt ist ein gutes Feedback für
den Lehrenden um den Schwierigkeitsgrad der Übung einzuschätzen und
wie interessant die Übung für die Lernenden war.
Es ist wichtig, dass man die Beispiele zusammen mit einem Betreuer implementiert, da dieser Hintergrundinformationen zu den Funktionen bieten und die Beispiele lösen kann. Die ganze Vorgehensweise sollte schriftlich Schritt für Schritt festgehalten werden, damit jeder Lernende folgen
kann und so sicher gegangen werden kann, dass alle Teilnehmer den Ab-
62
5.2 Robotik unterrichten
lauf verstanden haben, auch wenn sie in unterschiedlichen Geschwindigkeiten voran kommen. Eine mögliche Übungsablaufstruktur ist im Folgenden beschrieben, kann jedoch je nach Situation und Bedürfnissen angepasst
werden.
Einführung in die Übung
– Der Lehrer erklärt die neue Übung, geht alle nötigen theoretischen Inhalte durch und führt zusammen mit dem Teilnehmern
ein Beispielprogramm aus.
– Die Übungseinheit ist in kleinere Teile unterteilt, wobei jeder Teil
aus einem theoretischen und einem praktischen Teil besteht, in
welchem dann Quellcode entwickelt werden soll. Das bedeutet,
dass der Quellcode anhand von theoretischen Erklärungen entwickelt wird.
Individuelle Arbeit. Die individuelle Arbeit erfolgt gemäß den Arbeitsanweisungen der Übungseinheit. Hier sind Ziele, Arbeitsprozesse, Anforderungen und die Berichterstattung definiert. Die Schüler
lernen selbstständig (entweder alleine oder in einer kleinen Gruppe)
und erhalten, wenn nötig, Unterstützung von ihren Lehrern. Ziel des
eigenständigen Arbeitns ist jedoch, die Lösung selbstständig zu finden. Wenn möglich, sollten die Schüler das HomeLab kit mit nach
Hause nehmen können, um so auch dort arbeiten zu können. So sind
sie nicht an den Zeitrahmen und Ort der Übung gebunden.
Berichte. Lernende müssen einen Bericht verfassen, in welchem sie ih´ Anforderungen an einen Bericht beschreiben und
re Arbeit gemäden
welcher Antworten auf Fragen des Lehrers an die Gruppe gibt. Der
Bericht sowie die Lösung der Aufgabe (HEX-Datei) sollen dem Lehrer
per E-Mail zugeschickt oder in den E-Learning Bereich hochgeladen
werden.
Überprüfung
– Der Lehrer überprüft und bewertet den Bericht sowie die erarbeitete Lösung jeder Gruppe qualitativ.
63
5 Robotic HomeLab Kit
– Er kann überprüfen, ob die Lösung entsprechend der
Übungsvoraussetzungen funktioniert und darüber hinaus von den
Schülern verlangen, das Programm mündlich zu erläutern. In diesem Fall sollte jedes Gruppenmitglied einen Teil des Berichtes erklären.
3. Gruppenmanagement
Bei der Durchführung von Übungen in einem Klassenraum kommt es häufig vor, dass eine GRuppe langsamer arbeitet als die anderen und somit
stärker vom Lehrer unterstützt werden muss, um nicht hinterherzuhängen.
Ähnlich ist es, wenn eine Gruppe schneller arbeitet als alle anderen und
somit auf die nächste Aufgabe warten muss. Beide Probleme können minimiert werden, wenn der Arbeitsprozess für alle offensichtlich dargestellt
ist und jeder einzelne die vollständigen Übungsanweisungen zu Beginn
der Übung erhält. So kann die Gruppe arbeiten, ohne auf die nächstesn
Anweisungen des Lehrers warten zu müssen, indem sie einfach den Anweisungen folgt. Darüber hinaus enthält jeder Übungsabschnitt am Ende
Aufgaben in verschiedenen Schwierigkeitsgraden, die der Lehrer je nach
Fortschritt und Fähigkeiten der Gruppe verteilen kann.
4. Bewertung
Soll letztendlich sicher gestellt werden, dass alle Teilnehmer die vorgestellten Programmierfähigkeiten erlernt haben, so kann der Leherer die Gruppenarbeit derart gestalten, dass jedes Gruppenmitglied selbst programmieren und dieses auch präsentieren muss. Eine andere Möglichkeit wäre, dass
der Lehrer zufällig ein Mitglied der Gruppe auswählt, welches dann das
Programm vorstellen muss. Auch wenn diese Person den Code vielleicht
nicht persönlich geschrieben hat. Das Endergebnis wird dann für die gesamte Gruppe gezählt, ausgehend vom Schwächsten Mitglied. Sollte diese
Art der Bewertung ungerecht wirken, kann auch innerhalb der Gruppe eine individuelle Berichterstattung durchgeführt werden.
5. Fehlerbehebung
Die Schüler machen im Umgang mit der Hardware oder beim Programmieren häufig ähnliche Fehler. Daher ist es sinnvoll, auf der Webseite einen
Bereich für häufig gestellte Fragen (FAQ - Frequently Asked Questions)
einzurichten. So können die Lernenden Zeit sparen, da sie bei häufig auf-
64
5.2 Robotik unterrichten
tretenden Fragen oder Problemen schnell Hilfe finden. Der FAQ-Bereich
sollte zusammen mit den Lösungen im Support-Bereich der HomeLab Webseite verfügbar sein.
6. Wettbewerb
Zur Steigerung der Begeisterung für Robotik-Studien kann die praktische
Arbeit mit einer Art Wettbewerb verbunden werden. Die Gruppen müssen
zu einem gegebenen Problem eine Lösung erarbeiten, welche anschließend
gemeinsam bewertet wird. Die Beurteilungskriterien (Zeit, Geschwindigkeit, Entfernung, etc.) müssen klar definiert und bekannt gegeben werden.
Darüber hinaus können weitere Kriterien herangezogen werden um die
Ansicht, den Erfindungsreichtung, die Kosteneffizenz und weitere Aspekte der Lösung zu bewerten. Die Aufgabe kann darüber hinaus auch mit
Problemstellungen des täglichen Lebens verbunden werden wie zum Beispiel ein Projekt zu Batteriesortierern oder Sicherheitssystemen. Meistens
werden Aufgaben aus der Hobbyrobotk oder der mobilen Robotik gestellt,
wie beispielsweise ein Roboter, der einer Linie folgen soll, Sumoroboter,
Ballspiele etc.
Das folgende Beispiel veranschaulicht eine typische Übungsanweisung, die für
praktische Übungen verwendet werden kann.
Lab Nr 3. Sensoren und Analog-Digital Konverter
Leiter: Sven Seiler
Das Ziel
1. Grundlagen über Analog-Digital-Konverter und das Konvertieren analoger Signale mit dem AVR ATmega128 8-Bit Mikrocontroller.
2. Verschiedenen Sensoren mit analogem Output kennenlernen
3. Eine einfache Übung mit einem analogen Sensor durchführen.
Benötigte Ausrüstung
HomeLab Basic kit, Sensor and Motor Add-On kit, AVR Programmiersoftware.
65
5 Robotic HomeLab Kit
Arbeitsanweisungem
1. Führen Sie die Übung mit dem Potentiometer durch.
http://home.roboticlab.eu/en/examples/sensor/potentiometer
2. Führen Sie die allgemeine Aufwärmübung durch.
http://home.roboticlab.eu/en/exercises/sensor
3. Absolvieren Sie die gruppenspezifische Aufgabe. (diese wird rechtzeitig
vom Übungsleiter bekannt gegeben)
4. Beantworten Sie die Fragen (gruppenspezifische Fragen werden rechtzeitig
vom Übungsleiter bekannt gegeben)
Bericht
Der elektronische Bericht muss nach der eigenständigen Arbeit eingereicht werden und folgende Struktur aufweisen:
Arbeitsbericht
– Das Ziel
– Kurze Beschreibung der durchgeführten Arbeit
– Ausdruck des Algorithmus und Quellcodes für die Schritte 2 und 3.
Achtung! Der Quellcode muss kommentiert und farbig gekennzeichnet sein(um das Farbsystem korrekt in MS Word oder einem OpenOffice Programm darzustellen könnte das „Programmer’s Notepad“genutzt
werden)
– Anworten auf die Fragen (Schritt4)
– Ergebnisse und Kommentare
Lösungen (HEX-Dateien) von Schritt 2 und 3
Der Bericht muss den eigenen Namen, die Nummer des Übungsabschnitts, das
Datum sowie die Namen der Gruppenmitglieder (bei einer Gruppenarbeit) ent-
66
5.3 HomeLab Hardware
halten. Er sollte kurz und präzise verfasst sein wobei die Qualität wichtig ist,
nicht die Quantität. Sie sollten darauf vorbereitet sein, die Lösung zu präsentieren oder den Quellcode zu kommentieren. Der Bereicht muss in den Bereich für
Hausarbeiten des E-Learning Systems hochgeladen werden. Der letzte Abgabetermin für den Bericht ist eine Woche nach Beginn der Übung.
Lektüren
1. HomeLab Support-Center: http://home.roboticlab.eu
2. ATmega128 Datenblatt
3. Sharp Infrarotsensor Datenblatt
4. http://www.avrfreaks.net
5.3
HomeLab Hardware
Die Module des Robotik HomeLab sind in unterschiedliche Bausätze
(„kits“) eingeteilt, um so die am besten geeignete Ausstattung für die Bedürfnisse eines Studenten oder einer Schule auswählen zu können. Das einfachste
Set ist das HomeLab Basic kit, welches die für grundlegende Mikrocontrollerexperimente notwendigen Komponenten enthält. Darüber hinaus verfügt es über
eine Anwendungsoberfläche mit LCD Display. Das Basic kit kann zusammen
mit dem Motor and Sensor Add-On kit verwendet werden. Letzteres beinhaltet verschiedene Arten von Motoren und Sensoren sowie zusätzliches Zubehör
und Kommunikationsmodule. Das Sensor and Motor Add-On kit kann nicht ohne das Basic kit verwendet werden, da der Mikrocontroller nicht in dem AddOn enthalten ist. Außerdem enthält das Add-On kit RFID sowie Machine Vision Module. Basic und Add-On kit sind komfortabel im Gebrauch und können
bequem transportiert werden, um die Robotikexperimente zu Hause oder am
Arbeitsplatz durchzuführen.
67
5 Robotic HomeLab Kit
HomeLab Basic kit
Abbildung 5.1: HomeLab Basic kit
AVR ATmega2561 Entwicklungsplatine, inklusive Ethernet, SD Kartenlesen und integriertem JTAG Programmiergerät
Benutzerschnittstellenplatine (Schalter, LEDs, graphisches LCD, 7-Segment
Anzeige)
USB Kabel
Beispielaufgaben mit C-Quellcode
Softwarebibliothek
Stromversorgung
Multimeter
Software zur Programmierung in Assembler und C
Tragbarer Koffer
Sensor and Motor Add-On kit
Sensormodul
Analoge Sensoren- und Tiefpassplatine mit on-board Sensoren (Tempera-
68
5.3 HomeLab Hardware
tursensor, Lichtsensor, Potentiometer und Mikrofon)
Ultraschallentfernungssensor SRF05 mit Kabel
Infrarotentfernungssensor mit Kabel
Abbildung 5.2: Sensor and Motor Add-On kit
Motormodul
DC Motor (mit Getriebe und Kodierer)
RC Servomotor
Schrittmotor (uni- oder bipolarer Schrittbetrieb)
Motorentreiberplatine
Versorgungsteiler
Kommunikationsmodul
69
5 Robotic HomeLab Kit
Kommunikationsplatine, 2xRS232
ZigBee oder Bluetooth Funkeinheit
Zusätzliche HomeLab Module
Zusätzliche Module sind nicht in den Koffern enthalten, können jedoch direkt
mit dem HomeLab Kommunikationsmodul verbunden werden. Es gibt für diese
Module ebenfalls praktische Beispiele und Übungsaufgaben.
RFID Modul
Hochfreqzenz RFID Lesegerät
Tag (2)
Kabel
Machine Vision Module
Intelligentes Kamera Module (CMUcam3)
70
5.4 HomeLab Bibliothek
— MISSING PAGE —— MISSING PAGE —— MISSING PAGE —— MISSING
PAGE —
5.4
HomeLab Bibliothek
Die HomeLab Bibliothek besteht aus einigen C Header-Dateien (mit der Dateiendung „.h“) und einer statischen Bibliotheksdatei (mit der Dateiendung „.a“).
Während der Installation der Bibliothek werden diese Dateien vollständig in den
AVR-GCC Unterordner kopiert. Hier findet der Compiler sie automatisch. Der
Benutzer muss diese Dateien somit nicht mehr in den Programmordner kopieren.
71
5 Robotic HomeLab Kit
Abbildung 5.3: HomeLab Bibliothek Quellcode Dateien
Die schrittweisen Installationsanweisungen der AVR Entwicklungssoftware für
Windows und Linux sind im ersten Kapitel zu den praktischen Beispielen dargestellt. Auch wenn unterschiedliche Beispiele auf verschiedene Teile der Bibliothek zurückgreifen, muss in jedem Projekt die statische Bibliotheksdatei („.a“Datei)
vorhanden sein. Nur die Header-Dateien können wahlweise eingeladen werden. Header-Dateien, die in direktem Bezug zum AVR Mikrocontroller stehen,
sind im „homelab“-Ordner abgelegt. HomeLab modulspezifische Dateien sind
im Ordner „homelab/module“zu finden. Beide Ordner befinden sich im RootOrdner des Compilers. Um die Dateien dieser Ordner zu verwenden, müssen
größer- / kleiner-Zeichen genutzt werden um den Pfad anzugeben. Nachfolgend
finden Sie ein Beispiel, wie Header-Dateien für AVR Pins und HomeLab Motoren
integriert werden können:
72
5.4 HomeLab Bibliothek
# include <homelab/pin . h>
# include <homelab/module/motors . h>
Falls die HomeLab Bibliothek nicht genutzt wird, muss die folgende avrlibc
Header-Datei in das Projekt eingefügt werden:
# include <avr/ i o . h>
Die HomeLab Bibliothek enthält diese Datei bereits in der pin.h Datei.
Das Installationsprogramm für die HomeLab Bibliothek ist auf der HomeLab
Webseite verfügbar. Nutzer, die die Bibliothek an Ihre Bedürfnisse anpassen möchten, können hier auch den Quellcode dafür herunterladen. Das folgende Kapitel
beschreibt die Funktionen der Bibliothek.
5.4.1
Bitweise Operationen
Die Bibliothek für bitweise Operationen beinhaltet eine Zusammenstellung von
Makrofunktionen zur Durchführung von Bitmanipulationsoperationen. Sie werden von den anderen Komponenten der Bibliotheken genutzt und können überall angewandt werden. Da die Makrofunktionen keinen speziellen Typ haben,
sind sie mit jedem Datentyp kompatibel.
Der Bit-Index wird genutzt um das Bit in einer Binärzahl zu spezifizieren. Indizes
werden beginnend bei Null gezählt, wobei Null das niedrigstwertige Bit (LSB)
kennzeichnet. Eine 8-Bit-Zahl hat zum Beispiel Indizes von 0 bis 7, eine 16-Bit
Zahl Indizes von 0 bis 15.
Funktionen
bit_mask(bit)
Bit-Index zu Bitmaske konvertieren. Parameter:
– bit - Bit-Index.
– Gibt Bitmaske aus.
73
5 Robotic HomeLab Kit
bit_set(value, bit)
Setzt ein bestimmtes Bit in einer Variablen. Parameter:
– value - Variable.
– bit - Bit-Index.
bit_clear(value, bit)
Löscht ein bestimmtes Bit in einer Variablen. Parameter:
– value - Variable.
– bit - Bit-Index.
bit_set_to(value, bit, state)
Setzt ein bestimmtes Bit einer Variablen in einen gewünschten Zustand.
Parameter:
– value - Variable.
– bit - Bit-Index.
– state - Status (true or false).
bit_invert(value, bit)
Invertiert ein bestimmtes Bit der Variable. Parameter:
– value - Variable.
– bit - Bit-Index.
bit_is_set(value, bit)
Überprüft, ob ein bestimmtes Bit in einer Variablen gesetzt ist oder nicht.
Parameter:
– value - Variable.
– bit - Bit-Index.
74
5.4 HomeLab Bibliothek
– Gibt den Bool’schen Wert true, wenn das Bit gesetzt und false wenn
das Bit gelöscht wurde zurück.
bit_is_clear(value, bit)
Überprüft, ob ein bestimmtes Bit in einer Variablen gelöscht wurde oder
nicht. Parameter:
– value - Variable.
– bit - Bit-Index.
– Gibt den Bool’schen Wert true, wenn das Bit gelöscht wurde undfalse
wenn das Bit gesetzt wurde zurück.
Beispiel
Das dritte Bit einer 8-Bit Variablen b setzen und Invertieren des letzten Bits.
# include <homelab/ b i t . h>
i n t main ( void )
{
unsigned char b = 0 x00 ;
b i t _ s e t (b , 2) ;
bit_invert (b , 7) ;
}
Quelle
Nachfolgend eine gekürzte Version des Quellcodes der Bibliothek für bitweise
Operationen.
//
// Funktionen zur B e a r b e i t u n g von B i t s .
//
# define bit_mask ( b i t )
( 1 << ( b i t ) )
# define b i t _ s e t ( value , b i t )
value |= bit_mask ( b i t )
# define b i t _ c l e a r ( value , b i t )
value &= ~bit_mask ( b i t )
75
5 Robotic HomeLab Kit
# define b i t _ i n v e r t ( value , b i t )
# define b i t _ i s _ s e t ( value , b i t )
# define b i t _ i s _ c l e a r ( value , b i t )
# define b i t _ s e t _ t o ( v , b , x ) v =
bit_mask ( b ) ) )
value ^= bit_mask ( b i t )
( ( value ) & ( bit_mask ( b i t ) ) )
( ! ( ( value ) & ( bit_mask ( b i t ) ) ) )
( ( x ) ? ( v | bit_mask ( b ) ) : ( v & ~
//
// Funktionen zur B e a r b e i t u n g von Bitmasken .
//
# define b i t m a s k _ s e t ( value , bitMask )
value |=
# define b i t m a s k _ c l e a r ( value , bitMask )
value &=
# define b i t m a s k _ i n v e r t ( value , bitMask ) value ^=
# define b i t m a s k _ s e t _ t o ( v , m, x )
v = ((x)
)))
# define b i t m a s k _ i s _ s e t ( value , bitMask )
( ( value )
5.4.2
( bitMask )
~( bitMask )
( bitMask )
? ( v | (m) ) : ( v & ~(m
& ( bitMask ) )
Pins
Die Pins-Bibliothek erleichtert die Arbeit mit digitalen AVR In- und
Output-Pins. Der Nutzer kann eine zu einem Pin gehörige Variable erstellen und
mit dieser sämtliche Pin-Operationen vornehmen. Auf diese Weise entfällt die
Verwendung von Registernamen oder Bit-Indizes, wie es beim Programmieren
mit direktem Zugriff auf das Register nötig ist. Port und Index des Pins müssen
nur einmalig festgelegt werden, sodass Änderungen leicht implementiert werden können.
Datentypen
pin Datentyp für Adressen von Pin-Registern und Bitmasken. Um das effizienteste Programm zu entwickeln, sollten pin Variablen konstant sein
und am Anfang des Programmcodes initialisiert werden. Letzteres kann
mit der Makrofunktion PIN durchgeführt werden, deren erster Parameter
der Buchstabe des Ports ist (A, B, C, etc.) und zweiter Parameter der PinIndex (0 - 7). Es können nur bestehende Ports und Pins verwendet werden.
76
5.4 HomeLab Bibliothek
Funktionen
void pin_setup_output(pin pin)
Konfiguriert einen Pin als Output. Parameter:
– pin - Pin Variable.
void pin_setup_input(pin pin)
Konfiguriert einen Pin als Input ohne Pull-up Widerstand. Parameter:
– pin - Pin Variable.
void pin_setup_input_with_pullup(pin pin)
Konfiguriert einen Pin als Input mit Pull-up Widerstand. Parameter:
– pin - Pin Variable.
void pin_set(pin pin)
Setzt einen Output-Pin high. Parameter:
– pin - Pin Variable.
void pin_clear(pin pin)
Setzt einen Output-Pin low. Parameter:
– pin - Pin Variable.
void pin_toggle(pin pin)
Invertiert den Status eines Output-Pins. Parameter:
– pin - Pin Variable.
void pin_set_to(pin pin, bool value)
Setzt einen Output-Pin in den gewünschten Zustand. Parameter:
– pin - Pin Variable.
– value - Gewünschter Status als Bool’scher Wert.
bool pin_get_value(pin pin)
77
5 Robotic HomeLab Kit
Holt Pin-Wert. Parameter:
– pin - Pin Variable.
– Gibt Bool’schen Wert true wenn Pin high und false wenn Pin low ist
aus.
bool pin_get_debounced_value(pin pin)
Liest den Pinwert durch den Switch-Debounce-Filter. Das Filtern benötigt
mindestens 8 ms und kann bis zu 100 ms benötigen, je nachdem wann das
Bouncing endet. Falls es nicht endet wird false ausgegeben. Funktionen nutzen Softwareverzögerung. Parameter:
– pin - Pin Variable.
– Gibt dem Pin den Bool’schen Wert true wenn der Pin high ist und false
wenn der Pin low oder unbestimmt ist.
Beispiel
Beispiel um einen Pin-Wert zu erhalten und zu setzen. Pin PC0 Wert wird invertiert und an Pin PC3 angeschlossen.
# include <homelab/pin . h>
pin output_pin = PIN (C , 3 ) ;
pin i n p u t _ p i n = PIN (C , 0 ) ;
i n t main ( void )
{
bool value ;
// K o n f i g u r i e r t Pin a l s Output−Pin
pi n_s etup _output ( output_pin ) ;
// K o n f i g u r i e r t Pin a l s Input −Pin mit P u l l −up Widerstand
pin_setup_input_with_pullup ( input_pin ) ;
// E n d l o s s c h l e i f e
while ( t r u e )
{
78
5.4 HomeLab Bibliothek
// Wert e i n e s Input −Pins e r h a l t e n
value = p i n _ g e t _ v a l u e ( i n p u t _ p i n ) ;
// Wert f ü r den Output−Pin s e t z e n
p i n _ s e t _ t o ( output_pin , ! value ) ;
}
}
5.4.3
Analog-Digital-Wandler
Diese Bibliothek enthält Funktionen um den AVR Analog-Digital-Wandler zu
nutzen. Sämtliche Funktionen dieser Bibliothek sind blockierend, d.h. der Prozessor wartet so lange, bis die Ergebnisse da sind. Die Zeit für die Konvertierung
hängt von der ADC-Taktung ab.
Datentypen
adc_reference
ADC Vergleichsspannung, Aufzählungsdatentyp. Möglichkeiten:
– ADC_REF_AREF - Vergleichsspannung vom AREF Pin.
– ADC_REF_AVCC - Vergleichsspannung vom AVCC Pin.
– ADC_REF_2V56 - Interne 2,56 V Vergleichsspannung.
adc_prescale
ADC Takt-Vorteiler, Aufzählungsdatentyp. Der Vorteiler gibt den Divisionsfaktor für den Systemtakt an. Möglichkeiten:
– ADC_PRESCALE_2 - Divisionsfaktor 2.
– ADC_PRESCALE_4 - Divisionsfaktor 4.
– ADC_PRESCALE_8 - Divisionsfaktor 8.
– ADC_PRESCALE_16 - Divisionsfaktor 16.
79
5 Robotic HomeLab Kit
– ADC_PRESCALE_32 - Divisionsfaktor 32.
– ADC_PRESCALE_64 - Divisionsfaktor 64.
– ADC_PRESCALE_128 - Divisionsfaktor 128.
Funktionen
void adc_init(adc_reference reference, adc_prescale prescale)
Initialisiert ADC. Parameter:
– reference - Auswahl der Vergleichsspannung.
– prescale - Auswahl des Takt-Vorteilers.
unsigned short adc_get_value(unsigned char channel)
Konvertiert bestimmte analoge ADC Kanalwerte in digitale. Die Funktion
blockiert. Parameter:
– channel - ADC Kanalnummer (0 bis 7).
– Liefert einen digitalen 10-bit Wert.
unsigned short adc_get_average_value(unsigned char channel, unsigned char
num_samples)
Konvertiert eine gewünschte Anzahl analoger Werte eines bestimmten ADC
Kanals zur digitalen Werten und berechnet den Mittelwert. Die Funktion
blockiert.
– channel - ADC Kanalnummer (0 bis 7).
– num_samples - Anzahl der Werte für die Berechnung (1 bis 64).
– Liefert einen digitalen 10-bit Wert.
80
5.4 HomeLab Bibliothek
Beispiel
Der ADC sei initialisiert und zwei analoge Kanalwerte zu digitalen konvertiert.
Der Wert von Kanal 0 wird der Variable x zugewiesen und der durchschnittliche
Wert von Kanal 1 der Variable y.
# include <homelab/adc . h>
i n t main ( void )
{
unsigned s h o r t x , y ;
// I n i t i a l i s i e r u n g ADC. Vergleichsspannung von AVCC.
// Takt i s t 8 mal langsamer a l s der Systemtakt .
a d c _ i n i t (ADC_REF_AVCC, ADC_PRESCALE_8 ) ;
// Konvertierung des Wertes von Kanal 0 .
x = adc_get_value ( 0 ) ;
// K o n v e r t i e r e n des Wertes von Kanal 1 und Errechnung des
Durchschnitts .
y = adc_get_average_value ( 1 , 10) ;
}
5.4.4
Serielles Interface
Diese Bibliothek bietet die Funktionen für das AVR asynchrone serielle Interface
Datentypen
usart
Datentyp für USART Interfacekontroll-, Status- und Datenregisteradressen. usart Variablen sollten zu Beginn des Programms initialisiert werden.
Für die Initialisierung gibt es eine Macrofunktion USART dessen einziger
Parameter für den Index des Interface ist. (0 oder 1).
usart_databits
Zählen der Datenbits, Aufzählungsdatentyp. Möglichkeiten:
81
5 Robotic HomeLab Kit
– USART_DATABITS_5 - 5 Datenbits.
– USART_DATABITS_6 - 6 Datenbits.
– USART_DATABITS_7 - 7 Datenbits.
– USART_DATABITS_8 - 8 Datenbits.
– USART_DATABITS_9 - 9 Datenbits.
usart_stopbits
Zählen der Stop-Bits, Aufzählungsdatentyp. Möglichkeiten:
– USART_STOPBITS_ONE - Ein Stop-Bit.
– USART_STOPBITS_TWO - Zwei Stop-Bit.
usart_parity
Paritätsmodus, Aufzählungsdatentyp. Möglichkeiten:
– USART_PARITY_NONE - Ausgeschaltet.
– USART_PARITY_EVEN - Gerade Parität.
– USART_PARITY_ODD - Ungerade Parität.
Funktionen
USART_BAUDRATE_ASYNC(baud)
Makrofunktion um den USART Baudratenregisterwert im asynchronen Modus zu berechnen. Parameter:
– baud - Gewünschte Baudrate
– Gibt Baudratenregisterwert wieder.
void usart_init_async(usart port, usart_databits data_bits,
usart_stopbits stop_bits, usart_parity parity, usart_baudrate baudrate)
82
5.4 HomeLab Bibliothek
Initialisiert asynchrones USART. Parameter:
– port - USART Schnittstellenvariable.
– data_bits - Datenbits.
– stop_bits - Stop-Bits.
– parity - Paritätsmodus.
– baudrate - Baudratenregisterwert (kann mit der Makrofunktion USART_BAUDRATE_ASYNC errechnet werden).
void usart_send_char(usart port, char symbol)
Blockiert die Übertragung von Zeichen. Die Funktionen warten solange bis
der Ausgabespeicher leer ist, bevor ein Zeichen in den Speicher geschrieben wird. Parameter:
– port - USART Schnittstellenvariable.
– symbol - zu sendendes Zeichen.
void usart_send_string(usart port, char *text)
Blockierende String-Übertragung. Parameter:
– port - USART Schnittstellenvariable.
– text - Zeiger auf einen String(char array). Der String muss mit einer
Null enden.
bool usart_has_data(usart port)
Überprüft Empfangsspeicher auf Daten. Parameter:
– port - USART Schnittstellenvariable.
– Gibt true zurück wenn Zeichen im Empfangsspeicher und false wenn
nicht.
char usart_read_char(usart port)
83
5 Robotic HomeLab Kit
Liest ein Zeichen aus dem Empfangsspeicher. Zuvor muss der Nuter überprüfen ob tatsächlich ein Zeichen empfangen wurde. Parameter:
– port - USART Schnittstellenvariable.
– Gibt Zeichen aus.
bool usart_try_read_char(usart port, char *symbol)
Liest ein Zeichen aus dem Empfangsspeicher, falls eins vorhanden ist. Parameter:
– port - USART Interfacevariable.
– symbol - Verweis auf die Variable des Zeichens. Wenn ein Zeichen im
Empfangsspeicher vorhanden ist, wird es der betreffenden Variable
zugeschrieben.
– Gibt true aus, wenn ein Zeichen im Empfangsspeicher vorhanden ist
und false wenn nicht.
Beispiel
Die USART Schnittstelle ist konfiguriert um 8 Datenbits, ein Stop-Bit, 9600 bps
Baudrate und keinen Paritätsmodus zu nutzen. Das Programm sendet einen
String, wartet bis die Zeichen empfangen wurden und ließt sie dann aus.
# include <homelab/ u s a r t . h>
// Nutze USART S c h n i t t s t e l l e 0 .
u s a r t p o r t = USART( 0 ) ;
i n t main ( void )
{
char c ;
// I n i t i a l i s i e r u n g der S c h n i t t s t e l l e .
u s a r t _ i n i t _ a s y n c ( port ,
USART_DATABITS_8 ,
USART_STOPBITS_ONE ,
USART_PARITY_NONE,
84
5.4 HomeLab Bibliothek
USART_BAUDRATE_ASYNC( 9 6 0 0 ) ) ;
// Senden des S t r i n g .
u s a r t _ s e n d _ s t r i n g ( port , " Hello\n " ) ;
// Auf ankommende Daten warten .
while ( ! u s a r t _ h a s _ d a t a ( p o r t ) ) { }
// Empfangenes Zeichen a u s l e s e n .
c = usart_read_char ( port ) ;
}
5.4.5
Timer
Diese Bibliothek deckt einen großen Teil der Funktionen des Timers des ATmega128 ab. Es gibt Datentypen und Funktionen welche das Benutzen von Timern
vereinfachen. Aufgrund der Komplexität der AVR Timer gibt es leider keine allgemeingültige Funktion, die für verschiedene Timer genutzt werden kann. Die
Funktionen jedes Timers beginnen mit dem Präfix „timer“und seinem Index.
Datentypen
timer0_prescale
Timer 0 Vorteiler, Aufzählungsdatentyp. Möglichkeiten:
– TIMER0_NO_PRESCALE - Kein Vorteiler (keine Division).
– TIMER0_PRESCALE_8 - Clk / 8.
– TIMER0_PRESCALE_32 - Clk / 32.
– TIMER0_PRESCALE_64 - Clk / 64.
– TIMER0_PRESCALE_128 - Clk / 128.
– TIMER0_PRESCALE_256 - Clk / 256.
85
5 Robotic HomeLab Kit
– TIMER0_PRESCALE_1024 - Clk / 1024.
timer2_prescale
Timer 2 Vorteiler, Aufzählungsdatentyp. Möglichkeiten:
– TIMER2_NO_PRESCALE - kein Vorteiler (keine Division).
– TIMER2_PRESCALE_8 - Clk / 8.
– TIMER2_PRESCALE_64 - Clk / 64.
– TIMER2_PRESCALE_256 - Clk / 256.
– TIMER2_PRESCALE_1024 - Clk / 1024.
– TIMER2_PRESCALE_T2_FALLING - Taktgeber an Pin T2 fallende Flanke.
– TIMER2_PRESCALE_T2_RISING - Taktgeber an Pin T2 steigende Flanke.
timer1_prescale
timer3_prescale
Timer 1/3 Vorteiler, Aufzählungsdatentyp. Möglicheiten („n“bedeutet 1
oder 3):
– TIMERn_NO_PRESCALE - Kein Vorteiler (keine Division).
– TIMERn_PRESCALE_8 - Clk / 8.
– TIMERn_PRESCALE_64 - Clk / 64.
– TIMERn_PRESCALE_256 - Clk / 256.
– TIMERn_PRESCALE_1024 - Clk / 1024.
– TIMERn_PRESCALE_Tn_FALLING - Taktgeber an Pin Tn fallende Flanke.
86
5.4 HomeLab Bibliothek
– TIMERn_PRESCALE_Tn_RISING - Taktgeber an Pin Tn steigende Flanke.
timer1_ctc_top
timer3_ctc_top
Timer 1/3 CTC Modus, Höchstwert, Aufzählungsdatentyp. Möglichkeiten
(„n“bedeutet 1 oder 3):
– TIMERn_CTC_TOP_OCRA - Höchstwert des Timers 1/3 output compare register A.
– TIMERn_CTC_TOP_ICR - Höchstwert des Timers 1/3 input capture
register.
timer1_fast_pwm_top
timer3_fast_pwm_top
Timer 1/3 fast PWM mode top value enumeration data type. Options („n“means
1 or 3):
– TIMERn_FAST_PWM_TOP_256 - Höchstwert 255.
– TIMERn_FAST_PWM_TOP_512 - Höchstwert 511.
– TIMERn_FAST_PWM_TOP_1024 - Höchstwert 1023.
– TIMERn_FAST_PWM_TOP_ICR - Höchstwert des Timers 1/3 input
capture register.
– TIMERn_PAST_PWM_TOP_OCRA - Höchstwert des Timers 1/3 output compare register A.
timer1_fast_pwm_output_mode
timer3_fast_pwm_output_mode
Timer 1/3 fast PWM mode outputs configuration enumeration data type.
Options („n“means 1 or 3):
87
5 Robotic HomeLab Kit
– TIMERn_FAST_PWM_OUTPUT_DISABLE - No output.
– TIMERn_FAST_PWM_OUTPUT_TOGGLE_ON_MATCH - Output toggles on compare match.
– TIMERn_FAST_PWM_OUTPUT_CLEAR_ON_MATCH - Output clears
on compare match.
– TIMERn_FAST_PWM_OUTPUT_SET_ON_MATCH - Output sets on
compare match.
Funktionen
void timer0_init_normal(timer0_prescale prescale)
Initialisiert Timer 0 im normalen Modus. In diesem Modus zählt der Timer
von 0 bis 255 (inkl.). Overflowinterrupts können genutzt werden. Parameter.
– prescale - Prescaler.
void timer2_init_normal(timer2_prescale prescale)
Initialisiert Timer 2 im normalen Modus. In diesem Modus zählt der Timer
von 0 bis 255 (inkl.). Overflowinterrupts können genutzt werden. Parameter.
– prescale - Prescaler.
void timer0_stop()
void timer2_stop()
Stoppt Timer 0/2.
unsigned char timer0_get_value(void)
unsigned char timer2_get_value(void)
Returns timer 0/2 current value. Parameters:
88
5.4 HomeLab Bibliothek
– Return 8-bit timer value.
void timer0_set_value(unsigned char value)
void timer2_set_value(unsigned char value)
Sets timer 0/2 value. Parameters:
– value - New 8-bit timer value.
void timer0_overflow_interrupt_enable(bool enable)
void timer2_overflow_interrupt_enable(bool enable)
Enables or disables timer 0/2 overflow interrupt. The name of the interrupt
vector is „TIMERn_OVF_vect“where „n“represents 0 or 2. Parameters:
– enable - true to enable interrupt, false to disable.
bool timer0_overflow_flag_is_set(void)
bool timer2_overflow_flag_is_set(void)
Checks timer 0/2 overflow flag. Parameters:
– Returns true when overflow has happened, false when not.
void timer0_overflow_flag_clear(void)
void timer2_overflow_flag_clear(void)
Resets timer 0/2 overflow flag.
void timer1_init_normal(timer1_prescale prescale)
void timer3_init_normal(timer3_prescale prescale)
Initializes timer 1/3 in normal mode. In this mode timer counts from 0 to
65535 (including). Overflow interrupt can be used. Parameters:
– prescale - Prescaler.
void timer1_init_ctc(timer1_prescale prescale, timer1_ctc_top top)
89
5 Robotic HomeLab Kit
void timer3_init_ctc(timer3_prescale prescale, timer3_ctc_top top)
Initializes timer 1/3 in CTC (Clear Timer on Compare Match) mode. In this
mode timer counts to specified top value. Overflow interrupt can be used.
Parameters:
– prescale - Prescaler.
– top - Timer top value selection. Actual value must be specified with
register selected as a top value holder.
void timer1_init_fast_pwm(timer1_prescale prescale,
timer1_fast_pwm_top top,
timer1_fast_pwm_output_mode output_a,
timer1_fast_pwm_output_mode output_b, timer1_fast_pwm_output_mode
output_c)
void timer3_init_fast_pwm(timer3_prescale prescale,
timer3_fast_pwm_top top,
timer3_fast_pwm_output_mode output_a,
timer3_fast_pwm_output_mode output_b,
timer3_fast_pwm_output_mode output_c)
Initializises timer 1/3 in fast PWM mode. In this mode timer counts to a
specified value, which also determines the period of the PWM signal. Timer
1/3 has three 3 output compare units (A, B and C) to generate PWM signals.
Overflow and compare match interrupts can be used. Parameters:
– prescale - Prescaler.
– top - Timer top value selection. Actual value must be specified with
register selected as a top value holder.
– output_a - Output compare unit A pin configuration.
– output_b - Output compare unit B pin configuration.
– output_c - Output compare unit C pin configuration.
void timer1_stop()
90
5.4 HomeLab Bibliothek
void timer3_stop()
Stops timer 1/3.
unsigned char timer1_get_value(void)
unsigned char timer3_get_value(void)
Returns timer 1/3 current value. Parameters:
– Returns 16-bit timer value.
void timer1_set_value(unsigned char value)
void timer3_set_value(unsigned char value)
Sets timer 0/2 value. Parameters:
– value - New 16-bit timer value.
unsigned short timer1_get_compare_match_unitA_value(void)
unsigned short timer1_get_compare_match_unitB_value(void)
unsigned short timer1_get_compare_match_unitC_value(void)
unsigned short timer3_get_compare_match_unitA_value(void)
unsigned short timer3_get_compare_match_unitB_value(void)
unsigned short timer3_get_compare_match_unitC_value(void)
Returns timer 1/3 output compare unit A/B/C compare match register
value. Parameters:
– Returns 16-bit compare match register value.
void timer1_set_compare_match_unitA_value(unsigned short value)
void timer1_set_compare_match_unitB_value(unsigned short value)
void timer1_set_compare_match_unitC_value(unsigned short value)
void timer3_set_compare_match_unitA_value(unsigned short value)
91
5 Robotic HomeLab Kit
void timer3_set_compare_match_unitB_value(unsigned short value)
void timer3_set_compare_match_unitC_value(unsigned short value)
Sets timer 1/3 output compare unit A/B/C compare match register value.
Parameters:
– value - New 16-bit compare match register value.
unsigned short timer1_get_input_capture_value(void)
unsigned short timer3_get_input_capture_value(void)
Returns timer 1/3 input capture register value. Parameters:
– Returns 16-bit input capture register value.
void timer1_set_input_capture_value(unsigned short value)
void timer3_set_input_capture_value(unsigned short value)
Sets timer 1/3 input capture register value. Parameters:
– value - New 16-bit input capture register value.
void timer1_overflow_interrupt_enable(bool enable)
void timer3_overflow_interrupt_enable(bool enable)
Enables or disables timer 1/3 overflow interrupt. The name of the interrupt
vector is „TIMERn_OVF_vect“where „n“represents 1 vÕi 3. Parameters:
– enable - true to enable interrupt, false to disable.
void timer1_compare_match_unitA_interrupt_enable(bool enable)
void timer1_compare_match_unitB_interrupt_enable(bool enable)
void timer1_compare_match_unitC_interrupt_enable(bool enable)
void timer3_compare_match_unitA_interrupt_enable(bool enable)
void timer3_compare_match_unitB_interrupt_enable(bool enable)
92
5.4 HomeLab Bibliothek
void timer3_compare_match_unitC_interrupt_enable(bool enable)
Enables or disables timer 1/3 output compare unit A/B/C compare match
interrupt. The name of the interrupt vector is
„TIMERn_COMPx_vect“where „n“represents 1 or 3
and „x“represents A, B or C. Parameters:
– enable - true to enable interrupt, false to disable.
void timer1_input_capture_interrupt_enable(bool enable)
void timer3_input_capture_interrupt_enable(bool enable)
Enables or disables timer 1/3 input capture interrupt. The name of the interrupt vector is „TIMERn_CAPT_vect“, where „n“represents 1 or 3. Parameters:
– enable - true to enable interrupt, false to disable.
bool timer1_overflow_flag_is_set(void)
bool timer3_overflow_flag_is_set(void)
Checks timer 1/3 overflow flag. Parameters:
– Returns true when overflow has happened, false when not.
bool timer1_input_capture_flag_is_set(void)
bool timer3_input_capture_flag_is_set(void)
Checks timer 1/3 input capture flag. Parameters:
– Returns true when input capture has done, false when not.
void timer1_overflow_flag_clear(void)
void timer3_overflow_flag_clear(void)
Resets timer 1/3 overflow flag.
void timer1_input_capture_flag_clear(void)
void timer3_input_capture_flag_clear(void)
93
5 Robotic HomeLab Kit
Resets timer 1/3 input capture flag.
Beispiel
Im folgenden Programm wird Timer 0 im normalen Modus mit Overflowinterrupt gestartet.
# include <homelab/ t i m e r . h>
# include <avr/ i n t e r r u p t . h>
// Overflow i n t e r r u p t program .
ISR ( TIMER0_OVF_vect )
{
}
i n t main ( void )
{
// I n i t i a l i z i n g o f t i m e r 0 i n normal mode .
t i m e r 0 _ i n i t _ n o r m a l ( TIMER0_PRESCALE_32 ) ;
// Enabling t i m e r 0 overflow i n t e r r u p t .
timer0_overflow_interrupt_enable ( true ) ;
// Global i n t e r r u p t s e n a b l i n g .
sei () ;
}
5.4.6
Verzögerung
Dieser Teil der Bibliothek enthält die benötigten Funktionen, um in einem Programm mit Hilfe von Software Algorithmen oder Hardwaretimern Verzögerungen zu generieren. Verzögerungen blocken keine Interrupts, daher werden Softwareverzögerungen durch Interrupts unterbrochen. Verzögerungsfunktionen sind
nicht vor-kompiliert, sodass sie mit verschiedenen Taktfrequenzen genutzt werden können.
94
5.4 HomeLab Bibliothek
Funktionen
void sw_delay_ms(unsigned short count)
Softwareverzögerung in Millisekunden (ms). Für diese Funktion wird ein
Compiler Optimierungsmodus benötigt. Parameter:
– count - Verzögerungszeit in ms. 0 bis 65535 ms.
void sw_delay_us(unsigned short count)
Softwareverzögerung in Mikrosekunden (µs). Für diese Funktion wird ein
Compiler Optimierungsmodus benötigt. Parameter:
– count - Verzögerungszeit in µs. 0 bis 65535 µs.
void hw_delay_ms(unsigned short count)
’ Zeitgeber basierte Verzögerung in Millisekunden. Diese Funktionen verwenden den ATmega128 8-bit Timer 0. In Abhängigkeit von der Taktfrequenz kann eine Verzögerung von bis zu einigen Millisekunden auftreten.
Parameter:
– count - Verzögerungszeit in ms. 0 bis 65535 ms.
Beispiele
Demonstration beider Typen einer Verzögerung:
# include <homelab/delay . h>
i n t main ( void )
{
// Software − b a s i e r t e Verzögerung von 100 ms .
sw_delay_ms ( 1 0 0 ) ;
// Hardware− ( Timer −) b a s i e r t e Verzögerung von 100 ms .
hw_delay_ms ( 1 0 0 ) ;
}
95
5 Robotic HomeLab Kit
5.4.7 7-Segment
In Bezug auf:
LED Display
User Interface Module
Diese Bibliothek dient zur Nutzung des 7-Segment LED Displays der digitalen HomeLab digitalen I/O Modulplatine gedacht. Mit dieser Bibliothek können
Zahlen von 0 bis 9 dargestellt werden.
Funktionen
void segment_display_init(void)
Konfiguriert Kontrollpins für den Displaytreiber.
void segment_display_write(unsigned char digit)
Zeigt eine Ziffer auf dem Display an. Parameter:
– digit - Zahlenwert von 0 bis 9. Ansonsten wird ein E für „Error“angezeigt.
Beispiel
Die Zahl 5 wird auf dem LED-Display angezeigt.
# include <homelab/module/segment_display . h>
i n t main ( void )
{
// I n i t i a l i s i e r u n g des D i s p l a y s
segment_display_init ( ) ;
// Anzeige der Zahl .
segment_display_write ( 5 ) ;
}
96
5.4 HomeLab Bibliothek
5.4.8
Alphanumerisches LCD
Bezug nehmend auf:
lcd
Diese Bibliothek enthält die Funktionen, um das alphanumerische LCD des HomeLab zu nutzen.
Datentypen
lcd_alpha_mode
LCD Konfiguration, Aufzählungsdatentyp. Möglichkeiten:
– LCD_ALPHA_DISP_OFF - Display aus.
– LCD_ALPHA_DISP_ON - Display an mit unsichbarem Cursor.
– LCD_ALPHA_DISP_ON_CURSOR - Display an mit Cursor.
– LCD_ALPHA_DISP_ON_CURSOR_BLINK - Display an mit blinkendem Cursor.
Funktionen
void lcd_alpha_init(lcd_alpha_mode disp_attr)
Initialisiert LCD. Parameter:
– disp_attr - Display Konfiguration.
void lcd_alpha_clear(void)
Löscht die Anzeige. Cursor wird zum Anfang der ersten Zeile bewegt.
void lcd_alpha_clear_line(unsigned char line)
Löscht eine Zeile am Display. Cursor wird zum Anfang der ersten Zeile
bewegt. Parameter:
97
5 Robotic HomeLab Kit
– line - Zeilennummer: 0 oder 1.
void lcd_alpha_home(void)
Cursor wird zum Anfang der ersten Zeile bewegt.
void lcd_alpha_goto_xy(unsigned char x, unsigned char y)
Bewegt den Cursor zur gewünschten Position. Parameter:
– x - X Koordinate (Spaltennumner). 0 bis 15.
– y - Y Koordinate (Zeilennumner). 0 bis 1.
void lcd_alpha_write_char(char c)
Schreibt ein Zeichen auf die Position des Cursors. Parameter:
– c - ASCII Zeichen.
void lcd_alpha_write_string(const char *s)
Schreibt einen String aufs Display, beginnend bei der Cursorposition. Parameter:
– s - Zeiger auf einen String(char array).
void lcd_alpha_write_string_p(const char *progmem_s)
Schreibt einen String vom Programmspeicher aufs Displays, beginnt an der
Cursorposition. Parameter:
– progmem_s - Zeiger auf String im Programmspeicher.
Beispiel
Nutzung des alphanumerischen LCD zur Darstellung von Text:
# include <homelab/module/ l c d _ a l p h a . h>
i n t main ( void )
{
// I n i t i a l i s i e r u n g des LCD .
l c d _ a l p h a _ i n i t (LCD_ALPHA_DISP_ON) ;
98
5.4 HomeLab Bibliothek
// Lö schen des D i s p l a y s .
lcd_alpha_clear ( ) ;
// Cursor an den Beginn der zweiten Z e i l e s e t z e n .
lcd_alpha_goto_xy ( 0 , 1) ;
// Anzeige des T e x t s .
l c d _ a l p h a _ w r i t e _ s t r i n g ( " Hello " ) ;
}
5.4.9
Graphisches LCD
Related to:
User Interface Module
Diese Bibliothek enthält die Funktionen zur Nutzung des graphischen LCD des
HomeLab. Obwohl das LCD graphische Bilder wiedergeben kann, enthält die
Bibliothek diese Funktionen nicht. Das LCD wird als alphanumerisches Display
mit 14 x 6 Zeichen genutzt.
Funktionen
void lcd_gfx_init(void)
Intialisiert das LCD.
void lcd_gfx_backlight(bool set)
Schaltet die Hintergrundbeleuchtung des LCD an/aus. Parameter:
– set - true wenn Hintergrundbeleuchtung an, false wenn aus.
void lcd_gfx_clear(void)
Löscht das gesamte Display
void lcd_gfx_clear_line(unsigned char line)
Löscht eine Zeile Text. Parameter:
99
5 Robotic HomeLab Kit
– line - Zeilennummer. 0 bis 5.
void lcd_gfx_goto_char_xy(unsigned char x, unsigned char y)
Wählt eine Position zum Beschreiben aus. Parameter:
– x - X-Koordinate. 0 bis 13.
– y - Y-Koordinate. 0 bis 5.
void lcd_gfx_write_char(char c)
Schreibt ein Zeichen an eine zuvor bestimmte Position. Parameter:
– c - ASCII Zeichen.
void lcd_gfx_write_string(char *s)
Schreibt einen String an eine zuvor bestimmte Position. Parameter:
– s - Zeiger auf einen String(char array).
Beispiel
Nutzung des graphischen LCD:
# include <homelab/module/ l c d _ g f x . h>
i n t main ( void )
{
// I n i t i a l i s i e r u n g des LCD .
lcd_gfx_init () ;
// Lö schen des D i s p l a y s .
lcd_gfx_clear () ;
// Cursor i n d i e M i t t e des B i l d s c h i r m s bewegen .
lcd_gfx_goto_char_xy ( 5 , 2) ;
// Anzeige e i n e s T e x t e s .
l c d _ g f x _ w r i t e _ s t r i n g ( " Hello " ) ;
}
100
5.4 HomeLab Bibliothek
5.4.10
Sensoren
Bezug nehmend auf:
Sensors Module
Diese Bibliothek enthält Funktionen für die verschiedenen Sensoren im HomeLab kit.
Datentypen
ir_distance_sensor
Infrarotentfernungssensor, Distanzberechnungs-Parameterstruktur. Formel
für die Entfernungsberechnung ist a / (ADC + b) - k. Struktur:
– a - Dividend.
– b - Nicht-lineare Konstante.
– k - Lineare Konstante.
Konstante
ir_distance_sensor GP2Y0A21YK
Sharp GP2Y0A21YK Formelparameter zur Entfernungsberechnung.
Funktionen
signed short thermistor_calculate_celsius(unsigned short adc_value)
Berechnet die Thermistor Temperatur in Grad Celcius aus ADC Umrechnungsergebnissen. Die Funktionen benutzen eine vorgefertigte Umrechnungstabelle. Parameter:
– adc_value - ADC Umrechnungsergebnis (10-Bit mit +5 V Referenzspannung).
101
5 Robotic HomeLab Kit
– Gibt die Temperatur mit Grenzwerten von -20 bis 100 ◦ C an.
signed short ir_distance_calculate_cm(ir_distance_sensor sensor, unsigned
short adc_value)
Berechnet die Entfernung von ADC Ergebnissen die vom IR-Entfernungssensor empfangene Spannung an. Parameter:
– sensor - Kalkulationsparameter des Distanzsensors.
– adc_value - ADC Umrechnungsergebnis (10-bit mit +5 V Referenzspannung).
– Gibt die Entfernung in cm an, oder -1 wenn eine Messung nicht möglich ist.
unsigned short ultrasonic_measure(pin trigger, pin echo)
Misst die Entfernung mit dem Ultraschallentfernungsmesser. Die Funktionen generieren einen Auslöseimpuls an einem Pin und messen die Zeit bis
zum Echopulses am anderen Pin. Die Entfernung wird über die Zeit berechnet. Die Funktionen benötigen eine
14.7456Mhz Taktfrequenz. Die Messung kann bis zu 36ms dauern. Parameter:
– trigger - Variable des auslösenden Pins.
– echo - Variable des Echo-Pin variable.
– Gibt Entfernung in cm an, oder 0 wenn Messung nicht möglich.
Beispiel
Nutzung des Infrarot- und Ultraschallentfernungssensors.
# include <homelab/module/ s e n s o r s . h>
// K o n t r o l l −P ins des U l t r a s c h a l l e n t f e r n u n g s s e n s o r s .
pin p i n _ t r i g g e r = PIN (G, 1 ) ;
pin pin_echo
= PIN (G, 0 ) ;
102
5.4 HomeLab Bibliothek
i n t main ( void )
{
unsigned s h o r t adc_value = 4 0 0 ; // zuf ä l l i g e s ADC E r g e b n i s .
signed s h o r t d i s t a n c e ;
// Entfernungsberechnung des ADC E r g e b n i s s e s des IR−
Entfernungssensors .
d i s t a n c e = i r _ d i s t a n c e _ c a l c u l a t e _ c m ( GP2Y0A21YK , adc_value ) ;
// Messung mit U l t r a s c h a l l e n t f e r n u n g s s e n s o r .
d i s t a n c e = u l t r a s o n i c _ m e a s u r e ( p i n _ t r i g g e r , pin_echo ) ;
}
5.4.11
Motoren
Bezug nehmend auf:
Motor Module
Diese Bibliothek enthält Funktionen zur Steuerung der verschiedenen HomeLab
Motoren. Sie enthält Funktionen für Gleichstrom- (DC-), Schritt- und Servomotoren,
Funktionen
void dcmotor_init(unsigned char index)
Initialisiert einen der Controller für die DC Motoren. Parameter:
– index - Index des Motorencontrollers. 0 bis 3.
void dcmotor_drive(unsigned char index, signed char direction)
Betriebt einen der Controller der DC Motoren. Parameter:
– index - Index des Motorencontrollers. 0 bis 3.
– direction - Polarität des Motors. -1, 0 oder +1. Bei 0 wird der Motor
angehalten, ansonsten bewegt er sich in die vorgegebene Richtung.
103
5 Robotic HomeLab Kit
void unipolar_init(unsigned char index)
Initialisiert den Controller eines der unipolaren Schrittmotoren. Parameter:
– index - Index des Motorencontrollers. 0 oder 1.
void unipolar_halfstep(unsigned char index, signed char direction, unsigned short num_steps, unsigned char speed)
Befehl zum Halbschrittbetrieb für unipolaren Schrittmotor. Die Funktion
ist blockierend bis sie erfüllt ist, bis alle Schritte durchgeführt wurden. Parameter.
– index - Index des Motorencontrollers. 0 oder 1.
– direction - Rotationsrichtung. -1 oder +1.
– num_steps - Zählen der Halbschritte.
– speed - Zeit eines einzelnen Schritts in Millisekunden.
void bipolar_init(void)
Initialisiert den Controller des bipolaren Schrittmotors.
void bipolar_halfstep(signed char direction, unsigned short num_steps, unsigned char speed)
Befehl zum Halbschrittbetrieb für bipolaren Schrittmotor. Die Funktion ist
blockierend bis sie erfüllt ist, bis alle Schritte durchgeführt wurden. Parameter:
– direction - Rotationsrichtung . -1 oder +1.
– num_steps - Zählen der Halbschritte.
– speed - Zeit eines einzelnen Schritts in Millisekunden.
void servomotor_init(unsigned char index)
Initialisiert eine der PWM Signal-generierenden Einheiten eines Servomotors des ATmega128 Timers 1. Das PWM Signal beträgt 50 hz bei einer high
period of 1.5 ms ± 0.5 ms. Parameter:
104
5.4 HomeLab Bibliothek
– index - Index des Servomotors. 0 oder 1.
void servomotor_position(unsigned char index, signed short position)
Takt des Servomotors mit Kontrollbefehl. Die Position eines Servomotors
verändert sich wenn dieser betrieben wird. Wird er gedreht, verändert sich
seine Drehzahl. Parameter:
– index - Index des Servomotors. 0 oder 1.
– position - Position oder Drehzahl. -100 bis +100. Bei 0 stoppt der Motor.
Beispiel
Nutzung von Gleichstrom- (DC-), Schritt- und Servomotoren.
# include <homelab/module/motors . h>
i n t main ( void )
{
// I n i t i a l i s i e r u n g der DC Motoren .
dcmotor_init ( 0 ) ;
dcmotor_init ( 1 ) ;
// I n i t i a l i s i e r u n g des b i p o l a r e n S c h r i t t m o t o r s .
bipolar_init () ;
// I n i t i a l i s i e r u n g der Servomotoren .
servomotor_init ( 0 ) ;
servomotor_init ( 1 ) ;
// Ein DC Motor f ä h r t vorwä r t s , e i n anderer r ückwä r t s .
dcmotor_drive ( 0 , − 1) ;
dcmotor_drive ( 1 , +1) ;
// Bewegt den S c h r i t t m o t o r 100 S c h r i t t e i n e i n e Richtung
// und d a r a ufhi n zurück mit d o p p e l t e r Geschwindigkeit .
bi po lar _h al fst ep ( 1 , 100 , 50) ;
b i p o l a r _ h a l f s t e p ( −1 , 1 0 0 , 2 5 ) ;
// Bewegt Servomotoren i n e n t g e g e n g e s e t z t e Richtungen .
s e r v o m o t o r _ p o s i t i o n ( 0 , − 100) ;
s e r v o m o t o r _ p o s i t i o n ( 1 , +100) ;
105
5 Robotic HomeLab Kit
}
— MISSING PAGE —
106
6
Praktische Beispiele
Die, in diesem Kapitel vorgestellten, praktischen Beispiele sind einheitlich aufgebaut und so konkret und praxisnah wie möglich gestellt. Jedes Beispiel beginnt mit einer kurzen Einführung in die zugrunde liegende Theorie sowie einer
Darstellung des zum Verständnis der Beispiele nötigen Hintergrundwissens. Der
praktische Teil besteht hauptsächlich aus kommentierten Programmcode, welcher die konkrete Anwendung verdeutlicht. Normalerweise wird dabei die HomeLab Library genutzt, in einigen Fällen wird die Hardware jedoch auch direkt
über Register angesteuert.
Das erste Kapitel weicht etwas von diesem Schema ab, hier wird primär die Installation und Konfiguration der notwendigen Softwarekomponenten beschrieben. Die Installationsanweisungen sind für Windows und Linux Betriebssysteme
ausgelegt. Nachdem die Software einmal eingerichtet wurde, macht es keinen
Unterschied mehr, ob ein Windows oder ein Linux/Unix basierendes Betriebs-
6 Praktische Beispiele
system verwendet. Die Handhabung und Programierung wird dadurch nicht
beeinflusst.
Ein praktisches Beispiel beginnt immer mit einer Aufzählung von erforderlichen
Vorkenntnissen. Dabei werden Bezüge zu anderen Kapiteln hergestellt, welche
mit folgenden Abkürzungen gekennzeichnet sind:
Physikalisches Modul, das im Beispiel genutzt wird.
Teil der Softwarebibliothek, die im Beispiel genutzt wird.
Verweis auf das Kapitel über die Grundlagen der Elektronik.
Verweis auf das Kapitel über die AVR Mikrocontrollermodule.
Verweis auf andere Aufgaben.
Grundlegende Software für die Beispiele
Wie zuvor erwähnt werden die Codebeispiele auf Basis der HomeLab Bibliothek erstellt.Die meisten AVR-spezifischen Operationen und Verfahren, die auf
die HomeLab Kit Hardware zugreifen sind in dieser Bibliothek enthalten. Bei
Verwendung der HomeLab Bibliothek muss somit kein Hardware-spezifischer
Programmcode mehr erzeugt werden. Durch Bereitstellung der für die Hardware in den Beispielen und Übungen notwendigen Software,kann der Nutzer sich
vollkommen auf seine Algorithmen konzentrieren und muss keine Zeit mit Einzelheiten verbringen, die nicht für die zu benutzende Hardware notwendig sind.
Programmierstil in den Beispielen
Die Beispielprogramme sind in einem einheitlichen Stil geschrieben, um so einen
synoptischeren Programmcode zu erhalten. So wird das Programm leserlicher
und einfache Syntaxfehler können vermieden werden. Daher sollte dieser Stil
auch bei den Übungsaufgaben angewandt werden. Die Hauptcharakteristika
sind:
108
6.1 Anfang
Das Programm, all seine Funktionen und Variablen sind in englischer Sprache und Kleinbuchstaben geschrieben, die Wörter werden durch einen Unterstrich getrennt.
Die Funktionen werden wie folgt gekennzeichnet: object_action_subject.
Wichtigere Teile des Programms werden kommentiert.
Jeder Block in C-Code (markiert durch und )startet und beginnt in einer
neuen Zeile.
Blöcke werden mit der Tabulatortaste geordnet. Die Tabulatortaste wird
nicht innerhalb einer Zeile verwendet.
6.1
Anfang
109
6 Praktische Beispiele
Zur Programmierung des AVR Mikrocontrollers werden eine Programmierumgebung, ein Compiler für die betreffende Sprache sowie Software zum Laden der
erstellten Programme auf den Controller benötigt. Die komfortabelste Weg hierfür ist die Nutzung der speziellen DIE (Integrated Developing Environment).
Der AVR Mikrocontroller kann in folgenden Programmiersprachen programmiert werden: Assembler, C, C+, Pascal, Basic, etc. In diesem Buch wird C verwendet um den Mikrocontroller zu programmieren. Die Software ist sowohl für
Windows OS und Linux OS frei erhältlich. Die folgenden Kapitel führen in die
Verwendung dieser ein.
Sämtliche, zur Durchführung der Beispiele notwendige Software, ist auf der HomeLabHomepage zu finden.
6.1.1
Installationsanweisung für Windows
Dieser Abschnitt enthält alle notwendigen Informationen zur Installation der
AVR Entwicklungssoftware auf einem Windows Betriebssystem zu installieren.
Installation
Es wird die nachfolgende Software benötigt, die von der Homepage des Herstellers heruntergeladen werden kann. Wahlweise kann die Software auch von der,
im HomeLab Kit enthaltenen, CD installiert werden.
1. AVR Studio
AVR Studio 4 IDE (Integrated Development Environment) ist eine Software um den
Quellcode zu schreiben, zu kompilieren und das Programm in den Controller zu
laden. AVR Studio kann kostenlos von der Atmel Homepage bezogen werden.
2. WinAVR
WinAVR ist ein GNU-GCC Compiler für AVR Microcontroller. Das Programm ist
eine kostelose Software und kann welche von der Sourceforge Homepage gela-
110
6.1 Anfang
den werden. Währen der Installation von WinAVR schlägt das Programm einen
Ordnernamen mit einer langen Versionsnummer vor. Wir würden vorschlagen,
die Versionsnummer zu entfernen, und das Programm wie folgt zu installieren:
C: \WinAVR
3. HomeLab Bibliothek
Die HomeLab Bibliothek ist ein Set von Funktionen welches für das HomeLab
Kit und AVR Controller entworfen wurde. Die Nutzung dieser Bibliothek macht
das Programmieren wesentlich einfacher und effektiver. Die neuste Version der
Bibliothek kann von der HomeLab Webseite heruntergeladen werden. Diese Bibliothek sollte in den gleichen Ordner installiert werden, in dem sich auch WinAVR befindet.
4. Virtualer COM Port Treiber
Der Treiber ermöglicht den Anschluss des USB JTAG-ICE Programmiergerätes
an den PC. Er muss vor Anschluss des Programmiergerätes installiert werden.
Der Dateiname des Treibers ist „CDM x.xx.xx.exe“, wobei „x“für die Versionsnummer steht. Nach der Installation des Treibers kann das JTAG-ICE Programmiergerät über den USB Port angeschlossen werden und Windows wird es automatisch erkennen. Folgende Meldung sollte in der Taskleiste zu sehen sein:
Abhängig von der Anzahl vorher bereits definierter virtueller Ports, wird Windows dem neuen Gerät eine Portnummer zuweisen. Es wird ein neuer Name für
den COM Port generiert, sobald das Gerät an einen anderen USB Port des selben
Computers angeschlossen wird. Einige AVR Studio Versionen können nicht auf
111
6 Praktische Beispiele
das Programmiergerät zugreifen, wenn die Nummer des COM Ports größer ist
als 10, bzw. größer als 4 wenn es als Debugger genutzt wird.
Um das zu verhindern, kann die Portnummer im Gerätemanager verändert und
auf einen Wert zwischen COM0 und COM4 einstellt werden.
See the complete procedure here .
Ein neues Projekt erstellen
Um ein Programm für den Controller zu schreiben muss man einen Projektraum
erstellen. Das Projekt beinhaltet typischerweise unterschiedliche Dateien wie Quellcodes, Headerdateien, kompilierte Programmdateien usw. Es wird dringend dazu geraten, für jedes Projekt einen separaten Ordner zu erstellen (Diese Funktion
wird auch vom New Project Wizard angeboten).
Wird ein neues Projekt mit Hilfe des Wizards erstellt, sind folgende Schritte zu
durchlaufen:
1. Öffnen Sie AVR Studio und klicken Sie auf New Project. Falls sich das Dialogfeld nicht automatisch öffnet, wählen Sie Project - New project aus der Menüleiste
aus. Klicken Sie auf Next.
112
6.1 Anfang
2. In dem nächsten Dialogfeld geht es um den Compiler und die Starteinstellungen. Wählen Sie den AVR GCC Compiler aus. Fügen Sie dann links den Namen
des Projekts und den Hauptquelldateinamen ein. Der Quelldateienname sollte
die Endung „*.c“haben. Außerdem sollten noch zwei Ankreuzfelder angeklickt
werden, welche einen Neuen Ordner und die Startdatei erzeugen. Man sollte
auch den Ordner angeben wo die Projektdateien erstellt werden. Nachdem diese Einstellungen vorgenommen wurden, klicken Sie auf Next.
Achtung! Fehlt der AVR GCC in der Compilerliste, ist er nicht richtig installiert.
In diesem Fall muss die WinAVR Software installiert werden bevor mit dem Programmieren begonnen wird.
113
6 Praktische Beispiele
3. Im nun folgenden Dialogfeld sind die Debuggerplattform sowie der Mikrocontroller auszuwählen. Das HomeLab kit nutzt die JTAG ICE Debuggerplattform
und den ATmega128 Mikrocontroller. Klicken Sie nach der Auswahl auf Finish.
114
6.1 Anfang
4. Nun wird der Projektraum erstellt und ein neues Fenster öffnet sich, in welchem mit dem Programmieren begonnen werden kann.
115
6 Praktische Beispiele
5. Vor der ersten Kompilierung, müssen einige Parameter des Projekts eingestellt werden.Die wichtigen Parameter sind die Taktfrequenz des Controllers und
Optimierungsmethode.Der HomeLab Controller hat eine Frequenz von 14,7456
MHz (14745600 Hz). Sie kann in den Projekteinstellungen in Hz (nicht MHz) angegeben werden : Project → Configuration Options → General. Die Optimierungsmethode sollte -Os sein, falls keine andere Methode benötigt wird.
116
6.1 Anfang
6. Um die Funktionen der HomeLab Bibliothek zu nutzen muss die Software
richtig installiert sein. Bei jedem neuen Projekt benötigt muss die Bibliothek zur
Liste der verlinkten Objekte hinzugefügt werden. Hierzu gehen Sie auf: Project
→ Configuration Options → Libraries und fügen Sie „libhomelab.a“hinzu.
117
6 Praktische Beispiele
Falls das Objekt libhomelab.a in der Liste links fehlt, ist die Bibliothek nicht richtig
installiert und sollte erneut installiert werden.
Test der Einstellungen
Nach Installation der Entwicklungsumgebung sollte diese getestet werden, um
sicherzustellen, dass sie korrekt funktioniert. Der einfachste Weg hierfür ist, ein
kleines Programm zu schreiben, es zu kompilieren und in den Controller zu laden.
1. Schließen Sie das Programmiergerät an dem ATmega128 an. Stellen Sie sicher,
dass es korrekt am JTAG Anschluss angeschlossen ist. (Kabel zeigt vom Board
weg - siehe Abbildung) Schließen Sie nun die Stromversorgung an (eine kleine
grüne LED sollte leuchten wenn alles korrekt angeschlossen ist.).
118
6.1 Anfang
Fügen Sie nun folgenden C Code ein:
# include <avr/ i o . h>
# include <homelab/delay . h>
i n t main ( void )
{
// Pin PB7 a l s Output
DDRB = 0 x80 ;
// E n d l o s s c h l e i f e
while ( t r u e )
{
// I n v e r t i e r u n g Pin PB7
PORTB ^= 0 x80 ;
hw_delay_ms ( 5 0 0 ) ;
}
}
Abbildung 6.1: Kompilierung und Schalter des Programmiergerätes
Kompilieren Sie das Projekt mit dem Build Befehl (Taste F7). Stellen Sie sicher,
dass die Kompilierung erfolgreich ist. Dafür sollte folgende Nachricht im Nachrichtenfenster stehen:
Build succeeded with 0 Warnings . . .
2. Öffnen Sie das Controllerfenster Tools → Program AVR → Auto Connect. Stellen
Sie sicher, dass der Tab Program geöffnet ist.
119
6 Praktische Beispiele
Falls sich das beschriebene Fenster nicht öffnet und sich stattdessen das Connection Failed Fenster öffnet, ist das Programmiergerät oder die Platine nicht richtig
angeschlossen. Überprüfen Sie zunächst, ob der Mkcrocontroller an die Stromversorgung angeschlossen ist (grüne LED leuchtet) und ob das Programmiergerät korrekt an den JTAG angeschlossen ist. Falls das korrekt erfolgt ist, überprüfen Sie die von Windows vergebene COM Port Nummer. Ist diese größer als
9, kann Das AVR Studio das Programmiergerät nicht erkennen. Folgen Sie den
120
6.1 Anfang
Anweisungen zu Beginn des Kapitels, um eine Portnummer zwischen 0 und 4
zuzuweisen.
3. Fügen Sie im Fenster des Programmiergerätes Flash-sektion Textbox Input HEX
File durch Betätigung der “. . . “Taste den Ort des kompilierten Programms ein.
Das kompilierte Programm ist normalerweise in dem Unterordner default des
Projekts zu finden und hat den gleichen Namen wie das Projekt jedoch mit der
Endung „*.hex“, z.B. „Labor1.hex“. Nach Auswahl der richtigen Datei wählen
Sie Programm um das Programm in den Controller zu laden.Wenn alles richtig
gelaufen ist, sollte folgende Nachricht am Ende des Fensters zu sehen sein:
OK
Reading FLASH input f i l e . . OK
S e t t i n g d e v i c e parameters f o r j t a g programming . . OK
E n t e r i n g programming mode . . OK
E r a s i n g d e v i c e . . OK
Programming FLASH . .
OK
Reading FLASH . .
OK
FLASH c o n t e n t s i s equal t o f i l e . . OK
Leaving programming mode . . OK
Laut Programm sollte die on-Board LED (PB7) blinken. Wenn das Programm
funktioniert ist das Setup der Programmierumgebung richtig und das erste Pro-
121
6 Praktische Beispiele
gramme wurde erfolgreich kompiliert.Glückwunsch!
122
6.1 Anfang
Debugger
Abbildung 6.2: Liste der Register des Debuggers des ATmega128.
Debuggen eines Programms bedeutet, dass man nach Fehlern im Programm
sucht.Dazu gibt es Programme, genannt Debugger, welche erlauben das Programm Schritt-für-Schritt auszuführen und an den notwendigen Stellen zu stoppen. Eine Implementierung des Programms ermöglicht das Überprüfen von Werten einer Variable in jeder Phase des Programms, sowie des Inhalts der Register und der Sequenz des Ausführens des Programms.Debugging ist sehr wichtig, wenn man mit komplexeren Programmen arbeitet, in denen die Fehlersuche
häufig schwierig ist. Bei der Arbeit mit Mikrocontrollern ist es wichtig, dass eine
Schritt-für-Schritt Implementation des Programms im Controller stattfindet, wodurch die Veränderung des tatsächlichen Outputs und auch die Werte der Register gesehen werden können. Zur Nutzung eines Debuggers müssen zwei erfüllt
sein: Der Mikrocontroller muss das Debugging unterstützen und man muss über
123
6 Praktische Beispiele
die notwendige Hardware verfügen, nämlich den JTAG Programmer welcher
Debuggen erlaubt. Günstigere Programmiergeräte, welche das ISP Programmier
Interface nutzen, können zwar kompilierte Programme in den Controller laden
aber nicht unbedingt debuggen.
Um das Programm im Debugmodus mit dem AVR Studio zu starten, sollte es
zuerst durch build (F7) kompiliert und daraufhin mit dem Befehl run (F5) gestartet werden.Zuvor können break points (F9) an bestimmten Stellen im Quellcode eingefügt werden.Erreicht die Implementation des Programms einen solchen
Punkt, wird das Programm angehalten, um den Status des Mikrocontrollers an
diesem Punkt festzulegen. Die Implementation des Programms kann mit dem
Befehl Run fortgeführt oder durch Step Into (F11) mit nur einem Befehlt vollständig implementiert werden.
Die Nutzung von oating-point Variablen
Manchmal ist es bei AVR Programmen notwendig, Floating-Point Variablen zu
nutzen. Um mit ihnen zu rechnen und sie mit printf -Typ Funktionen darzustellen, müssen folgende Installationsänderungen in der Konfiguration des Projekts
vorgenommen werden:
1. Öffnen Sie die Installationsdatei des Projekts aus dem Menü Project → Configuration Options. Fügen Sie libprintf_flt.a und libm.a zu libhomelab.a der Homelab
Bibliothek im Konfigurationstab Libraries hinzu.
2. Öffnen Sie anschließend Custom Options und wählen Sie [All files]. Fügen Sie
daraufhin Zeilen mit “-lprintf_flt“ja “-lm“in die Box rechts sowie die Zeile mit “uvfprintf“zu der [Linker Options] Sektion hinzu.
3. Klicken Sie auf OK und schließen Sie das Konfigurationsfenster.
6.1.2
Die Softwareumgebung für Linux
Die folgende Anleitung beschreibt die Installation und de Benutzung des AVR
Toolkit 9:10 Ubuntu OS.
124
6.1 Anfang
Installation der Software
Installieren Sie die folgende Software:
1. Linux Softwarepakete
gcc-avr - GNU C-Compiler für den AVR
avrdude - Programm um die HEX-Dateien in den Controller zu laden.
avr-libc - C-Code Bibliotheken, um Code für die AVR Plattform zu schreiben
Um die Pakete zu installieren, nutzen Sie folgenden Terminalbefehl:
sudo apt −g e t i n s t a l l gcc −avr avrdude avr − l i b c
oder die graphische Installationssoftware (wie das Ubuntu Softwarecenter oder
Synaptic Packet manager).
2. HomeLab Bibliothek
Die Bibliothek vereinfacht das schreiben von Programmcode, da Grundfunktionen bereits fertig sind. Laden Sie sich die Datei Homelab library vX.X.run von der
HomeLab Webseite herunter, wobei XX für die Versionsnummer steht. Zur Installation der Bibliothek führen Sie den folgenden Befehl aus:
sudo sh homelab_library_vX . X . run
Stellen Sie sicher, dass die Installation erfolgreich war.
3. KontrollerLab
KontrollerLab ist eine IDE (integrated development environment) um zum schreiben, kompilieren, debuggen und laden von AVR Software. Laden Sie die KontrollerLab Software herunter und und speichern sie diese in einem Ordner (z.B.
˜/Documents/AVR/KontrollerLab). Führen sie den folgenden Befehl in dem Ordner
aus:
sudo dpkg − i k o n t r o l l e r l a b ∗ . deb
125
6 Praktische Beispiele
Falls es Probleme mit Paketabhängigkeiten gibt, führen Sie den Befehl aus welcher die fehlende Pakete installiert:
apt −g e t i n s t a l l − f
Das Programmiergerät anschlieÿen.
Schließen Sie das Programmiergerät an den Computer an und überprüfen Sie ob
es vom Computer erkannt wird. Schreiben Sie den Befehl
„lsusb“ins Terminalfester, woraufhin eine Liste der angeschlossenen USB Geräte
ausgegeben werden sollte. Der Name des Programmiergerätes ist: „Future Technology Devices International, Ltd FT 232 USB-Serial (UART) IC“.
126
6.1 Anfang
Um den Port zu erhalten an welchem das Programmiergerät angeschlossen ist,
überprüfen Sie /dev mit dem Befehl cd /dev (setzt /dev als aktuellen Ordner) und
dir (zeigt den Inhalt des Ordners an). Da das Programmiergerät eine serielle USB
Schnittstelle ist, ist es als „ttyUSBx“benannt, wobei „x“den Index der Schnittstelle anzeigt.Gibt es kein anderes serielles USB Gerät, ist diese Zahl null.
Ein neues Projekt erstellen
Um ein AVR Programm zu schreiben, muss ein Projekt erstellt werden, welches
alle notwendigen Dateien enthält: Quellcode, Headerdateien, kompilierte Programme, usw. Um die Projekte klar voneinander zu trennen, sollte für jedes Projekt ein eigener Ordner erstellt werden. (Diese Option gibt es auch im Project
Wizard).
Folgende Schritte müssen durchlaufen werden um ein Projekt zu erstellen:
127
6 Praktische Beispiele
1. Öffnen Sie KontrollerLab (Applications → Programming → KontrollerLab) und
starten Sie ein neues Projekt File → New → New project. Ein Fenster öffnet sich
in welchem der Projektort festgelegt werden muss. In diesem Beispiel ist das
../Homelab/blinkingLED/.
2. Das Projekt muss mindestens eine C-Datei haben in welcher der Programmcode geschrieben wird. Dateien können mit dem File → New → New Menu hinzugefügt werden. In dem sich nun öffnenden Fenster wählen Sie C source als
Dateityp und wählen Sie einen Namen für die Datei.
128
6.1 Anfang
3. Anschließend muss das Projekt für das Homelab Kit konfiguriert werden. Öffnen Sie hierzu das Konfigurationsfenster unter Project → Configure Project und
wählen Sie Common. Der CPU Type sollte ATmega128 sein und die Taktfrequenz
14745600,0 Hz. Darüber hinaus sollten hier die Namen der HEX- und MAP- Dateien angegeben werden. Durch Set as default werden diese Einstellungen zur
Standardeinstellung für alle neuen Projekte. Dieses ist sinnvoll, wenn nur mit
dem HomeLab AVR Microcontroller gearbeitet wird. Da die HEX und MAP Dateien als Standard gespeichert werden, sollte man ihnen allgemeine Namen geben, z.B. „out.hex“.
Achtung! Da die HomeLab Library nicht im Linker Konfigurationstab eingefügt
werden kann, muss der Befehl “-lhomelab“an den Namen der MAP-Datei angehängt werden.
129
6 Praktische Beispiele
Wenden Sie die Einstellungen im Compiler Tab an, wie auf dem folgenden Screenshot gezeigt.Bevor Sie auf OK klicken, sollte die Compilerkonfiguration ebenfalls
als Standard gesetzt werden.
130
6.1 Anfang
4. Konfigurieren Sie das Programmiergerät durch öffnen von Project → Configure Programmer. Wählen Sie „AVRDUDE“als Programmiergerät. Setzen Sie im
„AVRDUDE“Tab den Typ des Programmiergerätes auf jtagmkI und den Anschlussport auf /dev/ttyUSBx (wobei „x“der Portindex ist.). Stellen Sie diese Konfiguration ebenfalls als Standard ein.
131
6 Praktische Beispiele
5. Ordnen Sie schließlich die Fenster im KontrollerLab so an, wie es angenehm
ist und bereiten Sie sich darauf vor, das erste Programm zu schreiben.
132
6.1 Anfang
Ein Programm schreiben und testen
Nachdem die Konfiguration abgeschlossen ist, ist es Zeit zu programmieren.
1. Schließen Sie das Programmiergerät am Controllermodul an. Überprüfen Sie
noch einmal ob das Programmiergerät richtig am JTAG Anschluss angeschlossen
ist. Das Kabel muss von der Platine weg zeigen (siehe Abbildung). Schließen Sie
nun die Stromversorgung an und überprüfen ob die grüne LED leuchtet.
2. Schreiben Sie das folgende Programm in das Dateieditor-Fenster des KontrollerLab und kompilieren Sie es:
# include <avr/ i o . h>
# include <homelab/delay . h>
i n t main ( void )
133
6 Praktische Beispiele
{
// S e t z e Pinn PB7 a l s output
DDRB = 0 x80 ;
// Loeputu t s u e k k e l
while ( t r u e )
{
// I n v e r t i e r e PB7
PORTB ^= 0 x80 ;
hw_delay_ms ( 5 0 0 ) ;
}
}
Abbildung 6.3: Toolbar
Stellen Sie sicher, dass das Outputfenster die Nachricht „File compiled successfully“anzeigt.Falls eine “Error(s) Occurred:“Nachricht erscheint, überprüfen Sie
den Programmcode auf Fehler.
3. Um das Programm in den Controller zu laden wählen Sie Ignite. Wurde es erfolgreich in den Controller geladen, sollte die Nachricht „Project built and uploaded successfully“erscheinen.
Falls alles richtig gemacht wurde, sollte die rote LED auf dem Controller in 1Sekunden Intervallen blinken.
Nutzung von oating-point Variablen
Manchmal ist in es in AVR Programmen notwendig, floating-point Variablen zu
nutzen. Um mit ihnen zu rechnen und sie mit Funktionen vom Typ printf zu
nutzen, müssen die folgenden Anpassungen in der Projektkonfiguration vorgenommen werden:
134
6.1 Anfang
1. Öffnen Sie Project Configurations sowie den Tab Linker. Überprüfen Sie die erste
Zeile der Liste Linker flags (siehe Abbildung).
2. Klicken Sie auf OK und schließen Sie das Fenster.
135
6 Praktische Beispiele
6.2
Digitale Input/Output Pins
Die folgenden Kapitel stellen den digtalen Input/Output Pin dar, welche Grundfunktionen des Mickocontrollers sind. Input/Output Pins sind Mikrocontrollerkontakte. Es sind die sogenannten „Beine“(„legs“). Sie dienen dazu, digitale Signale zu empfangen und zu senden. Ist ein Pin als Input konfiguriert, kann der
Status von Schaltern oder einfachen Sensoren, die mit ihm verbunden sind, von
diesem Pin empfangen werden. Ist ein Pin als Output konfiguriert ist, kann er
benutzt werden um LEDs oder elektrisches Anlagen zu steuern.
Fast alle typischen Mikrocontroller Pins erlauben die Ausführung einfacher InputOutput Funktionen, auch wenn diese Pins häufig noch alternative Funktionen
haben. Zunächst sollen jedoch erst die Pins mit ihren Grundfunktionen dargestellt werden, bevor in separaten Kapiteln auf die alternativen Funktionen eingegangen wird.
136
6.2 Digitale Input/Output Pins
6.2.1
Light-emitting Diode (LED)
Notwendiges Wissen:
Controllermodul,
Berechnung des LED-Widerstands,
Pins
Digitales Input-Output Modul,
Register,
Digitale Inputs/Outputs,
Theorie
Abbildung 6.4: 5 mm legged LED
Leuchtdioden sind Halbleiter die Licht abstrahlen, wenn Strom in Durchlassrichtung durch die Diode fließt. Die Abkürzung LED steht für „light-emitting
diode“. Es gibt verschiedenfarbige Leuchtdioden, mittlerweile ist sogar weißes
Licht möglich. Wie jede normale Diode auch hat die LED 2 Kontakte - Anode und
Kathode. In Zeichnungen ist die Anode mit einem “+“markiert und die Kathode
mit einem “-“.
Abbildung 6.5: Schematische Darstellung einer LED and ihrer Polarität
Wenn Strom in Durchlassrichtung durch die LED fließt, ist die Anode mit der positiven und die Kathode mit der negativen Spannung verbunden. Die Spannung
137
6 Praktische Beispiele
der LED hängt von der Farbe der LED ab: lange Wellenlängen (rot) ˜2V, kürzere Wellenlängen (blau) ˜3V. Die Stromverbrauch einer LED ist in der Regel nicht
mehr als ein paar Dutzend mW. Die Stromstärke darf daher nicht zu hoch sein,
wenn größere Stromstärken oder Spannungen verwendet werden kann die LED
zerstört werden.
Wenn die LEDs nur zur Beleuchtung verwendet werden, sollte man spezielle
elektrische Schaltkreise verwenden, welche die Spannung und die Stromstärke
für die LEDs regulieren.Jedoch werden LEDs sehr oft als Indikatoren genutzt
und direkt vom Mikrocontroller mit Strom versorgt. Da die Betriebsspannung
eines Mikrocontrollers höher ist, als die der LEDs, muss ein Widerstand in Serie
mit der LED geschaltet werden um die Stromstärke zu regulieren und für den
nötigen Spannungsabfall zu sorgen. Das Kapitel „Elektronik“enthält Anleitungen zur Berechnung des richtigen Widerstands.
LEDs werden in vielen Formen gefertigt. Die meisten LEDs haben runde eine Hülle mit 3mm oder 5mm Durchmesser und zwei lange metallische Pins.
Der längere Pin ist die Anode, der kürzere die Kathode. „Surface mounted casing“LEDs (SMD - Surface Mounted Device) sind unten mit einem T gekennzeichnet, um so die Polarität anzugeben. Das Dach des T’s steht für die Anode
und der Fuß markiert die Kathode.
Abbildung 6.6: Polarität von legged und SMD LED’s
HomeLab Übung
1
Das HomeLab Controller Controllermodul hat eine rote LED, dessen Anode über
einen Widerstand an die +5V Stromversorgung angeschlossen ist und dessen
Kathode am ATmega128 Pin PB7.Um die LED an- und auszuschalten muss PB7
138
6.2 Digitale Input/Output Pins
als Output Pin definiert werden und entweder high oder low gesetzt werden.
Wenn der Pin high gesetzt wird ist die LED aus, wird er low gesetzt ist die LED
an. Grundsätzlich ist es möglich die LED so anzubringen, dass die Anode am PB7
angeschlossen wird und die Kathode geerdet wird (Widerstand nicht vergessen)
-dann leuchtet die LED wenn der Pin high gesetzt ist und der LED ist aus wenn
der Pin low ist.
Alle praktischen Beispiele für das HomeLab kit, inklusive LEDs schalten, nutzen die HomeLab Pin Bibliothek. Die Pin Bibliothek hat den Datentyp pin, welcher die Addressen des zum Pin gehörigen Register und der Bitmaske des Pins
enthält. Wenn eine Pin Variable mit der Makrofunktion Pin im Programm erschaffen und initialisiert wird, kann der Pin mit dieser Variable im gesamten
Programm genutzt werden, ohne Register benutzen zu müssen.Hier sind 2 Beispielprogramme, welche exakt das gleiche machen. Das eine Programm nutzt
die HomeLab Bibliothek, das andere nicht.
//
// HomeLab Controllermodule LED Testprogramm .
// Der Cose b a s i e r t auf der HomeLab B i b l i o t h e k .
//
# include <homelab/pin . h>
//
// LED Pin K o n f i g u r a t i o n .
//
pin debug_led = PIN ( B , 7 ) ;
//
// Hauptprogramm
//
i n t main ( void )
{
// k o n f i g u r i e r t LED Pin a l s Output
pi n_s etup _output ( debug_led ) ;
// Aufleuchten der LED
p i n _ c l e a r ( debug_led ) ;
}
//
// HomeLab Controllermodul LED Testprogramm .
// Der Code g r e i f t d i r e k t auf R e g i s t e r zu .
//
139
6 Praktische Beispiele
# include <avr/ i o . h>
//
// Hauptprogramm
//
i n t main ( void )
{
// K o n f i g u r i e r t LED Pin a l s Output
DDRB |= ( 1 << 7 ) ;
// Aufleuchten der LED
PORTB &= ~(1 << 7 ) ;
}
Das erste Beispiel nutzt die Pin Bibliothek (pin.h Datei). Zuerst wird eine Pin-Typ
Variable debug led erschaffen, welche Informationen über den LED Pin enthält.Im
Hauptprogramm wird dieser Pin mit pin_setup_output als Output gesetzt.Danach
wird der Pin low gesetzt: pin_clear. Das Ergebnis: die LED leuchtet.Im zweiten
Beispiel werden keine Variablen genutzt. Um die LED als Output zu markieren
und zum Leuchten zu bringen, werden die Datenrichtung des Port B und die
Output Registerwerte verändert. Der Leser, der mehr über den AVR weiß bemerkt, dass in beiden Beispielen kein Befehl nötig ist um die LED zum leuchten
zu bringen, da der Standardoutputwert des AVR 0 ist. Aus Gründen der Vollständigkeit wird es jedoch hier beschrieben.
Was ist der Unterschied zwischen dem Gebrauch von Bibliothek und Register?
Der Unterschied liegt im Komfort - Die Bibliothek ist einfacher, weil man die Registernamen und deren Auswirkungen nicht kennen muss. Der entscheidende
Vorteil der Bibliothek ist jedoch die Anpassungsfähigkeit.Arbeitet man mit Registern müssen im Programm stets die Registernamen und Bitmasken geändert
werden um einen Pin zu ändern. Nutzt man die Bibliothek muss dieses nur am
Anfang, bei Initialisierung der Variable erfolgen. Die Nutzung von Registern hat
jedoch einen entscheidenden Vorteil: Die Nutzung eines Pins erfolgt direkt und
nicht über den Programmspeicher und zeitfressenden Funktionen. Jedoch sind
die neuren AVR-GCC Kompiler Versionen so schlau, dass sie die Bibliotheksfunktionen zu direkten Befehle für die Registermanipulation transformieren, so
als würde man die Register direkt im Programm ansprechen. Die Compiler können den Code aber nur dann optimieren wenn sie mit konstanten Variablen arbeiten und nicht mit unbeständigen Variablen die sich während des Programms
140
6.2 Digitale Input/Output Pins
oder mit Arrays ändern.
Der folgende Programmcode ist ein Teil der Pin Operations Bibliothek, um die
Vorgehensweise mit Pin Variblen zu erklären. Es wird für Anfänger nicht einfach
sein zu verstehen, da C-Sprache Pointer genutzt werden, die nicht in diesem
Buch beschrieben sind. Es gibt jedoch sehr viel Material über Pointer in Büchern
und natürlich im Internet.
// Makrokonstante um R e g i s t e r −P o i n t e r zu d e f i n i e r e n
# define _REG_PTR_ v o l a t i l e u i n t 8 _ t ∗
//
// Pin Datentyp
//
typedef s t r u c t pin
{
_REG_PTR_ ddr ;
_REG_PTR_ p o r t ;
_REG_PTR_ pin ;
u i n t 8 _ t mask ;
}
pin ;
//
// Makrofunktion f ü r I n i t i a l i s i e r u n g der Pin V a r i a b l e
//
# define PIN ( p o r t _ c h a r , b i t _ i n d e x ) \
{ \
( _REG_PTR_ ) \ ## p o r t _ c h a r , \
( _REG_PTR_ ) \ ## p o r t _ c h a r , \
( _REG_PTR_ ) \ ## p o r t _ c h a r , \
bit_mask ( b i t _ i n d e x ) \
}
//
// K o n f i g u r i e r e Pin a l s Output
//
i n l i n e void pin_setup_output ( pin pin )
{
b i t m a s k _ s e t ( ∗ pin . ddr , pin . mask ) ;
}
//
// S e t z e Pin high
//
141
6 Praktische Beispiele
i n l i n e void p i n _ s e t ( pin pin )
{
b i t m a s k _ s e t ( ∗ pin . port , pin . mask ) ;
}
//
// S e t z e Pin low
//
i n l i n e void p i n _ c l e a r ( pin pin )
{
b i t m a s k _ c l e a r ( ∗ pin . port , pin . mask ) ;
}
HomeLab Übung
2
Zusätzlich zum Controllermodul befinden sich LEDs auch auf der digtalen I/O
Modulplatine.Sie sind elektrisch genau so angeschlossen wie auf dem Controllerboard, die Kathode ist also am AVR Pin angeschlossen. Die rote LED ist am
PC5 Pin angeschlossen, die gelbe am PC4, und die grüne am PC3. Das auf der
HomeLab Bibliothek basierende Beispielprogramm sieht folgendermaßen:
//
// HomeLab D i g i t a l e s i /o Modul LED Testprogramm .
//
# include <homelab/pin . h>
//
// LED Pin K o n f i g u r a t i o n .
//
pin l e d _ r e d
= PIN (C , 5 ) ;
pin l e d _ y e l l o w = PIN (C , 4 ) ;
pin l e d _ g r e e n = PIN (C , 3 ) ;
//
// Hauptprogramm
//
i n t main ( void )
{
// K o n f i g u r i e r e LED Pins a l s Output
pi n_s etup _output ( l e d _ r e d ) ;
pi n_s etup _output ( l e d _ y e l l o w ) ;
pi n_s etup _output ( l e d _ g r e e n ) ;
142
6.2 Digitale Input/Output Pins
// Aufleuchten der grünen LED
pin_clear ( led_green ) ;
// Ausschalten der r o t e n und gelben LED
pin_set ( led_red ) ;
pin_set ( led_yellow ) ;
}
˜˜Diskussion˜˜
6.2.2
Schalter
Notwendiges Wissen:
puts,
Pins,
User Interface Module,
Registers,
Digital Inputs/Out-
Light-emitting Diode
Theorie
Ein Schalter ist ein elektromagnetisches Gerät, welches einen elektrischen Schaltkreis verbindet oder trennt. Es gibt viele Typen von Schaltern, die am weitesten
verbreiteten sind einfache mechanische Schalter, bei denen elektrische Anschlüsse mechanisch geschaltet werden.Sind die Anschlüsse verbunden, wird der elektrische Schaltkreis geschlossen und Strom kann durch den Schalter fließen. Wenn
die Anschlüsse nicht verbunden sind, kann keine Elektrizität fließen.
Schalter werden normalerweise benutzt um elektrische Schaltkreise zu schalten, sie können jedoch auch als Sensoren benutzt werden. Der Schalter als Sensor ist auch Teil dieser Übung, Hochspannungsschalter werden jedoch ausgelassen. Schalter können anhand der Anzahl von Kontakten und ihrer Verbindungsmethode unterschieden werden. Unterschiedliche Typen sind: zwei-Kontakt Schalter und Doppelschalter, bei denen Kontaktpaare verbunden werden,
darüber hinaus auch Druckknopf-, Schiebe-, Kipp- und Wechselschalter, ebenso
wie Schalter die Verbindungen trennen anstatt zu verbinden.
Es werden unterschiedliche Schaltbildsymbole genutzt um die verschiedenen
143
6 Praktische Beispiele
Typen von Schaltern zu identifizieren. Unterhalb sind Beispiele typischer elektrischer Schalter in einem Schaltbild:
Druckknopfschalter
Wechselschalter
Kippschalter
Mikroschalter
DIL Schalter
Um einen Schalter als Sensor mit einem Mikrocontroller zu nutzen, muss ein Kontakt des Schalters mit dem
Pin des Mikrocontrollers verbunden sein und dieser muss als Input im Programm definiert werden. Wenn
der Kontakt mit der Masse oder einem Inputpotential verbunden ist, wir die Bus Bitrate des MikrocontrollerPins geändert. Es erscheint logisch einen Wechselschalter zu nutzen, welcher es erlaubt einen Kontakt an den
gewünschten Kontakt anzubringen (hier Masse oder Input). Für unseren Zweck ist es nicht ganz so einfach,
denn im Moment des Schaltens sind die Kontakte nicht verbunden. Der Moment an sich ist sehr kurz (ms),
aber in diesem Moment ist der Input-Pin des Mikrocontrollers nicht verbunden und hat daher einen unendlichen Wert.Auf Grund elektromagnetischer Störung (welche überall existiert) kann der Input-Pin der nicht
angeschlossen ist, zu jeder Zeit zufällig einen Wert von 0 oder 1 haben.
Die Störanfälligkeit macht die Nutzung von Schaltern kompliziert. Die am häufigsten verwendete Methode
um dies zu verhindern, ist den Input des Microcontrollers durch einen Widerstand an die Erde oder das Inputpotential anzuschließen. Einen so benutzten Widerstand nennt man einen pull-down oder pull-up Widerstand. Normalerweise liegt der Widerstand eines pull-down oder pull-up zwischen 1kΩ bis 1 MΩ. Wenn der
Schalter offen ist, wird der Input mit der Spannung des Widerstands geladen, wenn man den Schalter schließt,
empfängt der Input die Spannung des Schalters, da der Leitungswiderstand des Schalters im Vergleich zum
Widerstand beinahe 0 ist. Allgemein kann er als „volt-box“bezeichnet werden.
Abbildung 6.7: Schalter-Anschluss Schema mit einem pull-up Widerstand
144
6.2 Digitale Input/Output Pins
Ein einfacher zwei-Kontakt Schalter kann als Sensor mit einen pull-up oder pull-down Widerstand genutzt
werden. Hierzu wird ein Kontakt des Schalters mit dem Input verbunden und der andere mit dem Widerstand. Normalerweise haben Mikrocontroller eingebaute pull-up oder down Widerstände, daher ist es nicht
notwendig einen Widerstand in den Schaltkreis einzubauen.AVR Mikrocontroller haben beispielsweise 20 kΩ
- 50 kΩ pull-up Widerstände an ihren I/O Pins.Darüber hinaus muss noch erwähnt werden, dass mechanische Schalter ein weiteres Problem haben, den „switch bounce“. Hierdurch wird beim Schalten in sehr kleinen
Abständen die Verbindung durch die Schwingung des mechanischen Schalters unterbrochen. Die Beispiele
dieses Kapitels werden nicht durch den „switch bounce“beeinflusst, das Problem wird im nächsten Kapitel
ausführlicher bearbeitet.
Übung
Es gibt drei Druckknopf-Schalter am digitalen I/O Modul. Diese verbinden die Pins den Mikrocontrollers mit
der Erde, aber nicht direkt durch einen Widerstand. Auf diese Weise soll ein Kurzschluss vermieden werden,
wenn der Knopf gedrückt wird, während der Pin als Output definiert wird. Die Schalter besitzen einen pullup Widerstand, welcher aber einen viel größeren Widerstand als die Schutzwiderstände hat, daher liegt beim
Drücken des Schalter eine Spannung von nahezu 0 V am betreffenden Pin an.
Die Schalter befinden sich an den PC0, PC1 und PC2 Pins. Um den Status der Schalter zu lesen müssen die
betreffenden Pins des Mikrocontrollers als Input gesetzt werden. Man benötigt nicht die internen pull-up Widerstände des AVR, da die Pins schon externe Widerstände haben.Wenn der Schalter betätigt wird, hat der
entsprechende Bus des Pins den Wert 0, wird er losgelassen, den Wert 1. Mit Hilfe von LED Indikatoren kann
überprüft werden, ob der Mikrocontroller den Status den Schalters verstanden hat.
Der Beispielcode zur Benutzung der Schalter basiert auf der HomeLab Pins Bibliothek, welche im LED Kapitel
eingeführt wurde.
//
// Program zum Testen der S c h a l t e r des d i g i t a l e n I /O Moduls
//
# include <homelab/pin . h>
//
// F e s t l e g u n g der Pins von LED−d sowie der S c h a l t e r .
//
pin l e d s [ 3 ]
= { PIN (C , 5 ) , PIN (C , 4 ) , PIN (C , 3 ) } ;
pin b u t t o n s [ 3 ] = { PIN (C , 2 ) , PIN (C , 1 ) , PIN (C , 0 ) } ;
//
// Hauptprogramm
//
i n t main ( void )
{
unsigned char i ;
// S e t z t d i e LED Pins a l s Output und d i e S c h a l t e r −Pins a l s Input .
f o r ( i = 0 ; i < 3 ; i ++)
145
6 Praktische Beispiele
{
pi n_se tup _output ( l e d s [ i ] ) ;
pin_setup_input ( buttons [ i ] ) ;
}
// E n d l o s s c h l e i f e
while ( t r u e )
{
// J e d e r S c h a l t e r hat e i n e zugehö r i g e LED,
// d i e a u f l e u c h t e t , wenn e r b e t ä t i g t wird .
f o r ( i = 0 ; i < 3 ; i ++)
{
pin_set_to ( leds [ i ] , pin_get_value ( buttons [ i ] ) ) ;
}
}
}
Im Beispiel werden LEDS und Knöpfe als Array definiert - das ermöglicht es Sie in einer for Schleife zu nutzen.
Wird das Programm gestartet, werden die LED Pins als Output und die Schalter als Input gesetzt. In der
Endlosschleife des Programms wird durchgehend der Status der Schalter abgefragt, welcher den Status der
dazugehörigen LED bestimmt. Der erste Schalter ist für die grüne LED, der Zweite für die Gelbe und der
Dritte für die Rote.
6.2.3
Vermeidung von Kontaktprellung
Vajalikud teadmised:
Switch
User Interface Module,
Digital Inputs/Outputs,
Pins,
Delay,
Theorie
Abbildung 6.8: Kontaktprellung eines Schalters
Wie bereits im einleitenden Kapitel zu Schaltern erwähnt, gibt es im Ungang mit mechanischen Schaltern den
Effekt des Prellens (ungewolltes, kurzzeitiges, wiederholtes Öffnen und Schließen eines Kontaktes bei dessen
146
6.2 Digitale Input/Output Pins
Betätigung). Dieses Problem wird durch die Elastizität des Metalls, aus dem die Schalter bestehen, verursacht.
Im Moment des Ein- oder Ausschaltens prellen die Kontakte, was zu einer Vielzahl falscher Schaltungen führt.
Die Anzahl und Dauer der Schaltungen hängt von dem Schalter ab, liegt aber gewöhnlich im Bereich von
wenigen Millisekunden. Für den Fall, dass ein Schalter genutzt wird, um ein elektronisches Gerät zu starten,
hat dieses Problem keine großen Auswirkungen. Wird er jedoch zur Steuerung eines Gerätes verwendet kann
mehrfaches Schalten das Gerät beschädigen.
Abbildung 6.9: RC-filter eines Schalters
Die bekannteste Methode zur Vermeidung von Kontaktprellung ist die Filtrierung. Dieses kann elektrisch
oder durch Software erfolgen. Um elektrisch zu filtern muss der Schalter an einen Tiefpassfilter angeschlossen
werden - zum Beispiel an einen RC Filter - welcher die Spannungschwankungen beseitigt sodass der Pin des
Mikrocontrollers keine schwankenden Werte erhält. Ein solcher RC Filter ist auf der Zeichnung abgebildet.
Filtrierung mittels Software wird durchgeführt, indem dem Pin, an welchem der Schalter angeschlossen ist,
ein Wert zugewiesen wird. Bleibt dieser Wert zu verschiedenen Zeitpunkten innerhalb eines zuvor gesetzten
Zeitlimits gleich, kann angenommen werden, dass der Schalter stabil ist und kein Flimmer-Problem aufweist.
Es muss jedoch bei jeder Art der Filtrierung ein Verzögerungsfaktor bei Definition des Status berücksichtigt
werden.
Praktisches Beispiel
Elektrische Filtrierung wird für die HomeLab Schalter nicht verwendet, da hier die Beseitigung von Fehlschaltungen mit Hilfe von Software geübt werden soll. Die Übung besteht aus zwei Teilen. Das Ziel des ersten Teils
ist, das Prellen der Schalter des digitalen Input/Output Moduls zu zeigen. Hierzu wird das folgende Programm genutzt; durch jede Betätigung des Schalters wird die nachfolgende LED aufleuchten. Eine Fehlschaltung lässt die LEDs mehrfach und zufällig aufleuchten. Electrical filtering is not used on HomeLab switches,
since it would not allow practicing the elimination of miss switching’s with software. The exercise is in two
parts. The goal of the first part is to demonstrate the bouncing of Digital i/o module switches. The following
program is used for this; each pressing on the button will light the next LED in line. Wrongly pressed button
will causes LEDs to light several times and it appears as the LEDs light randomly.
//
// Das Programm um K o n t a k t p r e l l u n g am d i g i t a l e n Input/Output Modul zu
demonstrieren .
//
# include <homelab/pin . h>
//
147
6 Praktische Beispiele
// F e s t l e g u n g der LED−Pins und S c h a l t e r .
//
pin l e d s [ 3 ] = { PIN (C , 5 ) , PIN (C , 4 ) , PIN (C , 3 ) } ;
pin button = PIN (C , 0 ) ;
//
// Hauptprogramm
//
i n t main ( void )
{
unsigned char new_value , o l d _ v a l u e = 0 ;
unsigned char index , c o u n t e r = 0 ;
// LED−P i ns a l s Output s e t z e n .
f o r ( index = 0 ; index < 3 ; index ++)
{
pi n_se tup _output ( l e d s [ index ] ) ;
}
// S c h a l t e r −Pins a l s Input s e t z e n .
p i n _ s e t u p _ i n p u t ( button ) ;
// E n d l o s s c h l e i f e
while ( t r u e )
{
// S t a t u s des S c h a l t e r s a u s l e s e n .
new_value = p i n _ g e t _ v a l u e ( button ) ;
// K o n t o l l e , ob der S c h a l t e r h e r u n t e r g e d rü c k t wurde ,
// was bedeutet , dass der neue S t a t u s 1 i s t , der a l t e 0 .
i f ( ( new_value ) && ( ! o l d _ v a l u e ) )
{
// Erweiterung des Leseger ä t e s und Nutzungvon Modul 3
counter = ( counter + 1) % 3 ;
// Aufleuchten der LED, welche mit dem Wert des Leseger ä t e s ü
bereins timmt .
f o r ( index = 0 ; index < 3 ; index ++)
{
p i n _ s e t _ t o ( l e d s [ index ] , index ! = c o u n t e r ) ;
}
}
// Berü c k s i c h t i g u n g des a l t e n S t a t u s .
o l d _ v a l u e = new_value ;
148
6.2 Digitale Input/Output Pins
}
}
Es gibt diverse Softwarelösungen zur Filtrierung. Sie können einfach oder komplex sein, wobei jede ihre Vorund Nachteile hat. Sieht das Programm nur wenige seltene Betätigungen des Schalters vor, kann eine lange
Pause als Folge der Betätigung eingefügt werden. Auf diese Weise können durch Kontaktprellung verursachte
Wirkungen auf die Schaltung vermieden werden. Jedoch muss bei Anwendung dieser Lösung bedacht werden, dass, sofern der Nutzer den Schalter für eine längere Zeit gedrückt hält, das Programm ebenfalls auf die
Fehlschaltung, welche durch Lösen des Schalters hervorgerufen wird, reagiert. Ein Programm, welches den
Status des Schalters in einer festgeleten Zeitperiode mehrfach überprüft ist zuverlässiger (das Ergebnis ist umso besser, je länger die Periode und je größer die Anzahl der Kontrollen ist). Nachfolgend ist eine Funktion
abgebildet, um filtrierte Werte eines Schalters für das digitale Input/Output Mpdul auszulesen:
//
// Funktion zum Auslesen f i l t r i e r t e r Werte aus dem I /O
Erweiterungsmodul .
//
unsigned char pin_get_debounced_value ( pin button )
{
unsigned char b u f f e r = 0xAA ;
unsigned char timeout = 1 0 0 ;
// Abwarten , b i s der S t a t u s des S c h a l t e r s We wait u n t i l t h e s t a t u s o f
t h e button i s c e l a r or c l e a r i n g t h e s t a t e e x p i r e s
while ( timeout −− > 0 )
{
// Having 8 p l a c e ( b i t ) b u f f f e r o f s t a t e .
// A l l pr evious s t a t e s ( b i t s ) a r e s h i f t e d t o l e f t
// and a new s t a t e ( b i t ) i s added t o t h e r i g h t .
b u f f e r <<= 1 ;
b u f f e r |= ( p i n _ g e t _ v a l u e ( button ) ? 0 x01 : 0 x00 ) ;
// I f a l l 8 b i t s a r e high , then t h e button i s d e f i n i t e l y pressed
down
i f ( b u f f e r = 0xFF )
{
return 1 ;
}
// I f a l l 8 b i t s a r e low , then t h e button i s d e f i n i t e l y up .
i f ( b u f f e r = 0 x00 )
{
return 0 ;
}
// 1 ms break .
// This f u n c t i o n can be found from t h e l i b r a r y o f t h e HomeLab .
149
6 Praktische Beispiele
sw_delay_ms ( 1 ) ;
}
// I f we can not examine t h e s t a t e , then we assume t h a t t h e button
was not pressed .
return 0 ;
}
Diese Funktion generiert eine Verzögerung durch Nutzung einer Funktion, die in der entsprechenden Übung
erläutert wurde. Zu dieser Zeit müssen wir nur wissen, dass die Verzögerungsfunktion eine Verzögerung von
1 ms am Ende jedes Zyklus generiert, um den Status des Schalters lesen zu können. Befindet sich der Schalter
8 Lesezyklen lang in der gleichen Position, If the button is in the same position during 8 readings, it returns to
the counted position. In case the button is unstable the entire procedure may take up to 100 ms. This function
is included in the library of pins, hence there is no need to add it to the program for passing the example. In
order to try this first part of the exercise, it has to be altered a little - include library of generating the delay in
the program and at the point where the value of the button was read, directly apply the function with filter.
The result is as follows:
//
// The program f o r f i l t e r i n g t h e debounce o f b u t t o n s o f D i g i t a l i /o
module .
//
# include <homelab/delay . h>
# include <homelab/pin . h>
//
// Determining pin s o f LEDs and b u t t o n s .
//
pin l e d s [ 3 ] = { PIN (C , 5 ) , PIN (C , 4 ) , PIN (C , 3 ) } ;
pin button = PIN (C , 0 ) ;
//
// Main program
//
i n t main ( void )
{
unsigned char new_value , o l d _ v a l u e = 0 ;
unsigned char index , c o u n t e r = 0 ;
// S e t t i n g t h e p in s o f LEDs as outputs .
f o r ( index = 0 ; index < 3 ; index ++)
{
pi n_se tup _output ( l e d s [ index ] ) ;
}
// S e t t i n g t h e p in s o f button as input .
p i n _ s e t u p _ i n p u t ( button ) ;
150
6.2 Digitale Input/Output Pins
// Endless loop .
while ( t r u e )
{
// Reading t h e s t a t e o f t h e button .
new_value = pin_get_debounced_value ( button ) ;
// C o n t r o l whether t h e button was pressed down , t h a t means ,
// i s t h e new s t a t e 1 and t h e old s t a t e 0 .
i f ( ( ! new_value ) && ( o l d _ v a l u e ) )
{
// Widening t h e c o u n t e r and t a k i n g module number 3 .
counter = ( counter + 1) % 3 ;
// L i g h t i n g t h e LED witch corresponds t o t h e value o f t h e c o u n t e r
.
f o r ( index = 0 ; index < 3 ; index ++)
{
p i n _ s e t _ t o ( l e d s [ index ] , index ! = c o u n t e r ) ;
}
}
// Remember t h e old s t a t e .
o l d _ v a l u e = new_value ;
}
}
Testen wir das Programm nun, leuchten die LEDs in genau der Sequenz auf, in welcher der Nutzer den Schalter
betätigt.
Aufgaben: Digitale I/O
Ziel ist es, ein Programm zu schreiben, welches die unten beschriebenen Aufgaben ausführt.
Aufwärm-Übung
* Durch Drücken von S1 leuchtet eine LED auf, drückt man S2 leuchten zwei und bei S3 drei LEDs.
151
6 Praktische Beispiele
Für Anfänger
1. Es wird eine von Hand betriebene Ampel an einer Fußgängerkreuzung simuliert. Solange kein Schalter
gedrückt wird, leuchtet eine grüne LED für die Autos. Nach Betätigung eines zufälligen Schalters
beginnt die grüne LED für drei Sekunden zu blinken, daraufhin leuchtet die gelbe LED für 3 Sekunden
und die rote für 10 Sekunden. Nach dieser Sequenz leuchtet erneut die grüne LED.
2. Es soll gezählt werden, wie oft ein Schalter betätigt wurde. Nur durch ein vollständiges Lösen des
Schalters wird das Herunterdrücken vollendet. Das Ergebnis wird als Binärcode auf den LEDs angezeigt. Das maximale Ergebnis bei drei LEDs ist 7 (23-1). Die grüne markiert das erste, die gelbe das
zweite und die rote das dritte Bit.
3. Durch Drücken von Schalter 1 leuchten LED 1 und LED 3. Drückt man S2 leuchtet die gelbe LED,
Schalter 3 sorgt dafür, dass keine LED leuchtet. Diese Operation muss unter direkter Verwendung von
Registerwerten (also ohne Nutzung der HomeLab Bibliothek) durchgeführt werden.
4. Es soll gezählt werden, wie oft ein Schalter gedrückt wurde. Das Ergebnis wird durch Blinken der
LEDs dargestellt. Nach jeder Betätigung des Schalters wird die Anzahl der blinkenden LEDs um eins
erhöht. Der Schalter kann zufällig ausgewählt werden. Damit die LED blinkt muss eine Unterfunktion
genutzt werden, deren Parameter die blinkenden LEDs zählt.
5. Wird S1 betätigt, sendet die rote LED durch Blinken „SOS“im Morsecode. Drückt man S2, sendet die
gelbe LED „CQD“und durch Drücken von S3 zeigt die grüne LED „OK“.
Für Fortgeschrittene
1. Zu jedem der drei Schalter gehört eine LED, welche aufleuchtet wenn der Schalter betätigt wird. Zum
an- oder ausschalten sollen Register und nur eine zuordnende Operation genutzt werden (Hinweis:
Nutzen Sie Bitverschiebungen).
2. Für jede LED gibt es einen Schalter. Der Controller bringt die LEDs in zufälliger Reihenfolge zum
Blinken und der Nutzer muss diese Sequenz wiederholen. Die Blinksequenz verlängert sich, nach jeder
Runde kommt eine LED hinzu. Bei einem falschen Eintrag blinken alle LEDs dreimal (Die Anzahl
korrekter Einträge des Nutzers muss auf einem LCD-Display angezeigt werden).
3. Das Programm misst die Zeit für eine Reaktion. Eine zufällige LED leuchtet auf und der Nutzer muss
den zugehörigen Schalter so schnell wie möglich betätigen. Die Zeit bis zum Aufleuchten der LED ist
zufällig, aber nicht kleiner als 100 ms. Das Ergebnis wird auf einem LCD-Display in Millisekunden
dargestellt. Der Wert der Schalter kann nicht mit einer Filterfunktion für das Flackern gelesen werden,
da diese eine weitere Verzögerung verursacht.
Fragen
1. Was ist der Unterschied zwischen den Operationen “=“und “=“? Nennen Sie zwei Beispiele um Ihre
Antwort zu verifizieren.
152
6.3 Timer und Verzögerungen
2. Was ist der Unterschied zwischen den Operationen “|“und “||“? Nennen Sie zwei Beispiele um Ihre
Antwort zu verifizieren.
3. Schreiben Sie einen Ausdruck, welcher die Gleichung “x = x + 1“zwölfmal verwendet.
4. Wie wird eine Endlosschleife in C geschrieben? Nennen Sie zwei Beispiele.
5. Welcher Variablentyp wird in C verwendet um positive Werte zwischen 7 und 154 dazustellen?
6. Welches Register legt die Richtung eines Anschlusses fest? Nennen Sie ein Beispiel zur Konfiguration
von Input und Output eines Anschlusses.
7. Welche Methoden gibt es um das Zurückspringen von Kontakten zu sowie der durch Flimmern hervorgerufenen falschen Verbindungen zu verhindern? Geben Sie Lösungsbeispiele unter der Nutzung
von Hard- und Software.
8. Was versteht man unter einer Bitverschiebung? Nennen Sie ein praktisches Beispiel und erklären Sie
dieses.
9. Warum werden pull-up Widerstände in Schalter verwendet? Wie ist deren Widerstand festgelegt?
10. Errechnen Sie den Widerstand für die regulierende LED Stromstärke, die Spannung beträgt 5 V, die
Durchlassspannung der LED beträgt 2,7 V und die Stromstärke 30 mA.
6.3
Timer und Verzögerungen
153
6 Praktische Beispiele
Dieses Kapitel beschreibt die Möglichkeit, die Zeit der Mikrocontroller durch Timer und Verzögerungen zu
kontrollieren. Dies ist hilfreich für alle Anwendungen, die eine Zeitmessung benötigen, Unterbrechungen machen oder für präzise Steuerprozesse. Alle Timer und Verzögerungen sind ähnlich im Aufbau, jedoch können
sie voneinander unterschieden werden. Timer sind physikalische Module des Mikrocontrollers, welche unabhängig vom Prozessor des Mikrocontrollers funktionieren, Verzögerungen sind Abschnitte eines Softwareprogramms welche dazu entwickelt werden, die Arbeitszeit des Prozessors zu nutzen. Beide arbeiten ähnlich,
indem sie den Arbeitstakt des Microcontrollers zählen.
Beide Methoden haben ihre Vor- und Nachteile, welche in den entsprechenden Übungen besprochen werden.
Anfangs waren Timer separate Schaltkreise, die nicht Teil eines Mikroprozessors waren. Auch heute gibt es
noch immer separate Timerchips, da in einigen Anwendungen keine Mikrocontroller verwendet werden, und
einige Timer effizienter sind, als die eines Mikrocontrollers.
Timer haben sich von einfachen Zeitzählgeräten zu komplexen System entwickelt, welche Signale empfangen
und generieren. Sie modulieren und demodulieren Signale und ermöglichen, Taktsignale zu multiplizieren
und dividieren. Darüber hinaus gibt es spezielle „Time-To-Digital“Konverter (TDC), welche Zeit in Picosekunden messen können, aber wir werden uns hier nur auf einfachere Timer konzentrieren.
6.3.1
Softwareverzögerungen
Notwendiges Wissen:
Controller module,
Architecture,
Pins,
Delay
Theorie
Oft ist es wichtig in einem Programm eines Mikrocontrollers Verzögerungen einzubauen, einige Aktionen zu
terminieren, oder zu warten bis sie abgeschlossen sind. Die einfachste Methode die Arbeit eines Mikrocontrollers zu pausieren ist, ihn mit einer alternativen Operation zu überladen - z.B. durch einen Befehl, große
Nummern zu zählen. Aus der Taktfrequenz des Prozessors kann man errechnen, wie weit das Programm
zählen sollte um eine Verzögerung hervorzurufen.Eine Zahl von Null bis zum Wert der Taktfrequenz des Prozessors in Hz, sollte theoretisch eine Verzögerung von einer Sekunde erzeugen. Aus verschiedenen Gründen
ist dieses jedoch praktisch nicht ganz so einfach.
Wenn der Prozessor des Microcontrollers mit Nummern rechnet, deren Binärform so groß ist wie der innere
Bus (AVR hat 8 Bits), dann braucht es einen Taktzyklus des Prozessors um eine arithmetische Operation, wie
z.B. 1 zu einem Wert zu addieren, durchzuführen. Soll mit tausenden oder millionen gerechnet werden, muss
die Nummer 16 oder 32 Bit groß sein und ein 8-Bit Prozessor benötigt zur Berechnung mehr als eine Taktfrequenz. Daher sollte man sich mit der Arbeitsweise und insbesondere den Befehlen des Prozessors auskennen,
wenn man mit großen Werten arbeitet.
Wenn man in fortgeschrittenen Sprachen programmiert (z.B. C), werden die Programme nicht auf Basis des
Befehls geschrieben, um eine Softwareverzögerung zu erzeugen. Vielmehr muss man auch den Compiler kennen, welcher das Programm zu Maschinencode konvertiert. Davon hängt ab, wie viele Befehle (und Phasen) es
braucht um eine arithmetische Operation durchzuführen. Das wird durch mehrere Gründe komplexer, durch
die Fähigkeit des Compilers das Programm in Maschinencode umzuwandeln - z.B. dadurch, dass der Maschinencode für Speicherverbrauch optimiert, oder einfacher auszuführen wird. Diesen Compilervorgang nennt
man Optimierung. Durch verschiedene Optimierungsmodi verändern sich die Maschinencodes für die Soft-
154
6.3 Timer und Verzögerungen
wareverzögerung sowie die Dauer der Verzögerung.
Beispiel
Das folgende Beispiel generiert eine Softwareverzögerung im AVR Mikrocontroller. Ein Teil des in C geschriebenen Programms zählt eine Variable x in vier Zyklen von 0 bis 100.In jedem Zyklus wird ein leerer „no-action
empty“Befehl ausgeführt. Dieser wird benötigt, der Compiler einen Zyklus ohne Inhalt als nutzlos betrachtet
und ihn daher aus dem Programm werfen würde.
unsigned char x ;
// Zyklus b i s x i s t 100
f o r ( x = 0 ; x < 1 0 0 ; x ++)
{
// Mit " empty"− B e f e h l nop
asm v o l a t i l e ( " nop " ) ;
}
Dies ist der gleiche Teil des Programms nach dem Kompilieren. Die beiden Hexadezimalzahlen links geben
den Maschinencode an, und rechts befindet sich der Befehl mit den Operanden in Assembler.Der Maschinencode und die Assemblersprache sind konform; Assembler dient nur dazu, den Maschinencode für Menschen
lesbar zu machen. Kompiliert wurde mit der Optimierungsmethode für die Länge des Programms (Parameter
-Os).
80 e0
l d i r24 , 0 x00
; r 2 4 l ä dt Zahl 0 i n den index
00 00
nop
; " Empty " Operation
8f 5f
s u b i r24 , 0xFF
; s u b t r a h i e r e n von 255 aus dem r 2 4 Index ,
was b e d e u t e t +1 addieren
84 36
c p i r24 , 0 x64
; r 2 4 Index mit der Zahl 100 v e r g l e i c h e n
e1 f 7
brne . −8
; F a l l s der V e r g l e i c h n i c h t übereinstimmt ,
8− B i t s zurü c k t r a n s f e r i e r e n
In der kompilierten Form erkennt man, was mit dem Zyklus der C-Sprache passiert und man kann berechnen
wie viele Taktfrequenzen benötigt werden, um den Zyklus einer Periode zu beenden. Die Information über die
Wirkung der Befehle und ihre Laufzeit findet man im AVR Datenblatt. Im vorliegenden Beispiel, braucht es
4 Taktzyklen um 4 Befehle in einer Periode auszuführen, da jeder Befehl einen Takt benötigt. Zusätzlich wird
ein Takt vor dem Zyklus benötigt, um die Befehle zu laden und ein Takt, um den Zyklus zu beenden.Wenn
man nun den Arbeitstakt von 14,7456 MHz annimmt, kann man die vom Programm verursachte Verzögerung
berechnen.
(1 + 100 · 4 + 1) / 14745600 = 27,26 µs
Die Verzögerung in diesem Beispiel ist in Mikrosekunden angegeben und die Variable nutzt 8-Bit, daher ist
der Maschinencode recht einfach. Um eine Pause in Millisekunden zu verursachen, müssen weitaus größere
Nummern gezählt werden, wodurch dann der Maschinencode auch länger wird. Es können ebenfalls Zyklen
verwendet werden, die ineinander greifen, jedoch steht dann die Verzögerung nicht in linearer Relation mit
der Nummer des Zyklus, da mit jedem Level des Zyklus eine kleine zusätzliche Verzögerung verursacht wird.
155
6 Praktische Beispiele
Das Ziel dieser Übung ist es nicht präzise Softwareverzögerungen in Maschinencode zu erstellen, da diese
eine sehr präzise Arbeit ist und die Funktionen zur Erzeugung von Verzögerungen bereits in der avr-libc und
der Bibliothek von HomeLab hinterlegt sind. Diese werden auch in den folgenden Beispielen genutzt.
Bei der Arbeit mit Softwareverzögerungen arbeitet, ist es wichtig zu wissen, dass diese trotz ihrer Einfachheit,
eine sehr ineffiziente Methode sind was den den Stromverbrauch betrifft.Während jedes Taktes in dem der
Mikrocontroller unnötig Zahlen zählt, wird Energie verbraucht. Wenn also batteriebetriebene Anwendungen
genutzt werden, ist es nicht sinnvoll lange Softwareverzögerungen zu schreiben. Für diesen Fall sollte man
lieber Hardwaretimer nutzen, welche unabhängig arbeiten und den Prozessor aus dem Ruhezustand holen
wenn es an der Zeit ist die Arbeit fortzuführen.
Übung
Der folgende Programmcode beinhaltet die Softwareverzögerunsfunktion sw_delay_ms, welche einen gegebene Verzögerung in ms mit dem Parameter count verursacht. Die Funktionen nutzt die Funktion der Bibliothek
avr-libc _delay_ms welche zum Teil in Assembler geschrieben ist._delay_ms wird in dieser Übung nicht genutzt,
da hiermit bei langen Verzögerungen Probleme auftreten können. sw_delay_ms erlaubt es aber bis zu 65535ms
lange Verzögerungen ohne Komplikationen zu nutzen.
//
// S o f t w a r e v e r z ögerung i n Millisekunden .
//
void sw_delay_ms ( unsigned s h o r t count )
{
// Zä hlen der V a r i a b l e der Verzögerung auf 0
while ( count −− > 0 )
{
// 1ms Verzögerung mit s p e z i e l l e r Funktion .
_delay_ms ( 1 ) ;
}
}
Das folgende Programm dient dazu, die gegebene Funktion zu nutzen, es erzeugt zwei Verzögerungen in der
Endlosschleife: 100 ms und 900 ms. Während der kürzeren Verzögerung wird eine LED eingeschaltet und
während der längern ausgeschaltet. Das Resultat: die LED blinkt periodisch.
//
// Das Vorführprogramm des HomeLab f ü r S o f t w a r e v e r z ögerungen .
// Es l ä s s t e i n e LED f ü r ~1 Sekunde a u f l e u c h t e n .
//
# include <homelab/pin . h>
# include <homelab/delay . h>
//
// F e s t l e g u n g des Pins zum Testen der LED
//
pin debug_led = PIN ( B , 7 ) ;
156
6.3 Timer und Verzögerungen
//
// Hauptprogramm
//
i n t main ( void )
{
// S e t z t LED Pin a l s Output .
pi n_s etup _output ( debug_led ) ;
// E n d l o s s c h l e i f e
while ( t r u e )
{
// Aufleuchten der LED
p i n _ c l e a r ( debug_led ) ;
// S o f t w a r e v e r z ögerung f ü r 100 ms
sw_delay_ms ( 1 0 0 ) ;
// Ausschalten der LED
p i n _ s e t ( debug_led ) ;
// S o f t w a r e v e r z ögerung f ü r 900 ms .
sw_delay_ms ( 9 0 0 ) ;
}
}
Auch wenn es so aussieht, als blinke die LED jede Sekunde, dauert es tatsächlich etwas länger, da das ansprechen der LED und die Verzögerungsfunktionen ein paar Taktfrequenzen des Mikrocontrollers benötigen.
6.3.2
Hardwareverzögerung
Notwendiges Wissen:
Software delay
Controller module,
Counters/Timers,
Pins,
Delay,
Timers,
Theorie
Neben der Softwareverzögerung gibt es auch Timer, um Unterbrechungen zu erzeugen. Timer sind Hardwarekomponenten, die mit einer bestimmten Frequenz hoch oder runter zählen. Die Taktfrequenz des Timers
kann über die Frequenz des Mikrocontrollers oder einen externen Taktgeber erzeugt werden. Allgemein kann
die Taktfrequenz mit einem Multiplikator dividiert werden um eine geringere Frequenz zu erreichen. Hierzu
wird ein Vorteiler verwendet. Wichtig ist jedoch, dass die festgelegte Taktfrequenz des Timers linear zu der
157
6 Praktische Beispiele
Zeit ist. Die Zeit kann durch Multiplikation der Periode der Taktfrequent des Timers mit dem Wert des Timers
berechnet werden.
Abbildung 6.10: Durch Veränderung des AVR Timers hervorgerufene Ereignisse.
AVR Taktgeber können so eingestellt werden, dass sie bei Überlauf des Timers oder bei Vergleichstreffern informieren. Ein Überlauf tritt auf, wenn der Timer seinen maximalen Wert erreicht hat und der Zyklus wieder
bei 0 anfängt. Nach Erreichen eines vorgegebenen Wertes beginnt der Timer bei jedem Anstieg seines Wertes diesen mit einem vom Benutzer vorgegebenen Wert zu vergleichen. Daraufhin werden die Bits des AVRStatusindexes automatisch high gesetzt.
Um eine Verzögerung mit einem Timer zu generieren, muss man nur den Timer setzen und darauf warten,
dass das Statusbit high wird. Im Unterschied zur Softwareverzögerung ist die Arbeit des Timers nicht vom
Compiler abhängig, wodurch er zuverlässiger ist. Gleichzeitig ist die Diversität (bzw. Komplexität) der Einstellungen des AVR Timers hoch. Je nach Taktsignal des Mikrocontrollers kann es sein, dass es nicht exakt mit
der gewünschten Verzögerungsperiode dividiert und die Verzögerung so ungenau wird.
Übung
Der Programmcode unterhalb stellt eine vereinfachte Timer-basierte Verzögerungsfunktion dar. Das Zählen
funktioniert genauso wie bei einer Softwareverzögerungsfunktion. Es wird eine gewünschte Verzögerung von
1 ms mit dem Timer 0 eines 8-Bit ATmega128 erzeugt. Die zuvor errechnete Taktfrequenz liegt bei 14,7456
MHz und das Timersignal muss mindestens 64 Mal dividiert werden, so dass der Timer seinen Überlauf nicht
in einer Millisekunde erreicht.Der Wert den der Timer haben muss, so dass der Überlauf nach 1 ms stattfindet
wird mit durch die Variable timer_start dargestellt. F_CPU, eine Konstante in der Makrosprache, gibt die Taktfrequenz in Hz an. Diese sollte 25,6 betragen, da nur ganze Zahlen berücksichtigt werden, liegt der Startwert
bei 26.Leider entsteht hier eine gewisse Ungenauigkeit, welche aber sehr gering ist (- 1,7µs).
In dem Zyklus wird der Timer initialisiert und die Überlauf-Flagge genullt (in dem eine 1 hineingeschrieben
wird). Dann wird abgewartet bis der Timer vom Startwert bis 256 gezählt hat, also zum Überlauf. In dem
Moment wird die Flagge hoch gesetzt und eine Verzögerung von einer 1 ms hat stattgefunden. Am Ende der
Funktion wird der Timer gestoppt.
//
158
6.3 Timer und Verzögerungen
// Hardwareverzögerung i n Millisekunden .
//
void hw_delay_ms ( unsigned s h o r t count )
{
// Berechnung des S t a r t w e r t e s des Timers .
r e g i s t e r unsigned char t i m e r _ s t a r t = 256 − F_CPU / 1000 / 6 4 ;
// S t a r t des Timers .
t i m e r 0 _ i n i t _ n o r m a l ( TIMER0_PRESCALE_64 ) ;
// Zä hlen der Verzö g e r u n g s v a r i a b l e auf 0 .
while ( count −− > 0 )
{
// I n i t i a l i s i e r u n g des Timers .
timer0_set_value ( timer_start ) ;
// Üb e r l a u f −Flagge auf Null s e t z e n .
timer0_overflow_flag_clear ( ) ;
// Warten auf den Üb e r l a u f .
while ( ! t i m e r 0 _ o v e r f l o w _ f l a g _ i s _ s e t ( ) )
{
asm v o l a t i l e ( " nop " ) ;
}
}
// Üb e r l a u f −Flagge auf Null s e t z e n .
timer0_overflow_flag_clear ( ) ;
// Timer a n h a l t e n .
timer0_stop ( ) ;
}
Das folgende Programm ist ähnlich wie das für die Softwareverzögerung. In der kürzeren 100 ms langen halbPeriode wird die LED eingeschaltet und in der längeren 900 ms halb-Periode ausgeschaltet. Das Resultat: die
LED blinkt jede Sekunde. Leider beträgt die Periode in diesem Beispiel ebenfalls nicht exakt eine Sekunde, da
die Ausführung anderer Funktionen des Programms ebenfalls Zeit verbraucht. Für ein exaktes Timing, muss
ein 16-Bit Timer mit Interrupts genutzt werden.
//
// Beispielprogramm f ü r e i n e Hardwareverzögerung mit dem HomeLab .
// Das Programm l ä s s t e i n e LED immer nach ~1 Sekunde b l i n k e n .
//
# include <homelab/pin . h>
# include <homelab/delay . h>
159
6 Praktische Beispiele
//
// F e s t l e g u n g des Pins der Test −LED .
//
pin debug_led = PIN ( B , 7 ) ;
//
// Hauptprogramm .
//
i n t main ( void )
{
// LED Pin a l s Output s e t z e n .
pi n_s etup _output ( debug_led ) ;
// E n d l o s s c h l e i f e .
while ( t r u e )
{
// Aufleuchten der LED .
p i n _ c l e a r ( debug_led ) ;
// Hardwareverzögerung von 100 ms .
hw_delay_ms ( 1 0 0 ) ;
// Ausschalten der LED .
p i n _ s e t ( debug_led ) ;
// Hardwareverzögerung von 900 ms .
hw_delay_ms ( 9 0 0 ) ;
}
}
6.3.3
Periodische Interrupts
Notwendiges Wissen:
mers,
Pins,
Controller module,
Delay,
Timers,
User Interface Module,
Interrupts,
Counters/Ti-
Software delay
Theorie
Ziel dieses praktischen Beispiels ist es, die Verwendung von Interrupts an Beispiel von Timern darzustellen. Interrupts sind Programmteile welche auf Ereignisse, die in einem Mikrocontroller stattfinden, reagieren.
Normalerweise dienen sie dazu, schnell auf ein Event zu reagieren. Sie können jedoch auch dazu genutzt
160
6.3 Timer und Verzögerungen
werden, um mehrere parallel ablaufende Vorgänge oder zeitlich abgestimmte Aktionen auszuführen, oder
zur Energieeinsparung.Es ist beispielsweise möglich eine LED durch Interrupts blinken zu lassen, so dass die
Blinkfrequenz nicht von einem Programm abhängig ist.
Übung
Das folgende Programm zeigt wie Timer eingestellt werden, um einen Interrupt auszulösen.Das Programm
nutzt zwei LEDs des digitalen I/O Moduls. Der Status der roten LED wird mit einer Softwareverzögerung
periodisch geändert, der Status der grünen LED wird geändert wenn ein Interrupt auftritt. Es gibt ein separates
Beispiel für blinkende LEDs durch Softwareverzögerung, daher wird es an dieser Stelle nicht näher erläutert.
Ziel ist es, die Bibliothek für Counter und Interrupts zu verwenden.
Zu Beginn des Programms wird der 16-Bit Timer 1 mit der Funktion timer1_init_ctc eingestellt. Dadurch wird
der Timer in den CTC clear timer on compare match Modus gesetzt, wodurch sein maximaler Wert nicht 216 1 ist, sondern vom Benutzer eingestellt werden kann. In diesem Fall wird der maximale Wert so gesetzt dass
er gleich dem Wert des ICR1 Indexes ist.Der Teiler des Timers ist 1024 und der Wert des ICR1 beträgt 14400.
Bei einer Taktfrequenz von 14,7456MHz umfasst eine Periode somit genau eine Sekunde. Dieses kann mit
folgender Formel berechnet werden:
f = 14745600 Hz / 1024 / 14400 = 1
Nachdem zugelassen wurde, dass ein Interrupt den maximalen Wert von Counter 1 erreicht, muss ein Interrupt auch global, also im Mikrocontroller, zugelassen werden. Dazu gibt es die Funktion sei, um sie zu
untersagen die Funktion cli. Um den Programmteil für diese Funktionen und Interrupts festzulegen muss die
Headerdatei avr/interrupt.h eingefügt werden.Ein Interrupt wird im Programm durch die Makrofunktion ISR
definiert, deren Parameter der Name des Interruptvektors ist. Im folgenden Beispiel beträgt der Interruptvektor des maximal erreichbaren Wertes von Counter 1 TIMER1_CAPT_vect.
//
// HomeLab B e i s p i e l f ü r blinkende LED aufgrund von Counter− I n t e r r u p t s .
// Zum V e r g l e i c h b l i n k e n d e r LEDs aufgrund von I n t e r r u p t s ,
// g i b t es p a r a l l e l e i n e durch S o f t w a r e v e r z ögerung blinkende LED .
//
# include <homelab/pin . h>
# include <homelab/delay . h>
# include <homelab/ t i m e r . h>
# include <avr/ i n t e r r u p t . h>
//
// F e s t l e g u n g der Pins der LEDs .
//
pin l e d _ r e d
= PIN (C , 5 ) ;
pin l e d _ g r e e n = PIN (C , 3 ) ;
//
// I n t e r r u p t
//
161
6 Praktische Beispiele
ISR ( TIMER1_CAPT_vect )
{
// S t a t u s der grünen LED ä ndern .
pin_toggle ( led_green ) ;
}
//
// Hauptprogramm .
//
i n t main ( void )
{
// LED P in s a l s Output s e t z e n .
pi n_s etup _output ( l e d _ r e d ) ;
pi n_s etup _output ( l e d _ g r e e n ) ;
// Timer i n den CTC Modus s e t z e n .
timer1_init_ctc (
TIMER1_PRESCALE_1024 ,
TIMER1_CTC_TOP_ICR ) ;
// Maximaler Wert des Timers i s t 1 4 4 0 0 , wodurch
// d i e P er iode 1 s lang i s t .
// Formel : 1 4 , 7 4 5 6Mhz / 1024 = 14400
timer1_set_input_capture_value (14400) ;
// Dem I n t e r r u p t erlauben , den Wert zu e r r e i c h e n .
timer1_input_capture_interrupt_enable ( true ) ;
// Globalen I n t e r r u p t z u l a s s e n .
sei () ;
// E n d l o s s c h l e i f e .
while ( t r u e )
{
// S o f t w a r e v e r z ögerung 1000 ms .
sw_delay_ms ( 1 0 0 0 ) ;
// S t a t u s der r o t e n LED ä ndern .
pin_toggle ( led_red ) ;
}
}
Zu Beginn des Programms sieht man, dass unabhängig davon was der Mikrocontroller gerade im Hauptprogramm macht, Interrupts stattfinden und die grüne LED blinkt.
162
6.3 Timer und Verzögerungen
Läuft das Programm ein paar Minuten wird ein entscheidender Aspekt deutlich, der im Rahmen der Softwareverzögerung nicht so einfach zu erkennen ist. Auch wenn die Verzögerung der blinkenden roten LED
1000 ms beträgt, ist die tatsächlich benötigte Zeit um einen Zyklus zu beenden länger. Das liegt daran, dass
die Änderung vom LED-Status’, die Angabe der Verzögerungsfunktion und das Beenden vom Zyklus einige
Taktzyklen des Prozessors dauern. Daher sieht es so aus, als blinke die rote LED immer nach der grünen. Aus
diesem Grund sollten Taktgeber oder andere präzise Vorgänge nicht mit Verzögerungen, sondern mit TimerInterrupts ausgeführt werden.
6.3.4
Aufgaben
Ziel ist es, ein Programm zu schreiben welches die unten genannten Aufgaben durchführt.
Aufwärm-Übung
Lassen Sie die rote LED blinken. Die Periode soll 10 Sekunden (Halbperiode 5 Sekunden) betragen.
Nutzen Sie eine Softwareverzögerungsfunktion, mit der Sekundenanzahl als Parameter.
Für Anfänger
1. Zeigen Sie mit einer Genauigkeit von 100 ms auf dem LCD Display die Zeit zwischen der Betätigung
von 2 beliebigen Schaltern an. Die Art der Zeitmessung können Sie frei bestimmen.
2. Wird Schalter S1 betätigt, wird die Blinkgeschwindigkeit aller 3 LEDs zweimal reduziert. Durch Betätigung von S3, blinken die LEDs doppelt so schnell, und S2 setzt die Blinkfrequenz auf 1 Hz. Nutzen
Sie Verzögerungsfunktionen oder Interrupts (die Interrupts sind schwieriger, aber bei der Verwendung
von Verzögerungsfunktionen wird eine zusätzliche Verzögerung durch die Filterfunktion der Schalter
auftreten.)
3. zeige die Druckfrequenz von Schalter S1 auf dem 7 Segment LED-Display in Hz-s. Die Anzeige der
Frequenz muss nach unten mit 0 und nach oben mit 9 begrenzt werden.
4. Wird Schalter S1 gedrückt wird, zählt das Programm die Sekunden von 60 bis 0 herunter und schaltet
dann die rote LED ein. Bei S2 beträgt die Zeit nur 30 s, anschließend wird die gelbe LED eingeschaltet. Die Zeit bei Betätigung von S3 beträgt 10 s, dann leuchtet die grüne LED. Alle Prozesse müssen
gleichzeitig stattfinden. Die LEDs schalten sich aus, wenn der dazugehörige Schalter betätigt wird.
5. Zeigen Sie die Zeit auf dem LCD wie folgt an: hh:mm:ss. Nutzen Sie den Hardwaretimer 1 mit Interrupts, die Zeit muss mit den Schaltern eingestellt werden können. Es sollten drei Schalter genutzt
werden, S1 erhöht die Stunden, S2 die Minuten, und S3 die Sekunden.
163
6 Praktische Beispiele
Für Fortgeschrittene
1. Entwickeln Sie eine Stoppuhr, die Stunden, Minuten, Sekunden, und Millisekunden auf dem LCD
anzeigt. Schalter S1 startet die Zeit, S2 hält sie an, und S3 nullt die Uhr. Es müssen Interrupts des
Timers genutzt werden.
2. Die rote, gelbe und grüne LED müssen in 2-Sekunden Intervallen fließend nacheinander ein- und
ausgeschaltet werden. Das fließende Licht wird erzeugt, in dem man die LED mit mehreren hundert
Hertz moduliert (also sehr schnell ein- und ausschaltet) und die Abstände zwischen dem Ein- und
Ausschalten verändert. Dadurch wird für das Auge der Effekt erzeugt, dass sich die Helligkeit der
LED ändert (Pulsweitenmodulation).
3. Erstellen Sie einen Programmteil in C, welcher eine Verzögerung von 10 µs ± 10% bei einer Taktfrequenz von 14,7456 MHz erzeugt. Verifizieren Sie theoretisch, dass die Verzögerung funktioniert, indem
Sie die Assembler-Befehle in der .lss Datei des kompilierten Programms kommentieren.
Fragen
1. Welche Methoden zur Erstellung von Verzögerungen gibt es?
2. Wie wird eine Softwareverzögerung erstellt? Von welchen Parametern hängt die Softwareverzögerung
ab?
3. Warum werden Hardwareverzögerungen/Timer mit Interrupts genutzt?
4. Berechnen sie die die Überlauf-Interruptperiode für einen 8-Bit Timer, wenn Taktfrequenz 16M Hz und
Frequenzteilerfaktor 1024 betragen.
5. Was ist ein Echtzeitgeber in einem Computer?
6. Was geschieht am 19.01.2038 in der Computerwelt?
7. Wozu können AVR Timer noch genutzt werden, außer um Zeit zu zählen?
8. Welche Indizes können genutzt werden um den ATmega128 Timer 0 einzustellen? Was kann mit diesen
Register verändert werden?
9. Wie lang ist die längste Zeitspanne von Unterbrechungen in Millisekunden, die mit einem ATmega128
mit einer Taktfrequenz von 14,7456 MHz erreicht werden kann? Stellen Sie die Berechnung dar.
10. Hat es einen Effekt auf die Genauigkeit von Timern, wenn der Prozessor mit der Ausführung eines
Programms stark ausgelastet ist (z.B. mehrere Motoren und Werte verschiedener Sensoren gleichzeitig
kontrollieren)? Erläutern Sie Ihre Antwort.
164
6.4 Anzeigen und Displays
6.4
Anzeigen und Displays
Einer der einfachsten Methoden um sicher zu gehen, dass ein Mikrocontroller funktioniert ist Code zu einem
Programm hinzuzufügen, um eine oder mehrere LEDs bei einer bestimmten Aktivität blinken zu lassen. Sehr
oft ist dies nicht genug, weil mehr Informationen überprüft werden müssen, als mit einer LED möglich oder
da einige Anwendungen brauchen eine Benutzerschnittstelle, welche Text oder Nummern anzeigt, benötigen. Hier finden alle Arten von Indikatoren und Displays Verwendung, welche das Anzeigen von Nummern,
Texten oder sogar Bildern ermöglichen. Computerbildschirme zählen zu den bekanntesten Anzeigegeräten.
Für einen Programmierer ist die Arbeit mit ihnen alltäglich, jedoch ist es sehr aufwändig Pixel mit Hilfe von
Mikrocontrollern auf einem Bildschirm anzuzeigen.
Das folgende Kapitel befasst sich mit einfachen Displays und Bildschirmen. Anzeigen mit LED-Segmenten
und zwei Typen von monochromen LCD´s. Zusätzlich zu diesen werden auch LED-Matrizen und organischen
Farb-LED´s(OLED) mit Mikrocontrollern genutzt. Früher wurden Nixie-Röhren verwendet, welche separate
Glühdrähte für jede Zahl hatten. Darüber hinaus gibt es elektromechanische Anzeigen, deren verschiedenfarbige Segmente physisch gedreht werden. Neuerdings erfreuen sich E-Paper-Displays, mit denen gedruckte
Texte nachgebildet werden können, großer Beliebtheit. Die Ersten E-Paper (elektronisches Papier) bestanden
aus Kugeln mit verschieden farbigen Seiten, welche in einem elektrischen Feld gedreht wurden. Neuere EPaper enthalten kleine Kapseln, in denen geladene Partikel zweier Farben durch ein elektrisches Feld dahingehend beeinflusst werden, ob sie herabsinken oder an der Oberfläche bleiben sollen. Die letzten beiden Beispiele wurden zur Erläuterung diverser Anzeigetechniken dargestellt, sie werden im HomeLab jedoch nicht
165
6 Praktische Beispiele
weiter verfolgt.
6.4.1 7-Segment-LED-Anzeige
Notwendiges Wissen:
Diode
User Interface Module,
Delay,
7-segment LED Display,
Light-emitting
Theorie
Die 7-Segment-LED-Zifferanzeige ist ein Display, welches aus sieben, in Form einer Acht angeordneten, LEDs
besteht. Durch Ein- oder Ausschalten der entsprechenden LED´s (Segmente) ist es möglich Zahlen von 0-9
sowie einige Buchstaben darzustellen.
Abbildung 6.11: Positionierung der Anzeigensegmente des LED sowie elektrisches Schema.
Elektrisch werden alle Anoden der LEDs an einer Anode am Pin ca angeschlossen. Die LEDs leuchten durch
Schalten ihrer Kathoden (a, b, c . . . ). Es gibt auch andere Verbindungen, bei denen die Anzeigen eine gemeinsame Kathode cc haben. Allgemein werden verschiedene Zifferanzeigen zur Darstellung mehrstelliger Ziffern
genutzt. Hierzu verfügt das Display über ein Komma- (Punkt-) Segment dp. Insgesamt besitzt eine Anzeige dann 8 Segmente, wird jedoch aufgrund der Anzahl von Ziffer-Segmenten weiterhin 7-Segment-Display
genannt.
LED number-indicators are easy to use, they can be controlled directly from the pins of the microcontroller, but
there are also special drivers, which able to control number-indicators using fewer pins of the microcontroller.
There are different colors of LED number indicators, which can be very bright and very large. For displaying
the entire Latin alphabet exist indicators with extra segments.
Die Benutzung von LED Zifferanzeigen ist recht einfach. Sie können direkt über die Pins des Mikrocontrollers kontrolliert werden. Es gibt jedoch auch spezielle Treiber, die dafür sorgen, dass für die Nutzung der
Anzeige weniger Pins des Mikrocontrollers benötigt werden. Es gibt zwei verschiedene Farben von LED-Zifferanzeigen, die sehr klar und groß sein können. Zur Anzeige des gesamten Alphabets gibt es Anzeigen mit
zusätzlichen Segmenten.
166
6.4 Anzeigen und Displays
Übung
Am digitalen I/O Modul befindet sich eine 7-Segment-LED-Zifferanzeige. Sie wird über einen Treiber mit der
seriellen Schnittstelle A6275 kontrolliert. Die serielle Schnittstelle des Treibers ist dem SPI ähnlich, bei dem
sowohl Taktsignal als auch Datensignale genutzt werden. Anders als beim SPI wird chip-select nicht genutzt
und wird durch die latch Funktion ersetzt. Es ist mit dem ATmega128 wie folgt verbunden:
Abbildung 6.12: Aufbau des Verschiebungsindexes des LED Treibers mit den zugehörigen
Segmenten der Anzeige.
Latch-Signal (latch) - PG2
Taktsignal (clock) - PC7
Datensignal (data) - PC6
Die Daten werden in Form von Bits über den Datenpin gesendet. Immer, wenn das Taktsignal high wird, wird
der Inhalt des Verschiebungsindexes nach rechts geschoben und das Bit vom Datenpin wird in die Zelle ganz
links gelesen. So werden 8 Bits in den Verschiebungsindex geladen. Wenn das Latch-Signal high gesetzt wird,
wird der Wert des Verschiebungsindexes in den Latch-Index geladen, und verbleibt dort bis zu einem erneuten
Laden. Jedes Bit des Latch-Indexes ist durch eine Spannungsschaltung mit einem Segment der Zifferanzeige
verbunden. Das Segment leuchtet während die Bitrate high ist.
Zur Darstellung von Ziffern auf der digitalen I/O Modulanzeige des HomeLab sind die folgenden Funktionen
in der Bibliothek von HomeLab enthalten:
//
// E i n r i c h t u n g der Pins
//
s t a t i c pin s e g m e n t _ d i s p l a y _ l a t c h =
PIN (G, 2 ) ;
s t a t i c pin se gment_display_data_out = PIN (C , 6 ) ;
s t a t i c pin s e g m e n t _ d i s p l a y _ c l o c k =
PIN (C , 7 ) ;
//
// Markierung der Karte .
167
6 Praktische Beispiele
// Die B i t s markieren Segmente . Ein n i e d r i g e r Rang wird mit A, e i n
hoher mit DP gekennzeichnet .
//
s t a t i c c o n s t unsigned char segment_char_map [ 1 1 ] =
{
0 b00111111 ,
0 b00000110 ,
0 b01011011 ,
0 b01001111 ,
0 b01100110 ,
0 b01101101 ,
0 b01111100 ,
0 b00000111 ,
0 b01111111 ,
0 b01100111 ,
0 b01111001
// E wie " E r r o r "
};
//
// S t a r t der 7−Segment−Anzeige .
//
void s e g m e n t _ d i s p l a y _ i n i t ( void )
{
// S e t l a t c h , data out and c l o c k pin s as output
pi n_s etup _output ( s e g m e n t _ d i s p l a y _ l a t c h ) ;
pi n_s etup _output ( segment_display_data_out ) ;
pi n_s etup _output ( s e g m e n t _ d i s p l a y _ c l o c k ) ;
}
//
// D a r s t e l l u n g e i n e r Z i f f e r auf der 7−Segment−Anzeige .
//
void s e g m e n t _ d i s p l a y _ w r i t e ( unsigned char d i g i t )
{
unsigned char map ;
signed char i ;
// Überprüfung der Z i f f e r
i f ( digit > 9)
{
digit = 10;
}
// Z i f f e r wie Segmentkarte .
map = segment_char_map [ d i g i t ] ;
168
6.4 Anzeigen und Displays
// Latch −S i g n a l aus
pin_clear ( segment_display_latch ) ;
// Senden von he B i t s . Hö h e r r a n g i g e z u e r s t .
f o r ( i = 7 ; i >= 0 ; i −−)
{
// Pin entsprechend B i t w e r t der Karte s e t z e n .
p i n _ s e t _ t o ( segment_display_data_out , b i t _ i s _ s e t (map , i ) ) ;
// T a k t s i g n a l high s e t z e n .
pin_set ( segment_display_clock ) ;
_delay_us ( 1 ) ;
// T a k t s i g n a l low s e t z e n .
pin_clear ( segment_display_clock ) ;
_delay_us ( 1 ) ;
}
// Latch −S i g n a l e i n .
pin_set ( segment_display_latch ) ;
}
Um Ziffern und den Buchstaben „E“darzustellen, wird ein konstantes Array segment_char_map erstellt, bei
dem das Leuchten von allen acht Segmenten mit Bit 1 und das Ausschalten mit Bit 0 markiert wird. Die
Bits markieren von hoch zu niedrig (von links nach rechts in Binärform) Segmente DP, G, F, E, D, C, B, A.
Die Kontrollschnittstelle des Treibers wird durch SPI Software realisiert, zum Beispiel durch Nutzung einer
Software, die die Datenkommunikationspins des Programms kontrolliert. Alle drei Pins werden durch segment_display_init als Outputs gesetzt. segment_display_write dient der Darstellung der Funktion, welche die
Segmentkarte der Markierung vom Array erkennt und diese bitweise zum Treiber überträgt. Die Taktfrequenz
mit Softwareverzögerung liegt bei ungefähr 500 kHz.
Das nachfolgende Beispielprogramm beschreibt die Nutzung der Zifferanzeige. Die zuvor beschriebene Funktion der Bibliothek wird in dem Programm erläutert. Das Programm Zählt Ziffern von 0 bis 9 mit einem Intervall von etwa einer Sekunde. Dieses wird dadurch erreicht, dass ein Modul mit einer weitaus größeren Ziffer
verwendet wird.
//
// Das Beispielprogramm der 7−Segment−LED−Anzeige des I /O−Moduls des
HomeLab
//
# include <homelab/module/segment_display . h>
# include <homelab/delay . h>
//
// Hauptprogramm .
//
169
6 Praktische Beispiele
i n t main ( void )
{
int counter = 0 ;
// E i n r i c h t u n g der 7−Segment−Anzeige .
segment_display_init ( ) ;
// E n d l o s s c h l e i f e .
while ( t r u e )
{
// Anzeige der Werte des Timers .
segment_display_write ( counter % 10) ;
// Lange zä hlen .
c o u n t e r ++;
// Verzögerung von 1 Sekunde .
sw_delay_ms ( 1 0 0 0 ) ;
}
}
6.4.2
Alphanumerisches LCD
Notwendiges Wissen:
lcd,
Alphanumeric LCD,
Delay,
Periodic interrupt
Theorie
Das alphanumerische LCD ist ein Flüssigkristall-Display, welches zur Darstellung von Buchstaben und Ziffern
dient. In einfachen LCD’s werden flüssige Kristalle verwendet, welche zwischen transparenten Elektroden
angeordnet sind und die Polarisation des durchstrahlenden Lichts im elektrischen Feld verändern. Auf den
Elektroden befinden sich Polarisationsfilter, welche sicher stellen, das nur in eine Richtung polarisiertes Licht
auf den Bildschirm trifft.Wenn der Flüssigkristall seine Polarisation durch das elektrische Feld ändert, erreicht
das Licht den Bildschirm oder ein Segment des Bildschirms nicht und er bleibt schwarz.
Hauptmerkmal eines alphanumerischen LCD ist die Anordnung der Segmente. Der Bildschirm ist in verschiedene Anzeigen unterteilt. Jede Anzeige hat entweder genügend Segmente um Buchstaben oder Nummern
anzuzeigen oder es wird eine Matrix aus Pixeln gebildet. Eine Matrix aus 5×7 Pixeln ist beispielsweise ausreichend, um alle Nummern und Buchstaben des lateinischen Alphabets darzustellen. Die Anzeigeelemente
bestehen gewöhnlich aus 1 bis 4 Zeilen sowie 8 bis 32 Spalten. Zwischen den Elementen befinden sich kleine
Abstände ähnlich wie bei Buchstaben im Text.
170
6.4 Anzeigen und Displays
Abbildung 6.13: Darstellung eines Textes durch eine Pixelmatrix eines alphanumerischen LCD.
Neben dem Bildschirm hat das alphanumerische LCD auch einen Controller, welcher die Segmente des Bildschirms gemäß den Befehlen der Kommunikationsschnittstelle steuert. Ein Controller verfügt über eine vorprogrammiertes Set von Buchstaben mit einem eigenen Index für jeden Buchstaben, jede Nummer sowie jedes Symbol. Die Darstellung des Textes auf dem Bildschirm erfolgt, einfach gesagt, indem die Indizes zum
Controller gesendet werden. Tatsächlich müssen jedoch weitere Kontrollbefehle übermittelt werden, bevor
irgendetwas dargestellt werden kann. Da es viele verschiedene Ausführungen von LCDs gibt, die jeweils unterschiedlich gesteuert werden, ist es wichtig, sich mit dem Datenblatt jedes LCDs vertraut zu machen.
Alphanumerische LCDs besitzen normalerweise eine passive Matrix. Hier erfolgt die Erneuerung des elektrischen Feldes der Segmente turnusmäßig. Aus diesem Grund sind Bildschirme mit einer passiven Matrix
langsamer und Darum sind die Bildschirme mit passiver Matrix langsamer und bieten weniger Kontrast,
als Bildschrime mit aktiver Matrix. Bei Aktivmatrix-Bildschrimen wird die Ladung jedes einzelnen Segments
durch einen eigenen Transistor gesteuert. Einige LCDs haben einen reflektierenden Hintergrund, andere haben
Hintergrundbeleuchtungen und wieder andere sogar verschiedene Hintergrundbeleuchtungen. Die Segmente eines alphanumerischen LCDs haben jedoch immer nur eine Farbe. In der Regel sind sie schwarz, es gibt
jedoch auch Bildschrime mit weißer oder farbiger Schrift.
Übung
Am digitalen I/O Modul des HomeLab ist ein alphanumerisches, 2×16 Zeichen großes, LCD WC 1602A angeschlossen. Zur Steuerung des Bildschirms gibt es einen 4-Bit Datenbus sowie 3 Kontroll-Pins. Da das Kommunikationsprotokoll des Bildschirms zu umfangreich ist, um es hier zu erläutern, enthält die HomeLab Library
die entsprechenden Funktionen zur Nutzung des Displays.
Vor der Nutzung des Displays ist es notwendig, seine Einstellungen anzupassen. Hierzu dient die lcd_alpha_init
Funktion, welche einen blinkenden Cursor auf dem Bildschirm erscheinen lässt. Hier gibt es nur eine aktive
Position für den Cursor, an welcher der nächste Buchstabe eingegeben werden kann. Bevor also Text eingegeben wird, muss der Cursor an die gewünschte Position bewegt werden. Um die Position des Cursors zu
verändern gibt es die Funktion lcd_alpha_goto_xy und für die Darstellung die Funktion lcd_alpha_write_string.
Sämtliche Funktionen des alphanumerischen LCDs sind in der Library erklärt.
Der folgende Programm-Code zeigt wie das alphanumerische LCD als Uhr genutzt werden kann. Die Zeit
beginnt bei 00:00:00 und nimmt etwa jede Sekunde zu. Da das Zählen der Zeit mit Hilfe einer Verzögerungsfunktion geschieht, ist das Ergebnis nicht sehr genau. Diese Ungenauigkeit wird im Rahmen der Aufgabe zu
periodischen Unterbrechungen erklärt. Das Programm zählt die Sekunden und konvertiert diese in Minuten
und Sekunden. Um Uhrzeit darzustellen wird die Standard-Funktion in C genutzt: sprintf.
//
// B e i s p i e l zur Nutzung des alphanumerischen LCD des HomeLab .
171
6 Praktische Beispiele
// Die S t a r t z e i t zu Beginn des Programms wird auf dem LCD a n g e z e i g t .
//
# include < s t d i o . h>
# include <homelab/module/ l c d _ a l p h a . h>
# include <homelab/delay . h>
//
// Hauptprogramm .
//
i n t main ( void )
{
i n t seconds = 0 ;
char t e x t [ 1 6 ] ;
// E i n r i c h t u n g des LCD .
l c d _ a l p h a _ i n i t (LCD_ALPHA_DISP_ON) ;
// Lö schen des LCD .
lcd_alpha_clear ( ) ;
// Name des Programms .
l c d _ a l p h a _ w r i t e _ s t r i n g ( " The Time Counter " ) ;
// E n d l o s s c h l e i f e
while ( t r u e )
{
// K o n v e r t i e r e n der Sekunden i n d i e Z e i t a n z e i g e :
// hh :mm: s s
s p r i n t f ( t e x t , " %02d:%02d:%02d " ,
( seconds / 3 6 0 0 ) % 2 4 ,
( seconds / 6 0 ) % 6 0 ,
seconds % 6 0 ) ;
// Anzeige der Z e i t am Anfang der zweiten Reihe des LCD .
lcd_alpha_goto_xy ( 0 , 1) ;
lcd_alpha_write_string ( text ) ;
// Anstieg der Sekunden um 1 .
seconds ++;
// Hardwareverzögerung 1000 ms .
hw_delay_ms ( 1 0 0 0 ) ;
}
}
172
6.4 Anzeigen und Displays
6.4.3
Graphisches LCD
Notwendiges Wissen:
lcd,
Graphic LCD,
Delay,
Alphanumeric LCD
Theorie
Das graphische LCD liquid crystal display ist ein Display zur Darstellung von Bildern und Text. Es ist ähnlich
aufgebaut wie das alphanumerische LCD, mit dem Unterschied, dass sich auf dem graphischen LCD alle Pixel
in einer großen Matrix befinden. Bei monochromen LCDs entspricht ein Pixel einem quadratischen Segment,
bei Farbdisplays besteht ein Pixel aus drei Unterpixeln. Jedes der Unterpixel lässt nur eine Lichtfarbe durch
(rot, grün oder blau). Da die Unterpixel sehr nah beieinander liegen, werden sie als ein Pixel wahrgenommen.
Abbildung 6.14: Der durch Pixel eines graphischen LCDs dargestellte Text.
Monochrome graphische Displays haben normalerweise eine passive Matrix, große Farbdisplays (auch ComputerBildschirme) eine aktive. Im Hinblick auf die Farbe des Hintergrunds und der Pixel entspricht das graphische
LCD dem alphanumerischen. Auch das graphische Display verfügt über einen separaten Controller, welcher
die Information über die Kommunikationsschnittstelle empfängt und das elektrische Feld für die Segmente
generiert. Im Gegensatz zum alphanumerischen LCD, welches Text anzeigt, indem die Indizes der darzustellenden Zeichen gesendet werden, kann das graphische LCD keine Buchstaben eigenständig generieren sämtliche Bilder und Texte müssen Pixel für Pixel vom Nutzer generiert werden.
Übung
Das HomeLab Kit enthält ein 84×48 Pixel großes, monochromes, graphisches LCD. Es ist das gleiche, welches
auch im Mobiltelefon Nokia 3310 verwendet wird. Ein Philips PCD8544 Controller ist am Display angebracht,
mit welchem über eine SPI-ähnliche serielle Schnittstelle kommuniziert werden kann. Die Hintergrundbeleuchtung des Displays wird separat gesteuert.Die Kommunikation mit dem Display ist nicht sehr schwer,
aufgrund der vielen Funktionen wird sie hier jedoch nicht erläutert. Die HomeLab Library enthält die dafür
notwendigen Funktionen.
Die Funktionen für das graphische LCD sind ähnlich zu denen des alphanumerischen LCD. Zuerst muss der
Bildschirm mit der Funktion lcd_gfx_initgestartet werden. Nach dem Start sollte man den Bildschrim, bzw. den
Speicher des Controllers mit der lcd_gfx_clear Funktion leeren. Die Library enthält eine Abbildung des vollständigen lateinischen Alphabets, der Zahlen sowie der am häufigsten verwendeten Zeichen. Die Buchstaben ist 7
Pixel hoch und 5 Pixel breit. Der Abstand zwischen den Buchstaben beträgt horizontal 6 und vertikal 8 Pixel. Es
können also Buchstaben in 6 Reihen mit 14 Spalten auf dem Display dargestellt werden. Zur Darstellung von
173
6 Praktische Beispiele
Buchstaben oder Text, muss zunächst mit der Funktion lcd_gfx_goto_char_xy die Position festgelegt werden.
Mit der Funktion cd_gfx_write_char wird ein Buchstabe angezeigt, die Funktion lcd_gfx_write_string ermöglicht
die Darstellung eines Textes.
Nachfolgend ist ein Beispiel des Zeitzählers dargestellt. Das Programm zählt Sekunden (annähernd), Minuten
und Stunden. Zum Konvertieren von Zeit in Text wird die Funktion sprintf genutzt.
//
// B e i s p i e l f ü r d i e Nutzung des graphischen LCD des HomeLab .
// Die T a g e s z e i t wird ab Beginn des Programms auf dem LCD a n g e z e i g t .
//
# include < s t d i o . h>
# include <homelab/module/ l c d _ g f x . h>
# include <homelab/delay . h>
//
// Hauptprogramm .
//
i n t main ( void )
{
i n t seconds = 0 ;
char t e x t [ 1 6 ] ;
// E i n r i c h t e n des LCD .
lcd_gfx_init () ;
// Lö schen des D i s p l a y s .
lcd_gfx_clear () ;
// E i n s c h a l t e n der Hintergrundbeleuchtung .
lcd_gfx_backlight ( true ) ;
// Anzeige des Programmnamens .
lcd_gfx_goto_char_xy ( 1 , 1) ;
l c d _ g f x _ w r i t e _ s t r i n g ( " Aja loendur " ) ;
// E n d l o s s c h l e i f e .
while ( t r u e )
{
// Sekunden i n d i e Form der U h r z e i t k o n v e r t i e r e n .
// hh :mm: s s
s p r i n t f ( t e x t , " %02d:%02d:%02d " ,
( seconds / 3 6 0 0 ) % 2 4 ,
( seconds / 6 0 ) % 6 0 ,
seconds % 6 0 ) ;
// Anzeige des Z e i t t e x t e s .
174
6.4 Anzeigen und Displays
lcd_gfx_goto_char_xy ( 3 , 3) ;
lcd_gfx_write_string ( text ) ;
// Eine Sekunde h i n z u fügen .
seconds ++;
// Hardwareverzögerung von 1000 ms .
hw_delay_ms ( 1 0 0 0 ) ;
}
}
6.4.4
Aufgaben
Ziel ist es, ein Programm zu schreiben, welches die unten beschriebenen Aufgaben erüllt.
Aufwärmübung
Das Programm soll von 1 bis 9 und dann zurück von 9 bis 1 auf der 7-Segment-Anzeige zählen. Die
Zählperiode beträgt 1 Sekunde.
Für Anfänger
1. Stellen Sie die Zahlen im Hexadezimalsystem zufällig auf der 7-Segment-Anzeige dar. Die Frequenz
beträgt 1 Hz.
2. Lassen Sie die äußeren 6 Segmente der 7-Segment-Anzeige periodisch im Abstand von 500 ms aufleuchten.
3. Schreiben Sie ein Programm für das LCD, welches den Code und das zugehörige Symbol anzeigt.
Verwenden Sie Codes von 0 bis 255. Jedes Code-Symbol-Paar wird 1 Sekunde lang auf dem Display
angezeigt.
4. Schreiben Sie ein Programm, mit welchem das Symbol „X“über den Bildschrim bewegt werden kann.
Mit dem Schalter S1 kann es nach links bewegt werden, mit Schalter S3 nach rechts und mit Schalter
S2 wird die Reihe gewechselt.
5. Stellen Sie auf dem graphischen Display 10 Zeilen Text dar. Mit den Schaltern S1 und S2 kann innerhalb
des Textes hoch- und runtergescrollt werden.
6. Erstellen Sie eine Benutzerschnittstelle über welche mit den drei Schaltern Text eingegeben werden
kann. Ein Schalter wählt beispielsweise das Zeichen aus, der zweite überprüft das Zeichen und der
dritte überprüft schließlich den Text. Die maximale Länge des Textes beträgt 10 Zeichen und der Text
175
6 Praktische Beispiele
soll in umgekehrter Reihenfolge in der zweiten Reihe dargestellt werden. Sie können das lateinische
Alphabet nutzen und das Display selbst auswählen.
Für Fortgeschrittene
1. Stellen Sie griechische Buchstaben auf dem graphischen LCD dar. Dabei sollen folgende Zeilen angezeigt werden: “Widerstand Ω“, “∑R=∑ πR2 “, “π=3.141592“. Nutzen Sie den Quellcode aus der
HomeLab Library (von der Webseite).
2. Schreiben Sie ein Programm, um Dezimalzahlen in Binärzahlen zu konvertieren. Verwenden Sie die
Schalter S3 bis S1 zum Einfügen von Dezimalzahlen in zehn Sekunden ( S3 - Hunderter S2 - Zehner S1
- Einer). Durch vierfaches Betätigen von Schalter S3 wird so beispielsweise die Zahl 400 angezeigt. Das
Zeichen für den Beginn der Eingabe und für das Ergebnis sollen in Binärzahlen ausgegeben werden.
Verwenden Sie hierzu ein beliebiges LCD.
3. Schreiben Sie eine Funktion zur Darstellung eines Rechtecks auf dem LCD. Breite, Länge sowie die Koordinaten der oberen linken Ecke sind dabe vorgegeben. Die Linienstärke beträgt 1 Pixel. Überprüfen
Sie, ob das Rechteck ins Display passt. Hierzu ist es ratsam, sich mit der HomeLab Library zu befassen.
4. Programmieren Sie ein einfaches Wurm-Spiel für das graphische LCD. Der Wurm ist 1 Pixel breit und
5 Pixel lang. Durch Betätigung der Schalter kann der Wurm sich nach rechts oder links bewegen. Er
muss auf diese Weise Kollisionen mit dem Displayrand vermeiden können. Es gibt Bonuspunkte für
das Einsammeln von Eiern, wodurch der Wurm wächst. Die einfachste Lösung ist, den Wurm aus dem
Buchstaben „O“zu entwickeln.
5. Schreiben Sie ein Programm zur Darstellung verschiedener Wetterbedingungen auf dem graphischen
LCD. Nutzen Sie für sonniges Wetter ein Bild der Sonne, für Regen eine Regenwolke, für bewölkt eine
Wolke und für Schnee eine Schneeflocke. Die Größe der Bilder kann variieren, wichtig ist nur, dass die
Bilder sich deutlich voneinander unterscheiden. Die Bilder sollen mittels eines Schalters gewechselt
werden können.
Fragen
1. Wie viele Pins nutzt die 7-Segment Zifferanzeige (mit Punktsegment), wenn sie direkt mit dem Controller verbunden ist? Wie viele Pins werden benötigt, wenn sie über einen Treiber gesteuert wird?
(Treiber - A6275)
2. Was bestimmt die Helligkeit der 7-Segment Zifferanzeige? Wie kann sie angepasst werden wenn die
Anzeige a) direkt oder b) über einen Treiber (Treiber - A6275) gesteuert wird?
3. Wenn die 7-Segment Zifferanzeige direkt an Port A des Controllers angeschlossen ist sodass das Segment A PA0, B PA1 . . . und DP PA7 ist, wie lauten dann die Werte des PORTA Registers mit den Ziffern
0 bis 9?
4. Was ist der Unterschied zwischen alphabetischen 4-Bit und 8-Bit LCD Controllern?
5. Über welche Pins und wie wird die Hintergrundbeleuchtung der alphanumerischen LCDs reguliert?
176
6.5 Sensoren
6. Welches I/O Protokoll nutzt das graphische LCD? Erläutern Sie die Bedeutung der I/O Pins.
7. Wie können Dezimalzahlen in binäre (in Text) konvertiert werden und umgekehrt?
8. Zeichnen Sie die Schichten aus denen ein LCD besteht mittels der twisted nematic Technologie.
9. Wie werden Buchstaben auf dem graphischen LCD angezeigt?
10. Wie unterscheidet sich ein monochromes (schwarz/weiß) LCD von einem Farbdisplay?
6.5
Sensoren
Sensoren sind Geräte welche jede Form von physikalischen Attributen (Temperatur, Beleuchtung, Kraft, Beschleunigung usw. ) in eine verständliche Form für Menschen oder Maschinen bringen. Mit der Hilfe von
Sensoren erhält der Mikrocontroller Informationen über seine Umgebung und trifft Entscheidungen basierend
auf diesen Informationen. Es gibt viele Arten von Sensoren, ca. 195 verschiedene Typen werden in Wikipedia
aufgelistet. Nur Sensoren mit einem elektrischen Outputsignal können an einem Mikrocontroller angeschlossen werden. Basierend auf dem elektrischen Outputsignal ist es möglich, Sensoren in digitale oder analoge
Sensoren zu unterteilen.
Bei analogen Sensoren bewirkt jede physikalische Änderung eine Änderung des elektrischen Wertes, i. d. R.
Spannung, Stromstärke oder Widerstand. Da Mikrocontroller digitale Geräte sind, muss das analoge Signal in
ein digitales umgewandelt werden, bevor es zum Controller gesendet wird. Dafür werden Analog-zu-Digital
Konverter benutzt, welche normalerweise im Mikrocontroller verbaut sind.
Analoge Sensoren welche die Information digitalisieren, werden digitale Sensoren genannt. Digitale Sensoren
177
6 Praktische Beispiele
können darüber hinaus Information standardisieren, Sensoren kalibrieren und viele andere Funktionen ausführen. Es gibt verschiedene Möglichkeiten um Information von einem digitalen Sensor an einen Mikrocontroller zu senden. Die einfachste Möglichkeit ist es mit logischen Signalen Informationen zu übertragen. Eine
komplexere Variante geht über eine Datalink Schnittstelle. Die folgenden Übungen führen aber nur einfachere
und in der Robotik genutzte Sensoren ein.
6.5.1
Potentiometer
Notwendiges Wissen:
digital Converter,
Sensors Module,
Analog to Digital Converter,
User Interface Module,
Voltage Divider,
Analog-to-
7-segment LED Display
Theorie
Abbildung 6.15: elektrisches Symbol eines Potentiometers
Ein Potentiometer ist ein elektronisches Widerstandsbauelement mit drei Anschlüssen. Zwischen den beiden
Seitenkontakten ist der Widerstand fix, zwischen Seiten- und Mittelkontakt ist er variabel. Im Grunde ist ein
Potentiometer ein Spannungsteiler, dessen Widerstand zwischen den Seiten- und Mittelkontakten hergestellt
wird.
178
6.5 Sensoren
Abbildung 6.16: einfaches Drehpotentiometer
Ein typisches Potentiometer besteht aus einem Widerstand mit einer leitenden Oberfläche und einem Schiebekontakt (slider). Je näher der Schiebekontakt am Rand des Widerstandes angebracht ist, desto geringer ist der
Widerstand zwischen Slider und Ecke des Widerstands und umgekehrt. Ein Material mit hohem Widerstand
oder einer Spule aus Widerstandsdraht kann als Widerstand fungieren. Bei einigen Potentiometern sind die
Beziehungen zwischen Widerstand und Sliderposition linear oder logarithmisch. Potentiometer sind normalerweise einfache Drehpotentiometer (siehe Bild), es gibt aber auch Schiebepotentiometer. Ein spezieller Typ
von Potentiometer sind digitale Potentiometer, bei denen die Regulation des Widerstands intern über Signale
geschieht.
Übung
Am HomeLab Modul befindet sich ein 4,7 kΩ Drehpotentiometer. Das Potentiometer ist mit der Masse und
dem +5 V Potential angeschlossen, und der Schiebekontakt ist am Kanal 3 des analog-digital Konverters angeschlossen. So kann der Spannungsoutput des Potentiometers zwischen 0 und 5 V reguliert werden. Der
digitale Wert der Potentiometeroutputspannung kann gemessen werden indem die Vergleichsspannung vom
AVR digital-analog Konverter vom AVCC Pin genommen wird. die Folgende Funktionen für den ACR ADC
sind in der HomeLab Bibliothek enthalten.
//
// Data t y p e s f o r adjustment
//
typedef enum
{
ADC_REF_AREF = 0 x00 ,
ADC_REF_AVCC = 0 x01 ,
ADC_REF_2V56 = 0 x03
}
adc_reference ;
typedef enum
{
ADC_PRESCALE_2
ADC_PRESCALE_4
ADC_PRESCALE_8
= 0 x01 ,
= 0 x02 ,
= 0 x03 ,
179
6 Praktische Beispiele
ADC_PRESCALE_16
ADC_PRESCALE_32
ADC_PRESCALE_64
ADC_PRESCALE_128
=
=
=
=
0 x04 ,
0 x05 ,
0 x06 ,
0 x07
}
adc_prescale ;
//
// S t a r t i n g t h e ADC
//
void a d c _ i n i t ( a d c _ r e f e r e n c e r e f e r e n c e , a d c _ p r e s c a l e p r e s c a l e )
{
// Allowing ADC t o operate , s e l e c t i n g t h e frequency d i v i d e r
ADCSRA = bit_mask (ADEN) | ( p r e s c a l e & 0 x07 ) ;
// S e l e c t i n g comparison v o l t a g e
ADMUX = ( r e f e r e n c e & 0 x03 ) << REFS0 ;
}
//
// Converting t h e v a l u e s o f s e l e c t e d channel
//
unsigned s h o r t a d c _ g e t _ v a l u e ( unsigned char channel )
{
// S e t t i n g t h e channel
ADMUX = (ADMUX & 0 xF0 ) | ( channel & 0 x0F ) ;
// S t a r t i n g t h e c o n v e r s i o n
b i t _ s e t (ADCSRA, ADSC) ;
// Waiting t h e end o f t h e c o n v e r s i o n
while ( b i t _ i s _ s e t (ADCSRA, ADSC) )
{
asm v o l a t i l e ( " nop " ) ;
}
// Returning t h e r e s u l t s
r e t u r n ADCW;
}
Die Funktion adc_init muss zu Beginn des Programms ausgeführt werden. Sie sorgt dafür, dass der ADC
funktioniert. Die Vergleichsspannung muss entweder vom AREF oder AVCC Pin kommen, oder es muss die
eingestellte interne Spannung von 2,56 V ausgewählt werden. Dazu muss der Taktzyklus des Konverters mit
einem Vorzähler gesetzt werden (Faktor des Frequenzteilers), welcher den Taktzyklus des Controllers teilt. Die
Umsetzung ist schneller, wenn höhere Taktzyklen verwendet werden, jedoch kann die Genauigkeit drunter
leiden. Die Funktion adc_get_value dient zur Messung. Es kann der Kanal gewählt werden und sie gibt 10-Bit
180
6.5 Sensoren
Ergebnisse als ganze 16-Bit Zahlen aus. Die Funktion zur Messung wartet bis die Konversion beendet ist und
gibt das Ergebnis erst dann aus.
In den zuvor erklärten Beispielprogrammen werden die Bibliotheken des ADC und des 7-Segment-Zifferanzeige genutzt. Der 10-Bit Wert des ADC wird mit 10 multipliziert und durch 1024 dividiert um einen Wert
zwischen 0 und 9 zu erhalten. Der Wert 10 kann nicht erreicht werden, weil in C nur ganzzahligewerte berechnet werden und keine gerundeten Ergebnisse.Um die Genauigkeit des Ergebnisses zu erhöhen, wird eine
Funktion zur Berechnung des Durchschnitts der Ergebnisse des ACSs genutzt. Daraus abgeleitet gibt das Programm auf der Anzeige einen Wert von 0 bis 9 aus, welcher der Position des Potentiometers entspricht.
//
// Beispielprogramm f ü r das P o t e n t i o m e t e r des Sensormoduls
// Die P o s i t i o n des P o t e n t i o m e t e r s wird auf der 7− Segmentanzeige
dargestellt
//
# include <homelab/adc . h>
# include <homelab/module/segment_display . h>
//
// Auswahl des Kanals
//
// 1 = P h o t o r e s i s t o r
// 2 = Thermistor
// 3 = P o t e n t i o m e t e r
//
# define ADC_CHANNEL 3
//
// Hauptprogramm
//
i n t main ( void )
{
i n t value ;
// Anpassung der 7− Segmentanzeige
segment_display_init ( ) ;
// Anpassung des ADC
a d c _ i n i t (ADC_REF_AVCC, ADC_PRESCALE_8 ) ;
// E n d l o s s c h l e i f e
while ( t r u e )
{
// L i e s t viermal gerundete Werte aus dem Kanal
value = a d c _ g e t _ a v e r a g e _ v a l u e (ADC_CHANNEL, 4 ) ;
// Z e i g t Hunderter des a n g e z e i g t e n Wertes an
181
6 Praktische Beispiele
s e g m e n t _ d i s p l a y _ w r i t e ( value ∗ 10 / 1 0 2 4 ) ;
}
}
6.5.2
Thermistor
Notwendiges Wissen:
Sensors Module,
Analog to Digital Converter,
lcd,
Alphanumeric LCD,
Voltage Divider,
Analog-to-digital Converter,
Sensors
Theorie
Abbildung 6.17: NTC Thermistor
Ein Thermistor ist temperaturabhängiger Widerstand. Es gibt Thermistoren mit positiven und mit negativen
Temperaturkoeffizienten. Der Widerstand von Thermistoren mit positiven Koeffizienten nimmt mit steigender
Temperatur zu, bei Thermistoren mit negativen Koeffizienten steigt er mit sinkender Temperatur. Die dazugehörigen Abkürzungen sind PTC(positive temperature coefficient) und NTC (negative temperature coefficient).
Die Temperaturabhängigkeit des Widerstands verläuft nicht linear zu der Temperatur, was die Nutzung erschwert. Für genaue Temperaturmessungen bei größeren Temperaturschwankungen wird die exponentielle
Steinhart-Hart Gleichung dritter Ordnung genutzt, da der Thermistorwiderstand nur innerhalb kleiner Temperaturbereiche linear ist. Für NTC Thermistoren gibts es folgende vereinfachte Steinhart-Hart-Gleichung mit
dem Parameter B:
182
6.5 Sensoren
mit:
T0 - nominale Temperatur, normalerweise 25 ◦ C.
R0 - Widerstand bei nominaler Temperatur.
B - Parameter B.
Der Parameter B ist ein Koeffizient, welcher normalerweise im Datenblatt des Thermistors vorgegeben ist.
Aber er ist nur in bestimmten Temperaturbereichen ausreichend konstant, z.B. in Bereichen zwischen 25 und
50 ◦ C oder zwischen 25 und 85 ◦ C. Wenn der gemessene Temperaturbereich größer ist, sollte das Datenblatt
des Thermistors zu Rate gezogen werden um die Gleichung zu erhalten.
Normalerweise wird ein Spannungsteiler genutzt, um den Widerstand eines Thermistors zu messen. Dabei
wird ein Widerstand durch einen Thermistor ausgetauscht wird und die Inputspannung ist konstant. Es wird
die Outputspannung des Spannungsteilers gemessen, welche sich in Abhängigkeit der Widerstandsänderung
des Thermistors verändert. Wenn Spannung anliegt, fließt Strom durch den Thermistor, wodurch sich dieser
bedingt durch den Thermistorwiderstand aufheizt und damit den Widerstand verändert. Der durch das Aufheizen entstehende Fehler kann berechnet werden, jedoch ist es einfacher einen Thermistor zu nutzen, welcher
einen hohen Widerstand hat und sich nicht so viel aufheizt.
Bei begrenzten Ressourcen und geringerem Anspruch auf Genauigkeit, werden zuvor errechnete Diagramme
und Tabellen für die Temperaturen genutzt. Normalerweise enthalten die Tabellen Temperaturbereiche und
die entsprechenden Werte für Widerstand, Spannung und ADC. Alle exponentiellen Berechnungen wurden
bereits durchgeführt sodass der Nutzer nur noch die entsprechende Reihe finden und die Werte auslesen
muss.
Übung
Das Sensormodul des HomeLab enthält einen NTC Thermistor mit nominellem Widerstand von 10 kΩ. Bei
Temperaturen von 25 bis 50 ◦ C ist der Parameter B des Widerstands 3900. Ein Pin des Thermistors ist an die
+5 V Betriebsspannung angeschlossen der andere an Kanal 2 (Pin PF2). Ein typischer 10 kΩ Widerstand ist
auch am gleichen Pin des Mikrocontrollers und an die Masse angeschlossen. So entsteht zusammen mit dem
Thermistor ein Spannungsteiler. Da hier ein NTC Thermistor genutzt wird, bei welchem der Widerstand sinkt
wenn die Temperatur steigt, wird die Outputspannung des Spannungsteilers bei steigender Temperatur höher.
Während der Nutzung des AVR ist es nützlich, eine Tabelle mit den Temperaturwerten und den Werten des
ADC zu verwenden, um die korrekte Temperatur zu finden. Es ist sinnvoll, für jede Gradzahl der gewünschten Temperaturstufe des Messbereichs den korrespondierenden ADC Wert aus der Tabelle herauszusuchen,
183
6 Praktische Beispiele
da die Tabelle aufgrund der 10 Bit ADC Werte sehr groß sein wird. Es wird empfohlen, ein Tabellenkalkulationsprogramm (MS Excel, Openoffice Calc, etc.) zur Erstellung der Tabelle zu nutzen. Die Steinhart-Hart
Gleichung, welche für den NTC angepasst wurde, gibt den zur entsprechenden Temperatur korrespondierenden Widerstand aus. Abgeleitet aus dem Widerstand, ist es möglich die Outputspannung des Spannungsteilers
zu berechnen und daraus den Wert des ADC. Berechnete Werte können wie folgt in das Programm eingefügt
werden:
//
// T a b e l l e zur Konvertierung von Temperaturwerten ind ADC Werte .
// J e d e s Element des Arrays k e n n z e i c h n e t e i n Grad C e l s i u s .
// Die Elemente beginnen b e i −20 Grad und enden b e i 100 Grad .
// Ein Array enth ä l t 121 Elemente .
//
c o n s t signed s h o r t min_temp = − 20;
c o n s t signed s h o r t max_temp = 1 0 0 ;
c o n s t unsigned s h o r t c o n v e r s i o n _ t a b l e [ ] =
{
91 ,96 ,102 ,107 ,113 ,119 ,125 ,132 ,139 ,146 ,153 ,
160 ,168 ,176 ,184 ,192 ,201 ,210 ,219 ,228 ,238 ,247 ,
257 ,267 ,277 ,288 ,298 ,309 ,319 ,330 ,341 ,352 ,364 ,
375 ,386 ,398 ,409 ,421 ,432 ,444 ,455 ,467 ,478 ,489 ,
501 ,512 ,523 ,534 ,545 ,556 ,567 ,578 ,588 ,599 ,609 ,
619 ,629 ,639 ,649 ,658 ,667 ,677 ,685 ,694 ,703 ,711 ,
720 ,728 ,736 ,743 ,751 ,758 ,766 ,773 ,780 ,786 ,793 ,
799 ,805 ,811 ,817 ,823 ,829 ,834 ,839 ,844 ,849 ,854 ,
859 ,863 ,868 ,872 ,876 ,880 ,884 ,888 ,892 ,896 ,899 ,
903 ,906 ,909 ,912 ,915 ,918 ,921 ,924 ,927 ,929 ,932 ,
934 ,937 ,939 ,941 ,943 ,945 ,947 ,949 ,951 ,953 ,955
};
Folgender Algorithmus kann genutzt werden um die mit den ADC Parametern korrespondierende Temperatur zu finden:
//
// Konvertierung der ACD Werte i n Grad C e l s i u s :
//
signed s h o r t t h e r m i s t o r _ c a l c u l a t e _ c e l s i u s ( unsigned s h o r t adc_value )
{
signed s h o r t c e l s i u s ;
// T a b e l l e von h i n t e n beginnend durchgehen :
f o r ( c e l s i u s = max_temp − min_temp ; c e l s i u s >= 0 ; c e l s i u s −−)
{
// I s t der Wert aus der T a b e l l e g l e i c h oder hö her dem gemessenen
// Wert , i s t d i e Temperatur mindestens so hoch wie d i e mit dem
Element
184
6.5 Sensoren
// korrespondierende Temperatur .
i f ( adc_value >= c o n v e r s i o n _ t a b l e [ c e l s i u s ] ) )
{
// Da d i e T a b e l l e mit 0 beginnt , d i e Werte der Elemente j ed oc h
mit − 20,
// muss der Wert g e s h i f t e t werden .
r e t u r n c e l s i u s + min_temp ;
}
}
// Wurde der Wert n i c h t gefunden , wird d i e minimale Temperaur
ausgegeben .
r e t u r n min_temp ;
}
Der Algorithmus sucht den Bereich aus der Tabelle in dem der ACD Wert liegt und wählt die niedrigere
Nummer dieses Bereiches. Die Ranknummer markiert die Gradzahl und durch das Addieren der anfänglichen
Temperatur wird eine Genauigkeit von 1◦ C erreicht.
Umrechnungstabelle und Funktion sind schon in der HomeLab Bibliothek enthalten, sie müssen somit nicht
extra für diese Aufgabe erstellt werden. In der Bibliothek heißt die Umrechnungsfunktion thermistor_calculate_celsius.
Hierbei muss beachtet werden, dass die Funktion nur korrekt ist, wenn sie mit dem Thermistor des Sensormoduls aus dem HomeLab verwendet wird. Werden andere Thermistoren genutzt, muss eine entsprechende
Umrechnungstabelle erstellt und eine komplexere Funktion verwendet werden, welche im Handbuch der Bibliothek beschrieben wird. Das Beispielprogramm dieser Übung ist ein Thermometer, welches Temperatur in
◦ C mißt und sie auf dem alphabetischen LCD ausgibt.
//
// Beispielprogramm des T h e r m i s t o r s des Sensormoduls .
// Die Temperatur wird auf dem LCD a n g e z e i g t .
//
# include < s t d i o . h>
# include <homelab/adc . h>
# include <homelab/module/ s e n s o r s . h>
# include <homelab/module/ l c d _ a l p h a . h>
//
// Hauptprogramm
//
i n t main ( void )
{
unsigned s h o r t value ;
signed s h o r t temperature ;
char t e x t [ 1 6 ] ;
// E i n r i c h t e n des LCD
l c d _ a l p h a _ i n i t (LCD_ALPHA_DISP_ON) ;
185
6 Praktische Beispiele
// Lö schen des LCD
lcd_alpha_clear ( ) ;
// Name des Programms
l c d _ a l p h a _ w r i t e _ s t r i n g ( " Termomeeter " ) ;
// E i n r i c h t e n des ADC
a d c _ i n i t (ADC_REF_AVCC, ADC_PRESCALE_8 ) ;
// E n d l o s s c h l e i f e
while ( t r u e )
{
// Auslesen der 4− f a c h gerundeten Spannungswerte aus dem Thermistor
value = a d c _ g e t _ a v e r a g e _ v a l u e ( 2 , 4 ) ;
// K o n v e r t i e r e n der ADC Werte i n Grad C e l s i u s
temperature = t h e r m i s t o r _ c a l c u l a t e _ c e l s i u s ( value ) ;
// K o n v e r t i e r e n der Temperatur i n Text .
// To d i s p l a y t h e degree sign , t h e o c t a l v a r i a b l e i s 3 3 7 .
s p r i n t f ( t e x t , "%d\337C
" , temperature ) ;
// Anzeige des T e x t e s am Anfang der zweiten Z e i l e des LCDs .
lcd_alpha_goto_xy ( 0 , 1) ;
lcd_alpha_write_string ( text ) ;
}
}
Extra
Das Temperaturdiagramm eines 10 kΩ NTC Thermistors
6.5.3
Fotowiderstand
Notwendiges Wissen:
Sensors Module,
Analog to Digital Converter,
186
lcd,
Alphanumeric LCD,
Voltage Divider,
windows
Analog-to-digital Converter,
6.5 Sensoren
Theorie
Abbildung 6.18: Ein Fotowiderstand
Abbildung 6.19: Elektrisches Symbol für einen Fotowiderstand
Ein Fotowiderstand ist ein Sensor, dessen elektrischer Widerstand sich je nach einfallender Lichtintensität verändert. Je intensiver das Licht ist, desto mehr freie Ladungsträger werden gebildet, und umso geringer wird
dadurch der Widerstand des Bauteils. Durch das keramische Basismaterial führen zwei externe Metallkontakte
des Widerstands zur lichtempfindlichen Membran, dessen Widerstand abhängig von der Geometrie und den
Materialeigenschaften ist. Da lichtempfindliches Material durch die schmale, kurvige Spur zwischen den Elektroden bereits einen hohen Widerstand hat, kann der niedrigste totale Widerstand schon bei durchschnittlichen
Lichtintensitäten erreicht werden. Der Fotowiderstand reagiert ähnlich dem menschlichen Auge nur auf bestimmte Wellenlängen, was bei der Auswahl eines solchen Bauteils bedacht werden muss. Andernfalls kann es
vorkommen, dass der Widerstand nicht auf die in der Anwendung genutzte Lichtquelle reagiert. Nachfolgend
ist eine Tabelle abgebildet, welche vereinfacht die Wellenlängen des sichtbaren Lichts mit den entsprechenden
Farben darstellt:
Farbe
Violett
Blau
Grün
Gelb
Orange
Rot
Wellenlängen (nm)
400 - 450
450 - 500
500 - 570
570 - 590
590 - 610
610 - 700
Der Fotowiderstand arbeitet innerhalb eines bestimmten, festgelegten Temperaturbereichs. Soll der Sensor bei
anderen Temperaturen genutzt werden, müssen präzise Umrechnungen durchgeführt werden, da die Widerstandseigenschaften des Sensors abhängig von der Umgebungstemperatur sind.
Zur Kennzeichnung der Lichtintensität wird die Beleuchtungsstärke (E) genutzt. Diese zeigt die Menge Licht
an, die auf eine bestimmte Oberfläche trifft. Die Maßeinheit ist Lux (lx), wobei 1 Lux dem konstanten Lichtfluss
von einem 1 Lumen entspricht, welcher auf eine Oberfläche von 1m2 strahlt. In der Realität fällt Licht jedoch
187
6 Praktische Beispiele
eigentlich nie gleichmäßig auf eine Oberfläche weshalb die Beleuchtungsstärke meistens als Durchschnittswert
ermittelt wird. Unten sind ein paar Beispiele von Beleuchtungsstärken dargestellt:
Vergleichswerte von Beleuchtungsstärken:
Umgebung
Vollmond
Abenddämmerung
Auditorium
Klassenraum
Sonnenaufgang / -untergang
OP-Saal (Krankenhaus)
direktes Sonnenlicht
Beleuchtungsstärke (lx)
0,1
1
10
30
400
500 - 1000
10000
Übung
Das Sensormodul aus dem HomeLab verfügt über einen VT935G Fotowiderstand. Ein Pin des Widerstands ist
an der +5 V Stromversorgung angeschlossen, der zweite an Kanal 1 (Pin PF1) des ADC. Zwischen diesem Pin
und der Masse ist ein 10 kΩ Widerstand angeschlossen, welcher zusammen mit dem Fotowiderstand einen
Spannungsteiler erzeugt. Da sich der elektrische Widerstand des Fotowiderstands mit einfallender Lichtintensität verkleinert, wird die gemessene Spannung am Pin des Mikrocontrollers mit dem Ansteigen der Lichtstärke größer. Hierbei sollte bedacht werden, dass der Fotowiderstand des HomeLab am stärksten auf oranges
und gelbes Licht reagiert.
Der Sensor VT935G ist nicht als spezifisches Messinstrument gedacht. Er soll vielmehr dazu dienen, Informationen über die allgemeinen Lichtverhältnisse (z. B. befindet sich eine eingeschaltete Lampe im Raum oder
nicht) anzugeben. Dazu muss nur der Widerstand des Sensors in einem halbdunklen Raum gemessen und ins
Programm eingetragen werden. Daraufhin kann man die gemessenen Werte vergleichen und feststellen ob es
heller oder dunkler ist.
Die nun folgende Aufgabe ist ein wenig komplexer, da die Beleuchtungsstärke auch in Lux gemessen wird.
Hierzu werden eine Annäherungsformel sowie Gleitkomma-Variablen angewendet. In C sind GleitkommaVariablen float- und double--Typ Variablen, welche zur Darstellung von Brüchen genutzt werden können. Nachteilig ist jedoch, dass während der Nutzung dieser Variablen viele Ressourcen in Anspruch genommen werden
müssen. Während Computer spezielle Hardware zur Berechnung von Gleitkomma-Variablen besitzen, wird
diese bei den 8-Bit AVR Microcontrollern mittels einer Software durchgeführt, wodurch viel Zeit und Speicher
benötigt wird. Sofern die Nachteile jedoch nicht entscheidend sind, lohnt es sich, Gleitkomma-Variablen zu
verwenden.
188
6.5 Sensoren
Abbildung 6.20: Verhältnis zwischen Widerstand (R) des VT935G und Lichtintensität (E)
Das Datenblatt des Sensors beinhaltet eine Annäherungsformel für den Zusammenhang zwischen Beleuchtungsstärke und elektrischem Widerstand. Wie im logarithmisch skalierten Graphen rechts dargestellt, sind
Widerstand und Beleuchtungsstärke nahezu linear abhängig und bilden eine lineare Funktion, wenn folgende
Konversion angewendet wird:
log(a/b) = log(a) - log(b)
Die Relation wird durch den Anstieg des Y-Faktors (Steigung der Geraden) beschrieben, welcher für den
VT935G Sensor den Wert 0,9 hat. Darüber hinaus ist ein Punkt auf dieser Geraden bekannt: Der Widerstand beträgt 18.5 kΩ (R A ) bei 10 lx Beleuchtungsstärke (E A ). Mittels dieser Koordinaten und der Steigung der Geraden
lässt sich nun jeder beliebige Punkt berechnen. Das bedeutet, wird der Widerstand (RB ) am Sensor gemessen,
ist es möglich die Beleuchtungsstärke EB ) wie folgt mit der Formel der Geraden zu berechnen.
log(EB ) = log(R A /RB ) / γ + log(E A )
EB = 10log( R A /RB )/γ+log(EA )
So erhält man die Formel zur Berechnung der Beleuchtungsstärke bei gegebenem Widerstand. Da der Widerstand nicht direkt von Microcontroller gemessen werden kann befindet sich der Fotowiderstand im Spannungsteiler. Die Output-Spannung des Spannungsteilers wird durch den ADC zu einer spezifischen Variable
konvertiert. Zur Bestimmung des Widerstands muss diese Output-Spannung (U2 ) zunächst mittels des ADCWertes berechnet werden. Dabei muss auch die Vergleichs-Spannung des Konverters berücksichtigt werden.
Folgende Formel wird zur Berechnung verwendet:
U2 = Ure f * (ADC / 1024)
Mit Hilfe der Formel für Spannungsteiler (siehe Kapitel über Spannungsteiler) kann der Widerstand des Fotowiderstands (R1 ) ermittelt werden:
R1 = (R2 * U1 ) / U2 - R2
In der folgenden Berechnung von Spannung und Widerstand, werden die gegebenen Werte eingesetzt und die
Indizes entfernt:
189
6 Praktische Beispiele
U = 5 * (ADC / 1024)
R = (10 * 5) / U - 10
Die Beleuchtungsstärke kann dann mittels der folgenden vereinfachten Konversion genutzt werden:
E = 10log(18.5/R)/0.9+1 = 10log(18.5/R)∗10/9 * 101 =
= 10log18.5∗10/9−logR∗10/9 * 10 = (10log18.5∗10/9 / 10logR∗10/9 ) * 10 =
= (18.510/9 / R10/9 ) * 10 = 18.510/9 * 10 * R−10/9
Durch die Berechnung der Konstante vor der Variable des Feldes R, bleibt folgender Ausdruck:
E = 255,84 * R−10/9
Die dargestellten Formeln sind jedoch nur im Zusammenhang mit Fotowiderständen des HomeLab SensorModuls nützlich. Wird ein Schaltkreis mit anderen Komponenten bestückt, müssen die Variablen verändert
werden.Nachfolgend ist der Quellcode eines Beispielprogramms dargestellt, welches die Beleuchtungstärke
mit Hilfe des ADC misst und berechnet und auf dem LCD darstellt. Bevor das Programm kompiliert wird,
müssen die Einstellungen für die Gleitkomma-Variablen im Projekt festgelegt werden. Dieser Schritt wird in
dem Kapitel über die Installation der Software erläutert.
In diesem Beispielprogramm werden die Variablen für Spannung, Widerstand und Beleuchtungsstärke als
double Gleitkomma-Variablen definiert. Die Variablen, welche nun als Gleitkomma-Variablen genutzt werden,
müssen immer eine Dezimalstelle beinhalten (diese kann auch einfach 0 sein, so verarbeitet der Compiler
es korrekt). Wird die Funktion sprintf genutzt, um die Gleitkomma-Variable in Text zu konvertieren, muss
das “%f“Format genutzt werden, welches durch Nutzung von ganzen Zahlen und Dezimalstellen erweitert
werden kann. So gibt “%3.2“beispielsweise immer 3 ganze Zahlen und 2 Dezimalstellen an.
//
// Beispielprogramm des Fotowiderstands aus dem Sensormodul des HomeLab
// Der angen ä h e r t e Wert der B e l e u c h t u n g s s t ä rke wird auf dem LCD
dargestellt .
//
# include < s t d i o . h>
# include <math . h>
# include <homelab/module/ l c d _ a l p h a . h>
# include <homelab/adc . h>
# include <homelab/delay . h>
//
// Hauptprogramm .
//
i n t main ( void )
{
char t e x t [ 1 6 ] ;
190
6.5 Sensoren
unsigned s h o r t adc_value ;
double v o l t a g e , r e s i s t a n c e , i l l u m i n a n c e ;
// I n i t i a l i s i e r e LCD
l c d _ a l p h a _ i n i t (LCD_ALPHA_DISP_ON) ;
// Lö sche LCD .
lcd_alpha_clear ( ) ;
// Name des Programms
l c d _ a l p h a _ w r i t e _ s t r i n g ( " Luxmeter " ) ;
// E i n r i c h t e n des ADC
a d c _ i n i t (ADC_REF_AVCC, ADC_PRESCALE_8 ) ;
// E n d l o s s c h l e i f e .
while ( t r u e )
{
// D u r c h s c h n i t t l i c h e n Wert des F o t o r e s i s t o r s a u s l e s e n
adc_value = a d c _ g e t _ a v e r a g e _ v a l u e ( 1 , 1 0 ) ;
// Input −Spannung am ADC berechnen
v o l t a g e = 5 . 0 ∗ ( ( double ) adc_value / 1 0 2 4 . 0 ) ;
// Widerstand des F o t o r e s i s t o r s im S p a n n u n g s t e i l e r berechnen
resistance = ( 1 0 . 0 ∗ 5 . 0 ) / voltage − 1 0 . 0 ;
// B e l e u c h t u n g s s t ä rke i n lux berechnen
i l l u m i n a n c e = 2 5 5 . 8 4 ∗ pow( r e s i s t a n c e , − 10/9) ;
// B e l e u c h t u n g s s t ä rke i n Text k o n v e r t i e r e n
s p r i n t f ( t e x t , " %0.1 f lux
" , illuminance ) ;
// D a r s t e l l u n g auf dem LCD
lcd_alpha_goto_xy ( 0 , 1) ;
lcd_alpha_write_string ( text ) ;
// Verzögerung 500 ms
sw_delay_ms ( 5 0 0 ) ;
}
}
191
6 Praktische Beispiele
6.5.4
Infrarot-Entfernungsmesser
Notwendiges Wissen:
Converter,
Sensors Module,
Alphanumeric LCD,
lcd,
Analog-to-digital Converter,
Analog to Digital
Sensors
Theorie
Abbildung 6.21: Sharp GP2Y0A21YK
Um die Distanz zu einem Objekt zu messen, gibt es optische Sensoren, welche die Triangulation als Messmethode nutzen. Die am häufigsten verwendeten Infrarot-Entfernungsmesser werden von der Firma „Sharp“produziert
und verfügen über einen analogen Spannungs-Output. Diese Sensoren besitzen eine Infrarot-LED mit einer
Linse, welchen einen schmalen Lichtstrahl aussendet. Dieser wird von dem Objekt, zu welchem die Distanz
gemessen werden soll, reflektiert und dann durch die zweite Linse zu einem optischen Positionssensor (OPS)
gelenkt. Die Leitfähigkeit dieses OPS ist abhängig davon, an welcher Stelle der Lichtstrahl einfällt. Sie wird in
Spannung umgewandelt, die Spannung wird mittels eines Analog-Digital-Konverters digitalisiert und daraufhin kann die Entfernung berechnet werden. Die Zeichnung auf der rechten Seite zeigt die Wege von Strahlen,
die aus unterschiedlichen Entfernungen reflektiert werden.
192
6.5 Sensoren
Abbildung 6.22: Wege der Lichtstrahlen eines Infrarot-Entfernungsmessers
Abbildung 6.23: Das Verhältnis von Spannung und Entfernung eines InfrarotEntfernungsmessers
Der Output der Infrarot-Entfernungsmesser von „Sharp“ist anti-proportional. Das meint, mit größer werdender Entfernung verringert sich der Output (die Abnahme des Outputs, also der Spannung, wird jedoch nach
und nach schwächer). Der Graph mit dem exakten Verhältnis zwischen Entfernung und Spannung ist gewöhnlich im Datenblatt des Sensors abgebildet.Jeder Sensor-Typ hat seinen spezifischen Messbereich, innerhalb
welchem die gemessenen Ergebnisse verlässlich sind. Die maximale Messdistanz wird von zwei Aspekten beschränkt: Zum Einen von der Abnahme der Menge des reflektierten Lichts, zum Anderen vom Unvermögen
des OPS, kleine Positonsänderungen des reflektierten Strahls zu registrieren. Misst man die Entfernung zu
Objekten, welche zu weit entfernt sind, entspricht der Output nahezu dem, bei der Messung zur maximalen
Distanz.Die minimale Entfernung wird durch die Besonderheit der Sharp Sensoren eingeschränkt. So fällt der
Output steil ab, sobald die Entfernung einen bestimmten Punkt unterschreitet (je nach Baureihe liegt dieser
bei 4 bis 20 cm) Das hat zur Folge, dass zu einem Outputwert zwei korrespondierende Entfernungswerte existieren.Dieses Problem kann vermieden werden, indem beachtet wird, dass die Distanz zwischen Objekt und
Sensor nicht zu gering ist.
193
6 Praktische Beispiele
Übung
Das HomeLab Sensor-Kit enthält den Infrarot-Entfernungsmesser SHARP GP2Y0A21YK. Der Messbereich dieses Sensors liegt zwischen 10 cm und 80 cm. Seine Output-Spannung hängt von der Entfernung ab und erreicht
bis zu 3 V. Der Entfernungssensor ist am Sensormodul angeschlossen. Die Output-Spannung wird über Kanal 0 zum ADC des AVR gesendet. Aufbauend auf den vorangehenden Übungen zu Sensoren, ist es einfach
ein Programm zu schreiben, welches die Output-Spannung des Entfernungsmessers misst. Zusätzlich dazu
behandelt diese Aufgabe die Umwandlung der Spannung in eine Entfernung.
Das Datenblatt des GP2Y0A21YK beinhaltet einen Graphen welcher die Relation von Output-Spannung und
gemessener Entfernung darstellt. Dieser Graph verläuft nicht linear. Der Graph der inversen Werte ist jedoch
annähernd linear, wodurch relativ einfach die Formel zur Umwandlung von Spannung in Entfernung gefunden werden kann. Hierzu werden Punkte des Graphens in ein Tabellenkalkulationsprogramm eingefügt und
so ein neuer Graph generiert. Die meisten Programme berechnen automatisch eine Trendlinie.Nachfolgend
ist der Graph des GP2Y0A21YK mit der Relation der korrigierten inversen Werte der Outputspannung zu
den korrigierten inversen Werten der gemessenen Distanz, inklusive einer Trendlinie abgebildet. Zur Vereinfachung wurde die Output-Spannung schon in 10-Bit +5 V Werte des ADC mit Vergleichspannung konvertiert.
Abbildung 6.24: Graph zur linearen Darstellung von ADC Wert und Entfernung
Wie der Graph zeigt, überschneiden sich die blaue Trendlinie und die Punkte des Graphen fast genau. Dieses
wird durch die Nutzung einer Korrektur-Konstante erreicht. Diese Konstante wird mit der „trail-and-error“Methode gefunden - es werden dabei viele Variablen getestet, bis diejenige gefunden ist, die den Graph mit der
Trendlinie überlappen lässt.Im abgebildeten Graph ist die Korrektur-Konstantet +2; das bedeutet, zu allen realen Entfernungen muss +2 hinzuaddiert werden. Daruch verläuft der Graph nahezu gleich der Trendline und
194
6.5 Sensoren
es kann für die Relation zwischen Entfernung und Spannung verallgemeinert folgende Formel angenommen
werden:
1 / (d + k) = a * ADC + b
wobei
d - Entfernung in cm.
k - Korrektur-Konstante (gefunden mittels trial-and-error Methode)
ADC - digitalisierter Wert der Spannung.
a - lineares Element (Wert wird durch die Trendlinien-Gleichung bestimmt)
b - freies Element (Wert wird durch die Trendlinien-Gleichung bestimmt)
Die Entfernung d kann durch folgende Formel dargestellt werden:
d = (1 / (a * ADC + B)) - k
Nun ist es generell möglich die Entfernung mit der Formel zu berechnen. Da jedoch Brüche dividiert werden,
sind zudem Gleitkomma-Berechnungen nötig. Weiterhin muss die Formel vereinfacht und auf größere Quotienten ausgeweitet werden, da Microcontroller mit Ganzzahlen arbeiten. Durch die Division des Quotienten
mit einem linearen Element erhält man folgende Formel:
d = (1 / a) / (ADC + B / a) - k
Durch Aufnahme der Korrekturkonstante sowie des linearen und freien Elements der Trendlinien-Gleichung,
ergibt sich folgende Formel zur Berechnung der Entfernung:
d = 5461 / (ADC - 17) - 2
Diese Formel kann mit 16-Bit Zahlen berechnet werden und ist daher vollständig für den AVR geeignet. Vor
der Berechnung muss sicher gestellt sein, dass der Wert des ADC größer als 17 ist, ansonsten kann der Fall
eintreten, dass durch 0 geteilt werden muss oder eine negative Distanz ausgegeben wird.
Nachfolgend ist die Funktion dargestellt, die dazu dient, ADC-Werte in Centimeter zu konvertieren. Sie ist
in der HomeLab Library enthalten. Lineare und freie Elemente sowie die Korrektur-Konstante, sind nicht
fest in die Funktion integriert, sondern werden mittels der Objektparameter des Infrarot-Entfernungsmessers
eingespeist. Dadurch, dass diese Parameter als separate Konstanten verwendet werden, ist es sehr einfach,
neue Infrarot-Entfernungsmesser in das Programm zu integrieren.
//
// Die S t r u k t u r der Parameter des I n f r a r o t −Entfernungsmessers
//
typedef c o n s t s t r u c t
{
c o n s t signed s h o r t a ;
195
6 Praktische Beispiele
c o n s t signed s h o r t b ;
c o n s t signed s h o r t k ;
}
ir_distance_sensor ;
//
// Die P a r a m e t e r e i g e n s c h a f t e n des GP2Y0A21YK S e n s o r s
//
c o n s t i r _ d i s t a n c e _ s e n s o r GP2Y0A21YK = { 5 4 6 1 , − 17, 2 } ;
//
// K o n v e r t i e r e n der Werte des I n f r a r o t −Entfernungsmessers i n Centimeter
// Gibt −1 aus , wenn d i e Konvertierung n i c h t e r f o l g r e i c h war
//
signed s h o r t i r _ d i s t a n c e _ c a l c u l a t e _ c m ( i r _ d i s t a n c e _ s e n s o r sensor ,
unsigned s h o r t adc_value )
{
i f ( adc_value + s e n s o r . b <= 0 )
{
r e t u r n − 1;
}
r e t u r n s e n s o r . a / ( adc_value + s e n s o r . b ) − s e n s o r . k ;
}
Zur Durchführung der Konvertierung muss die Funktion ir_distance_calculate_cm genutzt werden. Der erste
Funktionsparameter gibt die Eigenschaften der Parameter des Infrarot-Entfernungsmessers an, der zweite den
ADC-Wert. Die Funktion gibt dann die berechnete Entfernung in Centimetern aus. Schlägt die Konvertierung
fehl (unzulässige ADC-Werte), wird der Wert -1 ausgegeben. Das folgende Programm veranschaulicht die
Verwendung des Infrarot-Entfernungsmessers und der Konvertierungsfunktion. Es wird das alphanumerische
LCD genutzt, auf welchem die gemessenen Werte dargestellt werden. Falls die Distanz unzulässig ist, wird ein
“?“angezeigt.
//
// Beispielprogramm des I n f r a r o t −Entfernungsmessers des HomeLab
// Die i n Centimetern gemessenen E r g e b n i s s e werden auf dem LCD
abgebildet
//
# include < s t d i o . h>
# include <homelab/adc . h>
# include <homelab/delay . h>
# include <homelab/module/ s e n s o r s . h>
# include <homelab/module/ l c d _ a l p h a . h>
//
// Hauptprogramm
196
6.5 Sensoren
//
i n t main ( void )
{
unsigned s h o r t value ;
signed s h o r t d i s t a n c e ;
char t e x t [ 1 6 ] ;
// E x t e r n a l s e n s o r s e l e c t i o n
pin e x _ s e n s o r s = PIN (G, 0 ) ;
pi n_s etup _output ( e x _ s e n s o r s ) ;
pin_set ( ex_sensors ) ;
// I n i t i a l i s i e r u n g des LCD
l c d _ a l p h a _ i n i t (LCD_ALPHA_DISP_ON) ;
// Lö schen des LCD
lcd_alpha_clear ( ) ;
// Name des Programms
lcd_alpha_write_string ( " Distance sensor " ) ;
// I n s t a l l a t i o n des ADC
a d c _ i n i t (ADC_REF_AVCC, ADC_PRESCALE_8 ) ;
// E n d l o s s c h l e i f e
while ( t r u e )
{
// Auslesen des viermal gerundeten Wertes der Outputspannung des
Sensors
value = a d c _ g e t _ a v e r a g e _ v a l u e ( 0 , 4 ) ;
// K o n v e r t i e r e n des ADC−Wertes i n Entfernung
d i s t a n c e = i r _ d i s t a n c e _ c a l c u l a t e _ c m ( GP2Y0A21YK , value ) ;
// War d i e Berechnung e r f o l g r e i c h ?
i f ( d i s t a n c e >= 0 )
{
// K o n v e r t i e r e n von Entfernung i n Text
s p r i n t f ( t e x t , "%d cm
" , distance ) ;
}
else
{
// Text f ü r e i n e unbekannte Entfernung erzeugen
s p r i n t f ( t e x t , " ? cm
");
}
197
6 Praktische Beispiele
// Anzeige des T e x t e s am Anfang der zweiten Z e i l e auf dem LCD
lcd_alpha_goto_xy ( 0 , 1) ;
lcd_alpha_write_string ( text ) ;
// Break
sw_delay_ms ( 5 0 0 ) ;
}
}
Zusätzliches Material
Graph des Sharp GP2Y0A21YK Sensors
Linearisierung der Sharp Entfernungsdaten
6.5.5
Ultraschall-Entfernungsmesser
Notwendiges Wissen:
LCD,
Controller module,
lcd,
Counters/Timers,
Timers,
Alphanumeric
Sensors
Theorie
Abbildung 6.25: Ultraschall-Entfernungsmesser SRF04
Ein Ultraschall-Entfernungsmesser bestimmt die Entfernung zu einem Objekt, indem er die Zeit misst, die ein
Schall zu einem Objekt hin und zurück benötigt. Die Frequenz des Geräusches liegt im Bereich des Ultraschalls.
Dies garantiert, dass die Schallwelle gebündelt gelenkt wird, da sich hochfrequenter Schall weniger in der Umgebnung zerstreut. Ein typischer Ultraschall-Entfernungsmesser besteht aus zwei Membranen. Eine Membran
produziert den Schall, die andere empfängt das Echo. Im Grunde besteht er also aus einem Lautsprecher und
einem Mikrophon. Der Schallgenerator generiert kurze (wenige Perioden umfassende) Ultraschallimpulse und
198
6.5 Sensoren
startet den Timer. Die zweite Membran registriert die Ankunft des Echos und stoppt den Timer. Mit der Zeit
des Timers ist es möglich, die zurückgelegte Entfernung des Schalls zu berechnen. Die Entfernung zu einem
Objekt entspricht der Hälfte der zurückgelegten Entfernung des Schalls.
Abbildung 6.26: Funktionsweise eines Ultraschall-Entfernungsmessers.
Der Ultraschall-Entfernungsmesser findet im täglichen Leben eine Vielzahl von Anwendungsmöglichkeiten.
Er wird beispielsweise als Ersatz für Maßbänder auf Baustellen eingesetzt, Autos besitzen Ultraschall-Entfernungsmesser als Parksensoren. Neben der Entfernungsmessung dient er auch dazu, das bloße Vorhandensein
eines Objekts im Messbereich zu erkennen, z. B. in der Gefahrenzone einer Arbeitsmaschine. Sind Ultraschalltransmitter und -empfänger getrennt, kann die Fließgeschwindigkeit des Materials zwischen ihnen bestimmt
werden, da Schallwellen langsamer aufwärts fließen.
Übung
Das HomeLab enhält einen Devantech SRF04/SRF05 Ultraschall-Entfernungsmesser. Der SRF04/SRF05 ist
jedoch nur ein Sensor und gibt keine direkte Information über die Distanz. Neben den Stromversorgungspins
besitzt der Sensor auch einen Trigger- und einen Echo-Pin.Ist der Trigger-Pin „high“, generiert der Sensor eine
acht Perioden lange 40 kHz Ultraschallwelle. Daraufhin wird der Echo-Pin „high“und bleibt „high“, bis das
Echo zurück kommt. Das Echo-Signal gibt also generell die Zeit an, die der Schall benötigt um das Objekt
zu erreichen und zum Sensor zurück zu kommen. Die Entfernung zum Objekt ergibt sich daraus, dass die
gemessene Zeit mit der Schallgeschwindigkeit multipliziert und dann durch zwei dividiert wird. Der folgende
Graph zeigt den Zusammenhang zwischen Zeit und den Signalen des Empfängers, Triggers und des Echos:
Abbildung 6.27: Die Signale des SRF04
199
6 Praktische Beispiele
Um den SRF04/SRF05 mit dem AVR zu nutzen, müssen Trigger- und Echo-Pin an den AVR Pins angeschlossen
werden. Zur Zeitmessung, sollte ein 16-Bit Timer genutzt werden, z.B. timer3. Nachfolgend ist eine Funktion
dargestellt, die alle Messvorgänge ausführt - sie generiert das Signal des Triggers, startet den Timer, misst die
Länge des Echosignals und konvertiert dies zur Entfernung in Centimetern. Die Funktion blockt, das bedeutet
sie hält den Prozessor beschäftigt, bis die Messung abgeschlossen ist oder zu lange dauert. Je schneller das
Echo ankommt, desto schneller erhält man ein Ergebnis. Falls kein Echo ankommt, wartet die Funktion 36 ms
und geht dann auf 0 zurück. Es ist wichtig zwischen den Messungen eine Pause von mindestens 20 ms Pause
einzuhalten, um den Soundgenerator komplett zum Stillstand kommen zulassen, so dass die neue Messung
nicht durch die alte beeinträchtigt wird.Außerdem sollte darauf geachtet werden, dass die Schallwellen sich
nicht gegenseitig stören, wenn verschiedene Ultraschallsensoren gleichzeitig genutzt werden.
# define ULTRASONIC_SPEED_OF_SOUND 33000 // cm/s
//
// S o f o r t i g e U l t r a s c h a l l −Entfernungsmessung
//
unsigned s h o r t u l t r a s o n i c _ i n s t a n t _ m e a s u r e ( pin t r i g g e r , pin echo )
{
// Pin−Setup
pi n_s etup _output ( t r i g g e r ) ;
p i n _ s e t u p _ i n p u t _ w i t h _ p u l l u p ( echo ) ;
// Timer 3 auf den normalen Modus s e t z e n
// mit der Periode des F_CPU / 8
t i m e r 3 _ i n i t _ n o r m a l ( TIMER3_PRESCALE_8 ) ;
// Erzeugung des Aulö se −Impulses
pin_set ( trigger ) ;
// Timer zurü c k s e t z e n
timer3_overflow_flag_clear ( ) ;
timer3_set_value ( 0 ) ;
// ~10 us warte
while ( t i m e r 3 _ g e t _ v a l u e ( ) < 1 8 ) { }
// Auslö se −Impuls beenden
pin_clear ( trigger ) ;
// Warten auf den Echo− S t a r t
while ( ! p i n _ g e t _ v a l u e ( echo ) )
{
// Timeout ?
if ( timer3_overflow_flag_is_set ( ) )
{
return 0 ;
}
200
6.5 Sensoren
}
// Timer e r n e u t zurü c k s e t z e n
timer3_set_value ( 0 ) ;
// Warten auf Beendigung des Echos
while ( p i n _ g e t _ v a l u e ( echo ) )
{
// Timeout ?
if ( timer3_overflow_flag_is_set ( ) )
{
return 0 ;
}
}
// Konvertierung von Z e i t i n Entfernung :
//
Entfernung = Timer ∗ ( 1 / ( F_CPU / 8 ) ) ∗ Geschwindigkeit / 2
r e t u r n ( unsigned long ) t i m e r 3 _ g e t _ v a l u e ( ) ∗
ULTRASONIC_SPEED_OF_SOUND / ( F_CPU / 4 ) ;
}
Die gegebene Funktion erlaubt dem Nutzer den Echo-und den Trigger-Pin so zu wählen, dass der Sensor dort
angeschlossen werden kann wo es am günstigesten ist und genug Platz vorhanden ist. Zusätzlich erlaubt dies,
die Funktion auch außerhalb von HomeLab zu nutzen. Die dargestellte Funktion ist bereits in der HomeLab
Library enthalten und muss somit nicht geschrieben werden. Es gibt noch eine Sache zu beachten: Die Funktion in der Library ist streng an die Taktrate des Controller-Moduls von HomeLab gekoppelt. Die Taktrate
beträgt 14,7456 MHz, wenn die Funktion mit anderen Taktraten genutzt wird, liefert sie falsche Ergebnisse.
Um die Funktion mit anderen Taktraten zu nutzen sollte sie manuell programmiert werden. Der folgende
Code demonstriert die Nutzung des SRF04/SRF05 Ultraschall-Entfernungsmessers mit der HomeLab Library:
//
// Beispielprogramm f ü r den U l t r a s c h a l l −Entfernungsmesser des HomeLab
// Die Entfernungsmessung wirkt b l o c k i e r e n d .
//
# include < s t d i o . h>
# include <homelab/pin . h>
# include <homelab/delay . h>
# include <homelab/module/ s e n s o r s . h>
# include <homelab/module/ l c d _ a l p h a . h>
//
// P in s des U l t r a s c h a l l s e n s o r s
//
pin p i n _ t r i g g e r = PIN (G, 1 ) ;
pin pin_echo
= PIN (G, 0 ) ;
//
201
6 Praktische Beispiele
// Hauptprogramm
//
i n t main ( void )
{
unsigned s h o r t d i s t a n c e ;
char t e x t [ 1 6 ] ;
// I n i t i a l i s i e r u n g des LCD
l c d _ a l p h a _ i n i t (LCD_ALPHA_DISP_ON) ;
// Lö schen des LCD
lcd_alpha_clear ( ) ;
// Name des Programms
l c d _ a l p h a _ w r i t e _ s t r i n g ( " U l t r a sound " ) ;
// K l e i n e Unterbrechung
sw_delay_ms ( 1 0 0 ) ;
// E n d l o s s c h l e i f e .
while ( t r u e )
{
// Messen
d i s t a n c e = u l t r a s o n i c _ m e a s u r e ( p i n _ t r i g g e r , pin_echo ) ;
// War d i e Messung e r f o l g r e i c h ?
i f ( distance > 0)
{
// Konvertierung von Entfernung i n Text .
s p r i n t f ( t e x t , "%d cm
" , distance ) ;
}
// Sind wä hrend der Messung F e h l e r a u f g e t r e t e n ?
else
{
// Text des F e h l e r s .
s p r i n t f ( text , " Error
");
}
// D a r s t e l l u n g des T e x t e s am Anfang der zweiten Z e i l e des LCD
lcd_alpha_goto_xy ( 0 , 1) ;
lcd_alpha_write_string ( text ) ;
// K l e i n e Unterbrechung .
sw_delay_ms ( 5 0 0 ) ;
}
202
6.5 Sensoren
}
6.5.6
Übungen
Ziel ist es, ein ein Programm zu schreiben welches folgende Aufgaben ausführt:
Aufwärmübung
Der Widerstand des Potentiometers soll auf dem LCD in Ohm angezeigt werden. Der nominale Wert
des Widerstands beträgt 5 kΩ.
=== Für Anfänger =
1. Der Widerstand des Potentiometers wird im Bereich von (0 Ω. . . 999 Ω) in Ohm dargestellt und im Bereich von (1000 Ω. . . 5000 Ω) in kOhm. Der nominale Wert des Widerstands beträgt 5 kΩ. Das Ergebnis
wird mit korrekten Einheiten und Symbolen dargestellt.
2. Messung der Distanz zu einem Objekt. Die Distanz zu dem Objekt wird mit einem Infrarot-Entfernungsmesser gemessen wenn der Schalter S1 betätigt wird. Während der Messung blinkt eine gelbe
LED. Ist das Objekt weiter als 50 cm entfernt, leuchtet eine grüne LED, ist es weniger weit entfernt, die
rote.
3. Die Distanz zu dem Objekt wird mit einem Infrarot-Entfernungsmesser gemessen. Das Ergebnis wird
im binären System mit den 3 LEDs dargestellt (LED1, LED2, und LED3). Vergrößert sich die Entfernung, muss auch der angezeigte Wert größer werden. Als Skala sollte etwa 1 dm = 1 Bit verwendet
werden.
4. Der Wert des NTC Temperatursensors wird auf dem LCD in Grad angezeigt. Durch Betätigung des
Schalters S2 können die Einheiten ausgewählt werden: Kelvin (K), Fahrenheit (F) und Celsius (C). Die
Temperatur wird in korrekten Einheiten und Symbolen angezeigt.
5. Mit dem Lichtintensitätssensor werden schnelle Änderungen der Lichtintensität festgestellt. (Licht an/ ausschalten). Verläuft die Änderung schnell, blinkt die rote LED für 5 Sekunden. Ändert sich die Intensität langsam, wird die Änderungsrichtung gezeigt. Die grüne LED zeigt an, dass die Lichtintensität
ansteigt, die gelbe, dass sie abnimmt.
Für Fortgeschrittene
1. Datenschreiber. Die Werte aller analogen Sensoren werden konstant gemessen und die minimalen und
maximalen Werte werden festgehalten. Mit Betätigung von S1 kann der Nutzer die auf dem LCD angezeigten Information wählen. Angezeigt werden muss: Der Name des Sensors(kurz) und die bislang
erreichten minimalen / maximalen Werte. Die Sequenz des Durchschaltens ist folgende: IR Entfernungsmesser → Fotowiderstand → Thermistor → Potentiometer.
203
6 Praktische Beispiele
2. Entfernungsmesser. Wenn der Schalter S2 gedrückt wird, werden der Reihe nach 10 Messungen in
einer Sekunde durchgeführt. Nach der Messung wird die durchschnittliche Entfernung zum Objekt in
Dezimeter auf dem 7-Segment Indikator angezeigt. Bei Betätigung des Schalters S1, wird die minimale
gemessene Entfernung angezeigt und durch S3 die maximale.
3. Geschwindigkeit. Die Änderungsrate der Entfernung zu einem Objekt wird wie folgt angezeigt: langsame Änderung - grüne LED, mittlere Änderung - gelbe LED, schnelle Änderung - rote LED. Die
Geschwindigkeit wird auf dem LCD dargestellt.
4. Automatische Messreichweite. Je nach aktueller Messung werden die minimal oder maximal gemessenen Temperaturen augegeben und der zugehörige Wertebereich wird auf einer Skala von 0 bis 9
angezeigt. Der Wert wird auf der 7-Segment-Anzeige dargestellt.
5. Durch Kombination von Infrarot- und Ultraschall-Entfernungsmesser kann die Entfernung zum Objekt, die Geschwindigkeit sowie die Richtung des Objektes bestimmt werden. Die Ergebnisse werden
auf dem LCD dargestellt.
Fragen
1. Wie exakt ist der ADC des ATmega128 Mikrocontrollers? Welches ist die kleinste noch messbare Veränderung der Inputspannung?
2. Wie lange dauert ein ADC-Prozess? Wie kann die Arbeitsfrequenz geändert werden?
3. Welchen Inputspannungsbereich hat der ADC? Kann dieser geändert werden? Wie?
4. Was ist der Unterschied zwischen PTC-Thermistoren und NTC-Thermistoren? Worin bestehen die jeweiligen Vorteile?
5. Was ist der Grund eines Spannungsteilers in einem Messschaltkreises?
6. Kombinieren Sie einen Spannungsteiler, welcher die Nutzung eines analogen Sensors mit dem ATmega128 Mikrocontrollers ermöglicht. Die maximale Outputspannung des Sensors beträgt 10 V. Ermitteln
Sie zusätzlich den Inhalt des ADMUX Registers.
7. Zusätzliche Widerstände werden an den Pins des Potentiometers angeschlossen und eine 5 V Spannung wird angelegt. Wie groß müssen die zusätzlichen Widerstände sein, damit die Spannung vom
Potentiometer zwischen 1 und 2 V reguliert werden kann (von einem Ende zum anderen)? Die Stromstärke darf 10 mA nicht überschreiten.
8. Welche Umgebungsparameter haben einen Effekt auf die Funktion des Ultraschallentfernungsmessers
und warum?
9. Welche Lichtsensivitätssensoren können in einem Robotikprojekt genutzt werden? Nennen Sie mindestens 3 grundlegende Komponenten und erklären Sie die Unterschiede.
10. Wie kann, neben der trigonometrischen Methode, die Entfernung mittels Licht gemessen werden?
Nennen Sie mindestens drei Methoden.
204
6.6 Motoren
6.6
Motoren
Motoren sind Antriebsgeräte, sie können in jeder Form sehr verschieden sein, vom Arbeitsprinzip bis hin zu
Kraft und Größe. In der Robotik werden hauptsächlich Elektromotoren benutzt. Diese wandeln elektrische
Energie in mechanische Energie (Arbeit) um. Sie funktionieren auf dem Prinzip des Elektromagnetismus.
Es gibt viele Möglichkeiten, elektrische Motoren zu klassifizieren. Die bedeutendste Unterscheidung ist die
zwischen AC- (Wechselstrom-) und DC- (Gleichstrom-) Motoren. Hinzu kommen Motoren mit Bürsten oder
ohne, lineare Motoren und Rotationsmotoren, Nano-Motoren und große Motoren usw. Dahingegen erfolgen
einige Klassifizierungen nur provisorisch. So werden z.B. lineare Bewegungen durch einen elektrischen Rotationsmotor bewerkstelligt, welcher mit Schrauben in einem einheitlichen Gehäuse verbaut ist und so als
linearer Antrieb zählt. In diesem Kapitel werden die drei häufigsten Motoren, die in der Robotik zum Einsatz
kommen,beschrieben: DC-Motoren mit Magneten, RC-Servomotoren und Schrittmotor.
6.6.1
Gleichstrommotor
Notwendiges Wissen:
Motor Module,
Digital Inputs/Outputs,
Motors,
Delay
205
6 Praktische Beispiele
Theorie
Abbildung 6.28: DC Motor
Ein Gleichstrommotor mit permanenten Magneten wird häufig für die verschiedensten Anwendungen genutzt, bei denen kleine Ausmaße, große Kraft und ein geringer Preis entscheidend sind. Auf Grund ihrer hohen
Geschwindigkeit, werden sie oft mit einer Übersetzung genutzt. (Um eine niedrigere Output-Geschwindkeit
und höheres Drehmoment zu erreichen.)
Abbildung 6.29: Der perfekte Graph des Verhältnisses von Geschwindigkeit (V), Stromstärke(I),
Kraft(P), Effizienz (η) und Drehmoment (T) eines DC Motors.
Gleichstrommotoren mit permanenten Magneten sind vom Aufbau her sehr einfache und ihre Bedienung ist
relativ einfach. Aber auch wenn die Kontrolle sehr einfach ist, wird die Geschwindigkeit nicht präzise über das
Steuersignal bestimmt, weil hierauf noch viele andere Faktoren, wie das Drehmoment und der Speisestrom,
einwirken. Das Verhältnis zwischen Drehmoment und Geschwindigkeit ist in einem idealen Gleichstrommotor
linear. Das bedeutet, je höher das zu erzeugende Drehmoment ist, desto geringer die Geschwindigkeit und
desto höher der Strom in der Spule.
Gleichstrommaschinen nutzen Gleichstrom und brauchen eigentlich keine spezielle Kontrollelektronik, da
dienNotwendige Kommunikation im Motor selbst passiert. Wenn der Motor arbeitet gleiten zwei statische
Schleifbürsten an dem sich drehenden Kommutator und halten die Spannung an den Spulen. Die Richtung in
der sich der Motor dreht, hängt davon ab, wie der der Strom durch den Motor fließt. Wenn der Motor sich nur
in eine Richtung bewegen muss kann der Strom über ein Relais oder ein einfache Schaltung kommen. Falls
206
6.6 Motoren
der Motor sich in zwei Richtungen drehen muss, wird ein Schaltkreis, der Vierquadrantensteller (H-Bridge),
genutzt.
Abbildung 6.30: Die Arbeitsweise eines Vierquadrantenstellers, genutzt an Schaltern.
Der Vierquadrantensteller besitzt vier Transistoren die den Strom lenken, um den Motor zu betreiben. Das
elektrische Schaltbild des Vierquadrantenstellers ist ähnlich des Buchstaben H, daher der englische Name HBridge. Das Besondere am Vierquadrantensteller ist, dass man damit beide Polaritäten am Motor anlegen kann.
Das Bild auf der Seite zeit das grundsätzliche Schema eines Vierquadrantenstellers am Beispiel der Schalter.
Werden zwei diagonale Schalter geschlossen, arbeitet der Motor. Die Drehrichtung des Motors hängt davon ab
welche diagonalen Schalter geschlossen werden. Im wirklichen Vierquadrantensteller sind die Schalter durch
Transistoren ersetzt, welche je nach Stromstärke und Spannung des Motors gewählt werden.
Zusätzlich zur Richtungsänderung kann der Vierquadrantensteller auch die Geschwindigkeit des Motors verändern. Dazu werden die Transistoren konstant durch Pulsweitenmodulation geöffnet und geschlossen. Damit
ist die Energie, die der Motor erhält irgendwo zwischen vollem und keinem Stromdurchfluss. Die Zeit in der
die Transitoren geöffnet sind, wird in der PWM-Periode Arbeitszyklus genannt, welche in % angegeben wird.
Bei 0 % ist der Transistor konstant geschlossen und es fließt kein Strom. Bei 100 % ist der Transistor ist durchgehend geöffnet, und Strom fließt die ganze Zeit. Die Frequenz der PWM muss hoch genug sein, um Vibrationen
der Motorwelle zu verhindern. Bei niedrigen Frequenzen produziert der Motor Geräusche, daher wird oft eine
Modulationsfrequenz von über 20 kHz genutzt. Auf der anderen Seite ist die Effizienz des Vierquadrantenstellers nicht so gut bei hohen Frequenzen. Vibrationen der Motorwelle werden durch die Trägheit des Rotors
und der Induktionswiderstand der Spulen reduziert.
Es gibt auch integrierte Vierquadrantensteller für niedrigere Stromstärken. Für höhere Stromstärken werden spezielle Metall-Oxid-Halbleiter-Feldeffekttransistoren verwendet. Der Vierquadrantensteller mit anderer
Elektronik wird Motorcontroller oder Treiber genannt.Der Teiber des Gleichstrommotors im HomeLab L293D
hat 2 eingebaute Vierquadrantensteller und Ausschaltdioden. Der Motor wird mit drei digitalen Signalen gesteuert, eins davon ist das enable Signal, welches Funktionen einschaltet, die anderen beiden bestimmten den
207
6 Praktische Beispiele
Status der Transistoren des Vierquadrantenstellers. Dabei dürfen niemals beide vertikalen Transistoren geöffnet werden, da dadurch ein Kurzschluss verursacht wird. Damit wurde der Treiber „idiotensicher“gemacht,
und nur eine Option bzgl. der Transistoren auf einer Seite des Vierquadrantenstellers ausgewählt werden kann.
Anders gesagt, die Polarität wird ausgewählt, indem die beiden Treibersignalen, die an den beiden Enden der
Spule des Motors anliegen, genutzt werden.
Beachte: Verwechslen Sie nicht RC PWM Signal und gewöhnliche PWM Signale.
Übung
Das Board der Motoren des HomeLab erlaubt den Anschluss von bis zu 4 Gleichstrommotoren. Das Schaltbild
und die Anleitung für die Anschlüsse können im Kapitel „Motormodul“gefunden werden. Für jeden Motor
gibt es einen Vierquadrantensteller, welcher über zwei digitale Output-Pins des Mikrocontrollers kontrolliert
wird, da der enable Pin konstant „high“ist.Wenn beide Kontrollpins den gleichen Wert haben, wird der Motor
gestoppt. Wenn verschiedene Werte vorliegen, wird der Motor in eine bestimmte Richtung gedreht. Der Status
des Vierquadrantenstellers ist in der folgende Tabelle beschrieben:
Input A
0
Input B
0
Output A
-
Output B
-
1
1
+
+
1
0
+
-
0
1
-
+
Result
Der Motor
stoppt
Der Motor
stoppt
Der Motor
Richtung 1
Der Motor
Richtung 2
wird gewird gedreht in
dreht in
Gleichstrommotoren können durch Änderung der dazugehörigen Treiberpins mit dem Mikrocontroller kontrolliert werden. Die speziellen Funktionen um den Motor zu steuern sind in der HomeLab Bibliothek enthalten.
//
// Die E i n r i c h t u n g von Pins a l s T r e i b e r p i n s .
//
s t a t i c pin dcmotor_pins [ 4 ] [ 2 ] =
{
{ PIN ( B , 7 ) , PIN ( B , 4 ) } ,
{ PIN (D, 1 ) , PIN (D, 0 ) } ,
{ PIN (D, 7 ) , PIN (D, 6 ) } ,
{ PIN (D, 5 ) , PIN (D, 4 ) }
};
//
// Steuerung des gewä h l t e n DC Motors z u l a s s e n .
//
void d c m o t o r _ i n i t ( unsigned char index )
{
pi n_s etup _output ( dcmotor_pins [ index ] [ 0 ] ) ;
208
6.6 Motoren
pi n_s etup _output ( dcmotor_pins [ index ] [ 1 ] ) ;
}
//
// F e s t l e g u n g der Funktion und Richtung des gewä h l t e n DC Motors .
//
void dcmotor_drive ( unsigned char index , signed char d i r e c t i o n )
{
p i n _ s e t _ t o ( dcmotor_pins [ index ] [ 0 ] , d i r e c t i o n < 0 ) ;
p i n _ s e t _ t o ( dcmotor_pins [ index ] [ 1 ] , d i r e c t i o n > 0 ) ;
}
Mit dem Array dcmotor_pins aus der Bibliothek, werden die Kontrollpins der vier Motorcontroller bestimmt.
Bevor der Motor gesteuert wird, muss die Funktion dcmotor_init mit der Nummer des Motorcontrollers (0-3)
benannt werden. Sie setzt die Pins als Output. Für die Steuerung ist die Funktion dcmotor_drive vorhanden,
der negative direction Parameter gibt die Richtung der Motordrehung an, die andere Richtung wird mit dem
positiven Parameter angegeben. 0 dient dazu, den Motor anzuhalten.
Das folgende Beispielprogramm steuert den ersten und zweiten Gleichstrommotor so, dass sie jede Sekunde
ihre Drehrichtung ändern. Die Geschwindigkeit kann gesteuert werden, wenn ein Kontrollpin mit einem PWM
Signal moduliert wird.
//
// Testprogramm f ü r den DC Motor aus dem DC Motorenmodul des HomeLab .
//
# include <homelab/module/motors . h>
# include <homelab/delay . h>
//
// Hauptprogramm
//
i n t main ( void )
{
// R i c h t u n g s v a r i a b l e
signed char d i r e c t i o n = 1 ;
// E i n r i c h t u n g von Motor 1 und 2 .
dcmotor_init ( 0 ) ;
dcmotor_init ( 1 ) ;
// E n d l o s s c h l e i f e
while ( t r u e )
{
// Ein Motor d r e h t s i c h i n d i e eine , der andere i n d i e
e n t g e g e n g e s e t z t e Richtung .
dcmotor_drive ( 0 , − d i r e c t i o n ) ;
dcmotor_drive ( 1 , + d i r e c t i o n ) ;
209
6 Praktische Beispiele
// Unterbrechung f ü r 1 Sekunde .
sw_delay_ms ( 1 0 0 0 ) ;
// Umkehr der Richtung .
d i r e c t i o n = −d i r e c t i o n ;
}
}
6.6.2
Servomotor
Notwendiges Wissen:
Motor Module,
Analog to Digital Converter
Theorie
Abbildung 6.31: RC Servomotor
210
Sensors Module,
Digital Inputs/Outputs,
Motors,
6.6 Motoren
Abbildung 6.32: Das Verhältnis von Signalweite und Position der PWM des Servomotors.
Servomotoren werden oft in funkgesteuerten (RC) Modellen benutzt und sind sehr nützlich für kleine robotischen Anwendungen, da sie sehr kompakt und günstig sind.Ein RC-Servomotor verfügt über einen eingebauten Gleichstrommotor, ein Getriebe, einen Positionsfeedbacksensor (meistens ein Potentiometer, und eine Steuerelektronik. RC-Servomotren können mit einem externen PWM-Signal gesteuert werden. Wenn das
Signal den RC Servotiming-Vorraussetzungen entspricht, „beschreibt“es normalerweise ein Positionsinput
für die Servo-Steuer-Elektronik. Die Servomotor Elektronik vergleicht die Achsenstellung mit der eingegebenen Position und versucht eine übereinstimmende Position zu erreichen. Das Positionskontrollsignal ist eine
durchgehende Rechteckschwingung, wie in dem Bild dargestellt.
RC (radio-controlled) Servomotoren sind in der Robotik und im Modellbau sehr verbreitete Antriebe. Sie bestehen aus einem kleinen Gleichstrommotor, einer Übersetzung und der logischen Kontrolleinheit. Normalerweise versucht der Rotor des Servomotors sich in eine bestimmte Position zu bringen und diese zu halten. Die
Position des Rotors hängt von dem Kontrollsignal ab, dass der Servomotor empfangen hat. Je nach Typ des
Motors kann der maximale Drehwinkel des Motors variieren. Servomotoren, die sich konstant drehen, sind
selten. In diesem Fall gibt das Kontrollsignal nicht den Rotationswinkel, sondern die Rotationsgeschwindigkeit an. Servomotor-Hacks sind auch sehr verbreitet. Hierdurch wird ein positionsbestimmender Servomotor
zu einem konstant drehenden. In diesem Fall wird das Feedback Potentiometer durch zwei Widerstände ersetzt, und der mechanische Widerstand, welcher verhindert, dass eine vollständige Rotation stattfinden kann,
wird entfernt.Eine wichtige Eigenschaft des Servomotors ist das Kraft-Gewicht-Verhältnis.
Das Kontrollsignal des Servomotors ist ein speziell pulsweitenmoduliertes Signal (PWM), bei dem die Pulsweite die Position des Rotors angibt. Die Periode des Signals liegt bei 20 ms (50 Hz) und die Weite der hohen
Periode ist 1 ms - 2 ms. 1 ms markiert die eine äußerste Position 2 ms die Andere. 1,5 ms markieren die Mittelposition des Servomotorrotors.
Traditionelle RC-Servomotoren sind auch bekannt als analoge Servomotoren. Dies liegt daran, dass in dem
letzten Jahrzehnt so genannte digitale Servomotoren auf den Markt kamen. Der Unterschied zwischen beiden
besteht darin, dass analoge RC-Servomotoren mit einem 50 Hz PWM Signal gesteuert werden, digitale RC-
211
6 Praktische Beispiele
Servomotoren durch einen Mikrocontroller mit einem höherfrequenten Signal. Das Inputsignal ist das Gleiche,
jedoch ist durch die höhere Modulationsfrequenz wird eine schnellere und präzisere Positionsbestimmung
ermöglicht.
Übung
Auf dem Platine des HomeLab Motormoduls sind 2 Anschlüsse für RC-Servomotoren vorhanden.Die PWMEnden der Stecker sind an den Pins PB5 und PB6 am Mikrocontroller angeschlossen, dessen sekundäre Funktion das Vergleichen der Einheiten A und B von Timer 1 ist. Timer 1 kann ein PWM Signal erzeugen, und daher
ist das Steuern eines Motors sehr einfach zu programmieren. Die einzige Schwierigkeit besteht im Einstellen
des Timers.
Timer 1 muss in den PWM-Produktionsmodus eingestellt werden, wobei der maximale Wert des Timers mit
dem ICR Register bestimmt wird. Durch Änderung des maximales Wertes im Programm und im Taktgeber
des Timers, kann die präzise PWM Frequenz zur Steuerung des Servomotors bestimmt werden. Mit dem
Vergleichs-Register des Timers werden die Längen für beiden hohen Semi-Perioden des Signals bestimmt.
Der Timer hat eine spezielle Vergleichseinheit, welche den Wert des Zählwerks beobachtet und für den Fall,
dass es gleich dem Wert des Vergleichs-Registers ist, den Output-Wert der Vergleichseinheit ändert. Es folgt
ein Programm-Code der Servomotor-Steuerbibliothek des HomeLab. Für die Ausführung nutzt es Parameter
für Timer welche durch Makrofunktionen bestimmt werden. Zum Beispiel, wird die Periode durch die F-CPU
Konstante angegeben, welche die Taktrate des Mikrocontrollers angibt. Wenn man Makros nutzt, müssen die
Parameter des Timers für verschiedene Taktzyklen nicht berechnet werden und der Compiler konvertiert die
Operationen mit Makros zu Konstanten. Dadurch erhöht sich der Programmspeicher nicht, und es wird auch
nicht mehr Rechenzeit benötigt.
//
// Der WErt des Timers ( 2 0 ms) zum ERreichen der v o l l e n PWM−Periode .
// F_CPU i s t d i e T a k t r a t e des M i k r o c o n t r o l l e r s , welche durch 50 Hz und
8 d i v i d i e r t wird .
//
//
# define PWM_PERIOD
( F_CPU / 8 / 5 0 )
//
// M i t t l e r e P o s i t i o n der PWM des Servomotors ( 5 ms / 20 ms)
// M i t t l e r e P o s i t i o n l i e g t b e i 15/200 der v o l l e n Periode .
//
# define PWM_MIDDLE_POS (PWM_PERIOD ∗ 15 / 2 0 0 )
//
// F a k t o r zur Konvertierung von Prozenten i n Perioden ( −100% t o 100%) .
// +1 wird a d d i e r t um s i c h e r z u s t e l l e n , dass d i e Halbperioden d i e
Grenzen von 1 ms und 2 ms e r r e i c h e n oder // etwas hö her l i e g e n .
//
# define PWM_RATIO
(PWM_PERIOD / 20 / 2 / 100 + 1 )
//
212
6.6 Motoren
// E i n r i c h t u n g der Pins .
//
s t a t i c pin s e r v o _ p i n s [ 2 ] =
{
PIN ( B , 5 ) , PIN ( B , 6 )
};
//
// Servomotor v o r b e r e i t e n .
//
void s e r v o m o t o r _ i n i t ( unsigned char index )
{
// Pin des PWM S i g n a l s a l s Output .
pi n_s etup _output ( s e r v o _ p i n s [ index ] ) ;
// E i n r i c h t u n g von Timer 1 .
// Vorzä h l e r = 8
// S c h n e l l e r PWM Modus , wobei TOP = ICR
// OUTA und OUTB auf low im V e r g l e i c h .
timer1_init_fast_pwm (
TIMER1_PRESCALE_8 ,
TIMER1_FAST_PWM_TOP_ICR ,
TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH,
TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH,
TIMER1_FAST_PWM_OUTPUT_DISABLE) ;
// F e s t l e g u n g der Periode durch maximalen Wert .
t i m e r 1 _ s e t _ i n p u t _ c a p t u r e _ v a l u e (PWM_PERIOD) ;
}
//
// F e s t l e g u n g der P o s t i t i o n des Servomotors .
// Parameter der P o s i t i o n l i e g e n zwischen −100% und +100%.
//
void s e r v o m o t o r _ p o s i t i o n ( unsigned char index , signed s h o r t p o s i t i o n )
{
switch ( index )
{
case 0 :
timer1_set_compare_match_unitA_value (
PWM_MIDDLE_POS + p o s i t i o n ∗ PWM_RATIO) ;
break ;
case 1 :
timer1_set_compare_match_unitB_value (
213
6 Praktische Beispiele
PWM_MIDDLE_POS + p o s i t i o n ∗ PWM_RATIO) ;
break ;
}
}
Das Beispielprogramm nutzt beschriebene Funktionen der HomeLab Bibliothek. Am Anfang des Programms
wird der erste PWM-Signal Generator des Servomotors mit der servomotor_init Funktion gestartet. Der Wert
der Position des Servomotors wird durch die Kanalnummer 3 des Analog-Digital-Konverters (ADC) empfangen, an dem ein Potentiometer an der Sensorplatine angeschlossen ist. Um die Reichweite von -100 % bis +100
%, die für die Steuerung des Servomotors notwendig, ist zu erhalten wird die Hälfte des Maximums (512)
vom ADC Wert abgezogen und das Ergebnis durch fünf dividiert. Das Ergebnis ist +/- 102, kleine Ungenauigkeiten können unbeachtet bleiben, da Servomotoren sich auch in der Relation des PWM-Signals und des
Drehwinkels unterscheiden. Die finale PWM Halbperiodenweite in Anwendungen muss über das „Try-andError“-Verfahren gefunden werden. Auch wenn die Funksteuerungen von RC-Modellen Möglichkeiten für ein
präzises Setup besitzen. Wenn das Programm läuft, wird die Rotorposition des Servomotors je nach Position
des Potentiometers verändert.
//
// Testprogramm des Motormoduls des HomeLab k i t .
//
# include <homelab/adc . h>
# include <homelab/module/motors . h>
//
// Hauptprogramm .
//
i n t main ( void )
{
short position ;
// E i n r i c h t u n g des ADC.
a d c _ i n i t (ADC_REF_AVCC, ADC_PRESCALE_8 ) ;
// E i n r i c h t u n g des Motors .
servomotor_init ( 0 ) ;
// E n d l o s s c h l e i f e .
while ( t r u e )
{
// Auslesen der P o s i t i o n aus dem P o t e n t i o m e t e r und Konvertiereung
der R e i c h w e i t e
// des Servomotors .
position = ( ( short ) adc_get_value ( 3 ) − ( short ) 512) / ( short ) 5 ;
// F e s t l e g u n g der P o s i t i o n des Servomotors .
servomotor_position ( 0 , position ) ;
}
214
6.6 Motoren
}
6.6.3
Schrittmotor
Notwendiges Wissen:
Motor Module,
Digital Inputs/Outputs,
Motors
Theorie
Abbildung 6.33: Schrittmotor
Schrittmotoren können generell in unipolare und bipolare Schrittmotoren eingeteilt werden.Unipolare Schrittmotoren haben charakteristische Windungen welche die zwei Spulen in vier unterteilen. Schrittmotoren haben
keine eingebauten Bürsten oder Elektronik, d.h. jegliche Kommunikation muss extern erfolgen. Der am meisten benutzte Kommutationstyp ist der offene-Regelkreis- („open-loop“) Modus: der Der Schrittmotortreiber
lädt die Spulen nach einem bestimmten Muster, nutzt aber kein Feedback. Schritte können so verpasst werden
falls die Motorwelle eine Drehmomentüberladung erfährt. Verpasste Schritte verursachen ungenaue Positionierung. Bipolare Schrittmotoren haben normalerweise vier Drähte und zwei separate Spulen im Inneren. Sie
ähneln den unipolaren Schrittmotoren stark. Unipolare Schrittmotoren können als bipolare Schrittmotoren
genutzt werden, aber nicht umgekehrt.
Schrittmotoren werden oft in Applikationen genutzt, die Genauigkeit benötigen. Anders als Gleichstrommotoren haben Schrittmotoren weder Bürsten, noch Kommutatoren. Sie haben verschiedene unabhängige Spulen,
welche durch externe Elektronik (Treiber) angetrieben werden. Um den Rotor anzutreiben, werden die Spulen
Schritt für Schritt umgeschaltet, ohne Feedback. Das ist der Nachteil des Schrittmotors. Bei mechanischer Überladung, wenn der Rotor nicht rotiert, werden so die Schritte durcheinander gebracht und die Bewegung wird
ungenau. Zwei Typen von Schrittmotoren werden anhand der Spulen unterschieden: Unipolare und bipolare
Schrittmotoren. Durch Aufbau werden drei zusätzliche Segemente bedacht:
∗ R e l u k t a n z s c h r i t t m o t o r ( hohe Genauigkeit , wenig Drehmoment , n i e d r i g e r
Preis )
215
6 Praktische Beispiele
∗ Permanentmagnetschrittmotor ( n i e d r i g e Genauigkeit , hohes Drehmoment ,
niedriger Preis )
∗ Hybrider S c h r i t t m o t o r ( hohe Genauigkeit , hohes Drehmoment , hoher
Preis )
Der Reluktanzschrittmotor verfügt über gezahnte Windungen und einen gezahnten Weicheisenrotor. Die größte Zugkraft entsteht, wenn die Zähne beider Seiten sich gegenseitig abdecken. Der Permanentmagnetschrittmotor bestitz, wie der Name schon sagt, Permanentmagneten welche sich je nach Polarität der Windung orientieren. Der hybride Schrittmotor nutzt beide Techniken.
Je nach Modell des Schrittmotors, braucht eine vollständige Rotation (360◦ ) des Rotors hunderte Schritte von
Stromwendungen. Für stabile und weiche Bewegungen, wird eine bestimmte Kontrollelektronik genutzt, welche den Motor je nach Parameter kontrolliert (Trägheit des Rotors, Drehmoment, Resonanz etc.). Zusätzlich
zur Kontrollelektronik werden verschiedene Methoden zur Stromwendung genutzt. Wird eine Windung in
Reihe umgewandelt, wird dieser Vorgang „Ganzschrittantrieb“genannt, verändert sich der Antrieb zwischen
zwei Wicklungen, nennt man diesen Halbschritt. Darüber hinaus werden „Kosinus-Mikroschritte“genutzt, um
eine sehr genaue und weiche Kontrolle zu ermöglichen.
Unipolare Schrittmotoren
Abbildung 6.34: Die Wicklungen eines unipolaren Schrittmotors
Unipolare Schrittmotoren haben fünf oder sechs Anschlüsse. Je nach Aufbau des Motors werden nur 1 /4
der Wicklungen aktiviert. Vcc Leitungen werden normalerweise an der positiven Stromquelle angeschlossen.
Während der Umwandlung sind die Enden der Wicklungen 1a, 1b, 2a und 2b über Transistoren (Transistorarray der Motorplatine ULN2803) nur an die Masse angeschlossen, was die Kontrollelektronik recht einfach
macht.
Bipolare Schrittmotoren
216
6.6 Motoren
Abbildung 6.35: Die Wicklungen eines Bipolaren Schrittmotors.
Bipolare Schrittmotoren unterscheiden sich von unipolaren, da sie die Polarität ihrer Wicklungen während
der Umwandlung verändern. Die Hälfte der Wicklungen wird gleichzeitig aktiviert, daher sind sie effizenter
als unipolare Schrittmotoren. Bipolare Schrittmotoren haben 4 Anschlüsse, jeder wird an einen anderen Vierquadrantensteller angeschlossen (Treiber L293 auf der Motorenplatine). Während der Kommutation legen die
Vierquadrantensteller entweder negative oder positive Spannung am Ende der Wicklung an. Unipolare Motoren können mit einem bipolaren Treiber gestartet werden indem einfach die Leitungen 1a, 1b, 2a und 2b der
Wicklungen angeschlossen werden (Vcc wird nicht angeschlossen).
Die notwendige Kommutation, um Schrittmotoren mit Wicklungen im Ganzschrittmodus und im Halbschrittmodus zu kontrollieren, wird in der Tabelle unhalb angezeigt. Da in Treibern für unipolare Schrittmotoren
nur das Öffnen von Transistoren stattfindet, werden die Schritte mit 0 und 1 markiert. Zur Steuerung eines
bipolaren Schrittmotors braucht es Signale und daher wird jeder Schritt mit der Polarität des Treiber-Outputs
markiert:
Schritt
Ganzschritt
1
2
3
4
Halbschritt
1
2
3
4
5
6
7
8
Unipolar
1A
Bipolar
2A
1B
2B
1A
2A
1B
2B
1
0
0
0
0
1
0
0
0
0
1
0
0
0
0
1
+
-
+
-
+
-
+
1
1
0
0
0
0
0
1
0
1
1
1
0
0
0
0
0
0
0
1
1
1
0
0
0
0
0
0
0
1
1
1
+
+
+
+
+
+
-
+
+
+
-
+
+
+
217
6 Praktische Beispiele
Übung
Das Ziel dieser Aufgabe ist es, unter Anwendung der oben beschrieben Methode einen bipolaren Schrittmotor
zu starten, welcher mit einem unipolaren Schrittmotor getauscht werden kann. Es gibt Treiber auf der Motorenplatine, welche vom Mikrocontroller über vier Inputpins kontrolliert werden. Jeder Pin gibt die Polarität
einer Wicklung wieder. Die Spannung am Ende der Wicklung ist positiv wenn der Pin high ist und negativ
wenn der Pin low ist.Zu den Enden 1A, 1B, 2A und 2B gehören die entsprechenden Pins PB0, PB1, PB2 Und
PB3 am Mikrocontroller.
In der HomeLab Bibliothek gibt es die Funktion bipolar_init, um bipolare Schrittmotoren zu steuern, indem
die Pins als Output gesetzt werden. Die Funktion bipolar_halfstep führt Rotationen mit bestimmten Halbschritten aus. Die Kommutation wird mit der Tabelle der Halbschritte durchgeführt, aber es werden komplexere
Bitoperationen genutzt.
//
// Vorbereitung der Steuerung des b i p o l a r e n S c h r i t t m o t o r s .
//
void b i p o l a r _ i n i t ( void )
{
DDRB |= 0 x0F ;
PORTB &= 0 xF0 ;
}
//
// Bewegung des b i p o l a r e n S c h r i t t m o t o r s mit H a l b s c h r i t t e n .
//
void b i p o l a r _ h a l f s t e p ( signed char d ir ,
unsigned s h o r t num_steps , unsigned char speed )
{
unsigned s h o r t i ;
unsigned char p a t t e r n , s t a t e 1 = 0 , s t a t e 2 = 1 ;
// F e s t l e g u n g der Richtung +− 1
d i r = ( ( d i r < 0 ) ? −1 : +1) ;
// Durchführung von H a l b s c h r i t t e n .
f o r ( i = 0 ; i < num_steps ; i ++)
{
s t a t e 1 += d i r ;
s t a t e 2 += d i r ;
// E r s t e l l u n g des Musters .
p a t t e r n = ( 1 << ( ( s t a t e 1 % 8 ) >> 1 ) ) |
( 1 << ( ( s t a t e 2 % 8 ) >> 1 ) ) ;
// Output s e t z e n .
PORTB = (PORTB & 0 xF0 ) | ( p a t t e r n & 0 x0F ) ;
218
6.6 Motoren
// Pause um auf d i e Ausführung des S c h r i t t e s zu warten .
sw_delay_ms ( speed ) ;
}
// Anhalten des Motors .
PORTB &= 0 xF0 ;
}
Die Funktion wird durch ein Beispielprogramm demonstriert, welches den Motor abwechselnd alle 200 Halbschritte in eine Richtung rotieren lässt. Die Geschwindigkeit der Rotation wird durch die Länge der Pausen
zwischen den Schritten bestimmt. Wenn die Pause zu kurz ist, kann der Motor sich aufgrund der Trägheit
nicht drehen.
//
// Das Testprogramm f ü r den b i p o l a r e n S c h r i t t m o t o r des Motormoduls
// des HomeLab .
//
# include <homelab/module/motors . h>
//
// Hauptprogramm .
//
i n t main ( void )
{
// E i n r i c h t u n g des Motors .
bipolar_init () ;
// E n d l o s s c h l e i f e .
while ( t r u e )
{
// Bewegung des Rotors 200 H a l b s c h r i t t e i n e i n e Richtung mit
e i n e r Geschwindigkeit von 30 ms/ S c h r i t t .
bi po lar _h al fst ep (+1 , 200 , 30) ;
// Bewegung des Rotors 200 H a l b s c h r i t t e i n d i e andere Richtung
mit e i n e r Geschwindigkeit von 30 ms/ S c h r i t t .
b i p o l a r _ h a l f s t e p ( −1 , 2 0 0 , 3 0 ) ;
}
}
6.6.4
Aufgaben
Ziel ist es, ein Programm zu schreiben, welches die folgenden Aufgaben erfüllen kann.
219
6 Praktische Beispiele
Aufwärmübung
Steuern des Gleichstrommotors mit dem digitalen Board. Durch Betätigung von Schalter S1 leuchtet
LED1 auf und der Motor dreht sich im Uhrzeigersinn. Durch Betätigung von Schalter S3 leuchtet die
LED3 auf und der Motor dreht sich gegen den Uhrzeigersinn. Durch Betätigung von Schalter S2 leuchtet LED2 auf und der Motor wird gestoppt.
Für Anfänger
1. Roboter: Durch Nutzung von zwei Gleichstrommotoren und Berührungssensoren wird die Bewegung
eines Roboters simuliert. Berührungssensoren sind die Schalter am digitalen Board (S1. . . S3). Die Motoren werden durch die Betätigung der Schalter gesteuert. S1 stoppt den linken Motor für zwei Sekunden und startet dann beide Motoren mit voller Geschwindigkeit. S2 stoppt den rechten Motor für zwei
Sekunden und startet dann beide Motoren mit voller Geschwindigkeit. Wenn beide Schalter betätigt
werden drehen beide Motoren rückwärts, bis der Schalter losgelassen wird.
2. Servomotor: Der Servomotor wird mit den Schaltern des digitalen Boards kontrolliert. Wenn S1 gedrückt wird macht der Servomotor einen Schritt nach rechts, bei S3 einen Schritt nach links und S2
bewegt den Servomotor wieder in die ursprüngliche Position (Mitte). Die Position des Motors wird
direkt auf dem 7-Segment Display dargestellt (jede Nummer steht für 10◦ Drehung, Mittelposition =
5)
3. Radar: Die Funktion eines Radars wird simuliert. Um ein Objekt, welches näher als 0.5 Meter ist, zu
identifizieren, wird auf dem Hebel des Servomotors der IR-Entfernungsmesser installiert. Der Hebel
des Servomotors bewegt sich konstant von einem Ende zum anderen Ende der Bewegungsreichweite
des Motors. Falls ein Objekt näher als 0.5 Meter am Sensor ist, wird der Servomotor für 5 Sekunden
gestoppt und eine LED (PB7) zeigt auf dem Controllerboard die Entdeckung eines Objekts an.
4. Schrittmotor: Nach jeder Betätigung von S1 oder S3, rotiert der Motor 10 Schritte im oder gegen den
Uhrzeigersinn. Die Rotation wird sofort angehalten wenn S2 gedrückt wird.
5. Alle drei Motorentypen werden angeschlossen. Durch Betätigung eines Schalters wird ein bestimmter
Motor gestartet und angehalten. S1 steuert den Gleichstrommotor, S2 den Servomotor und S3 den
Schrittmotor.
Für Fortgeschrittene
1. Der Gleichstrommotor beschleunigt wenn S1 gedrückt wird und hält die momentane Geschwindigkeit,
wenn der Schalter losgelassen wird. Wenn S2 gedrückt wird, erfährt der Motor eine gleichmäßige
Abbremsung. Wenn S3 gedrückt wird, hält der Motor sofort an (Simulation eines Notstopps).
2. Ein Objekt verfolgen: Durch das Nutzen des Ultraschall-Entfernungsmessers, welcher auf dem Hebel
des Servomotors installiert wird, verfolgt der Servomotor ein vorbeikommendes Objekt. Der Motor
dreht sich je nach Bewegung des Objekts, so das immer das Objekt in der Mitte des Mess-Sektors des
Sensors ist.
220
6.6 Motoren
3. der Schrittmotor hält die letzte Position des Motors nach Änderung jeder Sequenz. Wenn eine neue
Sequenz aktiviert wird, nutzen Sie eine Variable, so dass die Bewegung exakt von der letzten Position
des Motors fortgeführt wird.
4. Beschleunigung: Das Programm ermöglicht die Beschleunigung oder Abbremsung des Schrittmotors.
Nutzen Sie lineare Geschwindigkeitssteigerungen welche bei visueller Betrachtung einfach identifiziert werden können. Weite Bewegungen müssen folgendes Schema erfüllen: Beschleunigung ->konstante Geschwindigkeit ->Abbremsung.
5. Entwerfen Sie einen PID-Regulator für einen Gleichstrommotor. Achtung! Diese Aufgabe benötigt
einen Motor mit Feedback. Diese Aufgabe kann daher auch theoretisch gelöst werden.
6.6.5
Fragen
1. Welcher Vierquadrantensteller wird genutzt? Nach welchem Prinzip funktioniert er?
2. Wie wird die Position der Achse eines RC-Servomotors bestimmt?
3. Was ist der Hauptunterschied zwischen unipolaren und einem bipolaren Schrittmotoren?
4. Wie können Halbschritt und Mikroschrittmodi eines Schrittmotors genutzt werden? Nennen Sie ein
Beispiel.
5. Wie kann die Rotationsgeschwindigkeit eines DC Motors gesteuert werden? Nennen Sie ein Beispiel.
6. Welcher PWM-Arbeitszyklus wird benötigt um eine Gleichstrommotorrotation mit 70% der nominalen
Geschwindigkeit zu erreichen?
7. Wie wird die Richtung der Motorrotation bestimmt, wenn ein Encoder genutzt wird?
8. Wie kann ein Gleichstrommotor elektronisch gebremst werden?
9. Was passiert, wenn das Schema der Stromwendung eines Schrittmotors sich zu schnell ändert?
10. Ist dynamisches Bremsen möglich? Wenn ja, wie?
221
6 Praktische Beispiele
6.7
Datenschnittstellen
Mit Microcontrollern können Antriebe gesteuert werden, Werte von Sensoren ausgelesen werden und viel
mehr. Diese Geräte müssen dazu jedoch immer mit dem Mikrocontroller verbunden sein; es ist somit nicht
möglich, durch einfache Signale zu kommunizieren. Das liegt darin begründet, dass zu viele Steuerungssignale
zur Steuerung der Schnittstelle benötigt werden oder, dass zu viele Daten gesendet werden müssen. Daher
wurden zahlreiche Standards von Datenschnittstellen für Mikrocontroller oder andere Elektronik entwickelt.
Die Standards bestimmen die elektrischen Parameter der Signale und die Übertragungsregeln für die Signale
(das Protokoll).
Ein einfaches Beispiel eines Protokolls ist der Morse Code, womit Informationen durch Nutzung von Pieptönen und Pausen in verschiedenen Abständen übertragen werden. Digitale Datenübertragungsprotokolle
arbeiten ähnlich. Dort werden die Informationen als Bit Werte gesendet und je nach Schnittstelle Angepasst
an versschiedene Bedürfnisse wurden diverse Schnittstellen zur Datenübertragung entwickelt. Da die Datenmengen jedoch stetig ansteigen, werden immer wieder neue Methoden entwickelt. Bei elektronischen Komponenten ist die Situation dahingehend etwas stabiler. Die I2 C, SPI und UART Schnittstellen werden schon sehr
lange verwendet. Traditionellere Schnittstellensysteme für die Übertragung innerhalb eines Systems sind RS232, Rs-485, LIN and CAN, aber viele Mikrocontroller werden schon mit USB, Ethernet und kabellosen ZigBee
Schnittstellen produziert. Dieses Kapitel konzentriert sich auf die RS-232 Schnittstelle.
222
6.7 Datenschnittstellen
6.7.1
RS-232
Notwendiges Wissen:
Controller module,
USART,
Serial Interface,
Alphanumeric LCD
Theorie
Abbildung 6.36: Cable RS-232. Der linke Stecker ist „male“, der rechte „female“.“
Die RS-232 ist ein Standard unter den physischen Datenschnittstellen und wird zur Übertragung von Binärdaten genutzt. Dieser Standard wird überwiegend für serielle Anschlüsse von Computern verwendet, welche gewöhnlich als „COM“-Anschlüsse bezeichnet werden. Inzwischen wurden die RS-232 größtenteils durch USBSchnittstellen ersetzt. Aufgrund ihrer Einfachheit werden sie jedoch weiterhin erfolgreich in Freizeitanwendungen verwendet, insbesondere wenn USB - RS-232 Konverter vorhanden sind. Der RS-232 Standard legt die
Stecker, die elektronischen Parameter sowie die Bedeutung der Signale fest, nicht aber das Protokoll.
Die RS-232 Schnittstelle wird hauptsächlich in Verbindung mit dem UART Datenübermittlungsmodul genutzt.
Diese UART-Hardware verfügt über ein standardisiertes Protokoll, legt jedoch keine Stecker oder andere Dinge fest. Die RS-232 Schnittstelle erweitert somit das UART Modul. UART ist ein Peripheriemodul des Mikrocontrollers, dessen digitaler In- und Output nicht mit den elektronischen Parametern des RS-232 korrespondiert. Aus diesem Grund werden die beiden über einen speziellen Pegelkonverter miteinander verbunden.
Der bekannteste Pegelkonverter für RS-232 und TLL/COMS ist der MAX232.
Die Bezeichnung UART steht für „Universal Asynchronous Receiver Transmitter“. Die USART-Schnittstelle
bietet ergänzend die Möglichkeit, Daten synchron zum Taktsignal zu senden. UART kann auch als serielle
Schnittstelle bezeichnet werden. Die serielle Schnittstelle ist ein Datentransfermechanismus, wobei jedes Bit
einzeln übermittelt wird. Um beispielsweise 1 Byte zu senden, werden 8 Bits in einem bestimmten Intervall
übermittelt. Dadurch wird an der seriellen Leitungsschnittstelle, also an einen Pin des Mikrocontrollers, der
Wert der Stromspannung nach einer bestimmten Zeit verändert, zunächst ist dieser niedrig und daraufhin
hoch. Normalerweise gibt es zwei Geräte die an der seriellen Schnittstelle angeschlossen werden. Das eine
dient zur Übertragung von Information (durch Veränderung des Pinwertes), das andere zum Empfang (durch
Erfassung des Pinwertes). Der Übertragungspin ist mit TX, der Empfangspin mit RX gekennzeichnet. Auf
223
6 Praktische Beispiele
einer Leitung geht der Informationsfluss immer nur in eine Richtung. Um Daten in die andere Richtung zu
senden, muss eine andere Leitung genutzt werden. Werden Daten über zwei Leitungen gleichzeitig gesendet,
wird dieses „Full Duplex Bus“genannt.
Abbildung 6.37: Der Rahmen des UART, mit S als Startbit , 0-7 als Datenbits, P als Paritätsbit
(falls dieses existiert) und T als Stopbit (oder 2).
Die Datenübertragung erfolgt über den Rahmen der UART-Schnittstelle, welcher je nach Konfiguration 5 bis 9
Datenbits enthält. Am häufigsten sind 8 Bits (1 Byte). Zusätzlich zu den Datenbits werden durch den Rahmen
weitere Bits übertragen, welche dazu genutzt werden, den Augenblick der Ankunft von Daten sowie des
Abschlusses der Übertragung auf der Empfängerseite zu erkennen. Ersteres wird Startbit genannt und hat
immer den Wert 0. Das zweite ist das Stopbit, welches immer den Wert 1 hat. Vor dem Stopbit gibt es in einigen
Fällen noch das Paritätsbit. Dieses dient zur Kontrolle der Richtigkeit. Das Paritätsbit zeigt an, ob die Anzahl
der Einsen in den Datenbits gerade oder ungerade ist. Die Art der Ablesung hängt von der Konfiguration der
UART Schnittstelle ab. Das Paritätsbit wird aber normalerweise nicht mehr verwendet und kann im Rahmen
der Konfiguration unterdrückt werden. So wie das Paritätsbit konfiguriert werden kann, kann auch die Anzahl
von Daten- und Stopbits variiert werden.
Zusätzlich zur Rahmenstruktur gibt es einen weiteren wichtigen Parameter - die Baudrate, wodurch die Anzahl
der in einer Sekunde übertragenen Symbole festgelegt wird. Die Baudrate zeigt die Anzahl der Symbole an. Bei
der Verwendung von UART entspricht 1 Baud einem Bit, weshalb im Zusammenhang mit dem Rahmen von
Bits gesprochen wurde. Allgemein ist es egal, welche Baudrate zur Datenübertragung genutzt wird, es gibt
jedoch eine einige häufig verwendete Baudraten, welche verwendet werden sollten. Diese sind zum Beispiel:
9600 bps, 19200bps, 38400 bps, 57600 bps, 115200 bps.
Darüber hinaus ist es wichtig zu wissen, dass der RS-232 Standard zusätzlich zu den Datensignalen (RX, TX)
auch über Datenflusskontrollpins DTR, DCD, DSR, RI, RTS undCTS verfügt, welche zur Kontrolle der Kommunikation zwischen den Geräten dienen. Sie können zum Beispiel genutzt werden, um festzustellen ob das
Gerät zum Empfang von Daten bereit ist oder nicht. Da die RS-232 Schnittstelle ursprünglich darauf abzielt,
Computer an ein Modem anzuschließen, können (konnten) einige Signale dazu genutzt werden, um den Status
von Telefonleitungen anzuzeigen.
Praktisches Beispiel
Die Platine des Controllermoduls ist mit einem RS-232 male-Stecker ausgerüstet. Darüber kann der Controller
an einen Computer oder einen anderen Controller angeschlossen werden. Um ihn an einen Computer anzuschließen, muss ein normales nicht invertiertes Kabel genutzt werden, dessen eines Ende male und anderes
Ende female ist. Um den Controller an einen anderen Controller anzuschließen, muss ein Kabel verwendet
werden, bei dem RX, TX sowie Kontrollsignale für die Stromstärke senkrecht invertiert sind und beide Stecker female sind. Das invertierte Kabel wird auch Nullmodemkabel genannt. Nachfolgend ist ein Beispielprogramm zur Nutzung der UART Schnittstelle dargestellt. Wird das Programm gestartet, übermittelt es ein
„Willkommen“über die RS-232 Schnittstelle und zeigt empfangene Nachrichten an. Es werden das LCD-Display und die USART Bibliotheken genutzt.
224
6.7 Datenschnittstellen
//
// Anschluss des Controllermoduls des HomeLab an einen Computer über
d i e RS−232 S c h n i t t s t e l l e .
// Im B e i s p i e l wird e i n d i g i t a l e s Input −Output−Modul mit LCD Display
verwendet .
// Der im Terminal des Computers eingegebene Text wird auf dem LCD
Display a n g e z e i g t .
//
# include <homelab/ u s a r t . h>
# include <homelab/module/ l c d _ a l p h a . h>
//
// F e s t l e g u n g der USART S c h n i t t s t e l l e .
//
u s a r t p o r t = USART( 0 ) ;
//
// Hauptprogramm
//
i n t main ( void )
{
char c ;
unsigned char row = 1 ;
// I n s t a l l a t i o n der USART S c h n i t t s t e l l e .
u s a r t _ i n i t _ a s y n c ( port ,
USART_DATABITS_8 ,
USART_STOPBITS_ONE ,
USART_PARITY_NONE,
USART_BAUDRATE_ASYNC( 9 6 0 0 ) ) ;
// I n s t a l l a t i o n des LCD .
l c d _ a l p h a _ i n i t (LCD_ALPHA_DISP_ON_BLINK) ;
// Anzeige e i n e s Begrü ß u n g s t e x t e s auf dem Display .
l c d _ a l p h a _ w r i t e _ s t r i n g ( " Waiting f o r t h e message " ) ;
// Cursor an den Beginn der zweiten Reihe s e t z e n .
l c d _ a l p h a _ g o t o _ x y ( 0 , row ) ;
// " Hallo " zum Computer sagen .
u s a r t _ s e n d _ s t r i n g ( port , " Hello , w r i t e something ! \ r\n " ) ;
// E n d l o s s c h l e i f e
while ( t r u e )
225
6 Praktische Beispiele
{
// Zeichen aus der s e r i e l l e n S c h n i t t s t e l l e l e s e n .
i f ( u s a r t _ t r y _ r e a d _ c h a r ( port , &c ) )
{
// B e f a s s e n wir uns mit dem Zeichen zur Änderung der Reihe ?
i f ( c = ’ \r ’ )
{
// Änderung der Reihe .
row = 1 − row ;
// Vorherige Na ch ri ch t aus der Reihe l ö schen .
l c d _ a l p h a _ c l e a r _ l i n e ( row ) ;
}
else
{
// Ausgabe des Zeichens auf dem Display .
lcd_alpha_write_char ( c ) ;
}
}
}
}
Abbildung 6.38: Das Fenster des HyperTerminal
Windows XP OS beinhaltet das Programm HyperTerminal. Dieses Programm kann über das Start Menü geöffnet werden, indem Zubehör → Kommunikation → HyperTerminal ausgewählt wird. Wählen Sie zur Konfiguration 9600 bps aus, 1 Startbit und 1 Stopbit ohne Paritäts- und Datenstromkontrolle. Wenn HyperTerminal
geöffnet ist, während der Mikrocontroller startet, erscheint ein Begrüßungstext auf dem Display. Die über das
Fenster eingegebenen Buchstaben werden auf dem alphanumerischen LCD dargestellt. Durch Betätigung der
Enter Taste wird die Reihe auf dem LCD gewechselt.
226
6.7 Datenschnittstellen
6.7.2
ZigBee
— MISSING PAGE —— MISSING PAGE —
6.7.3
Aufgabe
Ziel ist es ein Programm zu schreiben, welches die folgenden Aufgaben erfüllt.
Aufwärmübung
Es wird eine Nummer an den Computer gesendet, diejede Sekunde größer wird. Die Nummer muss
in Textform sein und mit einem Reihenänderungszeichen enden (\n).
Für Anfänger
1. Es wird auf die Befehle (in Buchstaben), welche über die RS-232 Schnittstelle von einem Computer
gesendet werden, gewartet. Der Befehl „R“lässt die grüne LED leuchten, „K“die gelbe und „P“die
rote.
„R“schaltet alle LEDs aus.
1. Wenn ein Schalter betätigt wird, wird der Name dieses Schalters (S1, S2, S3) am Computer über dieRS232 Schnittstelle empfangen.
Für Fortgeschrittene
1. Kommunikation zwischen zwei RS-232 Controllern. Wird ein Schalter betätigt, sendet der eine Controller dem Anderen die Nummer des Schalters. Wenn die Nummer empfangen wurde, wird der Status
der zugehörigen LED verändert.’1’ → grün, ’2’ → gelb, ’3’ → rot. Benötigt 2 Controller, die Software
ist jedoch für beide identisch.
2. Erstellen Sie ein „Teletype“Gerät, welches Änderungen von Textnachrichten zwischen zwei Controllern über die RS-232 Schnittstelle ermöglicht. Nutzen Sie das LCD um die Nachrichten anzuzeigen. In
der ersten Reihe muss die eingegebene Nachricht zu sehen sein, in der zweiten Reiche die zuletzt empfangene Nachricht. Um eine Nachricht einzugeben können Potentiometer und / oder Schalter genutzt
werden.
227
6 Praktische Beispiele
6.7.4
Fragen
1. Beschreiben Sie das UART Paket.
2. Was ist die Baud-Rate?
3. Was ist der Unterschied zwischen Voll/Halb-Duplex?
4. Finden Sie mindestens 5 Sensoren, welche die serielle Schnittstelle nutzen.
5. Nennen Sie den Unterschied zwischen UART und USART Schnittstelle. Welche ist schneller?
6. Wie funktioniert die SPI Schnittstelle?
7. Nennen Sie Schnittstellen, die das Anschließen von mind. 100 Geräten an einen einzigen Bus erlauben.
8. Nennen Sie verschiedene Archtiekturen und erklären Sie ihre Unterschiede.
9. Auf welchem Spannungslevel finden RS-232 und UART Verbindungen statt?
10. Wie lange benötigt, es 1MiB bei einer Baud-Rate von 9600 dps , mit 8 Daten-Bits, einem Stop-Bit und
ohne Paritätskontrolle, zu senden?
228
7
Beispielprojekt
Das Beispielprojekt in diesem Kapitel enthält eine Anleitung zur Vorbereitung einer Projektdokumentation
und erläutert, welche Themen behandelt werden sollten sowie was zu den einzelnen Themen geschrieben
werden sollte. Es ist sehr hilfreich, eine Dokumentation eines typischen Projekts als Beispiel zu nehmen. Leider
ist die gesamte Projektdokumentation aufgrund des Bildmaterials zu umfangreich und würde den Rahmen
dieses Buches sprengen. Dennoch enthält das Beispielprojekt alle wichtigen Aspekte. So werden beispielsweise
nur wichtige Details einer Zeichnung oder nur ein PCB eines elektronischen Plans gezeigt. Dennoch sollte eine
tatsächliche Dokumentation Zeichnungen und Pläne für alle erstellten Details enthalten. Das Beispielprojekt
soll auch die Lehrer dahin gehend unterstützen, den Schülern zu verdeutlichen, was am Ende eines Projektes
erwartet wird und wie die Ergebnisse zu präsentieren sind. Je nach Situation und Lehrniveau können jedoch
einige Punkte der Dokumentation ausgelassen werden.
7.1
Bericht
Um ein einfaches mechatronisches Gerät herzustellen, muss man die Konstruktion und Mechanik, Elektronik
und Sensoren, Kontrollsystem und Software für das Gerät entwickeln.Am Ende des Projekts soll ein Bericht
erstellt werden. Es ist eine Dokumentation welche mindesten die folgenden Punkte enthalten soll:
Titelseite
7 Beispielprojekt
Zusammenfassung
Zusammenfassung (in Fremdsprache / Englisch)
Inhaltsverzeichnis
1. Ursprüngliche Aufgabe
2. Systemvoraussetzungen und Einschränkungen
3. Modell des Systems
Struktur und Funktionalität eines Systems als Blockdiagramm. Zusätzlich können eine Anleitung zur Nutzung des Anwendungsfalldiagramms, ein Interfacediagramm etc. verfasst werden.
4. Designlösungen
Mindestens drei verschiedene Konzeptlösungen für diese Aufgabe. Geeignet sind handgezeichnete Diagramme, Zeichnungen etc. Dokumentation mit Kommentaren.
5. Mechanik
Am Besten ein 3D Modell mit Zeichnungen von wichtigen Verbindungen und Bauanweisungen.
Falls eine Verbindung spezielle Anweisungen benötigt, dann auch Bauanleitungen und Zeichnungen hinzufügen. Wenn möglich eine Animation der Funktionen des Systems beifügen.
6. Elektronik
Darstellung aller genutzten Module in einem Blockdiagramm (Controller, Motorenantrieb, Motor, Encoder etc. und ihre Verbindungen). Falls möglich geben Sie ein Layout für den Aufbau
der Leiterplatte an.
7. Control System
Kontrollalgorhytmus und Quellcode. Falls selbst-erstellte Funktionen genutzt werden, eine Tabelle der Funktionen und Parameter, usw. angeben.
8. Gebrauchsfertige Lösung
Beschreibung und Bilder
9. Wirtschaftliche Rechnung
Auflistung von Komponenten wie Kosten, geschätzte, benötigte Zeit etc.
10. Projektmanagement
Zeitplan des Projekts, die Ressourcenbelegung, die Arbeitsteilung , Mitwirkung der Gruppe,
Termine für Meetings etc.
11. Zusammenfassung und Fazit
Was war schwer, was würden Sie anders machen, was wurde mit dem Projekt erreicht etc. Die
Zusammenfassung umfasst eine kleine Beschreibung der Arbeit, aufgetretene Probleme werden
genannt und das Ergebnis der Arbeit wird dargestellt. Darüber hinaus ist es sinnvoll, die eigene
Meinung bezüglich der Notwendigkeit des Projekts hinzuzufügen. Außerdem bezüglich des
Nutzens für die Projektmitgliedern bringt, dazu was in Zukunft anders gemacht werden sollte,
was man gelernt hat und was den Leitern und Organisatoren des Projekts vorschlagen werden
sollte.
230
7.2 Mobile Roboterplattform
Genutzte Quellen und Materialien
Anhang
Das folgende Beispielprojekt zeigt, wie eine Dokumentation und ein Bericht eines Projekts erstellt werden.
Aufgrund des begrenzten Umfangs dieses Buches kann der Bericht leider nur in gekürzter Fassung dargestellt
werden, er stellt aber immer noch die verschiedenen Aspekte einer Dokumentation dar.
7.2
Mobile Roboterplattform
Der mobile Roboter ist eine der populärsten Robotorkonstruktionen. Sehr verbreitet sind Sumoroboter, Sportroboter (Fußball, Volleyball usw.), Roboter die Rettungsoperationen simulieren (Feuerbekämpfung, Personenoder Objektsuche) und viele andere. Es gibt auf der ganzen Welt und in Estland diverse Wettbewerbe für diese Art Roboter, es wurden sogar Standardklassen entwickelt (z. B. Sumoroboter). Alle diese Robotor nutzen
eine mobile Plattform, welche zwar zum Teil unterschiedlich konstruiert ist oder andere Eigenschaften besitzt, deren Grundfunktion aber stets die gleiche ist. Diese umfasst die Steuerung von Motoren und einfacher
Navigation, inklusive dem Ausweichen vor Objekten und der Bewegung zu einem festgelegten Punkt. Gewöhnlich wird der Hauptfunktion eine spezifische Funktion hinzugefügt, die auf die Voraussetzungen und
Möglichkeiten des Projekts abgestimmt ist.
Nachfolgend werden eine Dokumentation eines typischen Projekts für eine mobile Roboterplattform sowie
die verschiedenen Projektphasen dargestellt.
Ursprüngliche Aufgabe
Planen und konstruieren Sie eine multifunktionale mobile Roboterplattform mit einfacher Navigationsfunktion unter der Verwendung von HomeLab Komponenten. Die Roboterplattform muss eine einfach zu ändernde
operationale Funktion besitzen, wenn sie mit verschiedenen Gadgets ausgerüstet wird:
Manipulator
Radar
Kamera
Der Roboter muss sich in geschlossenen Räumen auf flachen Böden bewegen können.
Voraussetzungen
Maximale Abmessung: 20 cm x 20 cm x 20 cm
maximales Gewicht: 2 kg
Höchstgeschwindigkeit: 0,2 m/s
231
7 Beispielprojekt
volle Selbstständigkeit
Einschränkung
Muss überwiegend aus HomeLab Komponenten bestehen
Kostengrenze: 10000 EEK (˜630 e)
Grundlegendes Modell des Systems
Das grundlegende Modell des System wird mit einem Blockdiagramm dargestellt. Es beschreibt die Struktur,
das Verhalten und andere wichtige Aspekte des Systems. Als Beispiel ist nachfolgend das hierarchische Modell
des System abgebildet.
Abbildung 7.1: Model der Systemstruktur
Designlösungen
Für diese Aufgabe hat das Team eine Brainstorming-Methode verwendet und drei vom Konzept völlig unterschiedliche Vorschläge erstellt. Es wurde eine Evaluationsmatrix erstellt und so die optimale Konstruktion
gefunden. Der größte Unterschied der drei Lösungen liegt im Bewegungsschema.
232
7.2 Mobile Roboterplattform
Abbildung 7.2: Designlösungen
Vereinfachte Evaluationsmatrix:
Funktion/Lösung
I
II
III
Kosten
Komplexität im Bau
Beweglichkeit
Permittivität
Anwendbarkeit in Homelab
Gewicht
Total (mit Gewichtungsfaktor)
3
2
4
5
5
5
19
4
4
8
8
4
6
27
6
7
8
2
5
7
28
Gewichtungsfaktor
0,8
0,7
0,5
0,3
0,9
0,8
Die Evaluationsskala umfasst Werte von 1 bis 10 und der Gewichtungsfaktor liegt zwischen 0 und 1. Der
Gewichtungsfaktor wird nach den Anforderungen und Einschränkungen des Systems ausgewählt. So ist beispielsweise Lösung 2 beweglicher auf unebenen Boden, dieses war jedoch nicht in der ursprünglichen Aufgabe
gefordert, daher ist der Gewichtungsfaktor niedrig.
Basierend auf der Auswertung, ist die optimale Lösung für die gestellte Aufgabe eine Plattform auf zwei
Rädern mit zwei separaten Motoren. Die weitere Arbeit besteht in der Entwicklung der gewählten Lösung in
ein reales System.
Mechanik
Die Mechanik wurde so einfach wie möglich gehalten, wobei dem Prinzip der Modularität gefolgt wurde.
Front- und Heckstossstange sind identische Module. Die Elektronik beseteht aus drei Modulen, welche übereinander platziert werden und mit einfachen Flachbandkabeln verbunden werden. Darüber hinaus wird so
sicher gestellt, dass die Module relativ einfach ausgewechselt werden können.Die Motoren entstammen dem
HomeLab kit: Motoren mit einem integrierten Drehzahlminderer und Coder, welche direkt mit den Antrieb
des Motors verbunden sind. Es wurden Modellflugzeugräder benutzt, da diese sehr leicht und robust sind.
233
7 Beispielprojekt
Um die Konstruktion zu vereinfachen sind Boden und Dachplatte identisch. Die Platten haben Löcher, damit
unterschiedliche Geräte an der Dachplatte angeschlossen werden können. Neben der Elektronik passt auch
eine Batterie problemlos zwischen den Platten.
Abbildung 7.3: Erstes 3D-Modell des Roboters und Anordnung seiner Komponenten.
Die Stoßstangen des Roboters werden separat geplant und sind mit Berührungs- und Linienfolgesensoren
ausgestattet. Die Stoßstange wird aus PCBs hergestellt und verfügt dadurch über Elektrizität. Die Linienfolgesensoren werden direkt auf die Stoßstange der Bodenplatte gelötet. Berührungssensoren (Mikroschalter)
werden zwischen den Stoßstangenplatten platziert und mit einem Gummistück an der Front geschützt. Das
Gummistück absorbiert den Aufprall und ermöglicht gleichzeitig zu identifizieren, woher der Aufprall kam.
234
7.2 Mobile Roboterplattform
Abbildung 7.4: Zeichnung der Stoßstangenplatte
235
7 Beispielprojekt
Elektronik
Die Elektronik des Systems ist in einem Prinzipsschema und Schaltplan mit PCB-Aufbau-Plan beschrieben.
Abbildung 7.5: Blockdiagramm der elektronischen Komponenten
Als Beispiel werden die Schaltpläne der Linienfolgesensoren sowie die dazugehörigen PCB-Aufbau Pläne der
Stoßstange des Roboters gezeigt.
236
7.2 Mobile Roboterplattform
Abbildung 7.6: Schaltplan der Stoßstangensensoren.
Abbildung 7.7: Aufbauplan der Stoßstange.
237
7 Beispielprojekt
Kontrollsystem
Das Kontrollsystem des Roboters, leitet sich von einem Verhaltensmodell ab und ist an Funktionalität, Anforderungen und Einschränkungen der ursprünglichen Aufgabe angepasst.Aus dem Verhaltensmodell des Systems wird ein spezifisches Kontrollprogramm entworfen, welches wiederum die Basis für den Softwareprogrammcode ist.Alle drei Ebenen (Verhaltensmodell-Algorihtmus-Quellcode) müssen miteinander vereinbar
sein.
Algorithmus Der Algorithmus beschreibt die Kontrolllogik des System und wird als Blockdiagramm
dargestellt. Einige Elemente und Beschreibungen der Verhältnisse genügen, um einen einfachen Algorithmus
zu erstellen. Wenn der Algorithmus für den Roboter richtig zusammengestellt ist, kann daraus sehr einfach
ein Kontrollprogramm erstellt werden.Grundsätzlich werden zwei verschiedene Objekte in einem Algorithmus genutzt: ein Rechteck mit runden Ecken, zur Darstellung einer Aktivität sowie ein kleiner Diamant zur
Kontrolle einer Bedingung, gefolgt von einem Start weiterer Aktivitäten, je nach Resultat der Kontrolle.
Bedeutung der im Algorithmus verwendeten Symbole:
Symbol
M1
Bedeutung
linker Motor
0
Stop
M2
rechter Motor
stop
F
erster mittlerer Berührungssensor
erster rechter Berührungssensor
erster linker Berührungssensor
Bezug
kein Signal
1
rotiert im Uhrzeigersinn
rotiert im Uhrzeigersinn
Signal
kein signal
Signal
kein signal
Signal
FR
FL
d
238
-1
rotiert gegen
Uhrzeigersinn
rotiert gegen
Uhrzeigersinn
den
den
7.2 Mobile Roboterplattform
Abbildung 7.8: Statusdiagramm eines Algorithmus
Quellcode Einfache Navigation
# include <homelab/module/motors . h>
# include <homelab/pin . h>
# include <homelab/delay . h>
// D e f i n i e r e n der S to ß s t a n g e n p i n s
pin f r o n t
= PIN (C , 0 ) ;
pin f r o n t l e f t = PIN (C , 1 ) ;
pin f r o n t r i g h t = PIN (C , 2 ) ;
//
// Hauptprogramm
//
i n t main ( void )
239
7 Beispielprojekt
{
// S t a r t e n von Motor 0 und 1
dcmotor_init ( 0 ) ;
dcmotor_init ( 1 ) ;
// S e n s o r p i n s a l s I n p u t s
pin_setup_input_with_pullup ( f r o n t ) ;
pin_setup_input_with_pullup ( f r o n t l e f t ) ;
pin_setup_input_with_pullup ( f r o n t r i g h t ) ;
// E n d l o s s c h l e i f e
while ( t r u e )
{
// M o t o r s t a r t im U h r z e i g e r s i n n
dcmotor_drive ( 0 , 1 ) ;
dcmotor_drive ( 1 , 1 ) ;
// K o n t r o l l e des m i t t l e r e n S e n s o r s i g n a l s
i f ( pin_get_value ( front ) )
{
// Umkehr der Motoren
dcmotor_drive ( 0 , − 1) ;
dcmotor_drive ( 1 , − 1) ;
// Pause 1 Sekunde
sw_delay_ms ( 1 0 0 0 ) ;
// S t a r t des l i n k e n Motors im U h r z e i g e r s i n n
dcmotor_drive ( 0 , 1 ) ;
// Pause 2 Sekunden
sw_delay_ms ( 2 0 0 0 ) ;
}
// K o n t r o l l e des l i n k e n S e n s o r s i g n a l s
else i f ( pin_get_value ( f r o n t l e f t ) )
{
// Umkehr des r e c h t e n Motors
dcmotor_drive ( 1 , − 1) ;
// Pause 2 Sekunden
sw_delay_ms ( 2 0 0 0 ) ;
}
// K o n t r o l l e des r e c h t e n S e n s o r s i g n a l s
240
7.2 Mobile Roboterplattform
else i f ( pin_get_value ( f r o n t r i g h t ) )
{
// Umkehr des l i n k e n Motors
dcmotor_drive ( 0 , − 1) ;
// Pause 2 Sekunden
sw_delay_ms ( 2 0 0 0 ) ;
}
}
}
Gebrauchsfertige Lösung
Die in diesem Projekt gebaute Roboterplattform besteht zum größten Teil aus Plastik, außer der Motorbefestigung, welche aus Aluminium hergestellt ist. Die elektrischen Module wurden auf einander platziert, die
Batterie liegt lose zwischen den Platten. Die Stoßstangen wurden aus PCB gebaut und schwarz gestrichen.
Die Dachplatte des Roboters ist flach und erlaubt das Anbringen verschiedener Geräten. Es wurde ein einfaches Radar installiert, welches aus einem kleinen RC Servomotor und einem Infrarotsensor besteht.Als zweite
Lösung wurde ein intelligentes Kameramodul installiert, welches beim Lösen visueller Probleme hilft. Beide
Lösungen werden auf den folgenden Bildern vorgestellt. Ein einfacher Manipulator wurde als drittes Gerät
getestet, dessen Komponenten mit standard Servomotoren sowie einer seriellen Schnittstelle zur Kontrolle des
Antriebs betrieben werden.
241
7 Beispielprojekt
Abbildung 7.9: Roboter mit Infrarotradar.
242
7.2 Mobile Roboterplattform
Abbildung 7.10: Roboter mit intelligentem Kameramodul (CMUcam3).
Kostenkalkulation
Die Kostenkalkulation enthält die Kosten für die Komponenten und die Produktion des Roboters
Tabelle der Komponentenkosten
243
7 Beispielprojekt
Komponent
Motor
Mikrocontroller
Motorenantriebsplatine
Power plate
Linienfolgesensoren
Berührungssensoren
Gehäuseblech
PCB Rohteil
Motorenbefestigungsprofil
Reifen
Batterie
Kabel
Muttern
Weiteres Zubehör
Total
Marke
M LE149.6.43
uC ATmega128
Actuator Board
v1.2
TP
LFS QRD1114
TS Microswitch
ABS
Al-L
60/10 mm
NI-MH 9,6 V
Anzahl
2
1
1
Preis
500.900.700.-
Kosten
1000.900.700.-
1
8
8
4
2
2
2
1
10
1
1
500.30.25.50.50.10.30.350.20.50.100.-
500.240.200.200.100.20.60.350.200.50.100.4620.-
Preis
300.500.250.300.300.250.-
Kosten
300.250.125.300.1500.750.3225.-
Kosten in EEK.
Geschätzte Arbeits- und Produktionskosten für ein einzelnes Modell.
Arbeit
Fräsen der Bauteile
Fräsen der PCBs (Stoßstangen)
Bau des Roboters
Bau der Stoßstangen (löten der Komponenten)
Programmierarbeit
Erstellen der Dokumentation
Total
Zeit (h)
1
0,5
0,5
1
5
3
11
Vorraussichtliche Kosten des Roboters 7845.Die Kostenkalkulation des Roboters basiert auf geschätzten, da es sich um ein Lehrprojekt handelt und aus
diesem Grund mehr Zeit für die Arbeit und Konstruktion verwendet wird und keine direkte Bezahlung erfolgt.
Daher spiegelt der berechnete Arbeitsaufwand keine reale Situationen wider.
Projektmanagement
Das mechatronische System (Roboter) ist in Gruppenarbeit mit straffem Zeitplan und Budget entstanden, und
besitzt damit die wichtigsten Eigenschaften eines Projektes. Die Schlüsselaktivitäten des Projekts waren: Erstellung des Zeitplans, Planung und Management der Gruppenarbeit, Überwachung des Budgets sowie Besorgung des Materials, Weitergabe aktueller Berichte an den Leiter, Präsentation sowie Dokumentation des
Ergebnisses. Der Projekbericht enthält Angaben zu den Arbeitsgruppen, Terminen von Meetings, dem Projektplan (am besten in einem Gantt Diagramm), der Ressourcenverteilung (inkl. Personalverteilung) sowie zum
geplanten und aktuellen Budget. Nachfolgend wird ein einfacher Projektplan als Gantt Diagramm dargestellt.
244
7.2 Mobile Roboterplattform
Abbildung 7.11: Projektplan
Fazit
Die Kostenrechnung hat gezeigt, dass die Produktionkosten des Roboters sehr hoch sind, besonders wenn man
nur mit einem Exemplar rechnet. Die Kosten blieben jedoch im anfänglich gesetzten Rahmen. Die Prouktionskosten könnten durch Optimierung des Materials und der Komponeten sowie durch gleichzeitige Fertigung
mehrerer Roboter wesentlich reduziert werden.Während des Projekts ist deutlich geworden, wie ein mechatronisches System geplant, gebaut und getestet wird.
Am Ende der Arbeit ist eines klar geworden: Damit der Roboter richtig funktioniert, sollte deutlich mehr Zeit
zum Testen eingeplant werden, insbesondere für Softwaretests.Unterschiedliche Module funktionieren nicht
immer einwandfrei zusammen, auch wenn dieses in einzelnen Experimenten klappt. Dadurch wird deutlich,
dass die Integration von Modulen in ein System eine echte Herausforderung darstellt, und hierfür mehr Zeit
und Ressourcen eingeplant werden sollten.
Abschließend hoffen wir, dass das Projekt sehr interessant und lehrreich war und einen Einblick in das Design
und die Konstruktion von integrierten Systemen geben konnte.
Genutzte Quellen und Materialien
1. Allgemeines Benutzerhandbuch des HomeLab http://home.roboticlab.eu
2. Datenblatt des ATmega128
3. Dudziak, R., Köhn, C., Sell, R., Integrated Systems & Design, TUT Press, 2008
4. Friendenthal, S., Moore, A., Steiner, A., A Practical Guide to SysML, Elsevier, 2008
5. Perens, A. Project Management, Külim, 1999
6. Bräunl, T. Embedded Robotics, Springer-Verlag, 2003
245
8
Ausblick
Wenn Sie am Ende dieses Buches angelangt sind, haben Sie einige Kenntnisse sowie praktische Fähigkeiten
in Bezug auf das Programmieren von Mikrocontrollern und den Umgang mit diversen Geräten erlangt, selbst
wenn Sie nicht alle Übungsbeispiele absolviert haben. Wir hoffen, dass dieses Buch Sie bei der Bewältigung von
Problemen sowie der Erlangung theoretischen Hintergrundwissens unterstützen konnte. Der nächste Schritt
wäre nun, eigene intelligente Geräte zu entwickeln, die Ihren Interessen oder Bedürfnissen angepasst sind.
Schüler und Studenten können sich darüber hinaus nach Robotikwettbewerben umsehen. Auf jeden Fall können Sie das erworbene Wissen dazu nutzen, Ihren Alltag einfacher und mit mehr Freude zu gestalten. Sie
können einfache Sicherheitssysteme für Ihr Ferienhaus oder Ihre Garage entwickeln, die mit verschiedenen
Sensoren arbeiten, um Einbrecher aufzuspüren und den Eigentümer zu warnen. Bei Problemen, fragen Sie um
Hilfe. Dieses Buch wird sich ständig in seiner elektronischen Form weiter entwickeln. Es ist Teil eines RobotikStudienkonzepts, welches die Pflege der Webseite einschließt. Zusätzlich zum online verfügbaren Material
existiert ein Benutzerforum, in welchem sie Antworten auf Ihre Probleme finden können. Die elektronische
Version enthält zusätzliche Kapitel zu den Themen Bluetooth, Ethernet, RFID, Machine Vision für Fortgeschrittene etc.
Für Lehrer: Registrieren Sie sich auf unserer Homepage und teilen Sie uns kurz mit, dass Sie Lehrer sind.
Daraufhin werden Sie Zugriff auf die Lösungen der Übungsaufgaben sowie Antworten auf die Fragen am
Ende jedes Übungsabschnittes erhalten.
8 Ausblick
Homepage:
http://www.roboticlab.eu
248
Was this manual useful for you? yes no
Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Download PDF

advertisement