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