Raspberry GPIO Inputs  

Elektronik-Labor  Projekte  Mikrocontroller  Raspberry     




Ein GPIO kann sowohl als Ausgang als auch als Eingang dienen. Ein Eingang kann z.B. abfragen, ob eine Spannung am Pin liegt oder ob ein Schalter geschlossen ist. Das folgende Programm fragt den Zustand des Ports 10 zehnmal ab und schreibt das Ergebnis in die Python Shell.  Wenn man einen isolierten Draht an den Pin 27 steckt und nur die Isolierung berührt, kann man diese Zufälle bereits beobachten. Durch die Isolierung kann kein Strom fließen, aber der Finger bildet zusammen mit dem Draht im Inneren des Kabels einen kleinen Kondensator, sodass doch noch ein sehr kleiner Wechselstrom dafür sorgen kann, dass der Eingang sich mal auflädt und mal entlädt. Die nötige Wechselspannung gibt es überall in Gebäuden. Sie stammt von den Netzleitungen in den Wänden und aus den Netzkabeln und Verlängerungsleitungen zu den einzelnen Geräten.

Die Versuche mit offenen Eingängen haben gezeigt, dass kein reproduzierbares Ergebnis erwarten kann. Um einen eindeutigen Zustand zu erreichen setzt man einen Widerstand ein, der den Port meist mit VCC verbindet, also in diesem Fall mit +3,3V. Am Port liegt dann ebenfalls eine Spannung von 3,3 V, sodass 1-Zustände (high) gelesen werden. Ein Schalter kann nun gegen GND angeschlossen werden. Wenn er geschlossen ist, liegt keine Spannung am Eingang, und es werden Nullen (low) gelesen. Der Widerstand versucht den Eingangszustand hoch zu ziehen (engl. Pull up), was ihm aber nur bei geöffnetem Schalter gelingt. Man nennt ihn daher auch Pullup-Widerstand.

Genauso kann man natürlich auch einen Pulldown-Widerstand einsetzen, der den Port auf Null zieht. Der Schalter muss dann gegen +3,3 V angeschlossen werden. Damit kehrt sich die Funktion des Schalters um. Im Ruhezustand wird eine 0 gelesen. Nur wenn die Taste gedrückt wird, ändert sich der Zustand. Viele Mikrocontroller besitzen intern über Software zuschaltbare Pullup-Widerstände, sodass man den äußeren Widerstand einsparen kann. Der Raspberry hat wahlweise auch interne Pulldown-Widerstände, sodass man ganz flexibel bleibt. 







Nach einem Tipp von Frank Behlich vereinfacht: 
# Tk_GPIO27input.py Input GPIO 27
from Tkinter import *
import RPi.GPIO as GPIO #Bibliothek laden
GPIO.setmode(GPIO.BCM) #Broadcom-Modus
GPIO.setwarnings(False) #Warnungen abschalten
GPIO.setup(27, GPIO.IN) #Pin 27 Input

def anzeige(lb):
if GPIO.input(27):
lb.config(text="high")
else:
lb.config(text="low")
lb.after(100, anzeige, lb)

def pullup():
GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def pulldown():
GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
def high_z():
GPIO.setup(27, GPIO.IN)

root = Tk()
root.title("Input GPIO 27")
Label(root, text="------------------").pack()
lb = Label(root, text="high")
lb.pack()
Label(root, text="------------------").pack()
Button(root, text="Pullup", width=40,command=pullup).pack()
Button(root, text='Pulldown',width=40, command=pulldown).pack()
Button(root, text='High Z', width=40,command=high_z).pack()
anzeige(lb)
mainloop()



Ein Kapazitätsmesser

Mit einem Digitalmultimeter kann man bei eingeschaltetem Pullup den Strom nach GND messen (ca. 67 µA) und daraus den Wert des internen Pullup-Widerstands berechnen (50 k). Das gleiche gilt für den Pulldown, der ebenfalls 50 k hat, und zwar recht genau, sodass man ihn für besondere Anwendungen in der Messtechnik einsetzen kann. Und auch die Schaltschwelle lässt sich mit einem Poti und einem Voltmeter leicht feststellen, etwa 1,2 V mit einer Hysterese von ca. 50 mV.  

Weil nun der interne Pullup-Widerstand eines Raspberry-GPIO mit 50 kΩ recht genau bekannt ist, kann er als Referenz für eine Kapazitätsmessung verwendet werden. Die Schaltung enthält trotzdem noch einen Widerstand von 1 kΩ, der aber nur eine Schutzfunktion ausübt. Bei dieser Messung sind nämlich auch größere Kapazitäten bis über 100 µF erlaubt. In einem solchen Kondensator steckt so viel Energie, dass er den Port gefährden kann. Der Schutzwiderstand aber begrenzt den Entladestrom auf ungefährliche Werte.

Das Programm benötigt keine Begrenzung der Ladezeit, weil ohne ein Messobjekt extrem kurze Zeiten gemessen werden. Damit entfällt eine Zeitmessung innerhalb der Messschleife. Da eine While-Struktur ohne Inhalt aber formal nicht zulässig ist, wird der pass-Befehl eingesetzt. Dieser tut nichts, außer dass er ein Befehl ist. Mit dieser leeren while-Schleife erhält man eine gute Zeitauflösung.

#GPIO22RC3.py GPIO22, C-Messung, int. Pulldown
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

while (1):
GPIO.setup(22, GPIO.OUT)
GPIO.output(22, 1)
time.sleep(0.1)
GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
t0=time.time()
while GPIO.input(22) > 0:
pass
t1=time.time()
t= int ((t1-t0)*1000000)
print t, "us"
c= int ((t1-t0)*19900)
print c, "nF"
GPIO.setup(22, GPIO.OUT)
GPIO.output(22, 1)
time.sleep(1)

Das Ergebnis ist ein brauchbarer Kapazitätsmesser ab 1 nF, den man mit einem genauen Folienkondensator kalibrieren kann. Die Messung an dem keramischen 100-nF-Kondensator zeigt übrigens, dass er eine relativ große Abweichung vom Sollwert hat und darüber hinaus einen großen Temperaturkoeffizienten. So groß, dass man daraus sogar ein Thermometer bauen kann!




#Tk_GPIO22RCtemp.py 100nF Tk 0,7%/Grad 100 k
from Tkinter import *
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

def rc(lb):
GPIO.setup(22, GPIO.OUT)
GPIO.output(22, 1)
time.sleep(0.05)
GPIO.setup(22, GPIO.IN)
t0=time.time()
while GPIO.input(22) > 0:
t1=time.time()
if (t1-t0)>1:
break
t1=time.time()
t=(t1-t0)*1000000
t=int(t)
delta_c= 1-t/9000.0
temp = 23.0 + 70 * delta_c
lb.config(text="Temp = " + str(int(temp)) + " C")
lb.after(1000, rc, lb)

root = Tk()
root.font=('Helvetica', 30, 'normal')
root.title("Temp GPIO 22")
Label(root, text="---------------------", font = root.font).pack()
lb = Label(root)
lb.config(text=" ", font = root.font)
lb.pack()
Label(root, text="---------------------", font = root.font).pack()
rc(lb)
mainloop()


Elektronik-Labor  Projekte  Mikrocontroller  Raspberry