Lichtsensoren (LDR) und Arduino
Heute mal wieder eine nützliche kleine Spielerei die sich in beliebigem Maße erweitern/abändern lässt.
Wir benutzen heute einen Lichtabhängigen Widerstand und einige LEDs die als Bar-Graph herhalten müssen.
Zunächst einmal der Aufbau auf dem Breadboard.
Die 10 Roten LEDs werten alle mit einem Vorwiderstand von 330Ω auf dem Breadboard aufgesteckt und an die gemeinsame Masse angeschlossen. Wichtigster Teil ist hier der Spannungsteiler aus einem 10KΩ Widerstand und dem LDR. Dieser wird an der 5V und Masse des Arduinos angeschlossen.
Der Analogeingang wird dabei zwischen beiden Widerständen angeschlossen.
Dieser Misst nun die Spannung die am 10kΩ Widerstand abfällt, in Abhängigkeit der Lichteinstrahlung des LDRs.
Wobei eine hohe Lichteinstrahlung auf dem LDR diesen niederohmiger werden lassen, sprich der Widerstand wird kleiner. Wird es dunkel, wird der LDR hochohmiger. Sprich der Widerstand wird größer. Viel Licht entspricht mehr Spannung am Analogeingang. Wenig Licht entspricht wenig Spannung am Analogeingang.
Der Analogeingang des Arduino Uno hat eine Auflösung von 10Bit, was 1024 Einheiten entspricht. Bei einer maximalen Eingangsspannung von 5V entspricht das 5/1023 = 0.0049 Volt. Also (4.9 mV) pro Einheit.
Da wir nur 10 LEDs statt 1024 zur Verfügung haben, müssen wir die Spannung die wir parallel zum 10kΩ Widerstand an unserem Analogeingang messen, entsprechend zuordnen.
Dies machen wir mit dem „map“-Befehl.
Wir nehmen also den Bereich von 0 bis 1023 und „quetschen“ diesen in den Bereich von 0 bis 9.
Dies ist selbstverständlich relativ ungenau, andererseits reicht es für den ersten Versuch.
Unter Weiterlesen gibt’s noch den passenden Code und eine Materialliste.
int analogPin = 0;
int analogWert = 0;
void setup()
{
for(int i=0;i < 10; i++)
{
pinMode(pin[i],OUTPUT);
} // Alle Pins auf OUTPUT setzen.
}
void loop()
{
// Spannung am Analogeingang lesen
analogWert = analogRead(analogPin);
// Wert an die Funktion Übergeben
bar_leds(analogWert);
}
void bar_leds(int wert)
{
// Funktion zum Ansteuern der LEDs
// Den Analogwert auf unsere 10 LEDs Mappen
int bargraphWert = map(wert,0,1023,0,9);
for(int i=0; i < 10; i++) { // Die Pins entsprechnd dem Analogwert schalten
digitalWrite(pin[i], (bargraphWert >= i)?HIGH:LOW);
}
}
Materialliste:
- 10x rote LED
- 10x Widerstand 330Ω
- 1x Widerstand 10KΩ
- 1x LDR
- 1x Flexible Drahtbrücken
- 1x Arduino Uno
Viel Spaß beim Basteln.
Kleiner Fehler im Code. Drittletzte Zeile steht im Kommentar steht noch Programmcode. Da wurde wohl einmal umschalten verschluckt.
Ansonsten nette Idee die ich mal nachbasteln werde.
Danke für den Hinweis!
Habe den Schönheitsfehler beseitigt
Warum hast du einen Widerstand von 10kOhm genommen?
Wie sollte man am besten den Widerstand für den Spannungsteiler auswählen?
Hallo,
Den 10kOhm Widerstand habe ich genommen damit das Verhältnis im Spannungsteiler einigermaßen übereinstimmt. Der LDR hat im Dunklen einen Widerstand von >1-100MOhm und bei Lichteinfall ca. 0,1-2kOhm.
Der Analogeingang braucht also einmal möglichst wenig Spannung (Dunkel / Spannung fällt am LDR ab). Und im anderen Fall “Helligkeit” möglichst viel bzw. die gesamte Spannung am Analogeingang (Spannung fällt am Widerstand ab).
Nehmen wir z.B. nur einen 100Ohm Widerstand würde der Spannungsteiler womöglich nicht funktionieren, da am LDR immer die gesamte Spannung abfallen würde weil er, ob bestrahlt oder auch nicht, immer größer sein würde als der einzelne Widerstand im Spannungsteiler.
Hier vll. noch ein bisschen was zum nachlesen und eine Formel die das verdeutlicht.
der Code mit den 10 leds ,oben,
…fehler in : for(int i=0; i < 10; i++) …?
Jean
Ja da ist der HTML-Code ein wenig durcheinander gekommen
for(int i=0; i & l t ; 10; i++) solle da eigendlich
for(int i=0; < 10; i++) heißen… hoffe der Code stimmt jetzt wieder.
André
Bei niedrigstem Lichtlevel leuchtet doch trotzdem eine LED!? Wenn ja, wie kann man den Sketch dann umprogrammieren, dass keine LED mehr leuchtet, wenn es total dunkel ist?
Philipp
Hallo,
versuche mal mit dem map() Befehl etwas zu Spielen.
int bargraphWert = map(wert,0,1023,0,9);
ändern zu
int bargraphWert = map(wert,256,768,0,9);
So dass nur ein bestimmter Bereich des Sensors erfasst wird.
André
Hallo,
habs jetzt so:
” int bargraphwert = map(wert, 150, 1000, 0, 9); ” und funktioniert… Aber warum gibt der map() – Befehl -1 aus, wenn es ganz dunkel ist? Das macht er, wenn der Analogeingang weniger als 150 liest??
Philipp
Ja stimmt da war noch was
Da sollte der Befehl “constrain() helfen, wenn man ihn direkt dahinter setzt.
http://arduino.cc/de/Reference/Constrain
also den Wert noch mal eingrenzen:
bargraphwert = constrain(bargraphwert,0,9);
bargraphwert kann so nur noch minimal 0 und maximal 9 ausgeben.
Aber dann ist ja das “Problem”, das immer eine LED leuchtet, wieder da… So ist es gar nicht schlecht, aber war halt über die -1 überrascht…
Philipp