Raspberry
Pi Portzugriffe
Elektronik-Labor
Projekte
Mikrocontroller
Raspberry
Ich war
neugierig, ob der Raspberry ein Thema für das Elektronik-Labor werden
könnte.
Interessant wäre der Einsatz als Messgerät oder als Signalquelle für
universelle Anwendungen. Für den ersten Start habe ich mir das aktuelle
Modell
Paspberry Pi 2 in einem Komplettsatz von Reichelt bestellt. Dabei ist
ein
Gehäuse, Netzteil, WLAN-Stick und eine vorbereitete
Speicherkarte mit dem
Betriebssystem. Weil ich mit Linux nicht vertraut bin, habe ich mir von
meinem
Sohn Fabian und meinem Freund Rainer helfen lassen. Insgesamt war ich
positiv
überrascht. Mit dem fertig installierten System kann man fast so wie
mit einem
Windows-PC umgehen. Surfen im Internet funktioniert einwandfrei. Da
kann man
sich gleich alle nötigen Informationen zur Programmierung aus den Netz
zusammensuchen.
Für den Start braucht man einen Bildschirm, eine USB-Maus und eine
USB-Tastatur
sowie den WLAN-Stick. Das System ist dann mit einem kleinen PC
vergleichbar,
wobei angenehm auffällt, dass keine Festplatte und kein Lüfter rauscht.
Inzwischen habe ich auch eine Verbindung zum Windows-PC mit TightVNC.
Der
Raspberry erscheint dann in einem Fenster auf dem PC und kann von dort
komplett
bedient werden. Das ist sehr praktisch für Screenshots und
die
Dokumentation von Ergebnissen. Außerdem kommt das System dann dem Ideal
eines
autonomen Messknechts näher.
Jetzt geht es primär erstmal um die elektronischen Möglichkeiten. Alles
steht
und fällt mit den Portzugriffen und der passenden Programmiersprache.
Ich
arbeite mit Python. Das ist eine
einfache und vielseitige Programmiersprache, die speziell für die
Ausbildung
entwickelt wurde. Hier wird die Version 2 verwendet, denn
sie wird
durch mehr Beispiele im Netz unterstützt. Die Nutzung der Programme mit
Python 3 erfordert einige kleine Anpassungen. Das Programm lässt sich
direkt aus der grafischen Oberfläche starten.
Alternativ kann es man auch über eine Kommandozeile aufrufen:
Das Programm heißt „ idle“
In beiden Fällen startet die Python Shell mit einer
Startmeldung und dem Prompt >>>. Ein erster Test
zeigt, wie Python
Befehle direkt, also ohne eine eigene Programmdatei ausführt. Mit
„print 4+4“
erhält man direkt das gesuchte Ergebnis. Nach File/New File kann man
ein eigenes Programm eingeben.
An die GPIO-Ports kommt man nur mit einer speziellen
Bibliothek mit dem Namen RPi.GPIO. Diese muss man mit import einbinden.
Ganz wichtig
ist die Groß/Kleinschreibung, sonst wird die Datei nicht erkannt.
Mit GPIO.setmode(GPIO.BCM) schaltet man in den
Broadcom-Modus um. Hier geht es um die Nummerierung der GPIOs. Durch
Hardwareänderungen zwischen den einzelnen Raspberry-Versionen würde es
immer
wieder zu Änderungen in der Nummerierung kommen. Broascom biegt das
wieder
zurecht, damit man immer weiß, welcher Pin gemeint ist.
Mit GPIO.setup(10, GPIO.OUT) schaltet man den Port 10 als
Ausgang, denn nach einem Neustart ist er ein Eingang. Und mit
GPIO.output(10,
1) soll er dann eingeschaltet werden. Soll! Denn erstmal gibt es eine
Fehlermeldung.
Zugang verweigert! Linux ist sehr streng mit solchen Dingen.
Da darf nicht einfach jeder ungefragt an alles heran. Es geht um die
Sicherheit,
Zugriffsrechte und solche Sachen. Aber es gibt einen Ausweg. Man muss
sich nur
selbst zum Superuser ernennen und das Programm mit „sudo“ aufrufen:
sudo idle
Nun kann eine Warnung erscheinen: Der GPIO-Port wird bereits
verwendet. Das kann einem vorher gestarteten Programm liegen und wird
in den
meisten Fällen immer wieder angezeigt. Aber die Warnung enthält ja
bereits den
Hinweis, was zu tun ist. GPIO.setwarnings(False) sollte die Warnungen
abschalten.
Also
hat das Programm nun eine Zeile mehr. Damit ist nun alles klar für die
Portausgabe. Der Port 10 wird eingeschaltet und kann eine LED mit
Vorwiderstand treiben.
In der Python Shell erscheint nun nur noch der Hinweis auf
den Neustart des Programms, aber keine Fehlermeldung oder Warnung mehr.
Und hier das fertige Progrämmchen nochmal in Textform zum einfachen
Kopieren:
# GPIO10test_2.py Testausgabe an GPIO 10
import RPi.GPIO as GPIO #Bibliothek laden
GPIO.setmode(GPIO.BCM) #Broadcom-Modus
GPIO.setwarnings(False) #Warnungen abschalten
GPIO.setup(10, GPIO.OUT) #Pin 10 als Ausgang
GPIO.output(10, 1) #Pin 10 einschalten
Der
Postenstecker am Raspberry Pi 2 hat 40 Pinne, darunter achtmal GND,
zweimal +3,3V und zweimal +5V. Das Anschlussbild zeigt die Pinbelegung
für alle verwendbaren GPIO-Pins. Sie sind 3,3-V-kompatibel, und eine
Verbindung mit den 5-V-Pinnen ist gefährlich. Auch Kurzschlüsse müssen
unbedingt vermieden werden. Bei 40 Pinnen kann man sich leicht mal
verzählen. Im Bild sind daher die Pinne 10, 20, und 30
beschriftet. Wenn man sich diese Pinne auf dem Raspberry
markiert, fällt die Orientierung leichter.
Na
klar, wenn man an den Port herankommt, muss man natürlich erstmal einen
Blinker programmieren. Hier ist er und blinkt genau zehnmal.
# GPIO10test_2.py Blinker an GPIO 10
import RPi.GPIO as GPIO #Bibliothek laden
from time import sleep
GPIO.setmode(GPIO.BCM) #Broadcom-Modus
GPIO.setwarnings(False) #Warnungen abschalten
GPIO.setup(10, GPIO.OUT) #Pin 10 als Ausgang
for n in range(10):
print (n)
GPIO.output(10, 1) #Pin 10 einschalten
sleep (0.5)
GPIO.output(10, 0) #Pin 10 ausschalten
sleep (0.5)
print ("fertig")
Alternative
WiringPi von Schimmi
Ich freue mich als alter Linux-User sehr darüber, dass Sie einen
Artikel über den Raspberry geschrieben haben. Sie beschreiben den
Zugriff auf die IO-Ports mittels RPi.GPIO aus Python heraus. Leider
verwendet diese Bibliothek seit Version 0.3.0a jetzt /dev/mem ( Das den
lesenden und schreibenden Zugriff auf den gesamten Speicherbereich ders
Raspi erlaubt ) und nicht mehr /sys/class/gpio, das nur auf die IOs
Zugriff erlaubt. Der Zugriff mittels /dev/mem ist zwar schneller, aber
er erfordert zwingend Rootrechte und ist wesentlich
unsicherer. Ein falscher Zugriff und der Raspi stürzt nicht
nur ab, sondern es kann auch der Inhalt der SD-Karte verfälscht oder
überschrieben sein. Root kann alles und damit auch allen Schaden
anrichten. Solange der geringe Geschwindigkeitsvorteil der
sich durch die Verwendung von /dev/mem ergiebt nicht zwingen
notwendig ist würde ich zur Verwendung von WiringPi raten, da hier die
Zugriffe als normaler User erfolgen können.
Geschwindigkeitsmessung für
Portzugriffe
Die Zugriffsgeschwindigkeit ist für viele Aufgaben wie Zeitmessungen,
Frequenzmessung und Spannungsmessung über Ports ganz
entscheidend. Hier deshalb zunächst ein Test mit RPi.GPIO.
#Time1.py Zeitmesung: 1000 Portausgaben
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) # set board mode to Broadcom
GPIO.setup(10, GPIO.OUT) # set up pin 18
while (1):
t0=time.time()
for n in range(1000):
GPIO.output(10, 1) #Pin 10 einschalten
GPIO.output(10, 0) #Pin 10 ausschalten
t1=time.time()
print t1-t0
time.sleep(1)
Das Programm liefert endlos Messungen der Zeit für jeweils 2000
Portzugriffe. Die Endlosschleife while(1) kann mit
der Tastenkombination Strg-C abgebrochen werden. Die Messergebnisse in
Sekunden werden mit print in die Python Shell ausgegeben.
Man sieht schwankende Zeiten im Bereich 4 ms bis 7 ms. Im Durchschnitt
dauert ein Portzugriff also rund 3 µs. Über längere Strecken hat man
sehr schnelle Zugriffe, die aber durch kurze Unterbrechungen gestört
werden, weil ja auch noch andere Prozesse laufen.
Messungen an einem Raspberry B von Rainer R.
Dieser Vergleich zeigt, dass die älteren Modelle mit 13 ms bis 38 ms für je 2000 Portzugriffe deutlich langsamer sind.
Siehe auch: Benchmarking Raspberry Pi GPIO Speed
Messungen mit WiringPi
Das
Programm führt ebenfalls wieder 2000 Zugriffe aus. Ergebnis der Messung
mit dem Rasqberry Pi 2: wiringPi ist etwas langsamer. Es werden
zwischen 6 ms und 10 ms benötigt. tatsächlich kommt man ganz ohne
sudo-Aufruf aus. Allerdings ist die Installation und die Verwendung von
WiringPi deutlich komplizierter als RPI.GPIO.
Elektronik-Labor
Projekte
Mikrocontroller
Raspberry