Pagina 1 van 1

Arduino – Spelen met licht gevoelige weerstanden (LDR)

Arduino – Spelen met licht gevoelige weerstanden (LDR)
   0

Na het bouwen van mijn eigen ambient TV verlichting (zie het Boblight Project) werd ik door een aantal lezers benaderd met de vraag of de LEDs gedimd konden worden, bijvoorbeeld ’s avonds iets minder helder, en overdag flink helder, zodat het licht effect een beetje vergelijkbaar blijft en zich dus aanpast aan het omgevingslicht.

Op basis van die vragen ben ik een gaan kijken naar het detecteren van licht met een Arduino, en in dit geval met name het gebruik van LDR’s – ik had er een paar rondslingeren dus vandaar. Een LDR (Light Dependent Resistor – Lichtgevoelige Weerstand) vermindert in weerstand naarmate licht toeneemt.

In alles wat ik zo’n beetje online kon vinden werd een analoge pin van de Arduino gebruikt – wat prima werkt, maar voor bepaalde omstandigheden te langzaam is. Het gebruik van een digital pin echter was nergens te vinden. De toepassingen zijn ook verschillend (analoog geeft een schaal van 0 tot 1023, terwijl digitaal alleen maar 1 of 0 geeft).

In dit artikel bespreek ik beide mogelijkheden.




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

LDR aan een Analoge Arduino pin

Breadboard tekening (ook gedaan met Fritzing):

LDR aan een Analoge Arduino pin

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

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 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 ...

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

LDR aan een Digitale Arduino pin

Breadboard tekening (ook gedaan met Fritzing):

LDR aan een Digitale Arduino pin

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

2 LDR’s aan een Digitale Arduino pin

Breadboard tekening (gedaan met Fritzing):

2 LDR's aan een Digitale Arduino pin

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.

Donatie Opties


Donaties worden zeer gewaardeerd, maar zijn zeker niet vereist. Donaties worden gebruikt voor het dekken van kosten voor web-hosting en project materialen, en eventueel voor een drankje of een snack. Voor wie al gedoneerd heeft: Hartelijk dank! Het is werkelijk geweldig om te zien dat men onze artikelen en applicaties waardeert.

Reacties


Er zijn nog geen reacties geplaatst.
Je kunt jouw eigen opmerkingen plaatsen m.b.v. dit formulier, of een reactie op een opmerking plaatsen door op de "Reageer" knop te klikken.



Jouw Reactie ...

Vriendelijk verzoek om hier geen lange teksten te plaatsen (zoals source codes, log files of config files). Gebruik daarvoor het Forum.

Deel met anderen:
*
*
Houd me op de hoogte van nieuwe reacties (email).
       Gebruik jouw RSS reader om reacties te volgen.


Tweaking4All uses the free Gravatar service for Avatar display.
Tweaking4All zal nooit jouw email adres met anderen delen.