Anwendung des Raspberry Pi in Forschung und Lehre

Transcription

Anwendung des Raspberry Pi in Forschung und Lehre
Anwendung des Raspberry Pi in Forschung und Lehre
Bachelor-Thesis
Nico Maas
Erstgutachter: Prof. Dr. Helmut G. Folz
Einreichung: 30. September 2014
Selbständigkeitserklärung
Ich versichere, dass ich die vorliegende Arbeit (bei einer Gruppenarbeit: den entsprechend gekennzeichneten Anteil der Arbeit) selbständig verfasst und keine anderen als
die angegebenen Quellen und Hilfsmittel benutzt habe.
Ich erkläre hiermit weiterhin, dass die vorgelegte Arbeit zuvor weder von mir, noch
von einer anderen Person an dieser oder einer anderen Hochschule eingereicht wurde.
Darüber hinaus ist mir bekannt, dass die Unrichtigkeit dieser Erklärung eine Benotung der Arbeit mit der Note „nicht ausreichend“zur Folge hat und einen Ausschluss
von der Erbringung weiterer Prüfungsleistungen zur Folge haben kann.
Saarbrücken, 30. September 2014
Nico Maas
iii
Zusammenfassung
Linux Einplatinen Computer sind seit dem Erscheinen des Raspberry Pi in 2012 immer
präsenter in der IT und ermöglichen die schnelle und unkomplizierte Verbindung und
Steuerung realer Hardware mittels modernen Hochsprachen wie C, Python oder Java. Die nachfolgende Arbeit soll an konkreten Beispielen versuchen, die Möglichkeiten
des damit eröffneten „Physical Computing“, zur leichteren Darstellung komplexerer
Lehrinhalte zu verwenden und damit den Lernerfolg nachhaltig zu steigern.
v
Any sufficiently advanced technology
is indistinguishable from magic.
— Arthur C. Clarke [4]
Danksagung
Für die geleistete Hilfe möchte ich mich in aller Form bei meinem Betreuer, Prof. Dr.
Helmut G. Folz, dem Labor der Elektrotechnik, namentlich Dipl.-Ing. Thomas Bertel,
sowie Prof. Dr. Peter Sturm, dem Team der PiAndMore und meiner Familie bedanken.
vii
Inhaltsverzeichnis
Inhaltsverzeichnis
1
Einleitung
2
Plattform Evaluation
2.1 Raspberry Pi und BeagleBone Black .
2.1.1 Raspberry Pi Modell B+ . . . .
2.1.2 BeagleBone Black Revision C .
2.1.3 Vergleich . . . . . . . . . . . . .
2.2 Raspberry Pi Modelle . . . . . . . . . .
2.2.1 Unterschiede Modell A und B .
2.2.2 Modell B pre 2.0 . . . . . . . . .
2.2.3 Modell A/B 2.0 . . . . . . . . .
2.2.4 Compute Module . . . . . . . .
2.2.5 Modell A+/B+ . . . . . . . . .
3
ix
1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
3
4
5
7
7
7
7
7
8
Grundlagen und Installation
3.1 Peripherie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.1 SD Karte . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.2 Netzteil mit Micro USB Anschluss . . . . . . . . . . . . . .
3.1.3 Netzwerkkabel . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.4 HDMI auf DVI Adapterkabel / Display mit DVI Eingang
3.1.5 Weitere Komponenten . . . . . . . . . . . . . . . . . . . . .
3.2 Anschluss des Raspberry Pi . . . . . . . . . . . . . . . . . . . . . .
3.3 Raspbian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4 Installation mittels Image . . . . . . . . . . . . . . . . . . . . . . .
3.4.1 Image downloaden . . . . . . . . . . . . . . . . . . . . . . .
3.4.2 Formatieren . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.3 Image kopieren . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.4 Backup und Wiederherstellung . . . . . . . . . . . . . . . .
3.5 Installation mittels noobs . . . . . . . . . . . . . . . . . . . . . . . .
3.5.1 noobs downloaden . . . . . . . . . . . . . . . . . . . . . . .
3.5.2 Formatieren . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5.3 noobs kopieren . . . . . . . . . . . . . . . . . . . . . . . . .
3.5.4 Raspbian mit noobs installieren . . . . . . . . . . . . . . . .
3.5.5 Vorteile von noobs . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9
9
9
10
10
10
11
11
11
11
12
12
14
14
15
15
15
16
16
16
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
ix
4
5
6
x
Konfiguration von Raspbian
4.1 Erster Boot . . . . . . . . . . . . . . . . . . . . .
4.1.1 raspi-config . . . . . . . . . . . . . . . .
4.2 WLAN Zugriff / eduroam . . . . . . . . . . . .
4.3 Updates . . . . . . . . . . . . . . . . . . . . . .
4.3.1 rpi-update . . . . . . . . . . . . . . . . .
4.3.2 apt-get . . . . . . . . . . . . . . . . . . .
4.4 Einrichtung Hardware . . . . . . . . . . . . . .
4.4.1 Vorbereitung des I²C / SPI Bus . . . . .
4.4.2 Vorbereitung der seriellen Schnittstelle
4.5 Einrichtung Software . . . . . . . . . . . . . . .
4.5.1 Installation von wiringpi2 . . . . . . . .
4.5.2 Installation von wiringpi2-python . . .
4.5.3 Test des SPI Bus (Optional) . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
19
19
19
22
23
23
24
25
25
26
27
27
28
29
GPIO Schnittstelle
5.1 Aufbau . . . . . . . . . . . . . . . . . . . . . . .
5.2 Sicherheitshinweise . . . . . . . . . . . . . . . .
5.2.1 Logik Level . . . . . . . . . . . . . . . .
5.2.2 Sicherungen . . . . . . . . . . . . . . . .
5.2.3 Belastbarkeit der Pins / 3,3 Volt Schiene
5.2.4 Belastbarkeit der 5 Volt Schiene . . . . .
5.2.5 Zusammenfassung . . . . . . . . . . . .
5.3 GPIO . . . . . . . . . . . . . . . . . . . . . . . .
5.3.1 GPIO . . . . . . . . . . . . . . . . . . . .
5.3.2 PWM . . . . . . . . . . . . . . . . . . . .
5.3.3 I2C . . . . . . . . . . . . . . . . . . . . .
5.3.4 I2S . . . . . . . . . . . . . . . . . . . . .
5.3.5 SPI . . . . . . . . . . . . . . . . . . . . .
5.3.6 Serial . . . . . . . . . . . . . . . . . . . .
5.4 Das Erweiterungsboard . . . . . . . . . . . . .
5.4.1 Design . . . . . . . . . . . . . . . . . . .
5.4.2 Routing . . . . . . . . . . . . . . . . . .
5.4.3 Testprogramm . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
31
31
32
32
32
32
32
33
33
33
34
35
36
36
37
38
38
38
40
Bash Programmierung
6.1 Grundlagen . . . . . . . . . . . . . . . . . . . . .
6.1.1 Simon . . . . . . . . . . . . . . . . . . . .
6.1.2 Ablaufdiagramm . . . . . . . . . . . . . .
6.2 Programmierung . . . . . . . . . . . . . . . . . .
6.2.1 Erweiterungsboard und Hilfsfunktionen
6.2.2 LED Ausgabe . . . . . . . . . . . . . . . .
6.2.3 Switch Eingabe . . . . . . . . . . . . . . .
6.3 Abschluss . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
43
43
43
44
44
45
46
46
47
7
8
9
Python Programmierung
7.1 Arbeiten auf dem Raspberry Pi . . . . . . . . . . . . .
7.1.1 Python 2 / Python 3 . . . . . . . . . . . . . . .
7.1.2 Programmierung mittels IDLE . . . . . . . . .
7.1.3 Programmierung mittels CLI . . . . . . . . . .
7.2 Grundlagen der Python Programmierung . . . . . . .
7.2.1 Ausführung . . . . . . . . . . . . . . . . . . . .
7.2.2 Variablen . . . . . . . . . . . . . . . . . . . . . .
7.2.3 Operatoren . . . . . . . . . . . . . . . . . . . .
7.2.4 Vergleiche und Schleifen . . . . . . . . . . . . .
7.2.5 Funktionen . . . . . . . . . . . . . . . . . . . .
7.2.6 Bibliotheken . . . . . . . . . . . . . . . . . . . .
7.3 Verwendung der GPIO mittels Python . . . . . . . . .
7.3.1 Digitale Ausgabe: LEDs . . . . . . . . . . . . .
7.3.2 Übungsaufgabe zur digitalen Ausgabe . . . .
7.3.3 Digitale Eingabe: Schalter . . . . . . . . . . . .
7.3.4 Übungsaufgabe zur digitalen Eingabe . . . . .
7.3.5 Abschlussprojekt GPIO: Binärzähler . . . . . .
7.4 Verwendung des I2C Bus mittels Python . . . . . . . .
7.4.1 Adressierung . . . . . . . . . . . . . . . . . . .
7.4.2 Register des Sensors . . . . . . . . . . . . . . .
7.4.3 Interpretation des Temperaturwertes . . . . .
7.4.4 Übungsaufgabe zur Verwendung des I2C Bus
7.5 Verwendung des SPI Bus mittels Python . . . . . . . .
7.5.1 Adressierung . . . . . . . . . . . . . . . . . . .
7.5.2 Kommunikation . . . . . . . . . . . . . . . . .
7.5.3 Übungsaufgabe zur Verwendung des SPI Bus
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
49
49
49
49
50
50
50
50
50
53
54
56
57
57
58
58
58
59
60
60
61
62
62
63
63
64
66
Mathematica
8.1 Grundlagen . . . . . . . . . . . . . . . .
8.2 Benutzung . . . . . . . . . . . . . . . . .
8.2.1 Beispiele Free-form input . . . .
8.2.2 Beispiele Wolfram Alpha query .
8.3 Verwendung mittels Erweiterungsboard
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
69
69
69
70
70
72
Fazit
9.1 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.2 Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
75
75
76
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Literatur
77
Abbildungsverzeichnis
79
Tabellenverzeichnis
80
xi
Listings
81
Abkürzungsverzeichnis
82
A Vorgefertigtes Raspbian Image
A.1 Übersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.2 Zusätzlich installierte Pakete . . . . . . . . . . . . . . . . . . . . . . . . .
85
85
85
B Raspberry Pi Hardware HTW
B.1 Übersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
87
C Erweiterungsboard
89
D Code Listings
D.1 boardTest.c . . . . .
D.2 gpio.sh . . . . . . .
D.3 demoLed.sh . . . .
D.4 demoSwitch.sh . .
D.5 simon.sh . . . . . .
D.6 uebungAusgabe.py
D.7 uebungEingabe.py
D.8 binaryCounter.py .
D.9 lm75b.py . . . . . .
D.10 uebungI2C.py . . .
D.11 mcp3002.py . . . .
D.12 mcp3002lib.py . . .
D.13 uebungSPI.py . . .
D.14 wpi.c . . . . . . . .
D.15 wpi.tm . . . . . . .
xii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
91
91
95
97
98
99
102
103
104
105
106
108
109
109
110
112
1 Einleitung
Mit dem Erscheinen des Raspberry Pi im Februar 2012 war zum ersten Mal ein kleiner, kostengünstiger und dennoch leistungsfähiger Linux Einplatinen Computer verfügbar. Der ursprünglich zur Fortbildung von Kindern, im IT Bereich gedachte Rechner, etablierte sich in kürzester Zeit im Umfeld von Universitäten, Industrie sowie im
Hobby und Freizeit Bereich. Andere Firmen entdeckten die potenziellen Möglichkeiten
des neuen Absatzmarktes und entwickelten konkurrierende Plattformen mit teils unterschiedlichen Zielsetzungen und Möglichkeiten. Dazu zählen der BeagleBone Black,
Intels Galileo, SECO / Aidilabs UDOO, Hardkernels Odroid sowie Adaptevas Parallella - um nur einige wenige zu nennen. All diese Plattformen haben gemeinsam, dass
sie dazu genutzt werden können, als Lehrplattform für den Bereich des sogenannten
„Physical Computing“ zu dienen. Beim Physical Computing ist die Software in der Lage durch eine spezielle Hardware Schnittstelle (General-purpose input/output (GPIO))
sowohl Eingaben aus der Umwelt zu empfangen, als auch selbst Ausgaben zu erzeugen. Dies könnte z.B. die Verwendung eines Schalters, Ultraschallsensors oder einer
Lichtschranke für die Eingabe, und einer LED, einem Display oder eines Motors für
die Ausgabe sein. Da durch verschiedene Frameworks und Libraries diese Schnittstellen nicht nur mittels spezieller Kommandos bedient werden können, sondern auch in
Standardsprachen wie z.B. Bash, C, Java oder Python verfügbar sind, ergibt sich damit
die Möglichkeit einer professionellen Entwicklung und die Integration dieser Einplatinen Computer in ganze Produkte und Automaten.
In der nachfolgenden Arbeit soll aufgezeigt werden, wie ein solcher Linux Einplatinen Computer im Bereich der Forschung und Lehre dazu genutzt werden kann, um
Studenten konkrete Lerninhalte leichter zu vermitteln. Dies beinhaltet die Evaluation
des geeigneten Produktes aus der Vielzahl der konkurrierenden Systeme, die korrekte
Installation und Konfiguration sowie die konkrete Nutzung in verschiedenen Projekten
mit Verknüpfung zu den Vorlesungen an der HTW Saar.
Um diese Umsetzung einfacher zu gestalten, wurden im Rahmen dieser Thesis eine eigene Erweiterungsplatine für den Raspberry Pi entworfen und gefertigt, wodurch
auch die Lehre im Bereich Hardware naher Anwendungen, wie z.B. dem Inter-Integrated
Circuit (I2C) oder Serial Peripheral Interface (SPI) Bus möglich wird.
Verwendung finden sollen die vorgestellten Aufgaben in einem breitgefächerten Spektrum an Vorlesungen: „Betriebssystem Einführung“ (Bash Programmierung), „Systemsicherheit und Management“ (Python Einführung), „Digitaltechnik“ (Python: 4-bit Zähler), „Rechnerarchitektur“ und „Mikroprozessortechnik“ (SPI und I2C), „Mathematik
1-3“, „Informatikgrundlagen“ und „Graphentheorie“ (Mathematica).
Obwohl bereits einige Vorlesungsbereiche damit aufgegriffen werden, sind die Möglichkeiten die dieser Einplatinen Computer bietet damit keinesfalls erschöpft und könn-
1
1 Einleitung
ten in Arbeiten anderer Studenten fortgeführt und ergänzt werden.
2
2 Plattform Evaluation
2.1 Raspberry Pi und BeagleBone Black
Wie bereits erwähnt gibt es neben dem Raspberry Pi noch zahlreiche weitere Konkurrenzprodukte welche ähnliches leisten. Der direkte Konkurrent allerdings ist das
von Texas Instruments vorgestellte BeagleBone Black. Nachfolgend werden die beiden
Plattformen mit ihren Vor- und Nachteilen verglichen und auf die besondere Eignung
im Bereich der Lehre untersucht.
2.1.1 Raspberry Pi Modell B+
Der Raspberry Pi ist ein Einplatinen Computer mit der ungefähren Grundfläche einer Kreditkarte, nutzt Linux als Betriebssystem und ist zum Preis von knapp 33 e erhältlich. Er verwendet ein Broadcom BCM2835 System on a chip (SoC), welches einen
700 MHz starken ARM1176JZFS (ARM11/ARMv6) Prozessor beinhaltet sowie die 24
GFlops starke Videocore IV Grafikeinheit und 512 MB Arbeitsspeicher. Trotz des geringen Preises verfügt der Raspberry Pi über 4 USB Anschlüsse, einen 100 MBit Netzwerkanschluss, einen Full HD fähigen HDMI Anschluss, sowie einen analogen Audio
und Cinch Video Ausgang (über ein Adapterkabel). Insgesamt stehen 40 GPIO Pins zur
Verfügung, welche neben generischen Ein- und Ausgängen auch als spezielle Schnittstellen wie Serial, I2C, Inter-Integrated Sound (I2S) und SPI genutzt werden können.
Eine Besonderheit bietet der Raspberry Pi mit den Camera Serial Interface (CSI) bzw.
Display Serial Interface (DSI): Diese Schnittstellen bieten direkten Anschluss einer speziellen Kamera beziehungsweise eines demnächst verfügbaren TFT Displays an die Videocore IV Grafikeinheit. Durch den Anschluss der eigens entwickelten Kamera können trotz der vergleichsweise geringen CPU Leistung Photos in 2592 x 1944 Pixel, respektive Video ins Full HD Auflösung (1920 x 1080 Pixel) aufgezeichnet und mit Filtern
versehen werden. Weiterhin kann die GPU auch in begrenztem Umfang zur Beschleunigung von eigenem Programmcode verwendet werden. Eine Micro SD Karte dient als
Massenspeicher und die Stromversorgung erfolgt mittels Micro USB Netzteil.
Als Betriebssystem kommt hauptsächlich Raspbian, eine für den ARMv6 optimierte
Version von Debian zum Einsatz. Weiterhin sind Versionen von Arch Linux (Arch), Fedora (Pidora), XBMC (XBian, OpenElec, Raspbmc), RiscOS, Android und zahlreichen
anderen Betriebssystemen zum Download verfügbar. Die Verwendung des Echtzeitbetriebssystems QNX ist allerdings wegen des fehlenden Board Support Packages nicht
möglich.
Die Entwicklung des Einplatinen Computers wurde von Eben Upton geleitet. Die
Idee zu diesem Projekt kam ihm während seiner Zeit als Director of Studies in Compu-
3
2 Plattform Evaluation
ter Science am St John’s College (Universität Cambridge). Er stellte mit seinen Kollegen
fest, dass die Anzahl der Studienbewerber im Bereich der Informatik seit dem Beginn
des Jahrtausend stetig rückgängig waren. Die heutigen Jugendlichen und Kinder würden sich zwar immer intensiver mit IT befassen, diese aber nur noch passiv Konsumieren anstatt aktiv damit zu arbeiten. Er sah die Begründung darin, dass eine günstige,
„hackbare“ Plattform fehlen würde, sowie er sie selbst in seiner Kindheit in Form des
BBC Micro erlebt hatte. [2]
Der erste Entwurf des Raspberry Pi war daher nicht der Computer wie er heute verkauft wird, sondern eine Art Klone des BBC Micro auf Basis eines Atmel ATMega 644
(22.1 MHz, 512K SRAM, 320x240 Pixel). Dieser wurde von Eben Upton 2006 während
seiner Zeit an der Universität Cambridge entworfen, das Projekt aber schnell eingestellt.
Im gleichen Jahr wechselte Eben Upton zum Chiphersteller Broadcom und arbeitete
am BCM2835, welcher später auch die Basis für den heutigen Raspberry Pi werden sollte. Insbesondere die Tatsache der guten Multimedia Unterstützung dieses SoC bewog
Upton die Arbeit am Raspberry Pi wiederaufzunehmen. Er befürchtete dass der BBC
Micro Klone bei der heutigen, mit Facebook und anderen grafischen Anwendungen
vertrauten Jugend keinen Anklang finden könnte - ein Computer mit dem BCM2835
hingegen doch. Er gründete die Raspberry Pi Foundation, welche auf Basis des Einplatinen Computers auch Materialien für die Nutzung im Unterricht und der Fortbildung
von Kindern und Jugendlichen in den sogenannten MINT Fächern erstellte. Damit ging
der erste Raspberry Pi im Februar 2012 in den Verkauf und wurde seither mehr als 3
Millionen mal verkauft [24].
2.1.2 BeagleBone Black Revision C
Das BeagleBone Black entstammt einer Reihe von verschiedenen Einplatinen Computern, welche ihre Entwicklung 2008 in Form des BeagleBoard, einem 150 US Dollar
teuren, 600 MHz schnellen Cortex-A8 Linux Boards begannen. Alle diese Entwicklungsboards haben die Gemeinsamkeit, dass sie von Texas Instruments Entwicklern
entwickelt wurden und jeweils als SoC den aktuellen Kern aus dem Portfolio der genanten Firma beinhalteten. Der aktuelle BeagleBone Black (53 e) verwendet ein Texas
Instruments AM335X SoC, welches eine 1 GHz starke ARM Cortex A8 CPU beinhaltet,
sowie eine PowerVR SGX530 Grafikeinheit mit 1,6 GFlops und 512 MB Arbeitsspeicher. Die Konnektivität nach außen geschieht beim Bone über einen USB Host Port,
einen USB Client Port, einen 100 Mbit Netzwerkanschluss sowie einen Micro HDMI
Port. Der BeagleBone Black bietet 92 GPIO Pins, welche sich auf zwei Pinleisten verteilen, allerdings je nach verwendeter Peripherie (z.B. dem HDMI Ausgang, oder dem
Onboard Speicher) nicht alle verfügbar sind. Als Protokolle dienen dort gleich mehrere Serial Schnittstellen, I2C und SPI Busse sowie ein Controller Area Network (CAN)
und I2S Bus zur Verfügung. Als Massenspeicher dienen entweder die verbauten 4 GB
eMMC Flashspeicher oder eine Micro SD Karte. Die Stromversorgung erfolgt über den
USB Client Port oder über ein 5 Volt, 1 Ampere Netzteil. Als Besonderheit existieren
4
2.1 Raspberry Pi und BeagleBone Black
beim BeagleBone Black zwei Programmable Realtime Unit (PRU), welche jeweils mit
200 MHz getaktet sind und unabhängig von der ARM CPU funktionieren. Diese 32
bit Microcontroller sind mit hoher Bandbreite, sowohl an den eigenen, als auch an den
Arbeitsspeicher der ARM CPU angeschlossen und können dazu verwendet werden, rechenintensive oder zeitkritische Aufgaben zu übernehmen, ohne die CPU zu belasten.
Alle Geräte der BeagleBoard und BeagleBone Reihe verwendeten Anfangs ein speziell angepasstes Ångström Linux, seit Anfang des Jahres wird das neue BeagleBone
Black allerdings mit einer Anpassung von Debian vorinstalliert verkauft. Weiterhin stehen Ubuntu und Android sowie das Echtzeitbetriebssystem QNX zur Wahl.
2.1.3 Vergleich
Raspberry Pi und BeagleBone Black scheinen auf den ersten Blick beide gleich gut zur
Verwendung im Bereich der Lehre geeignet zu sein, jedoch gibt es bei genauerer Betrachtung einige wesentliche Unterschiede. Der größte und wesentliche, welcher sich
sowohl im Design der Hardware, Software und verfügbaren Materialien widerspiegelt, ist die angepeilte Zielgruppe. Während der Raspberry Pi von Anfang an darauf
ausgelegt war im Bereich der Lehre verwendet zu werden und erst später aufgrund
des günstigen Preises von Hobbyisten und der Industrie aufgegriffen wurde, war das
BeagleBone Black als ein Entwicklungs- und Demoboard für das entsprechende, frei
zu erwerbenden SoC gedacht: Beide Hersteller haben die Baupläne ihres Produktes
offengelegt, was die eigene Produktion eines solchen Boards ermöglichen würde. Allerdings ist nur der Kern des BeagleBone Black in kleinen, und nicht industriell üblichen Mengen erhältlich. Damit wird schnell klar, dass die Zielsetzung des BeagleBone
Black ebenfalls das eines Referenzdesigns zur Integration in die eigene Schaltung ist.
Weiterhin unterstützt wird diese These durch die Ausstattung in Hardware und Software: Während der Raspberry Pi mittels digitalem HDMI, sowie analogem Video und
Audioanschlüssen, sowie vier USB Ports direkt als Standalone Rechner in fast allen Situationen eingesetzt werden kann, bietet der BeagleBone Black nur den digitalen HDMI Anschluss im unüblichen Micro HDMI Format, sowie einen USB Port - zu wenig
um die übliche Kombination aus USB Maus, Tastatur und WLAN Dongle ohne zusätzliches Zubehör anschließen zu können. Dies gilt allerdings nicht nur für den Bereich
der Hardware, sondern auch der Software: Während der Raspberry Pi mit einer Fülle
von Entwicklungswerkzeugen und Software (Python, Mathematica, Scratch, Verweis
auf Unterrichtsmaterialien uvm.) vorinstalliert kommt, verfügt der BeagleBone Black
neben verschiedenen Systemprogrammen ausschließlich über einen Texteditor, Terminal, File Browser, Chrome sowie ein IRC Chat Tool. Zusammengefasst lässt sich also
festhalten, dass der BeagleBone Black sicherlich ein gutes Werkzeug für die industrielle
Entwicklung auf Basis des verwendeten Chips ist, allerdings für den Einsatz in der Lehre und der Verdeutlichung des Zusammenspiels von Hard- und Software nur bedingt
geeignet ist. Nicht zuletzt auch wegen des mehr als anderthalbfach so hohen Preises
und der bestehenden Lieferengpässe (Juli 2014), wurde der Raspberry Pi als Basis für
die folgende Arbeit gewählt.
5
2 Plattform Evaluation
Tabelle 2.1: Übersicht [6]
Raspberry Pi Modell B+
BeagleBone Black Rev. C
SoC
Broadcom BCM2835
Texas Instruments AM3358
CPU
ARM1176 / ARMv6
ARM Cortex-A8 / ARMv7
700 MHz, Hardware FPU
1 GHz, Hardware FPU
RAM
512 MB
512 MB
GPU
Broadcom VideoCore IV
PowerVR SGX530
24 GFlops
1,6 GFlops
Int. Speicher
-
4 GB
Ext. Speicher
Micro SD
Micro SD
Netzwerk
10/100 Mbit
10/100 Mbit
Stromversorgung
5 V @ 2 A USB Micro
5 V @ 1 A USB Mini
5V @ 2.1mm Stecker
Abmessungen
85.6 mm x 56 mm
86.4 mm x 53,3 mm
Gewicht
45 g
40 g
Preis
33 e
53 e
Tabelle 2.2: I/O und Peripherie [6]
6
Raspberry Pi Modell B+
BeagleBone Black Rev. C
Digitale I/O Pins
28 @ 3,3V
65 @ 3,3V
Analoge Eingänge
-
7 @ 12-bit ADC (0-1,8V)
PWM Ausgänge
2
8
Serial
1
4
SPI
2
2
I2C
1
2
USB Host
4 USB A Anschlüsse
1 USB A Anschluss
USB Client
-
1 Mini B Anschluss
Video Eingang
CSI
-
Video Ausgang
HDMI, Cinch, DSI
Micro HDMI
Audio Ausgang
HDMI, Analog
Micro HDMI
Stromversorgung
3,3V @ 50 mA, 5V @ 1,2 A
3,3V @ 250 mA, 5V @ 1 A
Besonderheiten
-
PRU, CAN Bus
2.2 Raspberry Pi Modelle
2.2 Raspberry Pi Modelle
Seit Beginn der Entwicklung sind einige, verschiedene Modelle des Raspberry Pi erschienen. Am weitesten verbreitet ist das Modell B in der Version 2.0, weshalb auch der
Hardware Anteil dieser Bachelor Thesis mit diesem Raspberry Pi durchgeführt wurde.
Das neuste Modell, welches zukünftig als Standard dienen soll, ist der Raspberry Pi
Modell B+. Die Unterschiede der einzelnen Plattformen sollen nachfolgend kurz erläutert werden.
2.2.1 Unterschiede Modell A und B
Der prinzipielle Unterschied zwischen Modell A und B liegen in der Bestückung der
Platinen. Das Modell A verfügt mit 256 MB nur über die Hälfte des Arbeitsspeichers
des Modell B. Weiterhin wurde der SMSC LAN9512 entfernt. Dieser Chip diente zeitgleich als USB Hub für die beiden Ports des Modell B, wie auch als Netzwerkinterface.
Damit verfügt das Modell A über nur einen USB Port und keinen Netzwerkanschluss.
Dadurch wurde zum einen das Gewicht, der Stromverbrauch und schließlich der Preis
auf 25 e reduziert. Besonders für mobile Anwendungen ist dieses Modell daher sehr
geeignet.
2.2.2 Modell B pre 2.0
Das Modell B in der Version pre 2.0 war der erste erschiene Raspberry Pi im Februar
2012 und verfügte über 256 MB Arbeitsspeicher, da für das Modell A ursprünglich 128
MB Arbeitsspeicher geplant waren.
2.2.3 Modell A/B 2.0
Beim Übergang zu Revision 2.0 gab es einige Detailänderungen, so wurden z.B. wenige
Pins inklusive des I2C Bus auf der GPIO Leiste um rangiert. Zum ersten Mal gab es
auch das funktionsreduzierte Modell A.
2.2.4 Compute Module
Das Compute Module entstand aus der Notwendigkeit eine kleinere, besser in industrielle Systeme und kommerzielle Produkte integrierbare Plattform zu entwickeln. Das
Compute Module wurde daher im Format eines DDR2 SODIMM Riegels entworfen,
und lässt sich damit leicht und platzsparend integrieren. Zusätzlich zu dem Compute
Module wurde weiterhin ein Referenzdesign zur Verfügung gestellt, welches die notwendige Hardware zum Betrieb des Moduls enthielt. Aufgrund des kleinen Formfaktors und der hohen Anzahl an ausgeführten Ports über die SODIMM Leiste, konnte
die Anzahl der nutzbaren GPIO Ports von 17 (Modell A/B 2.0) auf 46 gesteigert werden. Zusätzlich erhielt das Compute Modul jeweils zwei Anschlüsse für die CSI und
DSI Systeme, was das Modul zur Anbindung von zwei speziellen Displays, sowie dem
7
2 Plattform Evaluation
Einsatz im Bereich von stereoskopischen Kameraanwendungen befähigte. Das Compute Module verwendet, ähnlich wie der BeagleBone Black (Rev. C), einen 4 GB großen
eMMC Flashspeicher.
2.2.5 Modell A+/B+
Das Modell B+ wurde im Juli 2014 vorgestellt und beinhaltete einige Verbesserungen
im Vergleich zur Revision 2.0. So verfügt der Raspberry Pi über eine neue, energiesparendere Stromversorgung, einen rauschärmeren analogen Audioausgang, vier statt
zwei USB Ports sowie anstatt der bisherigen 26, 40 GPIO Pins. Von diesen 40 Pins sind
28 (vorher 17) für eigene Projekte nutzbar, beim Rest handelt es sich um verschiedene
Spannungsschienen (3,3V / 5V), Masse oder die neue Schnittstelle für Erweiterungsmodule (Pi Hats). Das Modell A+ wurde noch nicht veröffentlicht, jedoch ist geplant
ähnlich wie beim Übergang von Modell B, Revision 2.0 eine neue Version des Modell A
herauszubringen, welche vermutlich ebenfalls die Verbesserungen im Bereich Stromversorgung und GPIO Erweiterung enthalten wird.
8
3 Grundlagen und Installation
In dem nachfolgenden Kapitel werden die Grundlagen zur Nutzung des Raspberry Pi
gelegt. Dies umfasst das benötigte Zubehör zum Betrieb, sowie die Vorbereitung der
SD Karte mittels der noobs Software beziehungsweise eines Images. Am Ende dieses
Kapitels wird der Raspberry Pi angeschlossen sein und zum ersten Mal booten.
3.1 Peripherie
Um den Raspberry Pi das erste Mal einzusetzen, ist es empfehlenswert diesen wie einen
handelsüblichen Personal Computer anzuschließen. Neben dem Raspberry Pi ist dazu
folgende Hardware nötig:
• SD Karte
• Netzteil mit Micro USB Anschluss
• USB Maus
• USB Tastatur
• Netzwerkkabel
• HDMI auf DVI Adapterkabel
• Display mit DVI Eingang
Bei der erwähnten Hardware sind allerdings noch einige Dinge zu beachten, bzw. kann
diese auch im Bedarfsfall durch andere Komponenten ersetzt werden.
3.1.1 SD Karte
Hier sollte mindestens eine 8 GB SD Karte eines Markenherstellers mit einer entsprechenden hohen Class eingesetzt werden. Die aktuelle Version von Raspbian belegt alleine etwas weniger als 4 GB Speicher, so dass beim Einsatz einer 4 GB Karte wenig
Platz für eigene Projekte und Erweiterungen blieb, weshalb eine 8 GB Karte empfohlen wird. In den Anfängen der Entwicklung der Raspberry Pi Firmware gab es große
Probleme bei der Verwendung von SD Karten unbekannterer Hersteller. Diese Probleme sind zum jetzigen Zeitpunkt fast ausgeschlossen, jedoch empfiehlt es sich dennoch
weiterhin aus Gründen der Datensicherheit in das Produkt eines Markenherstellers zu
investieren. Die Class beschreibt die Geschwindigkeitseinstufung einer SD Karte. Eine
9
3 Grundlagen und Installation
möglichst hohe Class, wie z.B. Class 10 empfiehlt sich bei der Verwendung des Raspberry Pi, damit diese nicht zum limitierenden Faktor bei Schreib- und Lesezugriffen wird.
Alternativ kann die SD Karte auch durch eine Micro SD Karte mit entsprechendem
Adapter ersetzt werden, was beim Raspberry Pi Modell B+ zwingend erforderlich ist.
3.1.2 Netzteil mit Micro USB Anschluss
Als Netzteil könnte beim Raspberry Pi (Modell A und B) prinzipiell ein altes Handyladegerät verwendet werden. Jedoch sollte man aufpassen, dass dieses mindestens 1,2
Ampere Strom liefern kann. Der Raspberry Pi könnte dank seiner auf 1,1 Ampere festgelegten Polyfuse bis zu 5 Watt an Leistung aufnehmen, oder weitere Leistung bis zu
dieser maximalen Grenzen an angeschlossene Verbraucher weitergeben. Da besonders
günstigere Netzteile den Strom bei höherer Belastung nicht konstant halten können,
geht daher die Empfehlung an ein entsprechend starkes Netzteil mit 1,2 Ampere oder
höher. Zu niedrige Versorgungsleistung kann sich in Schreib- / Lesefehlern bei der SD
Karte, Fehlfunktionen des RPi, bis hin zum Einfrieren des gesamten Systems äußern.
Beim Raspberry Pi Modell B+ sind dank der gesunkenen Anforderungen an Strombedarf ein Netzteil mit 1,2 Ampere weiterhin verwendbar, bei der Nutzung aller vier
USB Ports empfiehlt sich allerdings die Verwendung eines Netzteils mit mindestens 2
Ampere Leistung, da die 1,1 Ampere Polyfuse durch eine 2 Ampere Polyfuse ersetzt
wurde.
3.1.3 Netzwerkkabel
Das Netzwerkkabel soll den Raspberry Pi mit einem Netzwerk, welches Internetzugang wie auch DHCP Service anbietet, verbinden. Dies ist bei normalen Heim Routern
wie z.B. einer Fritz!Box Standard. Bei Firmen- oder Universitätsnetzwerken können
weitere Schritte zur Einrichtung der Internetverbindung notwendig sein.
3.1.4 HDMI auf DVI Adapterkabel / Display mit DVI Eingang
Um die Videoausgaben des Computers möglichst komfortable anzuzeigen, empfiehlt
es sich eine HDMI auf DVI Adapterkabel zu verwenden und dieses mit dem DVI Eingang eines Computer Displays zu verwenden. Alternativ kann der Raspberry Pi auch
direkt mit einem HDMI Kabel an einem HDMI Display oder modernen Fernseher angeschlossen werden. Letztere Methode hat den Vorteil, dass die Audiosignale zusammen mit dem Videosingal übertragen werden, was es zu einer idealen Anschlussart für
Multimedia Anwendungen macht. Bei der Verwendung des DVI Eingangs muss das
Audiosignal zusätzlich vom Raspberry Pi mittels 3,5 mm Klinkekabels abgegriffen und
z.B. zu einem Paar Aktivboxen weitergeleitet werden. Sollten weder DVI noch HDMI
kompatible Displays verfügbar sein, könnte man im letzten Schritt über die Chinch
Buchse einen alten Röhrenfernseher anschließen.
10
3.2 Anschluss des Raspberry Pi
3.1.5 Weitere Komponenten
Je nach Einsatzzweck kann es erforderlich sein, weitere Komponenten zu verwenden.
Aufgrund der Tatsache, dass der 5V Eingang des Raspberry Pi (Modell A und B) mit
einer 1,1 Ampere Polyfuse abgesichert ist [20] (S.1, oben, F1), welches den gesamten
Raspberry Pi versorgt wird schnell klar, dass die beiden USB Ports nicht wie sonst 500
mA pro Port liefern können. Daher müssen Geräte mit höherem Strombedarf (USB Festplatten, größere USB Sticks, etc) an einem aktiven USB Hub betrieben werden, um zum
einen die Anzahl der verfügbaren USB Anschlüsse zu erhöhen und zum anderen auch
Geräte mit erhöhter Leistungsaufnahme sicher am Raspberry Pi betreiben zu können.
Beim Modell B+ ist, insbesondere mit der Verwendung eines 2 Ampere Netzteils, die
Problematik zumindest bei größeren USB Sticks und WLAN Dongles behoben wurden.
Für besonders energiehungrige Endgeräte empfiehlt sich allerdings auch hier ein aktiver USB Hub. Weiterhin werden für die erste Inbetriebnahme ein aktueller Windows
Rechner mit SD Karten Lesegerät und Internetzugriff vorausgesetzt um die SD Karte
vorzubereiten.
3.2 Anschluss des Raspberry Pi
Für den weiteren Verlauf des Dokumentes wird vorausgesetzt, dass die angegebenen
Komponenten vorhanden und der Raspberry Pi angeschlossen, allerdings stromlos und
ohne SD Karte bereit steht.
3.3 Raspbian
Das bereits erwähnte Raspbian ist die Standard Distribution für den Raspberry Pi. Es
handelt sich dabei um ein Debian Derivat, welches den Anforderungen und der Architektur des ARMv6 Prozessors des Einplatinen Computers angepasst wurde. Zusätzlich
zu dem reinen Betriebssystem werden auch viele der unter Debian verfügbaren Software Pakete über den Paketmanager apt mit den entsprechenden Anpassungen angeboten. Um Raspbian auf der SD Karte zu installieren bieten sich zwei Möglichkeiten an.
Zum einen die Verwendung des sogenannten noobs Systems der Raspberry Pi Foundation oder das bitweise Kopieren eines fertigen Images.
3.4 Installation mittels Image
Die „traditionelle“ Art ein Betriebssystem per Image zu installieren ist auch nach der
Einführung des noobs Systems weiterhin beliebt. Dies ist darin begründet, dass diese
Art der Installation relativ schnell funktioniert. Weiterhin lassen sich auf gleichem Weg
Backups von vorhandenen Installationen erstellen und wiederherstellen. Zu guter Letzt
ist es auch für weniger bekannte Distributionen ohne Integration in noobs die einzige
Möglichkeit diese für die Nutzung auf dem Raspberry Pi vorzubereiten.
11
3 Grundlagen und Installation
3.4.1 Image downloaden
Um das Raspbian Image zu installieren, müssen wir es erst von der Website der Raspberry Pi Foundation herunterladen. Man findet es unter der Adresse http://www.raspberrypi.
org/downloads/. Dort kann man sich entscheiden, ob man das Image von Raspbian per
direktem HTTP Download oder per Torrent erhalten möchte. Für die meisten Einsatzzwecke sollte der Download als ZIP Datei die geeignete Wahl sein. In dieser Arbeit wird
das aktuelle Image vom Juni 2014 verwendet (Release 20.06.2014, Kernel 3.12, 788 MB).
Nach dem erfolgreichen Download muss die Datei mittels einem geeigneten Werkzeug
(z.B. 7-zip: http://www.7-zip.org/) entpackt werden. Bei der resultierenden, fast 3 GB
großen Datei mit der Endung „.img“ handelt es sich um die besprochene Image Datei,
welche bitweise die Kopie des Raspbian Betriebssystems enthält. Diese Datei wird in
den nächsten Schritten auf die vorhandene SD Karte kopiert.
3.4.2 Formatieren
Um das Image auf die SD Karte kopieren zu können, muss deren Inhalt zuerst gelöscht, die Karte also formatiert werden. Dies ist bei der Verwendung einer neuen und
leeren SD Karte nicht notwendig, da die Karte im nächsten Schritt bitweise überschrieben wird. Beim Überschreiben werden normalerweise zwei Partitionen angelegt: Eine
FAT32 Partition wie man sie auch bei USB Sticks kennt, sowie eine EXT Partition unterschiedlicher Version. Das EXT Dateisystem entstammt dem Linux Bereich und ist
unter Windows nicht lesbar. Will man nun also eine bereits für den Raspberry Pi verwendete SD Karte ein weiteres Mal neu beschreiben, oder ein Backup wiederherstellen,
so erscheint die ggf. mehrere GB große SD Karte als nur knapp 56 MB großer, FAT32
formatierter USB Stick im Dateisystem. Durch die Formatierung kann das ursprüngliche Format wiederhergestellt und anschließend mit der vollen Größe auch ein Image
wieder zurück gespielt werden.
Um unter Windows die SD Karte korrekt zu formatieren, sollte man nicht das Windows eigene Tool verwenden, sondern den SD Formatter der SD Association. Man kann
dieses Tool kostenlos unter https://www.sdcard.org/downloads/formatter_4/ per Klick
auf „Download SD Formatter for Windows“ herunterladen. Nachdem man die EULA
angenommen hat, startet der Download der wenigen MB großen ZIP Datei. Sobald
man die enthaltene Setup Datei entpackt und das Tool installiert hat, startet man dieses
einfach.
Das Tool selbst ist relativ einfach gehalten: Unter „Drive“ wählt man das korrekte
Laufwerk aus und per Klick auf „Format“ startet man die Formatierung der SD Karte.
Dabei ist jedoch darauf zu achten, dass das Tool alle Wechselmedien unter „Drive“
auflistet. Man muss also darauf achten wirklich seine SD Karte zu formatieren, und
nicht versehentlich einen USB Stick mit wichtigen Daten. Bevor man allerdings den
Vorgang startet, sollte man unter „Option“ noch eine Anpassung vornehmen.
In jedem Fall, besonders bei der Vorbereitung einer SD Karte für die Verwendung von
noobs, sollte man hier das „Format Size Adjustment“ auf „On“ stellen und den Dialog
per Klick auf „OK“ verlassen, sowie die Formatierung per Klick auf „Format“ starten.
12
3.4 Installation mittels Image
Abbildung 3.1: SD Formatter
Abbildung 3.2: SD Formatter Optionen
13
3 Grundlagen und Installation
Nachdem zwei weitere Sicherheitsabfragen bestätigt wurden, beginnt der Vorgang und
endet mit einer Übersicht über die tatsächliche Größe der SD Karte. Der Vorgang ist
damit abgeschlossen und das Tool kann beendet werden.
3.4.3 Image kopieren
Um das bereits heruntergeladene Image auf die nun vorbereitete SD Karte zu kopieren, benötigen wir ein weiteres Tool, die Freeware Win32 Disk Imager. Dieses Werkzeug
kann man unter der URL http://sourceforge.net/projects/win32diskimager/ per
Klick auf „Download unamed sequel here“ herunterladen, installieren und anschließend starten.
Abbildung 3.3: Win32 Disk Imager
Wie bereits beim SD Formatter gibt es auch hier ein Feld zur Auswahl des korrekten Wechsellaufwerkes („Device“). Es ist auch dieses Mal genaustens darauf zu achten
die SD Karte und nicht einen anderen Wechseldatenträger, wie z.B. einen USB Stick
auszuwählen, da im nächsten Schritt alle Dateien auf diesem überschrieben werden.
Nachdem die SD Karte als Laufwerk ausgewählt wurde, wählen wir per Klick auf
den Dateiordner das vorher heruntergeladene Raspbian Image aus (hier: 2014-06-20wheezy-raspbian.img). Nach dem Klick auf „Öffnen“ ist das Tool dann auch schon fertig konfiguriert. Per Klick auf „Write“ beginnt nach einer weiteren Sicherheitsabfrage
der Schreibvorgang. Nach Abschluss des selbigen kann die SD Karte ausgeworfen, aus
dem Lesegerät entfernt und in den Raspberry Pi eingesetzt werden. Dies schließt das
Kopieren des Raspbian Image auf die SD Karte ab. Der Raspberry Pi kann nun an die
Stromversorgung angeschlossen werden um Raspbian zu booten.
3.4.4 Backup und Wiederherstellung
Wie bereits eingangs erwähnt kann das Win32 Disk Imager Tool auch dazu verwendet
werden, Backups einer bestehenden Raspbian Installation anzufertigen, bzw diese Wiederherzustellen.
14
3.5 Installation mittels noobs
Wollen wir ein Backup erstellen, so setzen wir die SD Karte in das Lesegerät ein und
starten den Win32 Disk Imager. Anders als beim bisherigen Vorgang wählen wir diesmal
über den Dateiordner kein fertiges Image aus, sondern geben im entsprechenden Dialogfeld einen eigenen, nicht existierenden Dateinamen ein, z.B. „RaspbianBackup.img“.
Nach dem Klick auf „Öffnen“ sind wir wieder im Hauptdialog und können durch Klick
auf den Button „Read“ das Auslesen der SD Karte in die neu angelegte Datei starten.
Die Datei wird später die Größe der verwendeten SD Karte haben und kann ohne weitere Änderungen auch nur auf eine solch große, oder größere SD Karte wiederhergestellt
werden.
Zur Wiederherstellung gehen wir ähnlich vor wie beim Kopieren des Raspbian Images:
Wir führen zuerst eine Formatierung der SD Karte wie unter 3.4.2 angegeben durch,
anschließend kopieren wir das Backup Image anstelle des Raspbian Images auf die SD
Karte wie unter 3.4.3 beschrieben.
3.5 Installation mittels noobs
Um den Einstieg in die Welt des Raspberry Pi zu vereinfachen erfand die Raspberry Pi
Foundation die sogenannte noobs oder New Out Of Box Software. Es handelt sich dabei
um einen Installationsassistenten welcher, nachdem er auf der SD Karte installiert wurde, den Boot des Raspberry Pi und dort die Auswahl des gewünschten Betriebssystems
erlaubt. Erst dann findet die eigentliche Installation statt. Noobs gibt es auch vorinstalliert auf Micro SD Karten samt Adapter im Handel zu kaufen, um den Einstieg mit dem
Raspberry Pi zu einer echten „Plug and Play“ Lösung zu machen. Sollte der Installer
jedoch beschädigt werden, man noobs selbst auf einer leeren SD Karte installieren wollen oder andere Probleme auftreten, ist es gut die wenigen Schritte bis zur Einrichtung
und Nutzung dieses Systems zu kennen, welche nachfolgenden aufgelistet werden.
3.5.1 noobs downloaden
Wie auch bei der direkten Installation von Raspbian muss das noobs Paket erst von
der Raspberry Pi Website heruntergeladen werden. Dazu navigieren wir zu http://
www.raspberrypi.org/downloads/ und wechseln zum Eintrag „noobs“. Die New Out
Of Box Software gibt es in zwei Versionen: Full und Lite. Bei der Full Version sind alle wichtigen Betriebssysteme bereits auf der SD Karte hinterlegt, so dass eine Offline
Installation nach dem Download möglich ist. Die Lite Version benötigt, da nur der Installer auf der Karte untergebracht ist, bei der Installation eine Internetverbindung um
die Images herunterzuladen. Je nach Einsatzzweck downloaden wir die passende Version per Klick auf den „Download ZIP“ Button.
3.5.2 Formatieren
Wie bereits bei 3.4.2 erklärt muss nun auf gleichem Wege die SD Karte formatiert werden. Nachdem dies abgeschlossen ist, kann noobs selbst im nächsten Schritt auf die SD
15
3 Grundlagen und Installation
Karte kopiert werden.
3.5.3 noobs kopieren
Abbildung 3.4: noobs nach dem Entpacken auf die SD Karte
Nachdem wir die SD Karte vorbereitet haben, entpacken wir den Inhalt des heruntergeladenen Paketes direkt ins Hauptverzeichnis der SD Karte unter Beibehaltung der
Datei- und Ordnerstruktur. Auch hierbei wird empfohlen einen bewährten Entpacker
wie z.B. 7-zip (http://www.7-zip.org/) dem Windows eigenem Tool vorzuziehen. Anschließend kann die SD Karte sicher entfernt und schließlich in den Raspberry Pi eingesetzt werden. Damit ist noobs erfolgreich eingerichtet und wir können den Raspberry
Pi an die Stromversorgung anschließen, um Raspbian zu installieren.
3.5.4 Raspbian mit noobs installieren
Nach dem Boot des Raspberry Pi erscheint die Oberfläche von noobs, welche uns die
Möglichkeit gibt, zum einen die Sprachoptionen und Tastatureinstellungen zu ändern,
sowie zum anderen ein Betriebssystem zur Installation auszuwählen und den Prozess
zu starten. Da wir, wie auch in der manuellen Methode, Raspbian installieren wollen,
aktivieren wir diesen Eintrag mit einem Klick in das entsprechende Kästchen und klicken anschließend auf „Install“. Nach einer Sicherheitsabfrage beginnt die Installation
die nun einige Zeit dauern kann.
Nach dem Abschluss der Einrichtung informiert noobs den Nutzer mittels Dialogbox.
Nach dem Klick auf „OK“ startet der Raspberry Pi neu und bootet Raspbian.
3.5.5 Vorteile von noobs
Der Vorteil der Installation nach dieser Methode liegt zum einen darin, dass die Sprachoptionen und Tastatureinstellungen welche in noobs eingegeben wurden nach Raspbian
16
3.5 Installation mittels noobs
Abbildung 3.5: Installation von Raspbian unter noobs
übernommen werden, zum anderen aber auch darin, dass man jederzeit beim Booten
des Raspberry Pi die Shift Taste gedrückt halten kann, um das noobs Menü erneut aufzurufen. Damit hat man die Möglichkeit Einstellungen zu ändern, wie auch ohne den
Einsatz eines PCs andere Betriebssysteme zu installieren. Weiterhin ermöglicht noobs
die gleichzeitige Installation mehrerer Betriebssysteme auf einer SD Karte und dient
als Bootmanager.
17
4 Konfiguration von Raspbian
Nachdem der Raspberry Pi im letzten Kapitel zum ersten Mal in Betrieb genommen
wurde, muss nun die Grundkonfiguration erfolgen. Dies bedeutet zum Beispiel das
Tastaturlayout, die Zeitzone und die Internationalisierungsoptionen einzustellen. Anschließend werden die Schritte zur Installation neuer Software und Update bestehender, sowie dem Upgrade der Firmware beschrieben. Am Ende dieses Kapitels werden
alle notwendigen Vorbereitung zur Nutzung der GPIO Schnittstelle in verschiedenen
Programmiersprachen getroffen sein.
4.1 Erster Boot
Nachdem Raspbian nun auf der SD Karte installiert und der Raspberry Pi nun bootet, muss ersteres nun in einer Grundkonfiguration für die Verwendung beim Nutzer
eingerichtet werden. Im Idealfall wird dies direkt am Raspberry Pi durch die Verwendung von Maus, Tastatur und Bildschirm erledigt. Sollte dies nicht möglich sein, bzw.
eine Einrichtung headless, also ohne Bildschirm über das Netzwerk erfolgen, so kann
man dies unter Verwendung eines SSH Tools wie z.B. PuTTY (http://www.chiark.
greenend.org.uk/~sgtatham/putty/download.html) tun. Die Login Daten bei Raspbian sind, wie auch auf der Downloads (http://www.raspberrypi.org/downloads/) Seite vermerkt, Nutzer: pi sowie Passwort: raspberry. Dabei ist zu beachten, dass beim direkten Login über die Tastatur, so diese nicht von noobs auf QWERTZ umgestellt wurde,
im QWERTY Format Eingaben entgegen nimmt, also u.a. die Position von Z und Y auf
der Tastatur vertauscht ist.
4.1.1 raspi-config
Nachdem der Raspberry Pi zum ersten Mal gebootet ist, erscheint das Software Configuration Tool, auch bekannt als raspi-config. Sollte man diese Schritte in einer headless
Installation nachvollziehen wollen, so muss man nach Login über PuTTY das Tool manuell durch die Eingabe von sudo raspi-config starten.
raspi-config ermöglicht viele Änderungen und Grundeinstellungen. So kann man in
diesem Werkzeug z.B. die Verteilung des gemeinsam von CPU und GPU genutzten
RAMs ändern, das Nutzerpasswort ändern, den Boot in die grafische Benutzeroberfläche aktivieren oder die Raspberry Pi Kamera aktivieren. Alle Hardwarenahen Änderungen, wie z.B. Übertaktungseinstellungen werden vom Tool in Form der config.txt
[8] Datei in der FAT32 Partition der SD Karte abgelegt und sind auch manuell von einem normalen Windows PC änderbar und damit auch eine Wiederherstellung bei z.B.
19
4 Konfiguration von Raspbian
Abbildung 4.1: raspi-config
fehlerhaft konfigurierten Übertaktungseinstellungen möglich. Im Normalfall empfiehlt
sich allerdings die Verwendung dieses Tools um Fehler zu vermeiden.
Die Navigation in raspi-config erfolgt über folgende Tastenkombinationen:
Pfeiltasten
Hoch, Runter
Page UP, Page Down
Enter
ESC
Schnell Hoch, Schnell Runter
Menü betreten
Menü verlassen
Leertaste
Menüpunkt markieren, bei [ ] Auswahl
Wir beginnen die Konfiguration im Menü 8 Advanced Options, in dem wir unter Punkt
A3 Memory Split den Anteil der Grafikkarte am Gesamtarbeitsspeicher des RPi festlegen. Im Normalfall reicht die Standardeinstellung von 64 MB. Bei sogennaten Headless
Konfigurationen, also dem Betrieb des RPi ohne Bildschirm, Maus und Tastatur als Server, kann dort der Anteil der GPU auch auf 16 MB gesenkt werden. Der Name des RPi
im Netzwerk kann unter A2 Hostname festgelegt werden. Es empfiehlt sich dort einen
sprechenden Namen einzugeben und nicht alle RPi mit dem Standardnamen „raspberrypi“ zu belassen.
Unter 7 Overclock: Kann man die Übertaktung des Raspberry Pi einstellen, um eine
Leistungssteigerung zu erhalten. Die einzigen beiden sinnvollen Parameter sind dabei
None oder Turbo: Mit None betreibt man den Raspberry Pi innerhalb der Standardparameter, mit Turbo erhält man eine sehr starke Übertaktung und Steigerung u.a. der CPU
Geschwindigkeit von 700 MHz auf 1 GHz. Dennoch bleibt bei der Nutzung der Turbo
Einstellung die Garantie erhalten, da die CPU automatisch diese Übertaktung zurückregelt, sobald die Temperatur der CPU 85 Grad Celsius erreicht [23]. Diese Einstellung
ist allerdings auf Grund von Fertigungstoleranzen nicht auf jedem Raspberry Pi zu erreichen. Sollte es Probleme geben, so kann man durch Halten der Shift Taste beim Boot
20
4.1 Erster Boot
des Raspberry Pi in den abgesicherten Modus wechseln um diese Einstellung zu ignorieren.
Sollte man die Raspberry Pi Kamera nutzen wollen, so muss vor dem Anschluss dieses Moduls die Unterstützung für diese mit der Einstellung 5) Enable Camera aktiviert
werden. Danach kann man die Kamera an den ausgeschalteten Raspberry Pi anschließen und nach einem erneuten Start nutzen.
Um den Raspberry Pi sinnvoll in Deutschland zu nutzen, stellen wir nun unter 4 Internationalization Options die Internationalisierungsoptionen auf unseren Standort und
unsere Sprache um. Wir beginnen mit I1 Change Locale und wählen im erscheinenden
Menü den Punkt [*] de_DE.UTF-8 UTF-8 aus, bestätigen die Wahl und beantworten die
Frage nach dem Default locale mit de_DE.UTF-8. Nun werden die Standortparameter
erstellt, was einen kurzen Moment dauern kann.
Als nächstes ändern wir die Zeitzone unter dem Punkt I2 Change Timezone in dem wir
zuerst als Geographic area Europe und dann als Timezone Berlin angeben. Der Raspberry
Pi bezieht sich seine Zeitinformationen per NTP über das Netzwerk und stellt die Uhr
direkt korrekt ein.
Abschließend muss die Einstellung der Tastatur auf das deutsche Schema angepasst
werden. Der korrekte Unterpunkt dafür ist I3 Change Keyboard Layout.
• Generic 105-key (Intl) PC
• Other
• German
• German
• The default for the keyboard layout
• No compose key
• <No>
Anschließend wird die neue Keymap erstellt und mit dem nächsten Login aktiv.
Um beim nächsten Bootvorgang nicht wieder in der Kommandzeile zu landen, sondern direkt zum Desktop zu booten, aktivieren wir nun unter 3 Enable Boot to Desktop/Scratch die Option Desktop Log in as user ’pi’ at the graphical desktop.
Aus Sicherheitsgründen empfiehlt es sich im vorletzten Schritt das Passwort des
Standardnutzers pi unter 2 Change User Password zu ändern.
Zu guter Letzt möchten wir, dass der Raspberry Pi nicht nur die knapp 3 GB Speicher,
welche durch das Image bereitgestellt wurden nutzt, sondern die gesamte SD Karte belegt. Daher führen wir als letzte Aktion 1 Expand Filesystem aus. Mit der Bestätigung von
Finish im Hauptmenü beenden wir raspi-config und beantworten die Frage nach dem
gewünschten Reboot mit Yes. Mit dem Neustart wird das Dateisystem angepasst und
der Raspberry Pi bootet schließlich zur grafischen Benutzeroberfläche, dem Desktop.
21
4 Konfiguration von Raspbian
Abbildung 4.2: Raspbian Desktop
4.2 WLAN Zugriff / eduroam
Sollte ein Zugriff auf das eduroam WLAN benötigt werden, muss der Raspberry Pi zuvor mit einem USB WLAN Dongle ausgestattet werden. Eine entsprechende Kompatibilitätsliste geeigneter Modelle kann unter http://elinux.org/RPi_USB_Wi-Fi_Adapters
gefunden werden. Anschließend kann unter Nutzung des Wifi Config Tools des RPi
unter dem Punkt „Manage Networks“ und „Add“ das WLAN eduroam hinzugefügt
werden:
Tabelle 4.1: Einstellungen für eduroam
Einstellung
Wert
SSID
eduroam
Authentication
WPA2-Enterprise (EAP)
Encryption
CCMP
EAP method
PEAP
Identity
nutzername@htw-saarland.de
Password
Passwort
CA certificate
/etc/wpa_supplicant/deutsche-telekom-root-ca-2.crt
Inner auth
EAP-MSCHAPV2
Anschließend kann über den Reiter „Current Status“ und die Schaltfläche „Connect“
eine Verbindung hergestellt werden.
22
4.3 Updates
4.3 Updates
Nachdem wir nun die Grundkonfiguration des Raspberry Pi durchgeführt haben, ist es
zwingend erforderlich, zum einen die neuste Firmware wie auch Software Updates zu
installieren und die grundlegende Arbeit mit dem Paketmanager apt zu erlernen.
4.3.1 rpi-update
Das Firmware Paket besteht aus dem Kernel von Raspbian, dem GPU Bootloader sowie
den benötigten Modulen für den Kernel. Sobald der Raspberry Pi mit Strom versorgt
wird sucht die GPU automatisch auf der FAT32 Partition der SD Karte nach einem
passenden Bootloader. Mit diesem kann die Grafikeinheit dann die CPU und die restliche Peripherie initialisieren und schließlich den Kernel booten. Die Firmware auf einem aktuellen Stand zu halten ist wichtig, da man nur auf diese Art von Verbesserungen wie z.B. verbesserter Hardwareunterstützung oder Fehlerbeseitigung profitieren
kann. Die aktuelle Kernelversion kann man sich mit dem Kommando uname -a anzeigen lassen. Dazu verwenden wir das Tool LXTerminal welches in der oberen, linken
Ecke des Desktops abgelegt ist. Als Beispiel sei hier die Ausgabe unseres neu installierten Raspbian angegeben:
Linux raspberrypi 3.12.22+ #691 PREEMPT Wed Jun 18 18:29:58 BST 2014 armv6l GNU/Linux
Wie man erkennen kann, handelt es sich hierbei um den Kernel Version 3.12.22+ welcher am 18. Juni 2014 gegen 18:29:58 kompiliert wurde. Die Zahl #691 ist die Versionsnummer des Kernels. Die Version der GPU Firmware lässt sich durch das Kommando
/opt/vc/bin/vcgencmd version herausfinden:
Jun 18 2014 18:46:58
Copyright (c) 2012 Broadcom
version 1a6f79b82240693dcdb9347b33ab16f656b5f067 (clean) (release)
Um nun ein Update auf die neuste Version durchzuführen, reicht das Kommando sudo rpi-update. Da es sich hierbei um ein Kommando handelt welches tiefgreifend in
wichtige Bereiche des Linux Betriebssystems eingreift, zu welchen unser Standardnutzer pi keinen Zugriff hätte, müssen wir das Kommando sudo vorstellen. Durch dieses
Kommando wird der nachfolgende Befehl (hier: rpi-update) mit den Rechten des Linux
Administrators, root durchgeführt:
sudo rpi-update
*** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS
*** Performing self-update
% Total
% Received % Xferd Average Speed Time
Time
Time Current
Dload Upload Total Spent
Left Speed
100 135 100
135
0
0
227
0 --:--:-- --:--:-- --:--:-- 299
100 7037 100 7037
0
0 8049
0 --:--:-- --:--:-- --:--:-- 8049
*** Relaunching after update
23
4 Konfiguration von Raspbian
*** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
*** We're running for the first time
*** Backing up files (this will take a few minutes)
*** Backing up firmware
*** Backing up modules 3.12.22+
*** Downloading specific firmware revision (this will take a few minutes)
% Total
% Received % Xferd Average Speed Time
Time
Time Current
Dload Upload Total Spent
Left Speed
100 168 100
168
0
0
350
0 --:--:-- --:--:-- --:--:-- 465
100 21.2M 100 21.2M
0
0 902k
0 0:00:24 0:00:24 --:--:-- 525k
*** Updating firmware
*** Updating kernel modules
*** depmod 3.12.25+
*** Updating VideoCore libraries
*** Using HardFP libraries
*** Updating SDK
*** Running ldconfig
*** Storing current firmware revision
*** Deleting downloaded files
*** Syncing changes to disk
*** If no errors appeared, your firmware was successfully updated to
774062f644162e209214bc2d3a7ba79fdf765ba3
*** A reboot is needed to activate the new firmware
Um die Installation der neuen Firmware abzuschließen, müssen wir den Raspberry Pi neustarten. Dies geschieht entweder rechts unten im Desktop über die Abmelden
Schaltfläche, den Shutdown Icon auf dem Desktop oder mittels Kommandozeile über
die Befehle sudo shutdown -h now zum herunterfahren oder sudo shutdown -r now zum
neustarten. Nachdem wir nun die Firmware des Raspberry Pi aktualisiert haben, möchten wir uns im nächsten Schritt um seine Software kümmern.
4.3.2 apt-get
APT ist der sogenannte Paket Manager unter dem von Debian abstammenden Raspbian Linux. Pakete können die unterschiedlichsten Arten von Software, Libraries und
anderen Abhängigkeiten enthalten. Der Paket Manager selbst verwaltet die Installation sowie die benötigten Grundlagen / Abhängigkeiten um die gewünschte Software
auf dem Rechner zu betreiben. Weiterhin können über den Paket Manager nicht nur
Software installiert und gelöscht, sondern auch aktualisiert werden. Unter der Nutzung von LXTerminal führen wir den Befehl sudo apt-get update aus. Damit lädt sich
der Paket Manager die aktuellen Paketlisten herunter um zu wissen, welche Software
in welcher Version für den Nutzer zur Verfügung steht. Mit dem Kommando sudo aptget upgrade starten wir schließlich das Software update. Der Paket Manager berechnet
die Abhängigkeiten, benötigten neuen Pakete und verlangt schließlich die Bestätigung
24
4.4 Einrichtung Hardware
seitens des Nutzers.
sudo apt-get upgrade
Paketlisten werden gelesen... Fertig
Abhängigkeitsbaum wird aufgebaut.
Statusinformationen werden eingelesen.... Fertig
Die folgenden Pakete werden aktualisiert (Upgrade):
cups-bsd cups-client cups-common dbus dbus-x11 gnupg gpgv libcups2
libcupsimage2 libdbus-1-3 libjpeg8 libsmbclient libwbclient0 libxml2
openssh-client openssh-server python-picamera python-rpi.gpio
python3-picamera python3-rpi.gpio rpi-update samba-common smbclient ssh
tzdata
25 aktualisiert, 0 neu installiert, 0 zu entfernen und 0 nicht aktualisiert.
Es müssen 13,2 MB an Archiven heruntergeladen werden.
Nach dieser Operation werden 100 kB Plattenplatz zusätzlich benutzt.
Möchten Sie fortfahren [J/n]?
Nachdem diese Frage mit J und der Eingabe von Enter bestätigt wurde, führt der
Raspberry Pi die Updates durch. Danach empfiehlt sich ein Neustart von Raspbian.
Die Installation von neuen Paketen funktioniert mit dem Kommando sudo apt-get
install <Paketname> respektive die Entfernung mit sudo apt-get remove <Paketname>.
Diese Kommandos werden wir gleich u.a. bei der Installation von wiringpi2 verwenden.
4.4 Einrichtung Hardware
Wie bereits erwähnt, verfügt der Raspberry Pi über eine GPIO Schnittstelle. Die 26 (Modell A,B) respektive 40 Pins (Modell B+) lassen sich je nach Programmierung entweder als digitaler Ein- oder Ausgang verwenden um die unterschiedlichsten Aufgaben
zu erfüllen. Einige dieser Pins verfügen noch über spezielle Alternativfunktionen, wie
z.B. einen I2C Bus, einen SPI Bus oder einen Universal asynchronous receiver/transmitter (UART) in Form einer RS-232 seriellen Schnittstelle. Die ersten beiden Funktionen sind standardmäßig deaktiviert um dem Nutzer mehr freie GPIO Pins zu bieten,
die letztere wird aktiv als serielle Konsole von Raspbian verwendet. Wenn man diese
Schnittstellen und Funktionen also für eigene Projekte verwenden möchte, muss man
sie erst aktivieren respektive aus der Nutzung anderer Dienste entfernen.
4.4.1 Vorbereitung des I²C / SPI Bus
Um die I2C bzw SPI Funktionen der GPIO Pins zu verwenden, führen wir zunächst ein
Update des Paket Managers mit sudo apt-get update durch und installieren anschließend mit sudo apt-get install i2c-tools python-smbus die Pakete für die I2CTools sowie die Python Bibliothek für den SPI Bus.
Nachdem dies erfolgt ist, müssen wir die Module für I2C und SPI von der Blacklist
entfernen. Die Blacklist verhindert dass diese Module beim Start geladen und damit
25
4 Konfiguration von Raspbian
die alternativen Funktionen auf der GPIO zur Verfügung stehen. Um dies zu bewerkstelligen können wir entweder mittels LXTerminal und vi über Kommandozeile die entsprechenden Dateien editieren, oder per LXTerminal mit dem Kommando sudo leafpad
den Texteditor Leafpad mit root Rechten starten um anschließend die sonst schreibgeschützten Dateien zu editieren.
Im ersten Schritt öffnen wir die Datei /etc/modprobe.d/raspi-blacklist.conf und
kommentieren die beiden blacklist Befehle für die Module spi-bcm2708 und i2c-bcm2708
mittels vorangestelltem # Zeichen aus:
# blacklist spi and i2c by default (many users don't need them)
#blacklist spi-bcm2708
#blacklist i2c-bcm2708
Danach speichern wir die Datei.
Als nächstes müssen wir die beiden Module in /etc/modules vermerken, damit diese
auch beim Start des RPi geladen werden. Dazu hängen wir einfach nach dem letzten
Eintrag in der genannten Datei die folgenden Zeilen an:
i2c-bcm2708
spi-bcm2708
i2c-dev
Das Ergebnis sieht wie folgt aus:
#
#
#
#
#
/etc/modules: kernel modules to load at boot time.
This file contains the names of kernel modules that should be loaded
at boot time, one per line. Lines beginning with "#" are ignored.
Parameters can be specified after the module name.
snd-bcm2835
i2c-bcm2708
spi-bcm2708
i2c-dev
Abschließend müssen wir nur noch den Standardnutzer pi zu den entsprechenden
Linux Gruppen hinzufügen, damit er die Berechtigung zur Nutzung dieser Dienste
erhält. Standardmäßig sind die Berechtigungen für die SPI und GPIO Gruppe schon
erteilt ( groups pi zeigt die zugeteilten Gruppen an). Daher müssen wir nur noch mit
dem Befehl sudo adduser pi i2c den Nutzer pi die Rechte für die Gruppe I2C geben.
Die durchgeführten Änderungen werden erst nach einem Neustart aktiv.
4.4.2 Vorbereitung der seriellen Schnittstelle
Da im Standardfall die serielle Schnittstelle des RPi von Raspbian als Terminal genutzt
wird, kann diese nicht direkt dazu verwendet werden um z.B. einen Global Positio-
26
4.5 Einrichtung Software
ning System (GPS) Empfänger oder eine Microcontroller Unit (MCU) wie den Arduino anzuschließen. Um diese Funktionalität zu entfernen müssten wir aus der Datei
/boot/cmdline.txt die Einträge console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 entfernen sowie in der Datei /etc/inittab den Eintrag T0:23:respawn:/sbin/getty -L ttyAMA
0 115200 vt100 durch voranstellen eines # Zeichens auskommentieren [10]. Da diese Änderung jedoch so häufig durchgeführt wurde und ins besondere Fehler in der
/boot/cmdline.txt zu einem nicht bootfähigen System führen können, hat der Nutzer lurch auf Github das Programm rpi-serial-console (https://github.com/lurch/
rpi-serial-console) geschrieben, welches diese Änderung vollautomatisch durchführt. Die Installation erfolgt mit den Befehlen
sudo wget https://raw.github.com/lurch/rpi-serial-console/master/rpi-serial-console
-O /usr/bin/rpi-serial-console Enter
sudo chmod +x /usr/bin/rpi-serial-console Enter
was dafür sorgt, dass das Programm nach /usr/bin/rpi-serial-console heruntergeladen und anschließend ausführbar gemacht wird.
Anschließend können wir mit sudo rpi-serial-console disable die serielle Konsole
von Raspbian deaktivieren. Mit dem Parameter enable diese im Übrigen wieder aktiviert und mit status der aktuelle Zustand der UART abgefragt werden.
Wie auch bei den Änderungen für I2C und SPI werden die Änderungen erst nach
einem Neustart des RPi aktiv.
4.5 Einrichtung Software
Nachdem nun die Hardware soweit vorbereitet ist, beginnen wir damit die entsprechenden Schnittstellen zur Software zu installieren. Als wichtigstes wäre da das Framework wiringpi2 (http://wiringpi.com/), welches die Schnittstelle zwischen Hardware
und weiteren, spezialisierten Libraries für unterschiedliche Programmiersprachen wie
Python oder Java bereitstellt.
4.5.1 Installation von wiringpi2
Um wiringpi2 zu installieren, wechseln wir mit dem Kommando cd ~ ins Heimverzeichnis unseres Nutzers pi. Anschließend laden wir mittels git clone git://git.drogon
.net/wiringPi den Quellcode der Software herunter und wechseln mit cd wiringPi/
in das entsprechende Verzeichnis. Mit dem Kommando ./build starten wir schließlich den Build Prozess, sorgen also dafür dass das Programm kompiliert und installiert
wird. Dies kann einige Minuten dauern. Nach dem Abschluss des Vorgangs kann man
als ersten Test mit dem Kommando gpio -v Informationen über die Software, sowie
den verwendeten RPi Type (Model B, Rev.2) ausgeben lassen.
gpio version: 2.20
Copyright (c) 2012-2014 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
27
4 Konfiguration von Raspbian
For details type: gpio -warranty
Raspberry Pi Details:
Type: Model B, Revision: 2, Memory: 512MB, Maker: Sony
Und schließlich mittels gpio readall alle GPIO Pins auf ihren Status abfragen.
+-----+-----+---------+------+---+-Model B2-+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name
| wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
|
|
|
3.3v |
|
| 1 || 2 | |
| 5v
|
|
|
| 2 | 8 | SDA.1 | ALT0 | 1 | 3 || 4 | |
| 5V
|
|
|
| 3 | 9 | SCL.1 | ALT0 | 1 | 5 || 6 | |
| 0v
|
|
|
| 4 | 7 | GPIO. 7 | IN | 0 | 7 || 8 | 1 | ALT0 | TxD
| 15 | 14 |
|
|
|
0v |
| | 9 || 10 | 1 | ALT0 | RxD
| 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 0 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | |
| 0v
|
|
|
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |
|
|
|
3.3v |
|
| 17 || 18 | 0 | IN
| GPIO. 5 | 5
| 24 |
| 10 | 12 |
MOSI | ALT0 | 0 | 19 || 20 |
|
| 0v
|
|
|
| 9 | 13 |
MISO | ALT0 | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 |
SCLK | ALT0 | 0 | 23 || 24 | 1 | ALT0 | CE0
| 10 | 8 |
|
|
|
0v |
| | 25 || 26 | 1 | ALT0 | CE1
| 11 | 7 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| 28 | 17 | GPIO.17 |
IN | 0 | 51 || 52 | 0 | IN | GPIO.18 | 18 | 29 |
| 30 | 19 | GPIO.19 |
IN | 0 | 53 || 54 | 0 | IN | GPIO.20 | 20 | 31 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name
| wPi | BCM |
+-----+-----+---------+------+---+-Model B2-+---+------+---------+-----+-----+
4.5.2 Installation von wiringpi2-python
Als Bindeglied zwischen wiringpi2 und der Programmiersprache Python dient die Library wiringpi2-python (https://github.com/Gadgetoid/WiringPi2-Python). Um diese einzurichten, müssen wir vorher noch einige Erweiterungen für Python installieren:
sudo apt-get update Enter
sudo apt-get install python-setuptools python-dev Enter
Anschließend erfolgt die eigentliche Installation:
cd ~ Enter
git clone https://github.com/Gadgetoid/WiringPi2-Python.git Enter
cd WiringPi2-Python/ Enter
sudo python setup.py install Enter
Um die Funktionalität der Library zu testen möchten wir, wie auch mit gpio -v ermittelt, die Revision unseres RPi Boards anzeigen lassen - diesmal allerdings in Python.
28
4.5 Einrichtung Software
Wir beginnen also in dem wir mit dem Befehl sudo python die Umgebung starten. Anschließend importieren wir die wiringpi2 Library mittels import wiringpi2 und lassen
uns die Revision des Boards ausgeben wiringpi2.piBoardRev(). Als Ausgabe erhalten
wir wieder >> 2. Damit war der Test erfolgreich und wir können Python mit exit()
verlassen.
4.5.3 Test des SPI Bus (Optional)
Um Funktionalität des SPI Bus zu testen, müssen wir die GPIO Pins 9 (MISO) und 10
(MOSI) kurzschließen. Anschließend muss das Testskript heruntergeladen, kompiliert
und ausgeführt werden:
cd ~ Enter
wget http://www.nico-maas.de/spidev_test.c Enter
gcc spidev_test.c -o spidev_test Enter
./spidev_test Enter
Sofern die Ausgabe nicht ausschließlich aus Nullen besteht, war der Loopback Test
erfolgreich:
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)
FF FF FF FF FF FF
40 00 00 00 00 95
FF FF FF FF FF FF
FF FF FF FF FF FF
FF FF FF FF FF FF
DE AD BE EF BA AD
F0 0D
Damit wären alle Vorbereitungen abgeschlossen und wir können mit der Nutzung
des Raspberry Pi beginnen.
29
5 GPIO Schnittstelle
Nachdem alle Vorbereitungen zur Nutzung der GPIO Schnittstelle in den letzten Kapiteln getroffen wurden, wird das Ziel in diesem Kapitel sein, mehr über diese Schnittstelle und deren Funktionen zu lernen. Es werden die grundlegenden Sicherheitshinweise
im Umgang mit der Schnittstelle erörtert, wie auch die Funktion der einzelnen Bus Systeme. Zum Schluss wird das Erweiterungsboard, welches für diese Arbeit entwickelt
wurde, erklärt und mittels einer Testsoftware in C auf Funktionalität getestet.
5.1 Aufbau
Die GPIO Schnittstelle ist eine der besonderen Eigenschaften, welche den Raspberry
Pi von einem normalen PC unterscheidet. Durch diese Anschlüsse kann der RPi mit
zahlreichen Sensoren, Aktoren und Schaltern verbunden werden, um eine Vielzahl von
Einsatzzwecken zu ermöglichen. Zu diesem Zweck verfügt die GPIO Leiste über mehrere Arten von Pins:
• Einfache GPIO Pins
• GPIO Pins mit Zusatz- / Alternativfunktionen
• 3,3 Volt / 5 Volt / Ground Anschlüsse
Die genannten Pins können in nachfolgender Abbildung 5.1 eingesehen werden:
Abbildung 5.1: GPIO Schnittstelle Raspberry Pi Modell A / B / B+ [11]
Im vorangegangenen Kapitel 4 haben wir bereits die Alternativfunktionen einiger
Pins erwähnt und diese auch für die spätere Nutzung aktiviert. Bevor wir uns aller-
31
5 GPIO Schnittstelle
dings näher mit den Pins und deren Funktion beschäftigten, müssen wir uns zuerst mit
den Einschränkungen des Raspberry Pi und dessen GPIOs vertraut machen.
5.2 Sicherheitshinweise
5.2.1 Logik Level
Der Raspberry Pi arbeitet mit einem Logik Level von 3,3 Volt. Dies bedeutet, dass die
interne Schaltung des Einplatinen Computers die Spannung 3,3 Volt als „HIGH“ oder
„TRUE“ erkennt, während 0 V (Ground) als „LOW“ oder „FALSE“ interpretiert wird.
Im Bereich der MCU (z.B. Arduino) und SoC (z.B. Raspberry Pi) sind die Verwendung
von Spannungen im Bereich von 1,8 Volt, 3,3 Volt und 5 Volt üblich. Im Unterschied
zu z.B. dem Arduino ist der Raspberry Pi allerdings keines Falls 5 Volt tolerant, was
bedeutet, dass niemals mehr als 3,3 Volt direkt an einen der GPIO Pins angelegt werden
dürfen, da sonst das SoC beschädigt werden könnte.
5.2.2 Sicherungen
Der Raspberry Pi verfügt über eine 1,1 Ampere (Modell A und B), respektive 2 Ampere
(Modell B+) starke Polyfuse welche direkt an den Micro USB Port der Spannungsversorgung angeschlossen ist. Die GPIO Pins selbst verfügen über keinerlei Schutz gegen
Verpolung, Kurzschluss oder Überspannung. Daher sollten Änderungen an den GPIO
Pins nur im ausgeschalteten / stromlosen Zustand des RPi gemacht werden.
5.2.3 Belastbarkeit der Pins / 3,3 Volt Schiene
Die 3,3 Volt Versorgung des Raspberry Pi wurde ursprünglich so entworfen, das jeder
der 17 Pins mit 3 mA belastet werden konnte, was eine Gesamtbelastbarkeit von 51
mA ergibt. Allerdings bezieht sich diese Bewertung nur darauf, wenn alle Pins genutzt
werden. Prinzipiell ist jeder Pin in der Lage bis zu 16 mA belastet zu werden - solange
die feste Gesamtlast 51 mA nicht überschreitet, weil sonst Schäden an der Hardware
auftreten können [16].
Diese Zahlen beziehen sich ausschließlich auf die Raspberry Pi Modelle A und B, das
neue Modell B+ erhielt eine neue Spannungsversorgung und stellt weitere GPIO Pins
zur Verfügung. In wieweit dadurch die Versorgung der GPIO Pins verbessert wurde,
ist noch nicht publiziert wurden.
5.2.4 Belastbarkeit der 5 Volt Schiene
Die 5 Volt Versorgung wird beim Raspberry Pi Modell A und B durch eine 1,1 Ampere Polyfuse eingeschränkt, welche selbst ca. 100 mA Stromabfall bewirkt. Daher ist die
Belastbarkeit durch die Differenz aus der Beschränkung der Polyfuse und dem Eigenbedarf des Raspberry Pi, sowie weiterer angeschlossener Geräte zu errechnen. Beim
Raspberry Pi Modell A (ca. 500 mA) erhält man daher 500 mA, beim Modell B (ca. 700
32
5.3 GPIO
mA) 300 mA Reserven für z.B. Erweiterungsplatinen oder USB Geräte. Beim Modell B+
wurde die Polyfuse auf 2 Ampere erhöht und zusätzlich durch die neue Spannungsversorgung der Strombedarf des Raspberry Pi selbst reduziert, weshalb man davon ausgehen kann, dass die zusätzlichen Reserven dort - je nach verwendetem Netzteil - mehr
als 1,3 Ampere betragen können.
5.2.5 Zusammenfassung
• Nur im ausgeschalteten Zustand an der GPIO Leiste arbeiten
• Keine Spannungen über 3,3 Volt an den Raspberry Pi anschließen
• Keine Pins kurzschließen
• Schaltung immer doppelt auf Verpolung / falsche Belegung überprüfen
• Belastbarkeit beachten, größere Lasten z.B. mit Transistor schalten
5.3 GPIO
Wie bereits in Abbildung 5.1 dargestellt, verfügt die GPIO Schnittstelle über eine Vielzahl an unterschiedlichen Pins deren Möglichkeiten wir nun genauer erörtern werden.
5.3.1 GPIO
Die in grüner Farbe gekennzeichneten Pins stellen die normalen GPIO Pins ohne weitere Zusatzfunktionen da. Diese Pins dienen je nach Nutzereinstellung als digitale Einoder Ausgabe und können entweder über Einsatz des gpio Programms aus dem wiringpi2 Package, oder direkt per echo angesteuert werden. Als erster Schritt muss zuerst der
entsprechende GPIO Pin exportiert, also für die Nutzung im Linux Userspace vorbereitet werden. Anschließend muss die Art der Verwendung angegeben werden, also
ob der Pin zur Ein- oder Ausgabe dienen soll. Abschließend kann der Status des Pins
ausgelesen, beziehungsweise „HIGH“ oder „LOW“ gesetzt werden - je nach Einsatzzweck.
# Beispiel für die direkte Verwendung in Bash mittels echo
# Pin 24 exportieren
sudo echo "24" > /sys/class/gpio/export
# Pin 24 als Ausgabe festlegen
echo "out" > /sys/class/gpio/gpio24/direction
# Pin 24 auf HIGH setzen
echo 1 > /sys/class/gpio/gpio24/value
# Pin 24 auf LOW setzen
echo 0 > /sys/class/gpio/gpio24/value
# Export von Pin 24 aufheben
33
5 GPIO Schnittstelle
echo "24" > /sys/class/gpio/unexport
# Pin 27 exportieren
sudo echo "27" > /sys/class/gpio/export
# Pin 27 als Eingabe festlegen
echo "in" > /sys/class/gpio/gpio27/direction
# Pin 27 auslesen
cat /sys/class/gpio/gpio27/value
# Export von Pin 27 aufheben
echo "27" > /sys/class/gpio/unexport
Die Verwendung mit dem Tool gpio geht noch etwas einfacher und benötigt keine
root Rechte:
# Beispiel für die direkte Verwendung in Bash mittels gpio
# Pin 24 exportieren und als Ausgabe festlegen
gpio export 24 out
# Pin 24 auf HIGH setzen
gpio -g write 24 1
# Pin 24 auf LOW setzen
gpio -g write 24 0
# Export von Pin 24 aufheben
gpio unexport 24
# Pin 27 exportieren und als Eingabe festlegen
gpio export 27 in
# Pin 27 auslesen
gpio -g read 27
# Export von Pin 27 aufheben
gpio unexport 27
5.3.2 PWM
Pulse-width modulation (PWM) ist ein Verfahren mit welchem die Breite eines ausgegebenen Stromimpulses kontrolliert werden kann. In diesem Zusammenhang wird der
Begriff „duty cycle“ verwendet, um die Dauer des „HIGH“ Zustandes des Pins innerhalb einer Zeiteinheit zu beschreiben. Entspricht der „duty cycle“ z.B. 60%, so führt
der Pin in genau diesem Prozent einer Zeiteinheit Strom. Durch das lückenhafte Versorgen des Gerätes mit Strom sinkt die Spannung je nach „duty cycle“ von 100% auf
bis 0% ab. Mit dieser Technik können damit nicht nur die Helligkeit von LEDs kontrolliert werden, sondern im Sonderfall auch die Stellung von Servo Motoren. PWM ist
bei dem Raspberry Pi auf dem GPIO 18 verfügbar. Aufgrund der besonderen Technik
(prinzipiell dem schnellen, kontrollierten Ein- / Ausschalten des Pins) ist eine sinnvolle
Nutzung mittels echo Befehls nicht gegeben. Allerdings kann auch in diesem Fall das
Programm gpio genutzt werden:
34
5.3 GPIO
# Beispiel für die direkte Verwendung in Bash mittels gpio
# Pin 18 exportieren und als Ausgabe festlegen
gpio export 18 out
# Pin 18 in PWM Modus versetzen
gpio -g mode 18 pwm
# Pin 18 als PWM auf 100% duty cycle setzen
gpio -g pwm 18 1023
# Pin 18 als PWM auf 25% duty cycle setzen
gpio -g pwm 18 256
# Pin 18 als PWM auf 10% duty cycle setzen
gpio -g pwm 18 102
# Pin 18 als PWM auf 1% duty cycle setzen
gpio -g pwm 18 10
# Pin 18 als PWM auf 0% duty cycle setzen
gpio -g pwm 18 0
# Export von Pin 18 aufheben
gpio unexport 18
5.3.3 I2C
Inter-Integrated Circuit (I2C) ist ein Bussystem, welches 1982 von der Firma Philips
(heute: NXP Semiconductors) veröffentlicht wurde. Dieses System sollte vorrangig dazu genutzt werden, einzelne Komponenten innerhalb eines geschlossen Systems miteinander zu verbinden, z.B. Mikrocontroller mit verschiedenen Arten von Sensoren,
Speichern und Analog/Digital bzw. Digital/Analog Wandlern. Da das System neben
der Versorgungsspannung und Masse nur zwei Leitungen (SDA für Daten, SCL für
Takt) benötigt wird es auch als Two Wire Interface (TWI) bezeichnet. SDA wie SCL müssen durch einen hochohmigen Widerstand an die Versorgungsspannung angeschlossen
werden, da der Bus im Leerlauf Konstant „HIGH“ signalisiert (Pull-Up). In einem normalen I2C Netzwerk erzeugt der Master, meist ein Mikrocontroller, den Takt für den
SCL Port und fragt die einzelnen Slaves, meist simple Sensoren oder Signalwandler,
unter Verwendung des SDA Ports ab. Es ist allerdings auch möglich Master-Master
Netzwerke zu erstellen und Teilnehmer bei aktivem Netzwerk an- und abzuklemmen
(Hot-Swap) [25], S. 444 / [19].
Der Raspberry Pi verfügt über zwei I2C Busse. Bei der Revision pre 2.0 wurde nur der
Bus 0 auf dem GPIO Header ausgeführt. Mit dem Wechsel zur Revision 2.0 wanderte
der Bus 0 auf ein zusätzliches Verbindungsfeld (P5) und auf dem GPIO Header lag
nun der Bus 1 an. Beim Modell B+ änderte sich dieser Zustand dahingehend, dass der
Header P5 wieder entfiel, der Bus 1 weiterhin auf seiner Stelle auf dem GPIO Header
verblieb und der Bus 0 fortan als ID_I2C geführt wurde und für die Nutzung durch den
Anwender nicht mehr verfügbar war.
Der I2CBus auf dem Raspberry Pi arbeitet in der Standard Geschwindigkeit (100
kHz) und im Fast-Mode (400 kHz). Theoretisch kann ein I2C Bus bis zu 127 Teilneh-
35
5 GPIO Schnittstelle
mer adressieren.
Mittels des Befehls i2cdetect -y 1 können alle Geräte auf dem Bus 1 angezeigt werden:
00:
10:
20:
30:
40:
50:
60:
70:
0 1
--------
--------
2 3
--- --- --- --- --- --- --- --
4
---------
5
---------
6
---------
7
---------
8
----48
---
9
--------
a
--------
b
---UU
----
c
--------
d
--------
e
--------
f
--------
Unter anderem ist hier die Adresse 0x48 angezeigt, welches die hexadezimale Adresse eines LM75B Temperatursensors ist. Da laut Datenblatt dieses Sensors die Temperatur bei diesem Gerät im ersten Register liegt, können wir nun mit dem Befehl i2cget
-y 1 0x48 0x00 auf dem Bus 1 an der Geräteadresse 48 das Register 0 auslesen. Wir
erhalten die Antwort in Form einer hexadezimalen Notation, z.B. 0x23, was im dezimal
System einer Temperatur von 35 Grad Celsius entspricht.
5.3.4 I2S
Nach dem Erfolg von I2C folgte 1986 Philips Erweiterung I2S. Dabei handelt es sich
um ein Bussystem, welches ausschließlich zur Verwendung innerhalb von Audiogeräten vorgesehen war. Es wurden hierbei wieder ein Takt Signal (SCK) und ein Daten
Signal (SD) verwendet, zusätzlich wurden diese beiden Leitungen allerdings noch um
eine sogenannte Word Select (WS) Leitung ergänzt. Je nachdem ob sich Word Select
im Zustand „LOW“ oder „HIGH“ befindet, werden die übertragenen Daten dem linken, respektive rechtem Audiokanal zugeordnet. Da die Übertragung vollständig digital geschieht, ist sie verlustfrei und daher für die Verbindung von z.B. Digitalen Signal
Prozessoren und Digital/Analog Wandlern geeignet.
Beim Raspberry Pi ist der I2S Bus bei der Revision pre 2.0 nicht vorhanden, bei der
Revision 2.0 auf dem Header P5 zu finden und bei dem Modell B+ auf dem GPIO
Header. [21]
5.3.5 SPI
Der Serial Peripheral Interface (SPI) Bus wurde 1979 von Motorola in Form eines Mikrocontrollers auf Basis des Motorola 68000 Mikroprozessors veröffentlicht. Im Gegensatz
zum I2C Bus von Philips wurde er nicht getrennt formal beschrieben, sondern ist nur
vage in den Unterlagen des Controllers als Teil dessen definiert [15]. Das SPI System
verwendet vier Anschlüsse: Takt (SCLK), Master Out - Slave In (MOSI), Master In -
36
5.3 GPIO
Salve Out (MISO), sowie Slave Select (SS). Der Takt wird hierbei konstant vom Master über SCLK vorgegeben, und die Daten je nach Senderichtung entweder über MOSI
(vom Master zum Slave) oder MISO (vom Slave zum Master) ausgetauscht. Zusätzlich
muss für jedes zu adressierende Gerät im Bus eine Slave Select Leitung bereitstehen.
Diese wird vom Master auf „LOW“ gezogen, um den Slave in Empfangsbereitschaft
zu schalten. Der Vorteil dieses Systems liegt in der vollduplexfähigen Kommunikation,
der Nachteil in der Anzahl der benötigten n Slave Select Leitungen pro n Geräte in der
Sternverbindung. Sollte man kompatible Slave Geräte gleicher Bauart verwenden, so
können diese auch kaskadiert werden, womit nur eine Slave Select Leitung nötig ist.
Die Geräte können dann wie ein Schieberegister ausgelesen werden [25], S. 440.
Auf dem Raspberry Pi sind drei SPI Controller verfügbar, jedoch nur einer auf die
GPIO Leiste ausgeführt. Der Controller kann auf 0.5 MHz, 1 MHz, 2 MHz, 4 MHz, 8
MHz, 16 MHz und 32 MHz Taktrate eingestellt werden [13]. Die maximal verwendbare
Taktrate hängt aber auch vom verwendeten Slave ab.
SPI kann unter Raspberry Pi am besten über die entsprechende Library mittels Python oder C angesteuert werden.
5.3.6 Serial
Die serielle Schnittstelle (auch V.24 oder RS-232-C genannt) wurde 1969 von der Electronic Industries Association (EIA) für die Nutzung im Computer Umfeld definiert, was
den ursprünglichen Einsatzzweck von RS-232 im Umfeld der Fernschreiber erweiterte
[7]. Serielle, asynchrone Verbindungen wurden vor den Zeiten der Breitbandverbindungen genutzt um Modems mit dem Computer zu verbinden um Zugriff zum Internet oder dem Telefonnetz herzustellen. Mit dem Aufkommen von A-/S-DSL und Kabelbreitbandverbindungen wurde diese Schnittstelle an regulären Rechnern immer unwichtiger, kann aber bis heute vorgefunden werden. Eine besondere Bedeutung nimmt
dieses Interface weiterhin bei eingebetteten Systemen, Mikrocontrollern, GPS Empfängern, wissenschaftlichen Geräten sowie Netzwerkequipment und Servern ein. Die
Übertragung der seriellen Schnittstelle erfolgt prinzipiell über zwei Adern: RX (Recieve) und TX (Transmit). Die Verbindung muss direkt zwischen Sender und Empfänger
hergestellt und die beiden Datenadern überkreuzt angeschlossen werden, also RX des
Senders auf TX des Empfängers und umgekehrt. Zusätzlich muss die Masse (GND)
beider Systeme miteinander verbunden werden. Als Geschwindigkeiten werden häufig 4800, 9600, 19200 und 115200 Baud (Zeichen pro Sekunde) verwendet. Eine Besonderheit ist im Bereich von eingebetteten Systemen, Mikrocontrollern, GPS Empfängern
und anderen Klein- und Kleinstgeräten zu beachten: Im Gegensatz zu den im RS-232C definierten Signalpegeln von -15 Volt bis +15 Volt [12] setzen diese Geräte oft einen
sogenannten TTL Pegel (Transistor-Transistor Logic) ein, welcher zwischen 0 Volt und
3,3 Volt, respektive 5 Volt liegen kann. Dies trifft auch auf den Raspberry Pi zu, weshalb dessen serielle Schnittstelle in keinem Fall direkt mit dem PC zu verbinden ist,
da sonst eine Beschädigung des SoC des Raspberry Pi möglich ist. Durch die Nutzung
eines TTL-Serial Konverters ist diese Verbindung gefahrlos möglich.
37
5 GPIO Schnittstelle
Auf dem Raspberry Pi kann die serielle Schnittstelle auf verschiedene Arten genutzt
werden. Zum einen um einen GPS Empfänger anzuschließen, einen Mikrocontroller
mit Arduino Bootloader zu programmieren oder um Modell A Boards ohne Netzwerkinterface per PPP (Point-to-Point Protocoll) in ein Netzwerk zu integrieren.
Ein einfaches und empfehlenswertes Tool um die serielle Schnittstelle zu nutzen,
stellt minicom dar.
5.4 Das Erweiterungsboard
Um die Nutzung der GPIO des Raspberry Pi zu ersten Testzwecken so einfach wie
möglich zu machen, wurde im Rahmen dieser Thesis ein Erweiterungsboard entworfen
und zur Verwendung im Rahmen der Lehre der HTW Saar in zehnfacher Stückzahl
aufgebaut.
5.4.1 Design
Das Design sollte so ausgelegt sein, dass es möglichst klein, kostengünstig und dennoch
vielseitig verwendbar sein sollte. Durch die Entwicklung des Boards sollten besonders
Fehler die beim Aufbau der Schaltungen mit der GPIO Leiste auftreten könnten verhindert werden, und der Fokus auf die Entwicklung der Software gelegt werden. Da zum
Zeitpunkt des Beginns dieser Thesis der Raspberry Pi Modell B+ noch nicht verfügbar
war, wurde die Platine auf Basis des Modell A/B Rev. 2.0 entwickelt und ist auf beiden
Versionen ohne Einschränkungen verwendbar. Ebenfalls ist die Nutzung mit dem neuen Modell B+ möglich, wobei allerdings keine korrekte mechanische Entlastung wie bei
den Modellen A/B Rev. 2.0 durch ein passendes Bohrloch gegeben ist.
Das Erweiterungsboard stellt folgende Merkmale zur Verfügung:
• Vier einfarbige LEDs
• Vier Taster
• LM75B (I2C Temperatursensor)
• MCP3002 (SPI Zweikanal Analog/Digital Wandler) mit angeschlossenem Light
Dependent Resistor (LDR)
Dabei sind die LEDs in einem Steuerkreuz angeordnet und den betreffenden Tastern
zugeordnet.
5.4.2 Routing
Die Belegung und Anschlüsse der einzelnen Komponenten auf dem Erweiterungsboard lässt sich der angefügten Grafik und Tabelle entnehmen.
38
5.4 Das Erweiterungsboard
LM75B
Nor
t
h
Eas
t
Wes
t
Sout
h
Bauteil
Bemerkung
GPIO
LED North
grün, PWM
18
LED East
rot
23
LED West
gelb
25
LED South
blau
24
Switch North
Pull-Down
4
Switch East
Pull-Down
17
Switch West
Pull-Down
22
Switch South
Pull-Down
27
LM75B
SDA
2
SCL
3
MOSI
10
MISO
9
SCLK
11
CS / SS
8
MCP3002
MCP3002
Abbildung 5.2 & Tabelle 5.1: Erweiterungsboard und Routing der Komponenten
Als Besonderheiten sei dabei zu erwähnen, dass die erste LED (LED North / grün)
am PWM Anschluss des RPi angeschlossen ist, um die Nutzung dieses Verfahrens zu
demonstrieren.
Die LEDs selbst werden nicht direkt von den GPIO Pins versorgt, sondern schalten
einen Transistor, welche wiederum die Schaltlast übernimmt und die LEDs mit 5 Volt
Spannung versorgt.
Weiterhin werden die Taster durch einen Pull-Down Widerstand konstant auf „LOW“
gezogen, sind also mit der Masse des Raspberry Pi verbunden. Es ist üblich Taster entweder per Pull-Down auf „LOW“ oder per Pull-Up auf „HIGH“ zu ziehen, um einen
stets definierten Zustand zu erreichen. Erst beim Schließen des Kontaktes wird der entsprechende GPIO Port mit 3,3 Volt Spannung verbunden.
Zur Temperaturmessung steht ein LM75B zur Verfügung, ein I2C Sensor, welcher direkt auf dem Board verbaut ist. Durch das normale Auslesen des Wertes mittels i2cget
erhält man den Temperaturwert in 8 bit Darstellung, also nur Abstufungen von einzelnen Grad. Möchte mit die kompletten 11 bit Auflösung des Sensors ausnutzen, also eine
Auflösung von bis zu 0,125 Grad Celsius Unterschied erreichen, so muss das entsprechende Register in doppelter Byte Länge ausgelesen und ausgewertet werden. Dazu
kommen wir in einem späteren Kapitel.
Der erwähnte Lichtsensor (LDR) verhält sich wie ein Widerstand und erreicht je nach
einfallendem Licht Werte zwischen 40,5 k und 1 M Ohm. Da der Raspberry Pi allerdings
39
5 GPIO Schnittstelle
über keinen Analog/Digital Wandler verfügt um z.B. eine Spannungsmessung durchzuführen, wird der an einem MCP3002 angeschlossen, einem externen Analog Digital
Converter (ADC) welcher über SPI angesprochen wird.
Insgesamt bleiben damit ausschließlich die GPIO Pins 14 und 15 (TX/RX der Serial
Verbindung) und GPIO 7 (SPI Slave Select 1) ungenutzt.
5.4.3 Testprogramm
Um die Funktionalität des Erweiterungsboards zu überprüfen, gibt es im Home Verzeichnis des Raspberry Pi Hauptnutzers pi den Unterordner RPi_HTW/boardTest, welchen das in C geschrieben Testprogramm boardTest beinhaltet. Es verwendet die bereit
vorher installierte wiringpi2 Library, um die unterschiedlichen Funktionen des Erweiterungsboards auf Funktionalität zu überprüfen. Dazu gehören die LEDs, die PWM
Funktionalität, die Schalter wie auch der I2C Bus mit dem angeschlossenen LM75B
Temperatursensor und dem SPI Bus mit dem MCP3002 ADC Wandler. Letzterer gibt
auf Kanal 0 den Helligkeitswert des angeschlossenen LDR wieder. Um es zu nutzen
muss es zuerst kompiliert werden, was der Aufruf von make erledigt. Anschließend
kann das Programm unter Verwendung von sudo sudo ./boardTest gestartet werden.
Eine Beispielausgabe sieht wie folgt aus:
LED Test beginnt
NORTH: LED gruen
EAST: LED rot
WEST: LED gelb
SOUTH: LED blau
LED Test beendet
PWM Test beginnt
PWM Test beendet
Switch Test beginnt
NORTH: Switch druecken
NORTH: Switch ok
EAST: Switch druecken
EAST: Switch ok
WEST: Switch druecken
WEST: Switch ok
SOUTH: Switch druecken
SOUTH: Switch ok
Switch Test beendet
LM75B Temperatursensor Test beginnt
LM75B: 34.12 Grad Celsius
LM75B: 34.25 Grad Celsius
LM75B: 34.12 Grad Celsius
LM75B: 34.12 Grad Celsius
LM75B: 33.88 Grad Celsius
40
5.4 Das Erweiterungsboard
LM75B: 34.00 Grad Celsius
LM75B: 34.00 Grad Celsius
LM75B: 34.00 Grad Celsius
LM75B: 34.12 Grad Celsius
LM75B: 34.00 Grad Celsius
LM75B Temperatursensor Test beendet
MCP3002 ADC Test beginnt
MCP3002 - Channel 0: 232
MCP3002 - Channel 0: 320
MCP3002 - Channel 0: 348
MCP3002 - Channel 0: 72
MCP3002 - Channel 0: 48
MCP3002 - Channel 0: 300
MCP3002 - Channel 0: 332
MCP3002 - Channel 0: 724
MCP3002 - Channel 0: 612
MCP3002 - Channel 0: 616
MCP3002 ADC Test beendet
Die boardTest.c ist im Anhang D.1 verzeichnet. Sollte ein eigenes Programm ohne die
make File kompiliert werden, so ist es wichtig, den Schalter -lwiringPi anzugeben. Beispielsweise: gcc -o test test.c -lwiringPi.
41
6 Bash Programmierung
In diesem Kapitel soll die Nutzung des Erweiterungsboards unter Verwendung der
Bash anhand eines Beispielprojektes aufgezeigt werden: Ziel wird es sein, einen Klon
des alten elektronischen Spiels „Simon“ zu erstellen, und damit die in der Vorlesung
„Betriebssystem Einführung“ gelernten Grundlagen zu vertiefen und festigen.
6.1 Grundlagen
6.1.1 Simon
Simon ist ein 1977 erfundenes, elektronisches reaktions- und Merkspiel auf Basis des
Texas Instruments TMS1000 Mikrocontrollers [18]. Simon verfügt über vier LEDs (grün,
rot, blau, gelb) und entsprechend, den Farben zugewiesene Taster. Das Spiel beginnt in
dem eine zufällige Farbe auf dem Spielzeug aufleuchtet und der Spieler eben dem dieser Farbe entsprechenden Schalter drückt. War er erfolgreich, werden in der nächsten
Runde die Farbe des ersten Zyklus plus eine weitere Farbe vorgegeben, welcher der
Spieler wieder in der richtigen Reihenfolge eingeben muss. Das Spiel endet falls der
Spieler eine falsche Kombination eingibt.
Abbildung 6.1: Simon
43
6 Bash Programmierung
6.1.2 Ablaufdiagramm
Ein prinzipieller grober Ablauf des Spiels ist in Abbildung 6.2 aufgezeigt. Darüber hinaus empfiehlt es sich zusätzlich den Start und das Ende des Programms durch die Verwendung aller LEDs zu kennzeichnen und gegeben falls einen rekursiven Aufruf beim
Ende durchzuführen.
Abbildung 6.2: Flowchart Simon
6.2 Programmierung
Alle genannten Dateien sind im Home Verzeichnis des Hauptnutzers pi im Unterordner RPi_HTW/Simon zu finden.
44
6.2 Programmierung
6.2.1 Erweiterungsboard und Hilfsfunktionen
Das Erweiterungsboard bietet für dieses Projekt die vier genannten LEDs, nebst den
benötigten Schaltern. Um die Entwicklung zu vereinfachen steht die gpio.sh im Anhang
D.2 zur Verfügung, welche die benötigten Funktionen zur Nutzung der an die GPIO
Pins angeschlossenen LEDs und Schalter bereitstellt. Für jede LED existiert jeweils eine Funktion, um diese ein-, beziehungsweise auszuschalten. Für die Schalter gibt es
jeweils eine Funktion, welche den aktuellen Status zurück gibt (0 für „LOW“ beziehungsweise nicht gedrückt, 1 für „HIGH“ beziehungsweise gedrückt).
• ledNorthOn()
• ledNorthOff()
• ledEastOn()
• ledEastOff()
• ledWestOn()
• ledWestOff()
• ledSouthOn()
• ledSouthOff()
• switchNorth()
• switchEast()
• switchWest()
• switchSouth()
Neben diesen Funktionen gibt es noch mehrere Hilfsfunktionen:
• ledOn()
• ledOff()
• ledBlink()
• ledBlinkFast()
Die beiden ersten Hilfsfunktionen schalten alle LEDs an, beziehungsweise aus. Die
letzteren beiden lassen jeweils alle LEDs einmal mit einem Abstand von 0,5, respektive 0,25 Sekunden aufblinken. In den nachfolgenden beiden Unterkapiteln werden wir
diese Funktionen nutzen.
45
6 Bash Programmierung
6.2.2 LED Ausgabe
Um eine LED per Bash anzusteuern, können wir unter Verwendung der gpio.sh folgendes Skript erstellen:
# !/ bin / bash
source gpio . sh
ledNorthOn
sleep 2
ledNorthOff
Mit source gpio.sh binden wir die gpio.sh und ihre Hilfsfunktionen ein, welche wir
mit ledNorthOn beziehungsweise ledNorthOff nutzen um die grüne LED an- beziehungsweise auszuschalten. sleep 2 rundet das ganze Programm ab und erzeugt eine Pause
von zwei Sekunden, damit der sonst zu schnelle Schaltvorgang für das menschliche
Auge sichtbar wird. Das Codelisting der demoLed.sh ist als Langversion auch im Anhang D.3 verfügbar. Nachdem die Datei erstellt wurde, muss sie unter Verwendung des
Befehls chmod +x dateiname ausführbar gemacht, und anschließend mittels ./dateiname
gestartet.
6.2.3 Switch Eingabe
Die Eingabe ist wie die LED Ausgabe ebenfalls sehr einfach zu bewerkstelligen:
# !/ bin / bash
source gpio . sh
while :
do
if [ $ ( switchNorth ) = 1 ]
then
echo " North gedrueckt "
ledNorthOn
else
ledNorthOff
fi
done
Das Programm läuft in diesem Beispiel in einer endlosen Schleife, welche mittels
der Tastenkombination Strg + C unterbrochen werden kann. Durch die while Schleife
wird ständig geprüft, ob der Schalter North gedrückt wurde. Ist dies der Fall, wird eine
entsprechende Nachricht ausgegeben, und die dazu passende LED angeschaltet. Sollte
dem nicht so sein, wird die LED ausgeschaltet. Es gibt auch die Möglichkeit Pins nicht
per polling, also dauerndem Abfragen auf einen Wechsel des Zustandes zu überprüfen,
sondern per Interrupt. Dies setzt aber eine höhere Programmiersprache voraus und
ist daher leider in Bash nicht möglich (siehe dazu: http://wiringpi.com/reference/
priority-interrupts-and-threads/).
46
6.3 Abschluss
6.3 Abschluss
Mit den hier gelernten Grundlagen, sowie dem Wissen aus der Vorlesung „Betriebssystem Einführung“ sollte es nun möglich sein, einen einfachen Klon des Spiels Simon
mittels des Raspberry Pi und dem Erweiterungsboard zu erschaffen. Das Musterprogramm simon.sh ist im Anhang D.5 zu finden, allerdings nicht auf der SD Karte vorinstalliert, um die Studenten zur Entwicklung einer eigenen Lösung anzuhalten.
47
7 Python Programmierung
Nachdem wir im vorangegangenen Kapitel die Nutzung der GPIO mittels Bash gelernt
haben, wollen wir diese Fähigkeiten nun mit der Programmiersprache Python vertiefen. Dieses Kapitel soll als leichter Einstieg in die Sprache Python die Grundlagen für
die Vorlesung „Systemmanagement und Sicherheit“ liefern, wie auch die praktische
Nutzung von Bus Systemen, wie sie in „Rechnerarchitektur“ und „Mikroprozessortechnik“ gelehrt werden verdeutlichen. Am Ende dieses Kapitels werden sowohl die
Grundlagen zur Nutzung von Python gelegt, als auch der I2C, wie auch der SPI Bus, in
die Nutzung eingeflossen sein.
7.1 Arbeiten auf dem Raspberry Pi
7.1.1 Python 2 / Python 3
Python ist ähnlich wie PHP, eine Skriptsprache die zur Ausführung einen Interpreter
benötigt. Von Python gibt es inzwischen zwei verschiedene Versionen: Python 2 (2.7.x)
und Python 3 (3.4.x). Python 3 enthält Verbesserungen, welche allerdings die Kompatibilität unter anderem wegen der Entfernung redundanter Befehle zu alten Skripten
brechen kann. Da die Version 2 bereits länger existiert, viele Bibliotheken nur in dieser
Version funktionieren, und dieser Branch immer noch mit aktuellen Updates versorgt
wird, ist Python 2 auch auf dem Raspberry Pi die empfohlene und verwendete Standardversion. Sollten durch den vorzeitigen Abbruch eines Programms LEDs im aktiven
Zustand verbleiben, können die GPIO Pins mittels des CLI Kommandos gpio reset zurückgesetzt und damit die LEDs ausgeschaltet werden.
7.1.2 Programmierung mittels IDLE
Verwendet man den Raspberry Pi als vollwertigen PC, empfiehlt sich die Nutzung des
Python Integrated Development Environment (IDE) IDLE. IDLE liegt auf dem RPi in
zwei Versionen vor. Einmal als IDLE (zur Nutzung mittels Python 2) als auch als IDLE3
(welches Python 3 einsetzt). Wie bereits erwähnt werden wir Python 2, und damit das
normale IDLE nutzen. Da die Nutzung der GPIO Pins root Rechte erfordert, sollte man
IDLE nicht per Klick auf das Desktop Icon, sondern mittels LXTerminal unter Verwendung des Befehls sudo idle & starten, um die Anwendung im Kontext des root Nutzers
zu starten. Die Nutzung selbst ist sehr einfach: Über das Menü File, New Window kann
man ein neues Editor Fenster erstellen, in welchem man seinen Python Code schreiben,
laden und speichern kann. Ausgeführt wird dieser Code über das Menü Run per Klick
auf Run Module.
49
7 Python Programmierung
7.1.3 Programmierung mittels CLI
Sollte man den RPi Headless verwenden, also ohne Bildschirm und Eingabegeräte,
empfiehlt sich die Nutzung eines Texteditors wie vi in Kombination mit python direkt
auf Ebene des Command Line Interface (CLI) / der Shell. Dazu sollte man seinen Programmcode mit einem Editor seiner Wahl schreiben, speichern und schließlich direkt
unter Verwendung von sudo python dateiname ausführen.
7.2 Grundlagen der Python Programmierung
7.2.1 Ausführung
Es gibt drei prinzipielle Möglichkeiten ein Python Programm auszuführen: 1.) Die direkte Eingabe der Befehle in eine interaktive Shell wie IDLE oder python auf dem
CLI. 2.) Der direkte Aufruf einer geschriebenen Skriptdatei mittels python dateiname
.py im CLI. 3.) Die Verwendung der Shebang Zeile (#!/usr/bin/python) als erste Zeile
in einer Skriptdatei, gefolgt vom setzen des X / Ausführungbarkeits-Bits (./chmod +x
dateiname.py) und dem anschließenden Aufruf im CLI (./dateiname.py). Um Python
kennen zu lernen empfiehlt sich besonders am Anfang die Arbeit in einer interaktiven
Shell, für die spätere Programmentwicklung die Methoden Zwei und Drei.
7.2.2 Variablen
Variablen werden bei Python durch Zuweisung eines Wertes angelegt:
# !/ usr / bin / python
meinInteger =2+3
meinFloat =5.0
meinString = " Hallo Welt "
print ( meinInteger )
print ( meinInteger / 2)
print ( meinFloat / 2)
print ( meinString + " ! " + " Binaer % s Hex % s " % ( bin ( meinInteger ) , hex (
meinInteger ) ) )
Dies erzeugt die Ausgabe:
5
2
2.5
Hallo Welt ! Binaer 0 b101 Hex 0 x5
7.2.3 Operatoren
Python verwendet die üblichen arithmetischen Operatoren. Besondere Beachtung fällt
dabei auf den verwendeten Datentyp: Sollte ein Integer Wert geteilt werden, so ist das
50
7.2 Grundlagen der Python Programmierung
Tabelle 7.1: Arithmetische Operatoren
Operation
Ergebnis
Bezeichnung
5+5
10
Summe
5-1
4
Differenz
5*1
5
Produkt
5/2
2
Quotient (Integer)
5.0 / 2
2.5
Quotient (Float)
5%2
1
Modulo
2 ** 3
8
Power
Ergebnis ebenfalls ein Integer. Wenn im Rahmen dieser Rechenoperation eine rationale
Zahl entsteht, so wird diese abgerundet und als ganze Zahl dargestellt.
Die Vergleichsoperatoren sind ebenfalls bekannt sofern man Vorkenntnisse in Java
besitzt:
Tabelle 7.2: Vergleichsoperatoren
Operation
Bezeichnung
x == y
Gleichheit
x != y
Ungleichheit
x>y
Größer
x<y
Kleiner
x >= y
Größer-gleich
x<= y
Kleiner-gleich
Da in diesem Dokument mit hardwarenahen Anwendungen gearbeitet wird, ist es
auch von Bedeutung die binären, bitweisen Operatoren zu kennen. Dies ist besonders
wichtig da Geräte in Bussystemen wie I2C oder SPI ihre Ergebnisse in einzelnen Registern speichern, welche meist wenige Byte umfassen. Dabei besitzt häufig jedes Bit
eines Bytes eine eigene Relevanz, zum Beispiel die Konfiguration eines Pins als Einoder Ausgang, je nachdem ob dessen Bit gesetzt ist oder nicht. Durch die binären, bitweisen Operationen können diese Werte entsprechend schnell gesetzt beziehungsweise
ausgelesen werden. Um einen Wert in binärer Schreibweise eingeben zu können, muss
ihm der Präfix 0B vorgestellt werden. So würde zum Beispiel die Zahl 0B11110000 von
Python als 240 verstanden werden. Alternativ können die binären, bitweisen Operationen auch mit den Werten in beliebiger anderer, zum Beispiel dezimaler Schreibweise
angewandt werden.
Die vier wichtigsten Operationen, welche auch schon in den Vorlesungen „Digital-
51
7 Python Programmierung
technik 1“ und „Mikroprozessortechnik“ gelehrt wurden, sollen an dieser Stelle noch
einmal kurz wiederholt werden:
1.) Binäres Und:
Es werden jeweils die Werte gleicher Position beider binärer Notationen per „Und“
miteinander verknüpft. Sollten diese beide „Wahr“ entsprechen, ist auch das Ergebnis
„Wahr“ - sonst „Falsch“.
Tabelle 7.3: Binäres Und
x
y
x&y
0
0
0
0
1
0
1
0
0
1
1
1
2.) Binäres Oder:
Das binäre „Oder“ entspricht der gleichen Wirkungsweise wie „Und“, allerdings wird
die Ausgabe „Wahr“ solange entweder eine oder beide Werte „Wahr“ sind.
Tabelle 7.4: Binäres Oder
x
y
x|y
0
0
0
0
1
1
1
0
1
1
1
1
3.) Binäres XOR:
XOR, welches auch zur Verschlüsselung genutzt wird, erwartet als Voraussetzung für
eine „Wahre“ Ausgabe zwei unterschiedliche Eingaben.
Tabelle 7.5: Binäres XOR
52
x
y
xˆy
0
0
0
0
1
1
1
0
1
1
1
0
7.2 Grundlagen der Python Programmierung
4.) Binäres 1er Komplement:
Das 1er Komplement wird zur Berechnung im Bereich der Mikrocontroller verwendet
und negiert alle Eingaben.
Tabelle 7.6: Binäres 1er Komplement
x
˜x
0
1
1
0
Tabelle 7.7: Binäre, bitweise Operatoren
Operation
Ergebnis
Bezeichnung
x&y
0000 0001 / 1
Binäres Und
x|y
1111 1111 / 255
Binäres Oder
xˆy
1111 1110 / 254
Binäres XOR
˜x
1111 0000 / -16
Binäres 1er Komplement
7.2.4 Vergleiche und Schleifen
Eine wichtige Besonderheit bei Python ist das Fehlen von Klammern zum Kapseln von
Schleifen oder Befehlsfolgen. Stattdessen verwendet Python Einrückungen wie die Tabulator Taste, um den Programmcode zu formatieren und strukturieren. Dies erzeugt
sauberen und lesbaren Code, welcher ohne diese Einrückungen nicht lauffähig ist. Im
nächsten Beispiel wird eine while Schleife und eine verschachtelte if Anweisung gezeigt. Da die letzte Zeile sich auf der gleichen Ebene wie die Vergleiche befinden, ist sie
kein Teil davon und wird nach der Abarbeitung der Vergleiche aufgerufen.
# !/ usr / bin / python
meinInteger =40
while meinInteger < 45:
if meinInteger == 42:
print ( " Integer ist 42! " )
elif meinInteger < 42:
print ( " Integer ist kleiner als 42 " )
else :
print ( " Integer ist groesser als 42 " )
meinInteger += 1
Dies erzeugt die Ausgabe:
Integer ist kleiner als 42
Integer ist kleiner als 42
53
7 Python Programmierung
Integer ist 42!
Integer ist groesser als 42
Integer ist groesser als 42
Die for Schleife kann auf mehrere Art genutzt werden:
# !/ usr / bin / python
# Zaehlschleife , Werte zwischen 0 und 5 ( von 0 -4) ausgeben
for i in range (0 ,5) :
print ( i )
# Äquivalent zur for each
# jedes Element einer Liste verwenden
sprachen = [ " Python " , " Java " , " C " , " Haskell " ]
for i in sprachen :
print ( " % s ist eine Programmiersprache " % i )
# jeden Buchstaben eines Strings ausgeben
meinString = " Hallo Welt "
for i in meinString :
print ( i )
Dies erzeugt die Ausgabe:
0
1
2
3
4
Python ist eine Programmiersprache
Java ist eine Programmiersprache
C ist eine Programmiersprache
Haskell ist eine Programmiersprache
H
a
l
l
o
W
e
l
t
7.2.5 Funktionen
Funktionen werden in Python mittels def definiert. Als Beispiel wollen wir an dieser
Stelle zwei Algorithmen aus der Vorlesung „Programmierung 1“ [9] verwenden, in diesem Fall die Berechnung des größten gemeinsamen Teilers.
54
7.2 Grundlagen der Python Programmierung
# !/ usr / bin / python
import timeit
# Importiere die Python Bibliothek timeit zur Laufzeitmessung von
Funktionen
def ggTintuitiv (m , n ) :
# Definiere die erste Funktion ggTintuitiv , welche die Teiler einzeln
probiert
m = abs ( m )
n = abs ( n )
teiler = 1;
groessterTeiler = 1
while (( teiler <= m ) and ( teiler <= n ) ) :
if ( ( m % teiler == 0 ) and ( n % teiler == 0) ) :
groessterTeiler = teiler
teiler += 1
return groessterTeiler
def ggTeuklid (m , n ) :
# Definiere die zweite Funktion ggTeuklid , welche den Algorithmus nach
Euklid verwendet
m = abs ( m )
n = abs ( n )
r = m % n
while ( r > 0) :
m = n
n = r
r = m % n
return n
t_intuitiv = timeit . Timer ( " ggTintuitiv (12345678 , 23456789) " , " from
__main__ import ggTintuitiv " )
# Erstelle ein neues Objekt von der Klasse Timer .
# Der erste Parameter ist die zur Messung auszuführende Funktion ,
# der zweite Parameter die einmalig auszuführende Setup Anweisung , bei
der wir die zu messende
# Funktion nocheinmal in den Kontext einbinden
zeit_intuitiv = t_intuitiv . timeit (1)
# Führe die Messung einmal durch und schreibe die vergangene Zeit in
die Variable
t_euklid = timeit . Timer ( " ggTeuklid (12345678 , 23456789) " , " from __main__
import ggTeuklid " )
zeit_euklid = t_euklid . timeit (1)
print ( " Inuitiv
: " + str ( ' {:.2 f } '. format ( zeit_intuitiv ) ) + "
Sekunden " )
print ( " Euklid
: " + str ( ' {:.10 f } '. format ( zeit_euklid ) ) + " Sekunden
")
# Gebe jeweils die abgelaufene Zeit für beide Berechnungen aus
# '{:.2 f } '. format ( Variable ) beschränkt die Anzahl der Nachkommastellen
print ( " Euklid ist : " + str ( ' {:.2 f } '. format ( zeit_intuitiv / zeit_euklid
) ) + " x schneller " )
55
7 Python Programmierung
# Berechne wie vielfach Euklid schneller ist , wandle den Float in einen
String um und gebe den Wert aus
Im direkten Vergleich zu den Folien (Seite 16/18) von Herrn Folz kann man erkennen, dass die nötigen Anpassungen in den Algorithmen minimal waren. Die Beispielausgabe zeigt dass die Berechnung die geringen Ressourcen des Raspberry Pi stark
beanspruchen und wie massiv der Unterschied zwischen beiden Implementationen in
der Laufzeit aussieht:
Inuitiv
: 28.54 Sekunden
Euklid
: 0.0000569820 Sekunden
Euklid ist : 500789.60 x schneller
Besonders interessant wird es, wenn man diese Werte jeweils der entsprechenden
Implementation in Java und C++ auf einem Intel Core i7-620M mit 2,66 GHz (JDK 1.6
und GNU C++) gegenüberstellt:
Tabelle 7.8: Laufzeiten beider Algorithmen in Sekunden
RPi Python
i7 Java
i7 C++
ggTintuitiv
28,54
0,163
0,043
ggTeuklid
0.0000569820
0,00000011
0,00000016
Wie man erkennen kann bleibt die effiziente Implementierung nach Euklid auch auf
dem Raspberry Pi mit seinen geringen Ressourcen gut verwendbar, während die intuitive Version spürbare Verzögerungen erzeugt. Es zeigt sich, dass im Bereich der Embedded Systeme auch heute noch eine ressourcensparende Programmierung notwendig ist
und unabhängig von der verwendeten Programmiersprache zum guten Stil gehören
sollte.
7.2.6 Bibliotheken
Im vorangegangen Abschnitt haben wir bereits mit timeit eine Bibliothek verwendet,
ohne auf die Verwendung dieser genauer einzugehen. Bibliotheken können, wie auch
in anderen Sprachen dazu genutzt werden, den Funktionsumfang zu erweitern. In
Python werden Bibliotheken normal durch die Verwendung von import, gefolgt vom
Bibliotheksname eingebunden. Beispielsweise import time, womit die gesamte Bibliothek time eingebunden wird. Möchte man nur einzelne Module aus der Bibliothek einbinden, so kann man dies mit dem Schema from time import sleep tun. Damit wird
nur das Modul sleep aus der Bibliothek time eingebunden. Um einer doppelten Nutzung
des gleichen Namespaces vorzubeugen, kann man Module und Bibliotheken auch beim
Import mittels as umbenennen: So kann nach dem Import mit import time as zeit das
Modul sleep unter Verwendung von zeit.sleep() aufgerufen werden.
56
7.3 Verwendung der GPIO mittels Python
7.3 Verwendung der GPIO mittels Python
Nachdem wir bereits die GPIO in Bash mittels der abstrahierenden gpio.sh verwendet haben, werden wir diesmal die Pins mittels der wiringpi2-python Bibliothek direkt ansprechen. Die wichtigsten Funktionen sind in der WiringPi API Dokumentation
(https://projects.drogon.net/raspberry-pi/wiringpi/functions/) bzw. WiringPi
Referenz (http://wiringpi.com/reference/) nachlesbar.
7.3.1 Digitale Ausgabe: LEDs
Beginnen wir mit der digitalen Ausgabe unter Verwendung des Erweiterungsboards.
Zur Hilfestellung sei an dieser Stelle die entsprechenden LEDs und ihre GPIO Nummern vermerkt:
Tabelle 7.9: LEDs auf dem Erweiterungsboard
Bauteil
Bemerkung
GPIO
LED North
grün, PWM
18
LED East
rot
23
LED West
gelb
25
LED South
blau
24
# !/ usr / bin / python
import wiringpi2 as wpi
# Importiere die Python Bibliothek wiringpi2 unter
# dem Namen wpi zur Nutzung der GPIO
from time import sleep
# Importiere das Modul sleep aus der
# Python Bibliothek time
wpi . wiringPiSetupGpio ()
# Initialisiert die Bibliothek unter Nutzung des
# BCM GPIO Namenschema
wpi . pinMode (18 ,1)
# Definiert den Port der gruenen LED als Ausgabe
wpi . digitalWrite (18 ,1)
# Setzt den Port der gruenen LED auf HIGH
sleep (0.5)
# Wartet eine halbe Sekunde
wpi . digitalWrite (18 ,0)
# Setzt den Port der gruenen LED auf LOW
Dieses Listing entspricht dem Hello World des Physical Computing: Es schaltet die
grüne LED an, aus und beendet das Programm.
57
7 Python Programmierung
7.3.2 Übungsaufgabe zur digitalen Ausgabe
Um das Verständnis für die grundlegende Nutzung von Python und der GPIO zu Vertiefen empfiehlt sich folgende Übungsaufgabe: Man erstelle einen Programmcode um
alle LEDs, beginnend mit der Grünen, im Uhrzeigersinn einzuschalten. Anschließend
sollen, wieder beginnend mit der Grünen, alle LEDs wieder ausgeschaltet werden.
Nachdem Durchlauf dieser Prozedur soll dieser Vorgang bis zur Eingabe von Strg
+ C wiederholt werden.
Die Lösung der Aufgabe findet sich im Anhang unter D.6.
7.3.3 Digitale Eingabe: Schalter
Nachdem wir nun die digitale Ausgabe beherrschen, wenden wir uns der digitalen
Eingabe zu. Wir beginnen mit der Auflistung der Schalter auf dem Erweiterungsboard:
Tabelle 7.10: Schalter auf dem Erweiterungsboard
Bauteil
Bemerkung
GPIO
Switch North
Pull-Down
4
Switch East
Pull-Down
17
Switch West
Pull-Down
22
Switch South
Pull-Down
27
# !/ usr / bin / python
import wiringpi2 as wpi
wpi . wiringPiSetupGpio ()
wpi . pinMode (4 ,0)
# Definiert den Port des North Switches als Eingabe
while True :
print ( " North Switch : % d " % ( wpi . digitalRead (4) ) )
# Wert des North Switches auslesen und ausgeben
In diesem Fall nutzen wir pinMode mit dem Pin des ersten Schalters und setzen
seinen Modus auf 0, was der Eingabe entspricht. Anschließend können wir in einer
endlos Schleife den Wert dieses Pins abfragen und auf der Python Konsole ausgeben.
7.3.4 Übungsaufgabe zur digitalen Eingabe
Als Übung zur digitalen Eingabe verwenden wir ein kleines Reaktionsspiel unter Nutzung der vier LEDs und einem Schalter. Wie bei der vorherigen Übung sollen bei diesem Programm alle LEDs zum Leuchten gebracht werden. Es gilt weiterhin die Richtung im Uhrzeigersinn, allerdings soll diesmal die blaue LED den Anfang machen.
58
7.3 Verwendung der GPIO mittels Python
Weiterhin sollen die LEDs nicht dauerhaft an- oder ausgeschaltet werden, sondern in
jedem Zyklus einmal kurz aufblinken. Zwischen jeder LED soll eine Pause von einer
halben Sekunde liegen. Ziel des Spieles soll es sein, den äußerten Schaltern (South /
S) zu drücken, kurz bevor die grüne LED leuchtet. Sollte dies erfolgreich sein, so soll
die LED zweimal kurz aufblinken, die Pause zwischen dem aufleuchten der einzelnen
LEDs um den Wert 0.05 reduziert, die aktuelle Rundenanzahl ausgegeben werden und
das Spiel wieder bei der blauen LED starten. Sollte man zu früh oder zu spät drücken,
so soll die falsche LED aufleuchten und eine entsprechende Nachricht auf dem Bildschirm angezeigt werden und das Programm sich selbst beenden. Gleiches gilt, falls
man gar nicht den Schalter in der Runde betätigt.
Die Lösung der Aufgabe findet sich im Anhang unter D.7.
7.3.5 Abschlussprojekt GPIO: Binärzähler
Als Abschlussprojekt soll an dieser Stelle ein Vier-Bit-Binärzähler programmiert werden. Dabei sollen zwei Schalter und alle vier LEDs verwendet werden. Der äußerte
Schalter (South / S) soll dabei bei jeder Betätigung im Python Programm eine Zählvariable um 1 erhöhen, während der darüber liegende Schalter (West / W) den Zähler
auf 0 zurücksetzen soll. Das Programm soll bis zu 15 zählen und danach wieder zu 0
umbrechen und von vorne zu zählen beginnen. Die LEDs sollen bei diesem Projekt die
Ausgabe der Zahl in binärer Notation ermöglichen. Dabei ist jede LED als eine Stelle
einer vierstelligen, binären Notation zu verstehen:
2³
2⁰
2¹
2²
Abbildung 7.1: Festlegung des binären Wertes jeder LED
Zusätzlich zu der Ausgabe der Zahl über die LEDs, soll das Programm weiterhin den
Wert über die Konsole in den Formen Dezimal, Binär und Hexadezimal ausgeben.
Die Lösung der Aufgabe findet sich im Anhang unter D.8.
59
7 Python Programmierung
7.4 Verwendung des I2C Bus mittels Python
Im nachfolgenden Beispiel wird schrittweise erörtert, wie der I2C Bus mit wiringpi2,
hier in Python verwendet wird. Als Beispiel dazu dient der verbaute LM75B Temperatursensor. Die nachfolgenden technischen Daten lassen sich im Datenblatt des Sensors unter [14], respektive in der Datei RPi_HTW/Datenblaetter/LM75B.pdf auf dem
Raspberry Pi finden.
7.4.1 Adressierung
Wie bereits unter Abschnitt 5.3.3 erklärt, hat jeder Teilnehmer im I2C Bus eine eindeutige, hexadezimal notierte Adresse. Da allerdings verschiedene Anwendungszwecke
mehrere Geräte einer Art erfordern könnten (zum Beispiel mehrere LM75B in einem
Bus, um die Temperatur an verschiedenen Punkten eines Raumes zu überwachen), haben viele Hersteller die Möglichkeit mitgegeben, die Adresse ihres I2C Gerätes durch
Adressanschlüsse zu verändern. Diese Adresspins können wir in dem Pinout des Datenblattes unter 6.1, Figure 2 (Pin configuration for SO8) einsehen:
Abbildung 7.2: LM75B Pinout
Da hier mit A0, A1 und A2 gleich drei Pins zur Verfügung stehen, können also je
nach unterschiedlichen Verbindungen mit „HIGH“ (3,3V) und „LOW“ (Ground) bis zu
23 , also acht unterschiedliche Adressen erzeugt werden. Dies bedeutet, dass bis zu acht
Geräte im gleichen Bus ohne Adresskonflikt angeschlossen werden können. Wie sich
diese Konfiguration der Pins auf die Adresse auswirkt, ist unter 7.3, Table 4 ersichtlich:
Abbildung 7.3: LM75B Adresstabelle
Die ersten vier Bit sind immer die Folge „1001“. Anschließend wird die Wertigkeit
der Bits (Eins oder Null) dadurch bestimmt, ob die Adresspins entweder „HIGH“ (1)
60
7.4 Verwendung des I2C Bus mittels Python
oder „LOW“ (0) sind. In dem Fall des vorliegenden Erweiterungsboards wurden alle
Adresspins mit Ground verbunden, entsprechen also Null. Dadurch entsteht die fertige
Geräteadresse von 1001000 oder 0x48. Das fehlende, letzte Bit wird im I2C Bus verwendet um festzulegen, ob es sich um lesende oder schreibende Anfrage im Bus handelt.
Dies wird allerdings durch die verwendete Bibliothek durchgeführt.
In unserem Beispiel öffnen wir die entsprechende I2C Verbindung wie folgt:
lm75b_file = wpi . wiringPiI2CSetup (0 x48 )
# Verbindung zu LM75B oeffnen
if lm75b_file < 0:
print ( " Kann den I2C Bus nicht oeffnen ! " )
else :
7.4.2 Register des Sensors
In I2C System wird sowohl die Konfiguration, als auch der Datenaustausch über 8 oder
16 Bit tiefe Register erledigt. Der LM75B hat, wie unter 7.4, Table 5 zu sehen ist vier
davon:
Abbildung 7.4: LM75B Register
Das 16 Bit tiefe Temperaturregister (0x00), das 8 Bit tiefe Konfigurationsregister (0x01)
sowie zwei 16 Bit tiefe Register für Temperaturschwellwerte bei denen der Sensor unterschiedliche Aktionen unternehmen kann: Hysteresis (0x02) und Overtemperature
shutdown (0x03). Damit ist klar, dass wir für die Auswertung der Temperatur das Register 0x00 mit 16 Bit auslesen müssen.
lm75_temp = wpi . wiringPiI2CReadReg16 ( lm75b_file , 0)
# Register 0 von LM75B in 16 Bit Tiefe auslesen
61
7 Python Programmierung
7.4.3 Interpretation des Temperaturwertes
Wie der ausgelesene Wert zu interpretieren ist, findet sich im Bereich 7.4.3, Table 9:
Abbildung 7.5: LM75B Temperatur Register
Die dort gekennzeichneten Bits D10-D0 enthalten den nötigen, 11 Bit langen Temperaturwert. Die restlichen Bits des LSByte (Stellen 4-0) sind durch das „X“ als „Don’t
Care“ gekennzeichnet und sollten ignoriert werden. Am einfachsten erhält man den
Temperaturwert, in dem man den ausgelesenen Wert wie im Datenblatt beschrieben in
den MSB und den LSB Bereich aufteilt. Der LSB Bereich muss anschließend um fünf
Stellen nach rechts geshiftet werden und mit einer sieben verundet werden, um die
übrigen Stellen in dem Byte gleich Null zu setzen. Anschließend muss das HSB um
drei Stellen nach links geshiftet und mit dem vorbereiten LSB Bereich logisch durch ein
Order verbunden werden. Damit werden die beiden Bestandteile sauber zusammengesetzt. Zum Schluss muss nur noch der erhaltene Wert mit 0.125 multipliziert, oder
durch acht geteilt werden, um die Temperatur in Grad Celsius zu erhalten.
lm75b_hi = ( lm75_temp & 0 xFF )
lm75b_lo = ( lm75_temp >> 8)
# In 2x 8 Bit Werte ( High und Low Bit ) umwandeln
n = lm75b_hi << 3 | (( lm75b_lo >> 5) & 0 x07 )
# gemaess Datasheet des Sensors aus den ausgelesenen
# 2 Bytes die korreten 11 Bits fuer den Temperaturwert
# extrahieren und shiften
lm75b_temp = n / 8.0
# 11 Bit Wert in Temperatur umwandeln
Das gesamte Listing ist im Anhang D.9 einsehbar.
7.4.4 Übungsaufgabe zur Verwendung des I2C Bus
Um die gelernten Fähigkeiten zu festigen, soll in dieser Übung eine Temperatursteuerung unter Verwendung des LM75B entwickelt werden. Der Sensor soll zum Start die
Umgebungstemperatur messen und diese als Standardtemperatur verwenden. Sollte
die Temperatur ein Grad unter diese Temperatur fallen, soll mit der blauen LED angezeigt werden, dass der Raum abgekühlt ist. Sollte die Temperatur hingegen ein Grad
über diese Temperatur steigen, soll dies mit der roten LED repräsentiert werden. Die
Idealtemperatur soll mit der grünen LED dargestellt werden. Zusätzlich zu den Übergängen dieser Zustände, soll - sofern der Zustand stabil ist - der Name des Zustandes
und die aktuelle Temperatur ausgegeben werden.
Die Lösung der Aufgabe findet sich im Anhang unter D.10.
62
7.5 Verwendung des SPI Bus mittels Python
7.5 Verwendung des SPI Bus mittels Python
Nachdem nun die Kommunikation über den I2C Bus erfolgreich funktioniert, wenden
wir uns dem letzten Bauteil auf dem Erweiterungsboard zu, dem MCP3002 2 Kanal 10
Bit Analog/Digital Wandler mit SPI Bus. Damit erweitern wir den RPi um zwei analoge Eingänge. In unserem Beispiel wird der erste Kanal, Kanal 0 dazu genutzt den
Wert eines angeschlossenen Lichtsensors / LDR auszulesen. Da es sich um einen 10
Bit Wandler handelt, kann dieser die angelegte analoge Spannung von 0 bis 3,3 V in
einem digitalen Wertebereich von 0 bis 1024 (210 ) darstellen. Das bedeutet, dass jede
analoge Spannungssteigerung von 3,3 mV sich in einer Erhöhung des digitalen Wertes
um 1 auswirkt. Die folgenden technischen Daten lassen sich im Datenblatt des Wandlers unter [17], respektive in der Datei RPi_HTW/Datenblaetter/MCP3002.pdf auf dem
Raspberry Pi finden.
7.5.1 Adressierung
Wie bereits in Abschnitt 5.3.5 beschrieben haben die SPI Bus Teilnehmer keine eigene Adresse, sondern werden über eine eigene Leitung zum Master (Slave Select) in
den Kommunikationsmodus geschaltet. In dem Fall des Erweiterungsboards wurde
der MCP3002 auf den Slave Select 0 gelegt, den ersten der beiden Slave Selects. Diese
sind in keinem Fall mit den internen beiden ADC Kanälen des MCP3002 zu verwechseln, welche nicht zur Kommunikation dienen, sondern zur Messung von analogen
Spannungen - der eigentlichen Aufgabe des MCP3002. Da wir weiterhin die Übertragungsgeschwindigkeit beim Öffnen des SPI Bus angeben müssen, suchen wir im Datenblatt nach den entsprechenden Angaben. Auf Seite drei findet man unter Timing
Parameters, Clock Frequency die entsprechenden Angaben:
Abbildung 7.6: MCP3002 SPI Bus Geschwindigkeit
Da der MCP3002 auf dem Erweiterungsboard mit 3,3 V Spannung versorgt wird,
liegt die maximale Geschwindigkeit für den SPI Bus bei 1,2 MHz. Da der Controller
des RPi allerdings ganze vielfache bevorzugt, werden wir eine Geschwindigkeit von 1
MHz verwenden - sowie den Slave Select 0.
# !/ usr / bin / python
import wiringpi2 as wpi
from binascii import hexlify
from binascii import unhexlify
mcp3002_channel =0
if wpi . wiringPiSPISetup (0 ,1000000) < 0:
print ( " Kann den SPI Bus nicht oeffnen ! " )
63
7 Python Programmierung
else :
7.5.2 Kommunikation
Die Kommunikation beim SPI Bus verläuft bidirektional, in dem eine gewisse Anzahl
an Bytes in Form eines Bytebuffers über den Bus versendet, und gleichzeitig wieder
von der Gegenstelle mit Daten gefüllt wird. Das heißt, dass nach erfolgter Kommunikation der Sendebuffer mit den Zieldaten überschrieben wurde. Der Ablauf dieser
Kommunikation kann im Datenblatt der Abbildung 6-2 entnommen werden:
Abbildung 7.7: MCP3002 SPI Kommunikation
DIN beziehungsweise „MCU Transmitted Data“ beschreibt dabei die Kommunikation vom RPi zum MCP3002, DOUT beziehungsweise „MCU Received Data“ die umgekehrte Richtung. Wie wir sehen beginnt die Kommunikation im ersten Byte bei DIN
mit einem „Don’t Care“, gefolgt von einem feststehenden Startbit. Anschließend folgen drei Bits welche bestimmte Optionen festlegen: „SGL/DIFF“, „ODD/SIGN“ und
„MSBF“. Beendet wird das Byte mit weiteren drei „Don’t Care“ Bits. Das zweite Byte
besteht völlig aus „Don’t Care“ Bestandteilen, die wir beliebig mit Eins und Null füllen
könnten. Für die bessere Lesbarkeit werden wir allerdings alle „Don’t Care“ Bits mit
Null füllen. Unser bisheriger Kommunikationsbuffer sieht also so aus:
Tabelle 7.11: Vorläufiger Kommunikationsbuffer
Bit
0
1
2
3
4
5
6
7
|
8
9
10
11
12
13
14
15
Mode
0
1
?
?
?
0
0
0
|
0
0
0
0
0
0
0
0
Die Bedeutung und korrekten Einstellungen für die noch fehlenden Werte von „SGL/DIFF“ und „ODD/SIGN“ kann man in der Tabelle 5-1 nachlesen:
64
7.5 Verwendung des SPI Bus mittels Python
Abbildung 7.8: MCP3002 Konfigurationsbits
Es handelt sich dabei um Konfigurationsbit mit welchem man die Funktionsart des
MCP3002 einstellen kann. „SGL/DIFF“ bestimmt ob der Analog/Digital Wandler entweder die Spannung an einem seiner beiden Kanäle lesen (Einstellung 1) oder ob er
den Unterschied zwischen beiden Kanälen feststellen soll (Einstellung 0). Da wir die
Spannung am Kanal 0, an dem auch der LDR angeschlossen ist messen wollen, müssen
wir das „SGL/DIFF“ Bit auf 1 setzen. In diesem Modus wird das „ODD/SIGN“ Bit dazu genutzt, den Kanal auszuwählen. Ist das Bit auf 0 gesetzt, wird Kanal 0 gemessen,
wird es auf 1 gesetzt, wird der Kanal 1 gemessen. Somit sind unsere Einstellungen für
„SGL/DIFF“ 1 und für „ODD/SIGN“ 0. Das letzte Bit, „MSBF", sorgt dafür, dass die
Kommunikation im MSB Format abläuft, wenn es gesetzt ist. Ansonsten arbeitet der
Wandler mit LSB. Wir lassen diese Einstellung auf 0.
Damit steht unser Buffer für die Kommunikation fest:
Tabelle 7.12: Kommunikationsbuffer
Bit
0
1
2
3
4
5
6
7
|
8
9
10
11
12
13
14
15
Mode
0
1
1
0
0
0
0
0
|
0
0
0
0
0
0
0
0
Wir müssen diese Werte nur entsprechend in Python in das entsprechende Format
bringen und auf Slave Select 0 übertragen:
buffer =((6+ mcp3002_channel ) < <12)
buffer = ' {0: x } '. format ( int ( buffer ) )
# Wandle den dezimalen Integer in einen
# hexadezimalen String um , ohne das Praefix
# 0 x davorzustellen
buffer = unhexlify ( buffer )
# Wandle den Hex String in einen Byte String um
if ( wpi . wiringPiSPIDataRW (0 , buffer ) == -1) :
# Anforderung auf den SPI Bus auf Slave
# Select 0 schreiben und
65
7 Python Programmierung
# gleichzeitig ( bi - direktional ) mit der
# Antwort den Buffer ueberschreiben
print ( " Schreibfehler auf SPI Bus !\ n " )
else :
Nachdem die Kommunikation beendet ist, befindet sich im Buffer bereits die Antwort in Form eines Byte Strings, welche dann nur noch in einen Integer Wert umgewandelt werden muss:
buffer = hexlify ( buffer )
# Wandle den Byte String nach Hex um
buffer = int ( buffer , 16)
# Wandle den Hex String in einen
# dezimalen Integer Wert um
Dieser Wert kann nun noch formatiert und ausgegeben werden. Das gesamte Listing ist im Anhang D.11 einsehbar. Zusätzliches zu der hier beschriebenen, manuellen
Kommunikation bietet wiringpi2 bereits eine Bibliothek, welche die Kommunikation
mit dem MCP3002 vereinfacht. Das entsprechende Listing befindet sich im Anhang
D.12
7.5.3 Übungsaufgabe zur Verwendung des SPI Bus
Nachdem nun die Nutzung des SPI Bus erlernt wurde, soll in der nachfolgenden Übungsaufgabe der Einsatz des LDR als Näherungssensor realisiert werden:
Um die Messwerte leichter zu visualisieren, soll dazu die Bibliothek curses verwendet werden. Mit dieser Bibliothek kann in der Konsole ein virtuelles Fenster erzeugt
werden, in dessen Koordinatensystem man zum Beispiel eine horizontale Linie zeichnen kann. Wichtig ist dabei zu erwähnen, dass diese Bibliothek nicht in IDLE läuft und
daher der Aufruf direkt aus LXTerminal wie in Abschnitt 7.2.1 als 2) und 3) beschrieben
erfolgen muss. Wegen dem Aufruf von curses wird das Programm in diesem Fall durch
das Drücken einer beliebigen Taste beendet und sollte nicht per Strg + C abgebrochen
werden.
# !/ usr / bin / python
import curses
from time import sleep
screen = curses . initscr ()
# curses in der Konsole initialisieren
dims = screen . getmaxyx ()
# y , x Groesse des Bildschirms in Array ablegen
# dims [0] entspricht y Wert
# dims [1] entspricht x Wert
screen . nodelay (1)
# nodelay Modus aktivieren um screen . getch ()
# im non - Blocking Modus zu betreiben
while ( screen . getch () == -1) :
# fuehre die Schleife aus solange keine
66
7.5 Verwendung des SPI Bus mittels Python
# Taste gedrueckt wurde
screen . erase ()
# Bildschirm loeschen
screen . hline (20 , 0 , ' - ' , 40)
# horinzontale Linie aus - Zeichen malen
# hline (y Koordinate , x Beginn , ch Zeichen , n Laenge )
screen . refresh ()
# Bildschirm neu laden
sleep (0.1)
curses . endwin ()
# Beenden
Die Aufgabe wird nun sein, dieses Skript dahingehend zu ergänzen, dass die horizontale Linie jeweils den aktuellen Messwert des an den MCP3002 angeschlossenen
LDR anzeigt. Wichtig wird dabei sein, jeweils zum Start des Skriptes den aktuellen
Messwert als Maximalwert zu erfassen, sowie den Wert jeweils korrekt zu skalieren,
damit der Lichtsensor als Eingabegerät für z.B. ein Spiel verwendbar werden könnte.
Die Lösung befindet sich im Anhang D.13.
67
8 Mathematica
In dem letzten Kapitel dieser Arbeit soll die Einführung in die Nutzung der Software
Mathematica und deren Verwendung mit den GPIO Pins im Vordergrund stehen. Dabei
soll gegen Ende des Kapitels sowohl die grundlegende Nutzung der Software selbst,
wie auch die Verwendung in Kombination mit dem Erweiterungsboard verständlich
geworden sein. Diese Software könnte besonders in den Vorlesungen „Mathematik 13“, sowie „Informatikgrundlagen“ und „Graphentheorie“ Verwendung finden.
8.1 Grundlagen
Die Software Wolfram Mathematica ist ein mathematisch-naturwissenschaftliches Programm zur Lösung unterschiedlichster Probleme. Dies beinhaltet die Lösung von Gleichungen, Zeichnung von Plots, Darstellung und Visualisierung von Problemen sowie
Datenanalyse. Damit kann Mathematica im Bereich der Mathematik, Computerwissenschaften, Physik, Biologie, Medizin, Ingenieurswesen, Finanz- und Sozialwissenschaften eingesetzt werden. Die Besonderheiten dieser Software umfassen neben zahlreichen
Sonderfunktionen wie Cloud- und Grindcomputing, wissensbasiertem Programmieren, Integration neuer Technologien wie Internet of Things und webbasierten Sensoren
auch eine leistungsfähige API, sowie die Möglichkeit eigene Programme mittels des
MathLink Protokolls als Datenquelle und -senke in Wolfram zu integrieren.
Aufgrund des großen Funktionsumfangs und der Leistungsfähigkeit dieser Software
ist diese im Normalfall für Studenten nur eingeschränkt oder gar nicht zugänglich.
Durch die kostenlose Integration der aktuellen Version von Wolfram Mathematica in
Raspbian, dem Betriebssystem des Raspberry Pi, wird dieses Werkzeug also für einen
größeren Nutzerkreis verfügbar.
Weiterhin können durch die Nutzung des Raspberry Pi als Schnittstelle auch I2C, SPI
und GPIO Sensoren und Aktoren mittels MathLink Protokolls von anderen Raspberry
Pis oder vollwertigen Mathematica Arbeitsplätzen verwendet werden.
8.2 Benutzung
Mathematica ist auf dem RPi in zwei Varianten installiert: wolfram, die CLI basierte
Form von Mathematica, welche ausschließlich zur Verwendung im reinen Textmodus
und in Verbindung mit Skripten gedacht ist, sowie mathematica, welche alle Features
in der grafischen Benutzeroberfläche bietet - inklusive der Ausgabe von Grafiken und
Plots. Für unsere Einsatzzwecke werden wir mathematica einsetzen.
69
8 Mathematica
8.2.1 Beispiele Free-form input
Zu berechnende Ausdrücke werden in Mathematica einfach in das sogenannte Sketchbook, dem Hauptfenster der Software eingegeben und durch Bestätigung mittels ⇑ +
Enter ausgewertet. Diese Form von Eingabe nennt sich „Free-form input“ und wird von
Mathematica offline auf dem RPi gelöst. So können Berechnungen wie 1+1, 3/4*(5-2)^2
oder ganze Gleichungen (Solve[x^3+x^2-8x-12==0,x]) und auch bestimmte Integrale
(Integrate[Sin[x],{x,0,Pi}]) einfach und direkt gelöst werden. Die möglichen Befehle und Verwendungsmöglichkeiten können in der ausführlichen Sprachreferenz von
Wolfram unter http://reference.wolfram.com/language/ nachgelesen werden.
8.2.2 Beispiele Wolfram Alpha query
Wesentlich leistungsfähiger ist allerdings die Nutzung der „Wolfram Alpha query“,
welches die Eingaben online an die Wolfram Alpha Compute Engine weiterleitet. Wie
in Abbildung 8.1 gezeigt, erfolgt die Umstellung dieser Eingabe per Klick auf das „+“
Zeichen im Sketchbook.
Abbildung 8.1: Umstellung der Eingabeart in Wolfram
Wichtig ist, dass die Nutzung dieses Softwareteils nur bei aktiver Internetanbindung
möglich ist. Die Stärke von Wolfram Alpha liegt in der Auswertung natürlicher Sprache in mathematische Zahlen. Kombiniert mit der Menge der in der Compute Engine
70
8.2 Benutzung
hinterlegten Daten, sind dadurch interessante Auswertungen mit sehr geringem Aufwand möglich. So zum Beispiel die wissenschaftlich nicht relevante Berechnung der
Anzahl aller Einwohner von Frankreich mal der Höhe des Eiffelturms:
Abbildung 8.2: Berechnung mittels Wolfram Alpha
Weitere Beispiele und mögliche Einsatzzwecke sind in der Dokumentation von Wolfram Alpha unter http://www.wolframalpha.com/examples/ zu finden.
71
8 Mathematica
8.3 Verwendung mittels Erweiterungsboard
Wie bereits erwähnt können die Sensoren und Aktoren des Erweiterungsboards auch
mittels Mathematica genutzt werden, um z.B. Temperatur- oder Helligkeitsdaten zu
sammeln und grafisch auszuwerten. Es wäre auch möglich die Schalter des Boards zur
Zählung von z.B. Besuchern einer Veranstaltung oder der Auslastung einer Straße einzusetzen, wie es häufig für statistische Erfassungen getan wird. Damit diese Peripherie
in Mathematica verfügbar wird, muss zuerst die entsprechende Library eingebunden
werden. Da es für Mathematica noch keine Erweiterung zur Nutzung der I2C und SPI
Bus Systeme gibt, wurde im Rahmen dieser Arbeit unter Nutzung von C, wiringpi2 und
dem MathLink Protokoll eine eigene geschrieben. Der Quellcode für diese wpi genannte
Library kann auf dem Raspberry Pi im Unterverzeichnis RPi_HTW/Mathematica/ des
Hauptnutzers pi, beziehungsweise im Anhang unter D.14 und D.15 gefunden werden.
Erzeugt wird das fertige Programm unter Aufruf von mcc wpi.c wpi.tm -o wpi -luuid
-lwiringPi.
Wichtig zu erwähnen ist, dass - unabhängig ob nun Mathematica oder Wolfram genutzt werden soll - beide Programme mit root Rechten über die CLI gestartet werden
müssen. Sonst kann der Zugriff auf die GPIO nicht erfolgen. Wir starten also Mathematica durch den Befehl sudo mathematica im LXTerminal. Nachdem die Software geladen ist, können wir durch den Befehl SetDirectory["/home/pi/RPi_HTW/Mathematica"]
das Heimverzeichnis von Mathematica temporär ändern und mit dem weiteren Befehl
link = Install["wpi"] die Library wpi laden.
Solange die Sitzung von Mathematica beziehungsweise Wolfram aktiv ist, sind ab
nun folgende weitere Befehle verfügbar:
setPinMode[pin, mode]
setDigitalWrite[pin, value]
setPwmWrite[pin, value]
getDigitalRead[pin]
getLM75B[]
getMCP3002[channel]
Zu jedem Befehl kann die entsprechende Hilfe durch das Vorstellen eines Fragezeichens (z.B. ?getLM75B) und die anschließende Auswertung per ⇑ + Enter ausgegeben
werden. Die ersten vier angegebenen Befehle sind die bekannten Kommandos der wiringpi2 Bibliothek, die anderen beiden basieren auf dem bereits in Abschnitt 7.4 und
Abschnitt 7.5 entwickelten Python Code zur Nutzung des LM75B Temperatur Sensors
und des MCP3002 ADC.
Dementsprechend einfach ist die Verwendung der GPIOs in Mathematica, um zum
Beispiel die grüne LED zu aktiveren:
setPinMode[18, 1]
(* Definiert den Port der gruenen LED als Ausgabe *)
setDigitalWrite[18, 1]
(* Setzt den Port der gruenen LED auf HIGH *)
72
8.3 Verwendung mittels Erweiterungsboard
Auch die Überprüfung des ersten Schalters und die entsprechende Ausgabe des Zustandes auf die erste LED ist sehr einfach:
setPinMode[18, 1]
(* Definiert den Port der gruenen LED als Ausgabe *)
setPinMode[4, 0]
(* Definiert den Port des North Switches als Eingabe *)
If[getDigitalRead[4]==1, setDigitalWrite[18,1], setDigitalWrite[18,0]]
(* Sollte der North Switch zur Zeit der Auswertung gedrueckt wurden sein,
schalte die gruene LED ein, sonst aus *)
Als nächstes sollen die Möglichkeiten von Mathematica in der grafischen Auswertung aufgezeigt werden, hier in Verbindung mit dem Temperatur Sensor:
t={}
(* Definiert die leere Liste t, fuer die Temperaturwerte *)
RunScheduledTask[(AppendTo[t,getLM75B[]]),1];
(* Definiert einen Task der jede Sekunde ablaeuft und den
aktuellen Wert des Temperatur Sensors in die Liste schreibt *)
Dynamic[ListLinePlot[t,Joined->True,PlotRange->Automatic]]
(* Erzeugt einen dynamischen Plot in Form einer Linie welcher sich
mit jedem neuen Wert der Liste neu zeichnet und sich selbst
skaliert *)
Der entstehende Plot wird mit der Erweiterung der Liste dynamisch aktualisiert bis
entweder eine gegebene, zeitliche Grenze erreicht wurde oder z.B. unter „Evaluation“
die Option „Dynamic Updating Enabled“ abgeschaltet wurde.
Abbildung 8.3: Plot des Temperatur Sensors über 400 Sekunden
Als letzten Punkt wollen wir die Messwerte des Lichtsensors in Form eines analogen
Messwerkes darstellen. Dazu verwenden wir wieder die Methode RunScheduledTask
73
8 Mathematica
um die Messwerte zu erfassen. Das Auswertung wird diesmal jedoch nicht über einen
ListLinePlot, sondern über AngularGauge erfolgen:
RunScheduledTask[val = getMCP3002[0], 1]
(* Definiert einen Task der jede Sekunde ablaeuft und den
aktuellen Wert des Lichtsensors in eine Variable schreibt *)
AngularGauge[Dynamic[val], {0, 1023}]
(* Erzeugt einen dynamischen Plot in Form eines analogen
Messwerkes welches sich mit jedem neuen Wert in der
Variable neu aktualisiert. Der Wertebereich wird mit 0
- 1023 vorgegeben *)
Abbildung 8.4: Darstellung des Lichtsensor Wertes als analoges Messwerk
Die Verbindung zur Library kann jederzeit durch den Befehl Uninstall[link] beendet werden, sollte z.B. ein Fehler auftreten. Weiterhin können alle Zellen und Auswertungen einzeln markiert, gelöscht oder angehalten werden. Es empfiehlt sich möglichst
wenige dynamische Objekte gleichzeitig zu erstellen, um den RPi nicht völlig auszulasten.
74
9 Fazit
9.1 Zusammenfassung
Im Rahmen dieser Bachelor Thesis wurde der Raspberry Pi dazu genutzt unterschiedliche Themen des Studienganges „Praktische Informatik“ aufzugreifen und deren Lehre
anhand von praktischen Beispielen und konkreten Projekten zu unterstützen. Dies umfasst folgende Punkte:
Tabelle 9.1: Stakeholder dieser Thesis
Veranstaltung / Labor
Aufgabe
Mikroprozessortechnik
Evaluation von Beagle Bone Black und Raspberry Pi
Elektrotechnik Labor
Erstellung eines Grundlagen Handbuches zum RPi
Systemtechnik Labor
Erstellung Standard Image zur Verwendung im STL
Betriebssystem Einführung
Praktisches Bash Projekt zur Vorbereitung der Klausur
Systemmanagement & Sicherheit
Einführung in die Sprache Python
Programmierung 1
Darstellung Nachteile ineffizienter Programmierung
Digitaltechnik 1
Binäre Logik / Binärer Zähler
Rechnerarchitektur
Grundlagen I2C / SPI Bussysteme & Verwendung
Theoretische Informatik
Primitiver Automat mit I2C / SPI Sensoren
Mathematik 1-3
Vorstellung von Wolfram Alpha / Mathematica
Darüber hinaus wurden zum Erreichen dieser Ziele, als Bestandteil dieser Thesis, das
in diesem Dokument besprochene Erweiterungsboard entwickelt und in zehnfacher
Stückzahl hergestellt, um anschließend mit den gleichzeitig vorbereiten Raspberry Pis
aktiv in der Lehre der HTW Saar eingesetzt zu werden.
Zum Abschluss lässt sich sagen, dass die gesteckten Ziele dieser Arbeit im Rahmen
der Möglichkeiten erreicht werden konnten und sich der Raspberry Pi trotz seines geringen Preises als gute Plattform für den Bereich der Forschung und Lehre erwiesen
hat.
75
9 Fazit
9.2 Ausblick
Aufgrund der gegebenen, zeitlichen Begrenzung dieser Thesis, war es leider nicht mehr
möglich die Assembler Programmierung des verbauten ARMv6 SoC zu erläutern, oder
eine Einführung in die objektorientierte Programmierung unter Python zu geben, was
den gegebenen Rahmen gesprengt hätte. Neben diesen Projekten ließen sich auch weitere Möglichkeiten finden den Raspberry Pi in Zukunft aktiv in die Lehre einfließen zu
lassen:
Tabelle 9.2: Ausblick auf mögliche Projekte
Veranstaltung / Labor
Aufgabe
Mikroprozessortechnik
Assembler Programmierung und Betriebssysteme [3]
Betriebssysteme
Verwendung RPi mit RTOS ChibiOS [1]
Parallele Programmierung
Nutzung RPi GPU zur parallelen Berechnung [22]
Verteilte Systeme 1
Einführung in MPICH [5]
Netzwerktechnik
Praktische Konfiguration von IPv4/IPv6 Servern
Weitere mögliche Anwendung wäre der Einsatz in der Vorlesung „Einführung in die
Robotik“, als Plattform für ein „Gamification“ Projekt, bei interdisziplinäre Arbeiten im
Bereich der Elektrotechnik bzw. Medizin- und Biotechnologie oder als Ausstellungsobjekt für den Tag der offenen Tür.
76
Literatur
[1]
Steve Bate. ChibiOS/RT on the Raspberry Pi. Okt. 2012. URL: http://www.stevebate.
net/chibios-rpi/GettingStarted.html.
[2]
Charles C. Mann. Eben Upton, 34. 2012.
com/tr35/profile.aspx?TRID=1307.
[3]
Alex Chadwick. Baking Pi - Operating Systems Development. Juli 2013. URL: http:
//www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/.
[4]
Arthur C. Clarke. Profiles of the Future: An Inquiry Into the Limits of the Possible.
An Indigo paperback. Indigo, 2000. ISBN: 9780575402775. URL: http://books.
google.de/books?id=fVp0PwAACAAJ.
[5]
Simon J. Cox. „Iridis-pi: a low-cost, compact demonstration cluster“. English. In:
Cluster Computing 17.2 (2014), S. 349–358. ISSN: 1386-7857. DOI: 10.1007/s10586013-0282-7. URL: http://dx.doi.org/10.1007/s10586-013-0282-7.
[6]
Tony Dicola. Embedded Linux Board Comparison. Adafruit. Mai 2014. URL: https:
//learn.adafruit.com/embedded-linux-board-comparison/overview.
[7]
EIA Engineering Dept. Interface between data terminal equipment and data communication equipment employing serial binary data interchange. EIA standard. Electronic
Industries Association, Engineering Dept., 1969. URL: http://books.google.de/
books?id=Tp08AAAAIAAJ.
[8]
Elatllat. RPiconfig. Juni 2014. URL: http://elinux.org/RPiconfig.
[9]
Prof. Dr. Helmut G. Folz. Programmierung 1: Kontrollstrukturen. HTW. Mai 2013.
URL : http://www.htwsaar.de/ingwi/fakultaet/personen/profile/helmutfolz/prog1/folien2013/folien2013-00-08.zip/view.
[10]
Geertivp. RPi Serial Connection. Feb. 2014. URL: http://elinux.org/RPi_Serial_
Connection.
[11]
Matt Hawkins. Raspberry Pi B+ GPIO Header Details And Pinout. Juni 2014. URL:
http://www.raspberrypi-spy.co.uk/2014/07/raspberry-pi-b-gpio-headerdetails-and-pinout/.
[12]
Heinrich Hübscher, Carsten Rathmann, Klaus Richter, Hans J Petersen und Dirk
Scharf. IT-Handbuch IT-Systemelektroniker/-in Fachinformatiker/-in: 7. Auflage, 2011.
7. Auflage. Westermann Schulbuch, Jan. 2011. ISBN: 9783142250427. URL: http:
//amazon.de/o/ASIN/3142250425/.
[13]
Gordon Henderson. Understanding SPI on the Raspberry Pi. Aug. 2012. URL: https:
//projects.drogon.net/understanding-spi-on-the-raspberry-pi/.
URL :
http://www2.technologyreview.
77
Literatur
[14] LM75B. 6. Aufl. NXP. Aug. 2014. URL: http://www.nxp.com/documents/data_
sheet/LM75B.pdf.
[15]
F. Leens. „An introduction to I2C and SPI protocols“. In: Instrumentation Measurement Magazine, IEEE 12.1 (Feb. 2009), S. 8–13. ISSN: 1094-6969. DOI: 10.1109/MIM.
2009.4762946.
[16]
Gert van Loo. GPIO Pads Control2. Aug. 2012. URL: http://de.scribd.com/doc/
101830961/GPIO-Pads-Control2.
[17] MCP3002. E. Microchip. Nov. 2011. URL: http://ww1.microchip.com/downloads/
en/DeviceDoc/21294E.pdf.
[18]
H.J. Morrison und R.H. Baer. „Microcomputer controlled game“. Pat. US4207087
A. US Patent 4,207,087. Juni 1980. URL: http : / / www . google . com / patents /
US4207087.
[19]
NXP. I2C-bus specification. 6. Aufl. NXP Semiconductor. Apr. 2014.
//www.nxp.com/documents/user_manual/UM10204.pdf.
[20]
PBL. Raspberry Pi Schematics R2.1. Nov. 2013. URL: http : / / www . raspberrypi .
org/documentation/hardware/raspberrypi/schematics/Raspberry-Pi-Rev2.1-Model-AB-Schematics.pdf.
[21]
Philips. I2S-bus specification. Philips Semiconductors. Feb. 1986.
sparkfun.com/datasheets/BreakoutBoards/I2SBUS.pdf.
[22]
Eben Upton. GPGPU Hacking on the Pi. Juni 2014. URL: http://www.raspberrypi.
org/gpgpu-hacking-on-the-pi/.
[23]
Eben Upton. Introducing Turbo Mode: Up to 50% more Performance for free. Sep. 2012.
URL : http : / / www . raspberrypi . org / introducing - turbo - mode - up - to - 50 more-performance-for-free/.
[24]
Liz Upton. Raspberry Pi at Buckingham Palace, 3 Million Sold. Juni 2014. URL: http:
//www.raspberrypi.org/raspberry-pi-at-buckingham-palace-3-millionsold/.
[25]
Roland Woitowitz. Digitaltechnik. 6. Aufl. Springer, Aug. 2011.
78
URL :
URL :
http :
https : / /
Abbildungsverzeichnis
3.1
3.2
3.3
3.4
3.5
SD Formatter . . . . . . . . . . . . . . . . . .
SD Formatter Optionen . . . . . . . . . . . . .
Win32 Disk Imager . . . . . . . . . . . . . . .
noobs nach dem Entpacken auf die SD Karte
Installation von Raspbian unter noobs . . . .
.
.
.
.
.
13
13
14
16
17
4.1
4.2
raspi-config . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Raspbian Desktop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
22
5.1
5.2
GPIO Schnittstelle Raspberry Pi Modell A / B / B+ [11] . . . . . . . . . .
Erweiterungsboard und Routing der Komponenten . . . . . . . . . . . .
31
39
6.1
6.2
Simon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Flowchart Simon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
44
7.1
7.2
7.3
7.4
7.5
7.6
7.7
7.8
Festlegung des binären Wertes jeder LED
LM75B Pinout . . . . . . . . . . . . . . . .
LM75B Adresstabelle . . . . . . . . . . . .
LM75B Register . . . . . . . . . . . . . . .
LM75B Temperatur Register . . . . . . . .
MCP3002 SPI Bus Geschwindigkeit . . . .
MCP3002 SPI Kommunikation . . . . . .
MCP3002 Konfigurationsbits . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
59
60
60
61
62
63
64
65
8.1
8.2
8.3
8.4
Umstellung der Eingabeart in Wolfram . . . . . . . . . . .
Berechnung mittels Wolfram Alpha . . . . . . . . . . . . . .
Plot des Temperatur Sensors über 400 Sekunden . . . . . .
Darstellung des Lichtsensor Wertes als analoges Messwerk
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
70
71
73
74
C.1 Erweiterungsboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
79
TABELLENVERZEICHNIS
Tabellenverzeichnis
80
2.1
2.2
Übersicht [6] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
I/O und Peripherie [6] . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
6
4.1
Einstellungen für eduroam . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
5.1
Erweiterungsboard und Routing der Komponenten . . . . . . . . . . . .
39
7.1
7.2
7.3
7.4
7.5
7.6
7.7
7.8
7.9
7.10
7.11
7.12
Arithmetische Operatoren . . . . . . . . . . .
Vergleichsoperatoren . . . . . . . . . . . . . .
Binäres Und . . . . . . . . . . . . . . . . . . .
Binäres Oder . . . . . . . . . . . . . . . . . . .
Binäres XOR . . . . . . . . . . . . . . . . . . .
Binäres 1er Komplement . . . . . . . . . . . .
Binäre, bitweise Operatoren . . . . . . . . . .
Laufzeiten beider Algorithmen in Sekunden
LEDs auf dem Erweiterungsboard . . . . . .
Schalter auf dem Erweiterungsboard . . . . .
Vorläufiger Kommunikationsbuffer . . . . . .
Kommunikationsbuffer . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
51
51
52
52
52
53
53
56
57
58
64
65
9.1
9.2
Stakeholder dieser Thesis . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ausblick auf mögliche Projekte . . . . . . . . . . . . . . . . . . . . . . . .
75
76
A.1 Raspbian Übersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.2 Per apt-get installierte Pakete . . . . . . . . . . . . . . . . . . . . . . . . .
A.3 Manuell installierte Pakete . . . . . . . . . . . . . . . . . . . . . . . . . . .
85
85
85
B.1 Raspberry Pi der HTW . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
C.1 Erweiterungsboard und Routing der Komponeten . . . . . . . . . . . . .
90
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Listings
Code/boardTest.c . . . . .
Code/gpio.sh . . . . . . .
Code/demoLed.sh . . . .
Code/demoSwitch.sh . . .
Code/simon.sh . . . . . .
Code/uebungAusgabe.py
Code/uebungEingabe.py
Code/binaryCounter.py .
Code/lm75b.py . . . . . .
Code/uebungI2C.py . . .
Code/mcp3002.py . . . .
Code/mcp3002lib.py . . .
Code/uebungSPI.py . . .
Code/wpi.c . . . . . . . .
Code/wpi.tm . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
91
95
97
98
99
102
103
104
105
106
108
109
109
110
112
81
Abkürzungsverzeichnis
ADC Analog Digital Converter
API
Application Programming Interface
CAN Controller Area Network
CSI
Camera Serial Interface
CLI
Command Line Interface
DSI
Display Serial Interface
GPIO General-purpose input/output
GPS
Global Positioning System
I2C
Inter-Integrated Circuit
I2S
Inter-Integrated Sound
IDE
Integrated Development Environment
LDR Light Dependent Resistor
MCU Microcontroller Unit
PRU
Programmable Realtime Unit
PWM Pulse-width modulation
RPi
Raspberry Pi
SoC
System on a chip
SPI
Serial Peripheral Interface
TWI
Two Wire Interface
UART Universal asynchronous receiver/transmitter
82
Anhang
83
A Vorgefertigtes Raspbian Image
A.1 Übersicht
Tabelle A.1: Raspbian Übersicht
Raspbian
Version
June 2014 (20.06.2014)
Kernel
3.12.28+ #712 PREEMPT Tue Sep 16
User / Passwort
pi / rpi
root
kein Passwort gesetzt / gesperrt
IP
per DHCP
A.2 Zusätzlich installierte Pakete
Tabelle A.2: Per apt-get installierte Pakete
Name
python-setuptools
python-dev
cpufrequtils
scrot
epiphany-browser
uuid-dev
gfortran
screen
minecraft-pi
python-minecraftpi
Tabelle A.3: Manuell installierte Pakete
Name
URL
wiringpi2
git://git.drogon.net/wiringPi
wiringpi2-python
https://github.com/Gadgetoid/WiringPi2-Python
rpi-serial-console
https://github.com/lurch/rpi-serial-console
MPICH 3.1.2
http://www.mpich.org/static/tarballs/3.1.2/mpich-3.1.2.tar.gz
MCPIPY Examples
https://github.com/brooksc/mcpipy
85
87
Name
rpi01
rpi02
rpi03
rpi04
rpi05
rpi06
rpi07
rpi08
rpi09
rpi10
Nr
1
2
3
4
5
6
7
8
9
10
RS
RS
RS
RS
RS
RS
RS
RS
RS
RS
Hersteller
B.1 Übersicht
Samsung
Samsung
Samsung
Samsung
Samsung
Samsung
Samsung
Samsung
Samsung
Samsung
Speicher
B Rev. 2.0
B Rev. 2.0
B Rev. 2.0
B Rev. 2.0
B Rev. 2.0
B Rev. 2.0
B Rev. 2.0
B Rev. 2.0
B Rev. 2.0
B Rev. 2.0
Modell
B8:27:EB:48:9A:63
B8:27:EB:BD:BA:96
B8:27:EB:10:C8:9D
B8:27:EB:89:B0:4B
B8:27:EB:2D:26:DC
B8:27:EB:1E:D8:E7
B8:27:EB:51:29:89
B8:27:EB:61:B4:4C
B8:27:EB:CB:3D:35
B8:27:EB:81:B9:6C
MAC
RS
RS
RS
RS
RS
RS
RS
RS
RS
RS
Netzteil
Tabelle B.1: Raspberry Pi der HTW
B Raspberry Pi Hardware HTW
Intenso Class 10
Intenso Class 10
Intenso Class 10
Intenso Class 10
Intenso Class 10
Intenso Class 10
Intenso Class 10
Intenso Class 10
Intenso Class 10
Intenso Class 10
SD Card
x
x
x
x
x
x
x
x
x
x
SD Karte ok
x
x
x
x
x
x
x
x
x
-
1 GHz Boot?
C Erweiterungsboard
LM75B
Nor
t
h
Eas
t
Wes
t
Sout
h
MCP3002
Abbildung C.1: Erweiterungsboard
89
C Erweiterungsboard
Tabelle C.1: Erweiterungsboard und Routing der Komponeten
Bauteil
Bemerkung
GPIO
LED North
grün, PWM
18
LED East
rot
23
LED West
gelb
25
LED South
blau
24
Switch North
Pull-Down
4
Switch East
Pull-Down
17
Switch West
Pull-Down
22
Switch South
Pull-Down
27
LM75B
SDA
2
SCL
3
MOSI
10
MISO
9
SCLK
11
CS / SS
8
MCP3002
90
D Code Listings
Alle Code Listings stehen unter http://www.nico-maas.de/RPi_HTW.tar.gz zum Download bereit. Die auf dem RPi vorinstallierten Listings enthalten nicht die Lösungen zu
den gestellten Übungen um diese nicht vorweg zu nehmen.
D.1 boardTest.c
/*
* boardTest . c :
* Programm zum halbautomatischen Test
* des Erweiterungsboards und Beispiel
* zur Nutzung der GPIOs mit wiringPi2 und C
* Testet
* - LEDs
* - PWM
* - Schalter
* - I2C LM75B
* - SPI MCP3002
*/
// Include wiringPi
# include < stdio .h >
# include < wiringPi .h >
// Include and Define I2C
# include < wiringPiI2C .h >
# include < stdlib .h >
# define lm75b_addr 0 x48
int lm75b_file ;
int n ;
int lm75_temp ;
signed char lm75b_hi ;
signed char lm75b_lo ;
float lm75b_temp ;
// Include and Define SPI
# include < stdint .h >
# include < wiringPiSPI .h >
# define ADCCHANNEL 0
// LED Pins
# define LEDNORTH
18
# define LEDEAST
23
# define LEDWEST
25
# define LEDSOUTH 24
// Switch Pins
# define SWITCHNORTH 4
91
D Code Listings
# define SWITCHEAST 17
# define SWITCHWEST 22
# define SWITCHSOUTH 27
// PWM Variable
int bright ;
int i ;
int main ( void )
{
wiringPiSetupGpio () ;
// wiringPi mit GPIO Bennungschema intialisieren
/*
* LED Test
*/
pinMode ( LEDNORTH , OUTPUT ) ;
pinMode ( LEDEAST , OUTPUT ) ;
pinMode ( LEDWEST , OUTPUT ) ;
pinMode ( LEDSOUTH , OUTPUT ) ;
// LED Pins als Ausgabe definieren
printf ( " LED Test beginnt \ n " ) ;
delay (750) ;
printf ( " NORTH : LED gruen \ n " ) ;
digitalWrite ( LEDNORTH , HIGH ) ;
// LED Pin North aktivieren
delay (750) ;
printf ( " EAST : LED rot \ n " ) ;
digitalWrite ( LEDEAST , HIGH ) ;
delay (750) ;
printf ( " WEST : LED gelb \ n " ) ;
digitalWrite ( LEDWEST , HIGH ) ;
delay (750) ;
printf ( " SOUTH : LED blau \ n " ) ;
digitalWrite ( LEDSOUTH , HIGH ) ;
delay (2000) ;
digitalWrite ( LEDNORTH , LOW ) ;
digitalWrite ( LEDEAST , LOW ) ;
digitalWrite ( LEDWEST , LOW ) ;
digitalWrite ( LEDSOUTH , LOW ) ;
// LED Pins deaktivieren
printf ( " LED Test beendet \ n " ) ;
/*
* PWM Test
*/
pinMode ( LEDNORTH , PWM_OUTPUT ) ;
// LED Pin North als PWM Ausgang definieren
92
D.1 boardTest.c
printf ( " PWM Test beginnt \ n " ) ;
for ( i =0; i < 4; i ++)
{
for ( bright = 0 ; bright < 1024 ; ++ bright )
{
pwmWrite ( LEDNORTH , bright ) ;
// LED Pin mit PWM Wert ansteuern .
delay (1) ;
}
for ( bright = 1023 ; bright >= 0 ; -- bright )
{
pwmWrite ( LEDNORTH , bright ) ;
delay (1) ;
}
}
printf ( " PWM Test beendet \ n " ) ;
/*
* Switch Test
*/
pinMode ( SWITCHNORTH , INPUT ) ;
pinMode ( SWITCHEAST , INPUT ) ;
pinMode ( SWITCHWEST , INPUT ) ;
pinMode ( SWITCHSOUTH , INPUT ) ;
// Switch Pins als Eingabe definieren
printf ( " Switch Test beginnt \ n " ) ;
printf ( " NORTH : Switch druecken \ n " ) ;
while ( digitalRead ( SWITCHNORTH ) == LOW )
// So lange der Switch North nicht gedrÃ×ckt ist , warten
delay (1) ;
printf ( " NORTH : Switch ok \ n " ) ;
printf ( " EAST : Switch druecken \n " ) ;
while ( digitalRead ( SWITCHEAST ) == LOW )
delay (1) ;
printf ( " EAST : Switch ok \ n " ) ;
printf ( " WEST : Switch druecken \n " ) ;
while ( digitalRead ( SWITCHWEST ) == LOW )
delay (1) ;
printf ( " WEST : Switch ok \ n " ) ;
printf ( " SOUTH : Switch druecken \ n " ) ;
while ( digitalRead ( SWITCHSOUTH ) == LOW )
delay (1) ;
printf ( " SOUTH : Switch ok \ n " ) ;
printf ( " Switch Test beendet \ n " ) ;
93
D Code Listings
/*
* LM75B Sensortest
* Original von http :// www . keesmoerman . nl / raspberry . html
* Fehlerkorrektur fÃ×r falschen Bus von Nico Maas
*/
printf ( " LM75B Temperatursensor Test beginnt \ n " ) ;
if (( lm75b_file = wiringPiI2CSetup ( lm75b_addr ) ) == -1)
{
printf ( " Kann den I2C Bus nicht oeffnen !\ n " ) ;
return -1;
}
// Verbindung zu LM75B oeffnen
for ( i =0; i < 10; i ++)
{
lm75_temp = wiringPiI2CReadReg16 ( lm75b_file , 0) ;
// Register 0 von LM75B in 16 Bit Tiefe auslesen
lm75b_hi = ( lm75_temp & 0 xFF ) ;
lm75b_lo = ( lm75_temp >> 8) ;
// In 2 x 8 Bit Werte ( High und Low Bit ) umwandeln
n = lm75b_hi << 3 | (( lm75b_lo >> 5) & 0 x07 ) ;
/* gemaess Datasheet des Sensors aus den ausgelesenen
2 Bytes die korreten 11 Bits fÃ×r den Temperaturwert
extrahieren und shiften */
lm75b_temp = ( float ) n / 8;
// 11 Bit Wert in Temperatur umwandeln
printf ( " LM75B : %4.2 f Grad Celsius \ n " , lm75b_temp ) ;
// Temperatur mit 2 Nachkommastellen ausgeben
delay (750) ;
}
printf ( " LM75B Temperatursensor Test beendet \ n " ) ;
/*
* MCP3002 ADC Test
* Angepasst von http :// raspberrypihobbyist . blogspot . de /2012/12/
analog - interface . html
*/
printf ( " MCP3002 ADC Test beginnt \ n" ) ;
// SPI Daten von MCP3002 Chip lesen , 2 moegliche Kanaele (0 und 1)
int readadc ( adcnum )
{
uint8_t buff [2];
if (( adcnum > 1) || ( adcnum < 0) )
{
return -1;
}
// Nur MCP Kanal 0 und 1 zulassen
buff [0] = (6+ adcnum ) < <4;
buff [1] = 0;
// korrekte Anfrage fuer MCP3002 gemaess Datenblatt erzeugen
wiringPiSPIDataRW (0 , buff , 2) ;
// Anfrage absenden und Antwort in den Puffer schreiben
94
D.2 gpio.sh
}
return (( buff [0]&3) << 8) + buff [1];
// Wert aus Puffer shiften
if ( wiringPiSPISetup (0 , 1000000) < 0)
{
return -1 ;
}
/* WiringPi SPI API initalisieren auf Slave Select / SPI Kanal 0
mit Geschwindigkeit 1 MHz */
for ( i =0; i < 10; i ++)
{
// Wert von MCP3002 , Kanal 0 ( LDR ) ausgeben
printf ( " MCP3002 - Channel 0: % d \ n " , readadc ( ADCCHANNEL ) ) ;
delay (750) ;
}
printf ( " MCP3002 ADC Test beendet \ n" ) ;
}
return 0 ;
D.2 gpio.sh
# !/ bin / bash
# LED
# GPIO als Ausgang deklarieren und Hilfsfunktionen fuer Steuerung
definieren
# LED gruen , norden
gpio export 18 out
ledNorthOn ()
{
gpio -g write 18 1
}
ledNorthOff ()
{
gpio -g write 18 0
}
# LED rot , east
gpio export 23 out
ledEastOn ()
{
gpio -g write 23 1
}
ledEastOff ()
{
gpio -g write 23 0
95
D Code Listings
}
# LED gelb , west
gpio export 25 out
ledWestOn ()
{
gpio -g write 25 1
}
ledWestOff ()
{
gpio -g write 25 0
}
# LED blau , south
gpio export 24 out
ledSouthOn ()
{
gpio -g write 24 1
}
ledSouthOff ()
{
gpio -g write 24 0
}
# LED , alle
ledOn ()
{
gpio -g write
gpio -g write
gpio -g write
gpio -g write
}
ledOff ()
{
gpio -g
gpio -g
gpio -g
gpio -g
}
write
write
write
write
18
23
25
24
1
1
1
1
18
23
25
24
0
0
0
0
ledBlinkFast ()
{
for i in {0..1}
do
ledOn
sleep 0.25
ledOff
sleep 0.25
done
}
96
D.3 demoLed.sh
ledBlink ()
{
for i in {0..1}
do
ledOn
sleep 0.5
ledOff
sleep 0.5
done
}
# Switch
# GPIO als Eingang deklarieren und Hilfsfunktionen fuer Steuerung
definieren
# Switch north
gpio export 4 in
switchNorth ()
{
echo ` gpio -g read 4 `
}
# Switch east
gpio export 17 in
switchEast ()
{
echo ` gpio -g read 17 `
}
# Switch west
gpio export 22 in
switchWest ()
{
echo ` gpio -g read 22 `
}
# Switch south
gpio export 27 in
switchSouth ()
{
echo ` gpio -g read 27 `
}
D.3 demoLed.sh
# !/ bin / bash
source gpio . sh
# GPIO Hilfsdatei einfuegen
echo '
97
D Code Listings
Raspberry Pi Shield Demo
Alle LEDs werden auf dem Shield aktiviert und
anschliessend deaktiviert .
Das Programm beendet sich automatisch .
';
ledNorthOn
sleep 0.25
ledEastOn
sleep 0.25
ledWestOn
sleep 0.25
ledSouthOn
# LEDs anschalten
sleep 2
# 2 Sekunden warten
ledNorthOff
ledEastOff
ledWestOff
ledSouthOff
# LEDs ausschalten
D.4 demoSwitch.sh
# !/ bin / bash
source gpio . sh
# GPIO Hilfsdatei einfuegen
echo '
Raspberry Pi Shield Demo
Druecke einen Schalter auf dem Shield um die
entsprechende LED zu aktivieren .
STRG + C um das Programm zu beenden .
';
while :
do
if [ $ ( switchNorth ) = 1 ]
# falls Schalter North gedrueckt ist
then
echo " North gedrueckt "
ledNorthOn
# North gedrueckt ausgeben und die entsprechende LED anschalten
else
ledNorthOff
# sonst die LED ausschalten
fi
if
98
[ $ ( switchEast ) = 1 ]
D.5 simon.sh
then
else
fi
echo " East gedrueckt "
ledEastOn
ledEastOff
if [ $ ( switchWest ) = 1 ]
then
echo " West gedrueckt "
ledWestOn
else
ledWestOff
fi
if [ $ ( switchSouth ) = 1 ]
then
echo " South gedrueckt "
ledSouthOn
else
ledSouthOff
fi
done
D.5 simon.sh
# !/ bin / bash
source gpio . sh
# GPIO Hilfsdatei einfuegen
# Konstanten
# Verzoegerung zwischen LED leuchten
DELAY_TIME_LED =0.25
# Verzoegerung bei Switch Eingabe
DELAY_TIME_SWITCH =0.2
# Variablen
# correct =0 Eingaben in Ordnung , Spiel geht weiter
# correct = -1 Eingabe falsch , Abbruch
correct =0
MakeRandom ()
{ # Zufallszahl zwischen 0 und 3
echo $ (( RANDOM %4) )
}
LightLed ()
{
# gibt alle Werte aus dem Array wieder , zeigt
# also an welche Werte eingegeben werden
# muessen um die Runde zu schaffen .
# Alle Werte im Array abrufen
99
D Code Listings
}
for value in " $ { simonArray [ @ ]} "
do
# gemaess dem Array Wert die pasende LED
# an - und ausschalten
case " $value " in
0)
ledNorthOn
sleep $ { DELAY_TIME_LED }
ledNorthOff
sleep $ { DELAY_TIME_LED }
;;
1)
ledEastOn
sleep $ { DELAY_TIME_LED }
ledEastOff
sleep $ { DELAY_TIME_LED }
;;
2)
ledWestOn
sleep $ { DELAY_TIME_LED }
ledWestOff
sleep $ { DELAY_TIME_LED }
;;
3)
ledSouthOn
sleep $ { DELAY_TIME_LED }
ledSouthOff
sleep $ { DELAY_TIME_LED }
;;
esac
done
ReadButton ()
{ # Liest den Zustand der 4 Schalter ein
# sollte einer gedrueckt sein wird die
# Abfrage abgebrochen und der Wert
# zurueck gegeben . Ist keiner gedrueckt ,
# wird -1 zurueck gegeben .
if [ $ ( switchNorth ) = 1 ]
then
echo 0
elif [ $ ( switchEast ) = 1 ]
then
echo 1
elif [ $ ( switchWest ) = 1 ]
then
echo 2
elif [ $ ( switchSouth ) = 1 ]
then
echo 3
else
echo -1
100
D.5 simon.sh
}
fi
CheckButton ()
{
# Ueberprueft ob die eingegebene
# Kombination der physikalischen
# Schalter der vorgegebenen
# entspricht . Falls ja , geht
# das Spiel weiter , wenn nicht ,
# wird correct = -1 gesetzt .
# Alle Werte im Array abrufen
for value in " $ { simonArray [ @ ]} "
do
# Wert der Schalter auslesen
btn = $ ( ReadButton )
# Solange kein Schalter gedrueckt
# ist , weiter auslesen
while [ $btn == -1 ]
do
btn = $ ( ReadButton )
done
# Falls ein Schalter gedrueckt wurde ,
# und der Wert der Stelle im Array
# entspricht , weiter machen
if [ $btn == $value ]
then
echo " Ok ! "
# sleep hilft an dieser Stelle einem
# zu lange gedrueckten Schalter vorzubeugen .
# Alternativ koennte man in ReadButton
# einen Flankenwechsel als Schalterdruck
# identifizieren
sleep $ { DELAY_TIME_SWITCH }
# Sonst : correct = -1 setzen und
# aus der Schleife ausbrechen
else
echo " Falsch ! "
correct = -1
break
fi
done
}
# 2 x schnelles blinken aller LEDs
# als " Willkommen "
ledBlinkFast
sleep 0.5
# Solange die eingegebenen Kombinationen richtig waren ,
# geht das Spiel immer weiter .
while [ $correct == 0 ]
do
# An der Stelle " groesse des Arrays " einen neuen Zufallswert
101
D Code Listings
# zwischen 0 und 3 in das Array einfuegen . Damit sparen
# wir uns die Zahlvariable / Iterationsvariable
simonArray [ ${ # simonArray [ @ ]}]= $ ( MakeRandom )
# Alle Zufallswerte des Arrays auf den LEDs abspielen
LightLed
# Die Eingabe der Zufallswerte ueber die Schalter
# erwarten und auf Fehler auswerten . Bei Fehler
# wird correct = -1 gesetzt und das Spiel endet .
# Sonst geht es endlos weiter .
CheckButton
done
# 2 x langsames blinken aller LEDs
# bei Fehler / Ende des Spiels
sleep 0.5
ledBlink
echo $ { # simonArray [@ ]}
echo $ { simonArray [ @ ]}
# Neustart des Spiels bei Fehler
./ simon . sh
D.6 uebungAusgabe.py
# !/ usr / bin / python
import wiringpi2 as wpi
from time import sleep
wpi . wiringPiSetupGpio ()
LEDs =[18 ,23 ,24 ,25]
# LED Pins als Array fuer
# gruen , rot , blau , gelb
led_mode =1
# Variable welche den Wert
# haelt ob die LED ein oder
# ausgeschaltet werden soll
for led_pin in LEDs :
wpi . pinMode ( led_pin ,1)
wpi . digitalWrite ( led_pin ,0)
# Setup : Alle Pins mit LEDs
# als Ausgabe setzen und
# abschalten
while True :
for led_pin in LEDs :
wpi . digitalWrite ( led_pin , led_mode )
sleep (0.25)
led_mode = not ( led_mode )
# Loop : Jeweils pro Durchlauf
102
D.7 uebungEingabe.py
# alle LEDs in den jeweils gueltigen
# Mode setzen und danach den Mode
# negieren ( An / Aus )
D.7 uebungEingabe.py
# !/ usr / bin / python
import wiringpi2 as wpi
from time import sleep
wpi . wiringPiSetupGpio ()
LEDs =[24 ,25 ,18 ,23]
# LED Pins als Array fuer
# blau , gelb , gruen , rot
for led_pin in LEDs :
wpi . pinMode ( led_pin ,1)
wpi . digitalWrite ( led_pin ,0)
# Setup : Alle Pins mit LEDs
# als Ausgabe setzen und ausschalten
wpi . pinMode (27 ,0)
# Setup : Schalter South
# als Eingabe setzen
def blinkLED ( ledPin , wieoftBlinken , verzoegerung ) :
for i in range (1 ,(( wieoftBlinken *2) +1) ) :
wpi . digitalWrite ( LEDs [ ledPin ] ,( i %2) )
sleep ( verzoegerung )
# Modul blinkLED nimmt die aktuelle LED entgegen
# und laesst diese mit gegebener Verzoegerung
# eine gewisse Anzahl blinken
aktuelleLED =0
# Gibt aktuelle LED as Position im Array an
aktuelleVerzoegerung =0.50
# Gibt die aktuelle Verzoegerung zwischen
# den LED wechseln an
aktuelleRunde =1
# Gibt die aktuelle Runde an
while True :
if ( wpi . digitalRead (27) ) :
# falls der Schalter gedrueckt wurde
blinkLED ( aktuelleLED , 2 , 0.5)
# lass die mit dem Schalter gewaehelte
# LED zwei mal blinken
if ( aktuelleLED ==2) :
if ( aktuelleVerzoegerung > 0.05) :
aktuelleVerzoegerung = aktuelleVerzoegerung -0.05
# reduziere die Verzoegerung fuer die
# nacheste Runde , falls moeglich
aktuelleLED =0
103
D Code Listings
# setze LED wieder auf Anfang vom Array zurueck
print ( " Runde % d bestanden " % aktuelleRunde )
# Erfolg
aktuelleRunde = aktuelleRunde +1
# naechste Runde
else :
print ( " Leider verloren in Runde % d ! " % aktuelleRunde )
# Niederlage , weil falsch / zu spaet gedrueckt
break
# Verlasse Schleife und beende Programm
blinkLED ( aktuelleLED , 1 , aktuelleVerzoegerung )
# die jeweils aktuelle LED einmal blinken lassen
aktuelleLED = aktuelleLED +1
# und zur naechsten iterieren
if ( aktuelleLED > 3) :
print ( " Leider verloren in Runde % d ! " % aktuelleRunde )
# Niederlage , weil gar nicht gedrueckt
break
# Verlasse Schleife und beende Programm
D.8 binaryCounter.py
# !/ usr / bin / python
import wiringpi2 as wpi
wpi . wiringPiSetupGpio ()
LEDs =[18 ,23 ,24 ,25]
# LED Pins als Array fuer
# gruen , rot , blau , gelb
for led_pin in LEDs :
wpi . pinMode ( led_pin ,1)
wpi . digitalWrite ( led_pin ,0)
# Setup : Alle Pins mit LEDs
# als Ausgabe setzen und ausschalten
wpi . pinMode (27 ,0)
wpi . pinMode (22 ,0)
# Setup : Schalter South ,
# Schalter West als Eingabe setzen
southState = wpi . digitalRead (27)
westState = wpi . digitalRead (22)
# Setup : Initialer Status
# von South und West einlesen
zahl =0
# Zaehlvariable
ledMode =[0 ,0 ,0 ,0]
# Zwischenspeicher fuer die
# Ergebnisse der Umrechnung
def showLED () :
ledMode [0] = zahl & 0 b0001
104
D.9 lm75b.py
ledMode [1] = zahl & 0 b0010
ledMode [2] = zahl & 0 b0100
ledMode [3] = zahl & 0 b1000
# jeweils aus der binaeren Verundung der
# Zahl und der Wertigkeit der LED
# den Status fuer die LED errechnen
# und speichern
for i in range (0 ,4) :
wpi . digitalWrite ( LEDs [ i ] , ledMode [ i ])
# alle LEDs auf den aktuellen Status setzen
print ( " Dezimal %d , Binaer %s , Hexadezimal % s " % ( zahl , bin ( zahl ) ,
hex ( zahl ) ) )
# die aktuelle Zahl als Dezimal ,
# Binaer und Hexadezminal Notation
# ausgeben
showLED ()
while True :
southValue = wpi . digitalRead (27)
# aktueller Status des
# Schalters einlesen
if ( southValue != southState ) :
# besteht ein Unterschied
# zum gespeicherten Status
if ( southValue ) :
# Ist der +1 Schalter gedrueckt ?
zahl = zahl +1
# Zahl erhoehen
if zahl >15:
zahl =0
# Zahl ruecksetzen falls zu hoch
showLED ()
# Anzeigen
southState = southValue
# neuen Wert des Schalters speichern
westValue = wpi . digitalRead (22)
if ( westValue != westState ) :
if ( westValue ) :
# Ist der Reset Schalter gedrueckt ?
zahl =0
# Zahl ruecksetzen
showLED ()
# Anzeigen
westState = westValue
D.9 lm75b.py
# !/ usr / bin / python
import wiringpi2 as wpi
lm75b_addr =0 x48
105
D Code Listings
lm75b_file = wpi . wiringPiI2CSetup ( lm75b_addr )
# Verbindung zu LM75B oeffnen
if lm75b_file < 0:
print ( " Kann den I2C Bus nicht oeffnen ! " )
else :
lm75_temp = wpi . wiringPiI2CReadReg16 ( lm75b_file , 0)
# Register 0 von LM75B in 16 Bit Tiefe auslesen
lm75b_hi = ( lm75_temp & 0 xFF )
lm75b_lo = ( lm75_temp >> 8)
# In 2x 8 Bit Werte ( High und Low Bit ) umwandeln
n = lm75b_hi << 3 | (( lm75b_lo >> 5) & 0 x07 )
# gemaess Datasheet des Sensors aus den ausgelesenen
# 2 Bytes die korreten 11 Bits fuer den Temperaturwert
# extrahieren und shiften
lm75b_temp = n / 8.0
# 11 Bit Wert in Temperatur umwandeln
print ( " LM75B : %4.2 f Grad Celsius " % ( lm75b_temp ) )
# Temperatur mit 2 Nachkommastellen ausgeben
D.10 uebungI2C.py
# !/ usr / bin / python
import wiringpi2 as wpi
from time import sleep
lm75b_addr =0 x48
# I2C Adresse des LM75B
LEDs =[24 ,18 ,23]
# LED Pins als Array fuer
# blau , gruen , rot
modifierState =[ -1 ,0 ,+1]
# Temperatur Unterschiede fuer Ubergang
nameState =[ " Kalt " ," Normal " ," Warm " ]
# Namen der States
currentState =0
# State der Pseudo State Machine
maxStates =3
# Anzahl der States
def readTemp () :
lm75_temp = wpi . wiringPiI2CReadReg16 ( lm75b_file , 0)
# Register 0 von LM75B in 16 Bit Tiefe auslesen
lm75b_hi = ( lm75_temp & 0 xFF )
lm75b_lo = ( lm75_temp >> 8)
# In 2x 8 Bit Werte ( High und Low Bit ) umwandeln
n = lm75b_hi << 3 | (( lm75b_lo >> 5) & 0 x07 )
# gemaess Datasheet des Sensors aus den ausgelesenen
# 2 Bytes die korreten 11 Bits fuer den Temperaturwert
# extrahieren und shiften
lm75b_temp = n / 8.0
106
D.10 uebungI2C.py
# 11 Bit Wert in Temperatur umwandeln
return lm75b_temp
def transition ( up ) :
global currentState , maxMod , minMod
# globale Variablen in Funktion laden
wpi . digitalWrite ( LEDs [ currentState ] ,0)
# Led des jetzigen State abschalten
if ( up ==1) :
# Falls State erhoeht wird
currentState = currentState +1
# State erhoehen
print ( " Transition von % s -> % s " % ( nameState [ currentState -1] ,
nameState [ currentState ]) )
# Ausgabe vorheriger State nach jetziger State
else :
currentState = currentState -1
# State verringern
print ( " Transition von % s -> % s " % ( nameState [ currentState +1] ,
nameState [ currentState ]) )
# Ausgabe vorheriger State nach jetziger State
wpi . digitalWrite ( LEDs [ currentState ] ,1)
# Led des nun aktuellen State einschalten
if ( modifierState [ currentState ]==0) :
# Falls State 1 / Normal aktiv
maxMod =1
# setze maximalen Wert auf +1
minMod = -1
# setze minimalen Wert auf -1
else :
# sonst setze Max / Min gemaess Array
maxMod = modifierState [ currentState ]
minMod = modifierState [ currentState ]
lm75b_file = wpi . wiringPiI2CSetup ( lm75b_addr )
# Verbindung zu LM75B oeffnen
if lm75b_file < 0:
print ( " Kann den I2C Bus nicht oeffnen ! " )
else :
# Setup
wpi . wiringPiSetupGpio ()
# Initialisiert die Bibliothek unter Nutzung des
# BCM GPIO Namenschema
for led_pin in LEDs :
wpi . pinMode ( led_pin ,1)
wpi . digitalWrite ( led_pin ,0)
# Alle Pins mit LEDs als Ausgabe setzen und abschalten
idealTemp = readTemp ()
# Ideal Temperatur messen
transition (1)
# Initalisieren auf Normal Modus
while True :
107
D Code Listings
if (( readTemp () > ( idealTemp + maxMod ) ) and ( currentState < (
maxStates -1) ) ) :
# falls aktuelle Temperatur groesser als Ideal Temperatur +
Modifier
# und aktueller State kleiner als die maximale Anzahl an States
transition (1)
# State erhoehen
elif (( readTemp () < ( idealTemp + minMod )) and ( currentState > 0) ) :
# falls aktuelle Temperatur kleiner als Ideal Temperatur + Modifier
# und aktueller State groesser als 0
transition (0)
# State verringern
else :
# falls innerhalb der Temperatur des States
print ( " % s : %4.2 f " % ( nameState [ currentState ] , readTemp () ) )
# aktueller State und aktuelle Temperaturmessung ausgeben
sleep (0.25)
D.11 mcp3002.py
# !/ usr / bin / python
import wiringpi2 as wpi
from binascii import hexlify
from binascii import unhexlify
mcp3002_channel =0
if wpi . wiringPiSPISetup (0 ,1000000) < 0:
print ( " Kann den SPI Bus nicht oeffnen ! " )
else :
buffer =((6+ mcp3002_channel ) < <12)
buffer = ' {0: x } '. format ( int ( buffer ) )
# Wandle den dezimalen Integer in einen
# hexadezimalen String um , ohne das Praefix
# 0 x davorzustellen
buffer = unhexlify ( buffer )
# Wandle den Hex String in einen Byte String um
if ( wpi . wiringPiSPIDataRW (0 , buffer ) == -1) :
# Anforderung auf den SPI Bus auf Slave
# Select 0 schreiben und
# gleichzeitig ( bi - direktional ) mit der
# Antwort den Buffer ueberschreiben
print ( " Schreibfehler auf SPI Bus !\ n " )
else :
buffer = hexlify ( buffer )
# Wandle den Byte String nach Hex um
buffer = int ( buffer , 16)
# Wandle den Hex String in einen
# dezimalen Integer Wert um
prozent = ( buffer /1024.0) *100
108
D.12 mcp3002lib.py
# Wandle dezimalen Integer in Prozentwert
# der eingegangen Beleuchtungsstaerke um
print ( " MCP3002 - Kanal % d : %4.2 f Prozent " % ( mcp3002_channel ,
prozent ) )
D.12 mcp3002lib.py
# !/ usr / bin / python
import wiringpi2 as wpi
mcp3002_channel =0
if ( wpi . wiringPiSPISetup (0 , 1000000) < 0) :
# Verbindung zu MCP3002 oeffnen
print ( " Kann den SPI Bus nicht oeffnen ! " )
else :
wpi . mcp3002Setup (64 , mcp3002_channel )
# MCP3002 Template laden , Kanal 0 auf virtuellen Port 64 legen
buffer = wpi . analogRead (64)
# Virtuellen Port 64 auslesen
prozent = ( buffer /1024.0) *100
# Wandle dezimalen Integer in Prozentwert
# der eingegangen Beleuchtungsstaerke um
print ( " MCP3002 - Kanal % d : %4.2 f Prozent " % ( mcp3002_channel , prozent
))
D.13 uebungSPI.py
# !/ usr / bin / python
import curses
from time import sleep
import wiringpi2 as wpi
mcp3002_channel =0
if ( wpi . wiringPiSPISetup (0 , 1000000) < 0) :
# Verbindung zu MCP3002 oeffnen
print ( " Kann den SPI Bus nicht oeffnen ! " )
else :
wpi . mcp3002Setup (64 , mcp3002_channel )
# MCP3002 Template laden , Kanal 0 auf virtuellen Port 64 legen
ldr_max = float ( wpi . analogRead (64) )
# Virtuellen Port 64 auslesen , als maximal Wert
screen = curses . initscr ()
# curses in der Konsole initialisieren
dims = screen . getmaxyx ()
# y , x Groesse des Bildschirms in Array ablegen
# dims [0] entspricht y Wert
109
D Code Listings
# dims [1] entspricht x Wert
screen . nodelay (1)
# nodelay Modus aktivieren um screen . getch ()
# im non - Blocking Modus zu betreiben
while ( screen . getch () == -1) :
# fuehre die Schleife aus solange keine
# Taste gedrueckt wurde
ldr = wpi . analogRead (64)
# aktuellen Wert einlesen
wert = int (( ldr / ldr_max ) * dims [0])
# LDR Wert auf Dimensionen des Bildschirms skalieren
if wert >= dims [0]:
# Sollte der Wert die y Dimension ueberschreiten
wert = ( dims [0] -1)
# dann einfach fuer diese Messung
# y - Dimension - 1 als Wert nehmen
wert = dims [0] - wert
# Gegenwert berechnen , da bei curses die linke , obere
# Bildschirm Ecke die x , y Koordinaten 0 ,0 hat
screen . erase ()
# Bildschirm loeschen
screen . hline ( wert , 0, ' - ' , dims [1])
# horinzontale Linie aus - Zeichen malen ,
# welche so breit wie die maximale x Dimension ( dims [1])
# ist und beim x Wert 0 beginnt
# hline (y Koordinate , x Beginn , ch Zeichen , n Laenge )
screen . refresh ()
# Bildschirm neu laden
sleep (0.1)
curses . endwin ()
# Beenden
D.14 wpi.c
// wiringPi 2 MathLink
# include " mathlink . h "
# include < stdio .h >
# include < wiringPi .h >
// Include and Define I2C
# include < wiringPiI2C .h >
# include < stdlib .h >
# define lm75b_addr 0 x48
int lm75b_file ;
int n ;
int lm75_temp ;
signed char lm75b_hi ;
signed char lm75b_lo ;
float lm75b_temp ;
// Include and Define SPI
110
D.14 wpi.c
# include < stdint .h >
# include < wiringPiSPI .h >
extern
extern
extern
extern
extern
extern
void setPinMode ( int pin , int mode ) ;
void setDigitalWrite ( int pin , int value ) ;
void setPwmWrite ( int pin , int value ) ;
int getDigitalRead ( int pin ) ;
float getLM75B () ;
int getMCP3002 ( int channel );
void setPinMode ( int pin , int mode )
{
pinMode ( pin , mode ) ;
MLPutSymbol ( stdlink , " Null " ) ;
}
void setDigitalWrite ( int pin , int value )
{
digitalWrite ( pin , value ) ;
MLPutSymbol ( stdlink , " Null " ) ;
}
void setPwmWrite ( int pin , int value )
{
pwmWrite ( pin , value ) ;
MLPutSymbol ( stdlink , " Null " ) ;
}
int getDigitalRead ( int pin )
{
return digitalRead ( pin ) ;
}
float getLM75B ()
{
if (( lm75b_file = wiringPiI2CSetup ( lm75b_addr ) ) == -1)
{
printf ( " Kann den I2C Bus nicht oeffnen !\ n " ) ;
return -1;
}
// Verbindung zu LM75B oeffnen
lm75_temp = wiringPiI2CReadReg16 ( lm75b_file , 0) ;
// Register 0 von LM75B in 16 Bit Tiefe auslesen
lm75b_hi = ( lm75_temp & 0 xFF ) ;
lm75b_lo = ( lm75_temp >> 8) ;
// In 2 x 8 Bit Werte ( High und Low Bit ) umwandeln
n = lm75b_hi << 3 | (( lm75b_lo >> 5) & 0 x07 ) ;
/* gemaess Datasheet des Sensors aus den ausgelesenen
2 Bytes die korreten 11 Bits fÃ×r den Temperaturwert
extrahieren und shiften */
lm75b_temp = ( float ) n / 8;
// 11 Bit Wert in Temperatur umwandeln
return lm75b_temp ;
111
D Code Listings
}
int getMCP3002 ( int channel )
{
uint8_t buff [2];
if (( channel > 1) || ( channel < 0) )
{
// Nur MCP Kanal 0 und 1 zulassen
return -1;
}
}
if ( wiringPiSPISetup (0 , 1000000) < 0)
{
return -1 ;
}
/* WiringPi SPI API initalisieren auf Slave Select / SPI Kanal 0
mit Geschwindigkeit 1 MHz */
buff [0] = (6+ channel ) < <4;
buff [1] = 0;
// korrekte Anfrage fuer MCP3002 gemaess Datenblatt erzeugen
wiringPiSPIDataRW (0 , buff , 2) ;
// Anfrage absenden und Antwort in den Puffer schreiben
return (( buff [0]&3) << 8) + buff [1];
// Wert aus Puffer shiften
int main ( int argc , char * argv [])
{
wiringPiSetupGpio () ;
return MLMain ( argc , argv ) ;
}
D.15 wpi.tm
float getLM75B () ;
: Begin :
: Function :
: Pattern :
: Arguments :
: ArgumentTypes :
: ReturnType :
: End :
getLM75B
getLM75B []
{ }
{ }
Float
: Evaluate : getLM75B :: usage = " getLM75B [] gives the Temperature in
degree Celsius . "
int getMCP3002 P (( int ) ) ;
112
D.15 wpi.tm
: Begin :
: Function :
: Pattern :
: Arguments :
: ArgumentTypes :
: ReturnType :
: End :
getMCP3002
getMCP3002 [ channel_Integer ]
{ channel }
{ Integer }
Integer
: Evaluate : getMCP3002 :: usage = " getMCP3002 [ channel ] gives 10 bit
reading (0 -1023) of the choosen ADC channel 0 -1. "
void setPinMode P (( int , int ) ) ;
: Begin :
: Function :
: Pattern :
: Arguments :
: ArgumentTypes :
: ReturnType :
: End :
setPinMode
setPinMode [ pin_Integer , mode_Integer ]
{ pin , mode }
{ Integer , Integer }
Manual
: Evaluate : setPinMode :: usage = " setPinMode [ pin , mode ] set the given pin
to 0 ( Input ) , 1 ( Output ) or 2 ( PWM Output ) . "
void setDigitalWrite P (( int , int ) ) ;
: Begin :
: Function :
: Pattern :
: Arguments :
: ArgumentTypes :
: ReturnType :
: End :
setDigitalWrite
setDigitalWrite [ pin_Integer , value_Integer ]
{ pin , value }
{ Integer , Integer }
Manual
: Evaluate : setDigitalWrite :: usage = " setDigitalWrite [ pin , value ] writes
a digital value (0 -1) to the pin . "
void setPwmWrite P (( int , int ) ) ;
: Begin :
: Function :
: Pattern :
: Arguments :
: ArgumentTypes :
: ReturnType :
: End :
setPwmWrite
setPwmWrite [ pin_Integer , value_Integer ]
{ pin , value }
{ Integer , Integer }
Manual
113
D Code Listings
: Evaluate : setPwmWrite :: usage = " setPwmWrite [ pin , value ] writes a pwm
value (0 -1023) to the pin . "
int getDigitalRead P (( int ) ) ;
: Begin :
: Function :
: Pattern :
: Arguments :
: ArgumentTypes :
: ReturnType :
: End :
getDigitalRead
getDigitalRead [ pin_Integer ]
{ pin }
{ Integer }
Integer
: Evaluate : getDigitalRead :: usage = " getDigitalRead [ pin ] gives the
digital reading (0 or 1) of the pin . "
114
Kolophon
Dieses Dokument wurde mit der LATEX-Vorlage für Abschlussarbeiten an der htw saar
im Bereich Informatik/Mechatronik-Sensortechnik erstellt (Version 1.0). Die Vorlage
wurde von Yves Hary und André Miede entwickelt (mit freundlicher Unterstützung
von Thomas Kretschmer und Helmut G. Folz).