Alle Programme können von hier heruntergeladen werden. |
Fotodetektoren messen die Intensität der elektromagnetischen Strahlung. Wenn sie im Spektralbereich des sichtbaren Lichts (Wellenlänge zwischen 300 nm und 700 nm) empfindlich sind, werden sie auch Lichtsensoren genannt. Wenn sie im Infrarotbereich reagieren (Wellenlänge zwischen 700 nm und 1 mm), werden sie als Infrarot-Sensoren (IR-Sensoren) bezeichnet. Sie können damit auch die Wärmestrahlung von Gegenständen bei Raumtemperatur erkennen, die im Bereich von 8-35 um liegt. |
Lichtsensoren |
Die meisten Lichtsensoren bestehen aus einer Halbleiter-Fotodiode, wo der innere fotoelektrische Effekt zu einem beleuchtungsabhängigen Widerstand führt. Bei Beleuchtung werden durch die einfallenden Lichtteilchen (Photonen) zusätzliche Elektronen ausgelöst. Diese springen vom Valenzband ins Leitungsband und erhöhen so die Leitfähigkeit (bzw. senken den Widerstand R). Innerhalb eines bestimmten Bereichs der Leuchtkraft L kann die Abhängigkeit zwischen Widerstand R und Leuchtkraft L approximativ wie folgt ausgedrückt werden:
Dies führt in einer doppelt-logarithmischen Darstellung zu einer Gerade:
Fotozellen werden beispielsweise in Fotokameras verwendet, um die richtige Blende und Verschlusszeit zu bestimmen. Hier ist der analoge Messwert von Bedeutung. Bei einer Lichtschranke werden nur zwei Zustände betrachtet: hell oder dunkel. Der Übergangswert zwischen den beiden Zuständen wird auch Triggerpegel genannt, da die Zustandsänderung in der Regel eine Aktion auslöst (triggert). Ziel: Schaltschema: Programm:[►] # LightSensor1.py # Light barrier with LDR sensor import smbus import time TRIGGER_LEVEL = 300 # user selectable def readData(port = 0): if port == 0: adc_address = 0x48 elif port == 1: adc_address = 0x4D rd = bus.read_word_data(adc_address, 0) data = ((rd & 0xFF) << 8) | ((rd & 0xFF00) >> 8) data = data >> 2 return data print "starting..." bus = smbus.SMBus(1) state = "DARK" while True: v = readData(1) # adapt to your ADC (0 or 1) if v >= TRIGGER_LEVEL and state == "DARK": state = "BRIGHT" print "BRIGHT event" if v < TRIGGER_LEVEL and state == "BRIGHT": state = "DARK" print "DARK event" Bemerkungen: |
Hardwarebasierter Schwellendetektor (Schmitt-Trigger) |
Das Überqueren des Trigger-Pegels kann mit einer einfachen elektronischen Schaltung festgestellt werden, die man einen Schmitt-Trigger nennt. Der Ausgang entspricht den digitalen Werten LOW oder HIGH und kann ohne ADC-Konversion direkt an einen GPIO Port angeschlossen werden. Dadurch vereinfacht sich das Programm stark und es wird wesentlich weniger Rechenleistung gebraucht, insbesondere wenn für eine Roboter-Applikation mehrere IR- oder LDR-basierte Abstandssensoren benötigt werden. In einer klassischen Schaltung verwendet man einen Operationsverstärker (OpAmp) mit hohem Verstärkungsfaktor. Da die Ausgangspannung proportional zur Differenz der Eingangsspannung am nicht-invertierenden und invertierenden Eingang ist, aber durch die Versorgungspannung begrenzt wird, wechselt der Ausgang schnell, wenn die Eingangsspannungsdifferenz durch Null läuft. Wenn der OpAmp mit der Versorgungsspannung VCC betrieben wird (single supply opamp), wechselt der Ausgang zwischen LOW und HIGH. Mit einem Potentiometer wird der Triggerpegel eingestellt. Als Lichtquelle kann eine einfache weisse LED dienen.
|
Infrarotsensoren / Distanz (Nahdistanz) Sensoren |
Infrarotsensoren werden auch oft als Lichtschranken verwendet, wobei die Infrarotquelle für das menschliche Auge nicht sichtbares Licht emittiert. Gegenüber Vorrichtungen, bei welchen der Lichtstrahl sichtbar ist, ist dies manchmal vorteilhaft. Infrarotsensoren werden auch oft in Kombination mit einem Detektor verwendet, der die Intensität des reflektierten Lichts misst. Da viele Materialien Infrarotwellen reflektieren, kann damit die Distanz zum Objekt bestimmt werden. Für kurze Distanzen (1 - 100 cm) verwendet man als Lichtquelle meist eine Fotodiode (IR-LED), die ein IR-Licht um 1000 nm erzeugt. Eine Fotodiode oder ein Fototransistor empfängt das reflektierte Licht und gibt eine von der Distanz abhängige Spannung ab.
Schaltschema:
Da die Input-Output-Beziehung nicht linear ist, ist die Transformation der Spannung auf eine Distanz ein algorithmisches Problem.
In diesem Beispiel schreiben wir statt der Distanz lediglich die Ausgangsspannung des Sensors aus. In vielen Anwendungen von Distanzsensoren spielt der absolute Wert der Entfernung keine Rolle, da der Sensor dazu verwendet wird, eine Aktion auszulösen, wenn der Abstand einen bestimmten Wert überquert (von nah nach fern oder umgekehrt). In diesem Beispiel wird ein Licht oder Summer eingeschaltet, wenn der Abstand zu klein wird (analoges Beispiel, um einen fahrenden Roboter in der Nähe eines Hindernis zu stoppen). Programm:[►] # Infrared1.py # using the PCF8591 ADC import smbus import time import RPi.GPIO as GPIO P_LED = 22 TRIGGER_LEVEL = 25 DT = 0.2 def setup(): GPIO.setmode(GPIO.BOARD) GPIO.setup(P_LED, GPIO.OUT) def beep(n): for i in range(n): GPIO.output(P_LED, GPIO.HIGH) time.sleep(0.05) GPIO.output(P_LED, GPIO.LOW) time.sleep(0.05) bus = smbus.SMBus(1) # RPi revision 2 (0 for revision 1) i2c_address = 0x48 setup() beep(3) # to say we are ready while True: data = bus.read_byte_data(i2c_address, 0) # read ch0 if data > TRIGGER_LEVEL: beep(2) time.sleep(DT)
Wie aus dem Datenblatt zu entnehmen ist, steht die Ausgangsspannung u leider nicht in einer einfachen Beziehung zur Distanz d. Aber u = f(1/d) kann mit einer Gerade u = mx + b mit m = 19.8 und b = 0.228 im Bereich d = 7 bis d = 80 cm gut approximiert werden. Das Programm zeigt die Distanz in der Konsole und (falls vorhanden) auf einem angeschlossenen Display. Programm:[►] # Infrared2.py # GP2Y0A21YK sensor with PCF8591 ADC import smbus import time from py7seg import Py7Seg # xxx bus = smbus.SMBus(1) # RPi revision 2 (0 for revision 1) i2c_address = 0x48 ps = Py7Seg() # xxx # u = mx + b, x = 1/d m = 19.8 b = 0.228 while True: data = bus.read_byte_data(i2c_address, 0) # use CH0 u = data / 255 * 5 d = int(m / (u - b)) print "d =" ,d, "cm" ps.showText("%4d" %d) # xxx time.sleep(0.1) Bemerkungen: |