Um z.B. eine Wetterstation zu betreiben ist es auch wichtig die Helligkeit zu kennen. Mit einem Raspberry Pi Helligkeitssensor (Fotowiderstand / Lichtsensor) ist es sehr einfach einen Wert zu ermitteln, womit man bspw. sagen kann ob es Tag, Dämmerung oder Nacht ist.
Damit ließen sich wiederum Projekte zum Steuern der (Außen-)Lichter realisieren, die ab einer gewissen Dunkelheit sich automatisch anschalten. In diesem Tutorial schließen wir einen solchen Helligkeitssensor an und lesen die Lichtwerte entsprechend aus, sodass wir darauf reagieren können.
Zubehör
Den verwendeten Fotowiderstand gibt es neben der eigentlichen Fassung auch auf einem PCB (Leiterplatte), worauf u.a. Widerstände aufgelötet sind. Dadurch kann zusätzlich ein digitales Signal ausgelesen werden, dass für „über/unter Schwellwert“ steht. Das Auslesen diesen digitalen Signals ist sehr einfach und wird in einigen anderen Tutorials behandelt (z.B. hier oder hier). Beide Versionen können mit diesem Tutorial genutzt werden, lediglich hat die eine Version eben noch eine zusätzliche Funktionalität. Für Projekte wie das Unterscheiden zwischen Hell/Dunkel ist es sicherlich eine einfache Alternative.
Folgende Bauteile sind für dieses Tutorial jedenfalls nötig:
- Raspberry Pi 3 o.ä.
- Fotowiderstand
- alertnativ Fotowiderstand als Modul
- MCP3008
- 10kΩ Widerstand
- Breadboard
- Jumper Kabel
Falls dich die Funktionsweise von Fotowiderständen (LDR) im Allgemeinen interessieren, kannst du hier mehr dazu lesen. Im Allgemeinen kann man sagen, dass sich der Widerstand je nach Helligkeit verändert.
Raspberry Pi Helligkeitssensor anschließen
Bevor wir den Fototransistor jedoch anschließen und auslesen können, müssen wir einen Analog-Digital-Wandler verbinden. Dazu findest du hier einen recht ausführlichen Artikel zum MCP3008, den wir auch in diesem Tutorial verwenden. Um diesen Artikel nicht unnötig aufzublähen gehe ich hier nicht näher auf den MCP3008 ein. Die genaue Verbindung zwischen ADC und Raspberry Pi findest du ebenfalls im Artikel.
Wichtig ist, dass der Helligkeitssensor auch eine Verbindung (über einen 10kΩ Widerstand) zum Masse Anschluss hat, da ansonsten der Wert nicht eindeutig auszulesen ist. Kommt durch den LDR überhaupt keine Spannung, so ist diese bei 0 (durch den Anschluss an GND).Falls Spannung fließt, geht ein Teil durch den 10kΩ Widerstand zurück, allerdings ist dieser Teil sehr gering, da der Widerstand groß ist. Wie bei anderen Widerständen auch spielt es keine Rolle auf welcher Seite die Positive Spannung am Fotowiderstand angelegt wird.
Schematisch sieht der Aufbau wie folgt aus:
Falls später selbst bei weniger Beleuchtung recht hohe Werte angezeigt werden, kannst du zwischen positiven Spannung und dem Pin des Lichtsensors noch einen zusätzlichen Widerstand setzen.
Solltest du einen aufgelöteten Photowiderstand nutzen, muss lediglich 3.3V (Pin 1) vom Raspberry Pi an VCC und GND kommt and GND (Pin 6) vom Pi. Der Pin A0 wird direkt an den Analog-Digital Wandler angeschlossen. Somit ist kein 10k Pullup Widerstand nötig. Der Vorteil besteht darin, dass du den Vorwiderstand per Potentiometer (Drehwiderstand) individuell einstellen kannst – je nach maximaler Helligkeit.
Helligkeitssensor am Raspberry Pi auslesen
In dem anderen Tutorial zum MCP3008 haben wir eine Klasse erstellt, welche wir auch hier nutzen werden. Stelle sicher, dass SpiDev wie beschrieben installiert ist. Zur Erinnerung findest du den Inhalt der Klasse hier noch einmal:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
from spidev import SpiDev class MCP3008: def __init__(self, bus = 0, device = 0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() self.spi.max_speed_hz = 1000000 # 1MHz def open(self): self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 1000000 # 1MHz def read(self, channel = 0): adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def close(self): self.spi.close() |
Sofern diese Klasse im aktuellen Verzeichnis besteht, kannst du einfach die Python Konsole per sudo python
öffnen (oder alternativ ein Skript erstellen) und folgendes eingeben:
1 2 3 |
from MCP3008 import MCP3008 adc = MCP3008() print( adc.read( channel = 0 ) ) # ggf. mehrfach ausfuehren |
Bei mir ergab komplette Dunkelheit (Finger darauf gehalten) einen Wert von ca. 600 was bedeutet, dass ca. 1.95V Spannung von den ursprünglichen 3.3V an den MCP3008 kamen. Bei Helligkeit hatte ich dauerhaft einen Wert von 1023.
Die maximalen Widerstandsgrößen unterscheiden sich ein wenig, je nachdem welcher Lichtwiderstand genommen wurde. Sofern die Helligkeit sehr hoch ist (Tageslicht) empfiehlt sich ein Vorwiderstand bzw. ein anderer Pull-Widerstand (bisher 10k).
42 Kommentare
Prima, da habe ich doch gleich mal 10 St. bestellt…
Prima, werde ich versuchen als Garagenlichtangelassenmelder zu nutzen. Das mit dem Temp.sensor funktioniert nicht optimal, weil das Kabel zu lang ist…
Apropos Kabellänge… kann es da zu Problemen kommen, wenn die Kabel vom Lichtsensor zu lang sind (ca. 8 m) oder kann man das mit einem kleineren Widerstand ausgleichen?
Gruß Ingo
Ist möglicherweise eine Dumme Frage,
aber wie lange dürfte die Verbindung vom rpi zum Helligkeitssensor sein. Und oder wäre dann eine Variante über Funk (v.a. welche Variante) bei etwas Entfernung sinnvoller ?
Und wie kann man (vielleicht was für eine weiteres Tutorial) mehrere Sensoren gleichzeitig/parallel abfragen?
Das kommt auf den Spannungsverlust an, welcher mit der Länge und Material des Kabels zusammenhängt.
Die Funkübertragung wäre eine Option, dafür eignet sich z.B. ein Arduino.
Mit dem MCP3008 kannst du bis zu 8 analoge Werte gleichzeitig auslesen.
LG, Felix
Es erschliesst sich mir nicht wie ich nun an irgendwelche Daten komme. Dazu muss es doch ein Befehl geben.
An analoge Daten? Oder von was für Daten sprichst du?
Ich habe das Problem, dass bei der letzten Zeile [print( adc.read( channel = 0 ) )], die Fehlermeldung:
//
Traceback (most recent call last):
print( adc.read( channel = 0 ) )
^
SyntaxError: invalid Syntax
//
erscheint. Hat da jemand eine Lösund? Bin mit meinem Latein am Ende.
LG, Marcel
Hallo Felix,
wie wäre die Verkabelung, wenn ich ein Modul nutze wie auf dem Bild oben?
Lesen hilft, habs gefunden danke =)
Erstmal vielen Dank für das super Tutorial, hat sehr weitergeholfen.
So wie ich den fritzing-Schaltplan interpretiere, ist die Schaltung recht simpel: Fotosensor ist in Reihe geschaltet zu einer Parallelschaltung aus MCP und 10k-Widerstand. Muss gleich dazu sagen, dass sich meine Elektrotechnikkenntnisse start in Grenzen halten.
Wenn ich nun einen zweiten Fotowiderstand auslesen möchte (über Ch.1 des MCP), kann ich den unteren Teil (AJ20-AJ23) einfach nochmal darunter „Copy-Pasten“? Natürlich mit dem Unterschied, dass das gelbe Kabel zu Ch.1 statt Ch.0 führt. Also im Endeffekt einen zweiten Fotowiderstand mit 10k-Widerstand und Verbindung zu Ch.1 parallel zu dem ursprünlichen Schaltplan.
Ist das möglich so? Müssen in dem Fall die 10k-Widerstände durch andere ersetzt werden? Und ist das Vorgehen skalierbar bis 8 Sensoren (bei diesem Schaltplan)?
Vielen Dank schonmal vorab! Grüße
Richtig, die Schaltung mit dem Widerstand nennt sih übrigens Pull-Up Widerstand und sorgt dafür, dass immer eine eindeutige Spannung anliegt.
Danke für die schnelle Antwort. Hat einwandfrei funktioniert.
Ich bekomme leider immer nur den Wert 0 zurück.
Nutze allerdings das ganze als Modul, also mit AD Wandler schon eingeschlossen.
Woran kann das liegen?
Hast du das Potentiometer schon gedreht / Widerstand verändert? Könnte sein, dass er zu hoch eingestellt ist.
Hey Felix,
Ich habe dein Projekt nachgebaut bekomme aber immer den Wert 0 heraus.
Kannst du mir sagen woran das liegt ?
Miss den analogen Wert mal mit einem Multimeter nach. Ich nehme an, dass einfach immer eine Spannung von 0V anliegt.
Danke mach ich 🙂
Menno,
jetzt hab ich dieses Problem schon wieder!!
also:
Das Steckbrett von mir sieht so aus
zwichen dem rotem kabel und dem fotowiderstand ist ein 100 ohm Widerstand geschaltet, denn ich weise mit einer weißen LED nach dem Fotowiderstand nach ob überhaupt eine Spannung anliegt. Der rest ist wie im Schema.
Zwichen Widerstand, Fotowiderstand und LED liegen 2,7 Volt an.
Zwischen Led und Channel 0 liegen 2,52 Volt an.
Software habe ich aus dem Forum kopiert.
Nein ich messe dort rund 3.3 volt
Also
Ich habe jetzt am gelben kabel zw. Fotowiderstand und Mcp3008 Spannung gemessen und da steht 0V kannst du mir den Grud sagen?
Sind auf der anderen Seite vom Fotowiderstand auch 0V? Falls nicht, ist das Licht unzureichend/der Widerstand zu groß.
Zwischen rotem und widerstand ?
Ja da sind 0Volt.
Zwischen dem schwarzen und dem richtigen widerstand Messe ich 2.8 V
Abe Danke noch mal
Ich glaube ich habe herausgefunden woran es liegt
An der +3v3 gpio meines Pi(1 ist das relevant ?) liegt keine spannung an.
Muss ich da etwas umschalten?
Dank im vorraus,
Peter
Der Pi hat mehrere 3.3V Pins (siehe Pinbelegung).
Pin 1
außerdem benutze ich einen Pi 1 model B
Hey Felix
Ich habe herausgefunden woran es liegt!
War ein Softwarefehler(hat eine Zeile gefehlt).
Danke für deine Hilfe, super Projekt!!
Hallo Felix,
Danke für die ganzen tollen Forum-Beiträge.
Ich habe mir für den Flur einen Smart-Bilderrahmen gebaut.
Ich würde nun gerne die Helligkeit des Bildschrimes, wenn viel Licht im Raum ist – Hoch, bei wenig Licht – Niedrig, vom Raspberry regulieren lassen. Ist das möglich? 🙂
Klar, dazu würden z.B. LED Strips passen 🙂
Können mit diesen Geräten auch die Lichtleistung gemessen werden? Würde eine drahtlose optische Nachrichtenübertragung damit möglich werden?
Ich würde sagen, dass das nur schwer möglich ist, da durch verschiedene Faktoren die Helligkeit beeinflusst wird. Simple Anwendungen wie Lichtschranken sind hingegen möglich.
Wie kann man das Programm anpassen, um etwas zu ein/auszuschalten, wenn die Helligkeit eine gewisse Zeit (1 Minute) über/unter einem gewissen Wert ist?
Bei mir klappt es nicht,
Fehlermeldung: Traceback (most recent call last)
line 3
print( adc.read( channel = 0 ) )
^
SyntaxError: invalid syntax
sorry print( adc.read( channel = 0 ) )
————–^
und ohne
kommt nur 0 raus
Mit der Bitte um Nachsicht für die Frage einer völlig orientierungslos herumirrenden Anfängerin…
Ich möchte unter Outdoor-Bedingungen (und entsprechend wechselhaften Lichtverhältnissen) „nur“ wissen, ob eine – ideal: mehrere – LED(s) leuchten oder nicht. Brauche ich da überhaupt Analog-Digital-Wandler oder kann ich direkt das digitale Signal auslesen? Ggfs. muß ich das Ganze irgendwie kalibrieren, was offenbar mit dem Potentiometer gehen soll… Oder hilft alles nichts und das wechselnde Tageslicht macht die Auswertung des analogen Signals notwendig? (Waaaah…!)
Bin ich überhaupt auf dem richtigen Weg oder gibt es dafür noch etwas Besseres für absolute DAUs?
Gern Hinweise auf Lektüre oder sinnvolle Suchbegriffe, die mir zum Verständnis verhelfen.
Leider bin ich aus dem Roboter- bzw. Ampel-Tutorial nicht klüger geworden in der Hinsicht.
Danke.
Hallo,
ich habe die Schaltung und den PI wie in der Anleitung eingerichtet. Frage ich nun mittels Python den Channel 0 ab, wo der Fotowiderstand ankommt, zeigt es mir 0 an. Auch bei mehren Abfragen in Folge (via Script). Lege ich nun eine Plastikkappe auf den Fotowiderstand erhalte ich beim Abfragen neben 0 Werte auch 248 als Wert bzw. Werte. Was stimmt da nicht? Am Eingang ADC kann ich entsprechend dem Lichtverhältnis die schlüssige Spannung messen. Hell mittlere Spannung dunkel keine Spannung.
Moin Felix,
Ich habe in der letzen Zeile immer einen Syntax Fehler:
print( adc.read( channel = 0 ) )
Ich Programmierre in Python 3.5.3 und du bzw. hat jemand einen Lösungsvorschlag?
Versuch es mal mit
print( adc.read( 0 ) )
Danke habe jetzt keine Syntax Fehler mehr bekomme aber nur die Werte 0 und 254 raus egal bei welcher Helligkeit. Liegt das am A/D Wandler ?
Versuch mal mit einem Drehpotentiometer den Widerstand zu verändern. Es könnte auch am AD Wandler liegen, aber das ist unwahrscheinlich (du kannst es mit anliegender Spannung und einem Widerstand testen).
Moin,
> Bei mir ergab komplette Dunkelheit […] einen Wert von ca. 600
Wenn ich mich nicht komplett täusche bedeutet dies, dass du eine sehr hohe Genauigkeit in der Dunkelheit hat, da Finger drauf ja schon recht Dunkel ist.
Wenn ich nun jedoch eine hohe Genauigkeit bei Licht benötige (Differenz direkte Sonneneinstrahlung, keine Sonneneinstrahlung/Bewölkt) muss ich doch den 10k-Wiederstand einfach nur entsprechend kleiner machen (z.B. 5k) oder?
Meine Theorie: Damit würde ein größerer Teil des Stroms wieder zurückgehen und der digitale Wert 1024 würde erst bei großer Helligkeit erreicht, was eine höhere Genauigkeit im hellen zur Folge hat.
Denke ich da richtig oder muss ich doch was anderes machen?
Danke
Hallo,
ich hatte schon so einen Photowiderstand als Modul – auf der Suche nach „wie am besten anschließen und auslesen“ bin ich auf dieses Tutorial gestoßen. Schön beschrieben – jedoch hat mein Modul keinen AO-Ausgang. Und die Bemerkung, man solle AO direkt mit dem DA-Wandler verbinden liess mich drüber nachgrübeln, was denn AO bitteschön überhaupt ist – meint der Felix damit vielleicht den ersten Analogeingang Ch. 0 vom Wandler? Oder ist einer der Pins der GPIOs vom Raspi alternativ so bezeichnet? OK – ich habs dann auch verstanden, als ich sah‘, dass manche dieser Module einen solchen Ausgang haben.
Man kann aber auch einfach auch den DO-Pin so eines Moduls nutzen, und diesen direkt mit einem freien GPIO-Pin des Raspis verbinden – dann spart man sich nicht nur den Vorwiderstand, sondern auch den Wandler und somit das komplette Breadboard – was ausreicht und enorm vereinfacht, wenn man nur die Info Hell oder Dunkel braucht.
Für meinen Zweck reichts – es soll die Stalltüren unseres Hühnerauslaufs steuern – bei Dunkelheit zu – und wenn es hell wird, wieder auf. Und um kein Hin- und Her in Dämmerungsphasen oder falls mal ’ne Taschenlampe leuchtet zu erzeugen, mach ichs einfach zeitversetzt, und guck‘ dann nochmal nach, ob (10, 20, 30 Minuten) später das Signal noch das gleiche ist.
Aber das Prinzip per Wandler hab ich verstanden – ist hier schön beschrieben – Dankeschön!