Omgevingslicht lezen met een LDR
Het eerste wat je moet weten, is dat een LDR (Light Dependent Resistor, ook wel Photo resistor of lichtgevoelige weerstand) is in principe een weerstand die reageert op omgevingslicht. Naarmate er meer licht gezien wordt door de LDR neemt diens weerstand af. Naarmate er minder licht is, neemt de weerstand dus weer toe.
LDR’s bestaan al heel erg lang (als kind speelde ik al met LDR’s) en erg goedkoop. Daarnaast zijn ze zeer betrouwbaar en makkelijk te vinden.
Het aansluiten van een LDR zou normaal gesproken via een analoge pin van een Arduino gaan. Maar analoge pins lezen gaat soms te langzaam en dus bespreken we ook het aansluiten van de LDR op een digitale pin van de Arduino.
Meten van licht en een LDR
Let wel op dat een LDR licht waarneemt, en daar ook erg geschikt voor is, maar niet echt een goed middel is voor het nauwkeurig meten van licht.
LDR aan een Arduino Analoge Pin
Dit is de meest voor de hand liggende aanpak: omdat een LDR varieert in weerstand kan het dus een range van waarden opleveren.
In deze opstelling zal de gelezen waarde toenemen naarmate er meer licht is – er zijn ook schakelingen waarbij dit net andersom gaat.
We gebruik een kleine schakeling waarbij de weerstand afname van een LDR er voor zorgt dat er meer “stroom” naar de pin van de Arduino gaat. Hierdoor leest de Arduino een hogere waarde. “stroom” staat bewust tussen haakje omdat dit niet helemaal de juiste term hiervoor is.
De analoge pin zal een waarde tussen 0 en 1023 geven. De ingebouwde ADC (Analoog Digitaal Converter) van de Arduino doet dit helemaal voor je.
Wat we nodig hebben:
- Arduino (I gebruikte een Uno, let wel op dat clones recentelijk problematisch blijken te kunnen zijn)
- USB kabel om de Arduino op de computer aan te sluiten
- Arduino IDE (gratis download)
- een LDR (duh!)
- een 100KΩ weerstand (bruin-zwart-geel, of zie ook onze Weerstand Calculator)
- 3 draadjes
- een kleine breadboard
De opstelling is erg eenvoudig:
In woorden:
Verbindt de +5V van de Arduino aan 1 van de pinnen van de LDR (een LDR is niet aansluit gevoelig).
Verbindt de andere pin van de LDR met A0 (een analoge pin van de Arduino) en een van de pinnen van de 100KΩ weerstand.
Verbindt de andere pin van de 100KΩ weerstand met GND (aarde) van de Arduino.
Schema (gedaan met Fritzing):
LDR aan een Analoge Arduino pin
Breadboard tekening (ook gedaan met Fritzing):
LDR aan een Analoge Arduino pin
De Arduino Sketch is eenvoudig en stuurt gegevens uit naar de seriële poort zodat we kunnen zien wat er gebeurt.
1 2 3 4 5 6 7 8 9 10 11 12 13
| #define LDRpin A0 // pin where we connected the LDR and the resistor
int LDRValue = 0; // result of reading the analog pin
void setup() {
Serial.begin(9600); // sets serial port for communication
}
void loop() {
LDRValue = analogRead(LDRpin); // read the value from the LDR
Serial.println(LDRValue); // print the value to the serial port
delay(100); // wait a little
} |
Verbindt de Arduino nu via de USB kabel aan de computer.
Start nu de Arduino IDE en zorg ervoor dat je het juiste Arduino model en seriële poort hebt ingesteld.
Voor het Arduino model ga je naar “Tools” “Board” “Arduino Uno” (als je een Arduino Uno gebruikt), en voor de seriële poort ga je naar “Tools” “Port” “/dev/cu.usbmodem1411 (Arduino Uno)” (dit is op mijn Mac, op jouw Mac of PC kan dit iets anders zijn).
Kopieer bovenstaande sketch in de IDE editor, of door bestaande code te vervangen of door een nieuwe sketch te starten (“File” “New“). Klik daarna op de “Upload” knop, wat in onderstaande afbeelding de “B” knop is.
Arduino Software – Handige snelkoppelingen
Start daarna de serieel monitor via “Tools” “Serial Monitor” zodat we een output kunnen zien wat op dit lijkt:
...
949
945
943
917
838
837
832
796
748
709
706
704
692
689
698
...
In mijn situatie, zonder iets te doen, schommelt de waarde tussen 917 en 950, maar zodar ik mijn hand over de LDR ga beweging (reduceren van licht) zien we de waarde zelfs onder de 800 vallen.
Speel er een beetje mee, en bedenk dat de waarden voor jou anders zullen zijn omdat het afhankelijk is van jouw omgevingslicht.
LDR aan een Arduino Digitale Pin
Nu dat we een LDR aan een analoge pin in actie hebben gezien, tijd om eens te kijken wat het doet met een digitale pin.
Bedenk wel dat een digitale pin alleen maar een 1 of een 0 (nul) geeft als antwoord, in tegenstelling tot de analoge pin!
Deze waarden zijn bijvoorbeeld handig als je iets AAN of UIT wilt zetten, b.v. als het te donker wordt: lichten aanzetten.
Het lijkt erop dat de Arduino een drempel van 2.2 Volt heeft, waarbij het schakelt tussen nul en 1. Merk op dat het lezen van een digitale pin aanzienlijk sneller is dan het lezen van een analoge pin, wat in bepaalde gevallen zeer handig is.
Dus laten we eens gaan proberen wat het doet …
Voor deze toepassing gaan we een zogenaamde potentiometer gebruiken. We hebben dit nodig zodat we kunnen instellen wanneer het licht genoeg is om een 1 te genereren, of donker genoeg om een nul te genereren. We willen dit variabel hebben omdat de tafel waarop we alles in elkaar aan het zetten zijn, een andere licht omgeving kan hebben dan de plaats waar we onze schakeling uit eindelijk willen gebruiken. Net zoals de hoeveelheid licht in mijn huis anders zal zijn dan die bij jou thuis.
We gaan precies dezelfde componenten gebruik als bij de analoge opstelling, maar in plaats van een vaste weerstand gaan we dus een variabele weerstand (de potentiometer) gebruiken.
Een potentiometer heeft in principe 3 pinnen. De pin in het midden is de variabele pin, de de pinnen rechts en links zijn in principe de “vaste” weerstand. De variabele pin tapt in principe de weerstand af van de “vaste” weerstand tussen nul weerstand en de maximale weerstand van de “vaste” weerstand.
Misschien legt een tekening dit beter uit:
R is de “hele” resistor. Het heeft twee pinnen: R1 en R2.
Als je de weerstand gaat meten tussen deze twee pinnen met een multimeter (R1 en R2) dan meet je de maximale weerstand van weerstand R.
Het variabele deel (V) maakt zeg maar een “aftapping”, dus als je de weerstand gaat meten tussen R1 en V, dan meet je alleen dat deel van de weerstand R dat zich tussen R1 en V bevindt. Meet je weerstand tussen R2 en V, dan meet je alleen dat deel van R tussen R2 en V.
Dus als we de knop draaien, dan zal de weerstand tussen bijvoorbeeld R1 en V veranderen. Hoe groter de afstand tussen beide pinnen, hoe hoger de weerstand wordt. Simpel niet waar?
In onze opstelling hebben we maar 2 pinnen nodig, de middelste en een van de twee buitenste pinnen.
Hoe een potentiometer werkt …
We hebben dus nodig:
- Arduino (I gebruikte een Uno, let wel op dat clones recentelijk problematisch blijken te kunnen zijn)
- USB kabel om de Arduino op de computer aan te sluiten
- Arduino IDE (gratis download)
- een LDR (duh!)
- een 10KΩ potentiometer
- 3 draadjes
- een kleine breadboard
De opstelling is erg eenvoudig:
In woorden:
Verbindt de +5V van de Arduino aan 1 van de pinnen van de LDR (een LDR is niet aansluit gevoelig).
Verbindt de andere pin van de LDR met A0 (een analoge pin van de Arduino) en de middelste pin van de 10KΩ potetiometer.
Verbindt de een van de zij pinnen van de 10KΩ potentiometer met GND (aarde) van de Arduino.
Schema (gedaan met Fritzing):
LDR aan een Digitale Arduino pin
Breadboard tekening (ook gedaan met Fritzing):
LDR aan een Digitale Arduino pin
De sketch lijkt erg op de sketch van de alaloge opstelling, uiteraard hebben we het aangepast voor het lezen van een digitale pin, in dit geval pin 8.
1 2 3 4 5 6 7 8 9 10 11 12 13
| #define LDRpin 8 // pin where we connect LDR and resistor
int LDRValue = 0; // result of reading the analog pin
void setup() {
Serial.begin(9600); // sets serial port for communication
}
void loop() {
LDRValue = digitalRead(LDRpin);// read the value from the LDR
Serial.println(LDRValue); // print the value to the serial port
delay(100); // wait a little
} |
Verbindt de Arduino nu via de USB kabel aan de computer.
Start nu de Arduino IDE en zorg ervoor dat je het juiste Arduino model en seriële poort hebt ingesteld.
Voor het Arduino model ga je naar “Tools” “Board” “Arduino Uno” (als je een Arduino Uno gebruikt), en voor de seriële poort ga je naar “Tools” “Port” “/dev/cu.usbmodem1411 (Arduino Uno)” (dit is op mijn Mac, op jouw Mac of PC kan dit iets anders zijn).
Kopieer bovenstaande sketch in de IDE editor, of door bestaande code te vervangen of door een nieuwe sketch te starten (“File” “New“). Klik daarna weer op de “Upload” knop.
Start vervolgens de seriële monitor met “Tools” “Serial Monitor” zodat we de output kunnen zien:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 1
1
1
1
1
1
1
1
1
1
1
1
1
1 |
De output kan ook een zooi nullen zijn …
Draai nu langzaam de knop van de potentiometer tot je ziet dat de waardes in eens omslaan, dus de nullen worden enen of de enen worden nullen. Ga niet te snel zodat je de zogenaamde “sweet spot” kunt vinden waar het net omslaat van 0 naar 1 of vice versa.
Als je nu de “sweet spot” hebt gevonden, beweeg jouw hand over de LDR en zie de waarde veranderen. Mocht dat niet gebeuren dan moet je nog een beetje door spelen met de knop van de potentiometer tot dit wel gebeurt.
LDR een een Arduino Digitale Pin uitbreiden
We hebben nu met de digitale pin een AAN e UIT staat kunnen waarnemen, wat handig is als je maar 2 situaties hebt: AAN of UIT.
Met een tweede LDR kunnen we dit uitbreiden naar 3, dus b.v. HOOG, MEDIUM, LAAG (er vanuit gaande dat de analoge pin in jouw toepassing te langzaam is).
Wat we dan in principe doen, is de ene LDR instellen voor b.v. “medium” licht en de tweede voor “veel licht” waardoor we 3 niveaus kunnen waarnemen. Als je nu denkt: er moeten er toch 4 zijn, bedenk dan dat er een overlap is – bijvoorbeeld als er veel licht is, dan is er automatisch ook “medium” licht.
Met een potentiometer voor iedere LDR kunnen we voor elke LDR specifiek instellen bij hoeveel licht we AAN of UIT willen zien.
We gebruiken voor de tweede LDR pin 7 (in de Sketch) – je kunt gerust een andere pin gebruiken, maar vergeet dan net de sketch aan te passen.
Schema (gedaan met Fritzing):
2 LDR’s aan een Digitale Arduino pin
Breadboard tekening (gedaan met Fritzing):
2 LDR’s aan een Digitale Arduino pin
De betreffende Arduino sketch:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #define LDRpin1 7 // pin where we connect LDR and resistor
#define LDRpin2 8 // pin where we connect LDR and resistor
int LDRValue1 = 0; // result of reading the digital pin
int LDRValue2 = 0; // result of reading the digital pin
void setup() {
Serial.begin(9600); // sets serial port for communication
}
void loop() {
LDRValue1 = digitalRead(LDRpin1);// read the value from the LDR
LDRValue2 = digitalRead(LDRpin2);// read the value from the LDR
Serial.print(LDRValue1); // print the LDR1 value to the serial port
Serial.print(" "); // print a space
Serial.println(LDRValue2); // print the LDR2 value to the serial port
delay(100); // wait a little
} |
Afhankelijk van de potentiometer instellingen ga je nu eerste een hoop “0 0”, “1 0”, “0 1” of “1 1” voorbij zien komen.
Draai nu eerste beide potentiometers naar een uiterste.
Instellen van het “laag” niveau:
Zorg er eerst voor dat het omgevingslicht naar de stand gaat waar je het licht als “donker” ziet – dus gordijnen dicht en lampen uit?.
Draai nu beide potentiometers tot er niks anders als “0 0” verschijnt – dit wordt onze “donker” of “laag” stand die we zo gaan finetunen.
Instellen van de “medium” stand:
Pas nu jouw omgevingslicht aan naar wat jij ziet als “medium”.
Draai nu slechts 1 van de potentiometers, b.v. van LDR1, tot je “1 0” ziet verschijnen.
(voor LDR2 zou dit “0 1” zijn)
Instellen van het “hoog” niveau:
Zorg er nu voor dat het omgevingslicht lekker helder is, of wat jij als “hoog” wilt gaan gebruiken.
Draai nu de ANDERE potentiometer (LDR2) tot je net “1 1” ziet verschijnen.
Speel hier een beetje mee om er gevoel voor te krijgen.
Onderstaande code is een aangepaste versie zodat je wat duidelijker informatie gaat zien:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #define LDRpin1 7 // pin where we connect LDR and resistor
#define LDRpin2 8 // pin where we connect LDR and resistor
int LDRValue1 = 0; // result of reading the digital pin
int LDRValue2 = 0; // result of reading the digital pin
void setup() {
Serial.begin(9600); // sets serial port for communication
}
void loop() {
LDRValue1 = digitalRead(LDRpin1);// read the value from the LDR
LDRValue2 = digitalRead(LDRpin2);// read the value from the LDR
Serial.print(LDRValue1); // print the LDR1 value to the serial port
Serial.print(" "); // print a space
Serial.print(LDRValue2); // print the LDR2 value to the serial port
if((LDRValue1==1)&&(LDRValue2==1)) {
Serial.print(" -> HIGH"); }
else if ((LDRValue1==1)&&(LDRValue2==0)) {
Serial.print(" -> MEDIUM"); }
else if ((LDRValue1==0)&&(LDRValue2==0)) {
Serial.print(" -> LOW"); }
Serial.println(" lighting");
delay(100); // wait a little
} |
Een voorbeeld van de output terwijl ik in een donkere kamer langzaam een zaklamp naar de LDR beweeg:
1 2 3 4 5 6 7 8 9 10 11 12
| 0 0 -> LOW lighting
0 0 -> LOW lighting
0 0 -> LOW lighting
0 0 -> LOW lighting
0 0 -> LOW lighting
1 0 -> MEDIUM lighting
1 0 -> MEDIUM lighting
1 0 -> MEDIUM lighting
1 0 -> MEDIUM lighting
1 1 -> HIGH lighting
1 1 -> HIGH lighting
1 1 -> HIGH lighting |
Om zoiets nu in bijvoorbeeld het Boblight project te gebruiken (niet getest!) dan zou je zoiets als deze functie kunnen toevoegen.
Je ziet misschien dat ik de LDR waarden optel nadat ik de waarde van de tweede LDR met 10 heb vermenigvuldigd. Ik heb dat expres gedaan om je een ide te geven hoe je makkelijk de waardes kunt vergelijken. De waardes kunnen in dit geval 0, 1, 10 en 11 zijn. Maar zoals eerder vermeld is er een overlap dus eindigen we met de volgende mogelijk uitkomsten: { 0, 1, 11 }.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #define LDRpin1 7 // pin where we connect LDR and resistor
#define LDRpin2 8 // pin where we connect LDR and resistor
... // some other code of your project
void loop() {
... // your project loop
AdjustBrightness();
... // More optional project code
}
void AdjustBrightness() {
int LDRValue = 0; // result of reading the digital pin
LDRValue = digitalRead(LDRpin1);// read the value from the LDR
LDRValue = LDRValue + (digitalRead(LDRpin2)*10);// Add the value from the next LDR
if(LDRValue==0) {
// Dark, so set LED brightness for example to 50%
}
else if(LDRValue==10 {
// Medium, so set LED brightness for example to 70%
}
else if(LDRValue==11) {
// Bright light, set LED brightness for example to 100%
}
} |
Conclusie
Met een LDR kunnen we prima licht waarnemen, en ook al is het geen 100% nauwkeurige licht meting, het is toch een prima middel om bijvoorbeeld lichten aan te zetten of te reageren op licht verschillen.
LDR’s werken prima met een Analoge pin of een Digitale pin, elke met hun eigenschappen en toepassingen.
Een Analoge pin geeft waardes tussen 0 en 1023 maar is helaas wat aan de trage kant en kan dus in bepaalde situaties niet bruikbaar zijn (Boblight project bijvoorbeeld). Als snelheid dus niet zo’n probleem is: prima!
De aanpak met een Digitale Pin is veel sneller, en het toevoegen van een tweede LDR helpt met het maken van bijvoorbeeld 3 niveaus’s (er is een overlap waardoor de 4de combinatie niet voorkomt. Dit is dan weer bruikbaar voor situaties waar we meer kijken naar een AAN en UIT antwoord, of met de 2 (of meer) LDRs de AAN/UIT combinaties tot meerdere antwoorden kan leiden.
Reacties
Er is slechts èèn reacie geplaatst welke je hieronder kunt lezen.
Je kunt jouw eigen opmerkingen plaatsen m.b.v. dit formulier, of een reactie op een bestaande opmerking plaatsen door op de "Beantwoorden" knop te klikken.
waar zen die berekeningen!!!
robert