LED, PWM und LDR.....versteh ich nicht...

Hallo zusammen,

habe gestern mal wieder vergeblich versucht was zum laufen zu bekommen :~. Was möchte ich haben:

Ich lese einen LDR von 0 - 1023 ein und möchte das wenn der Wert des LDR´s >600 wird, er die LED auf einen bestimmten Wert faded. In diesem Fall wäre es eine PWM von 200. Wenn LDR <600 soll die PWM 20 sein.

Ich habe es hinbekommen das er die LED mit den beiden Werten (PWM 20 und 200) hin und her schaltet und auch so bleibt… Siehe Code:

int ledPin = 9;      // LED connected to digital pin 9
int analogPin = 0;   // LDR connected to analog pin 0
int val = 0;         // variable to store the read value


void setup(void)
{
  pinMode(ledPin, OUTPUT);   // sets the pin as output
}


void Backlight()
{
  val = analogRead(analogPin);   // read the input pin 0 - 1023
  {
    if (val >600) {
      analogWrite(ledPin, 200);  // analogWrite value 200
    } 
    else {
      analogWrite(ledPin, 20);  // analogWrite value 20
    }
  }
}


void loop(void)
{ 
  Backlight();
}

Dieser Code funktioniert relativ gut und auch so wie ich es haben möchte, jedoch bekomme ich es nicht hin die LED auf die Werte (20 / 200) langsam rauf und runter zu faden. Hier mein code der nicht funktioniert:

int ledPin = 9;      // LED connected to digital pin 9
int analogPin = 0;   // LDR connected to analog pin 0
int val = 0;         // variable to store the read value


void setup(void)
{
  pinMode(ledPin, OUTPUT);   // sets the pin as output
}


void Backlight()
{
  val = analogRead(analogPin);   // read the input pin 0 - 1023
  
  {
    if (val >600) {
      // fade in from min to max in increments of 5 points:
      for(int fadeValue = 255 ; fadeValue >= 20; fadeValue -=5) { 
        // sets the value (range from 0 to 255):
        analogWrite(ledPin, fadeValue);         
        // wait for 30 milliseconds to see the dimming effect    
        delay(30);  
      } 
    }
    else {
      // fade in from min to max in increments of 5 points:
      for(int fadeValue = 20 ; fadeValue <= 255; fadeValue +=5) { 
        // sets the value (range from 0 to 255):
        analogWrite(ledPin, fadeValue);         
        // wait for 30 milliseconds to see the dimming effect    
        delay(30);  
      }
    }
  }
}


void loop(void)
{ 
  Backlight();
}

Es funktioniert zwar das er den Wert runter Dimmt, jedoch fängt er immer wieder von vorne an. Also quasi in einer Schleife und behält den Wert aber nicht. Wahrscheinlich liegt es an dem “int fadeValue =” der den schon gesetzten Wert überschreibt.

Ich möchte ja lediglich das wenn es Dunkel wird, die LED auch Dunkler wird (PWM = 20) und wenns wieder Hell wird soll auch die LED wieder Hell werden (PWM = 200) und das ganze soll halt per Fading passieren. Die LED soll auch nur zwischen den beiden Werte faden.

Hoffe es ist ausführlich beschrieben und jemand kann mir helfen.

Liebe Grüße Thomas

Du hast da vielzuviele { und }.

Probiers mal so:

int ledPin = 9;      // LED connected to digital pin 9
int analogPin = 0;   // LDR connected to analog pin 0
int val = 0;         // variable to store the read value


void setup(void)
{
  pinMode(ledPin, OUTPUT);   // sets the pin as output
}


void Backlight()
{
  val = analogRead(analogPin);   // read the input pin 0 - 1023
  
  
    if (val >600) {
      // fade in from min to max in increments of 5 points:
      for(int fadeValue = 255 ; fadeValue >= 20; fadeValue -=5) { 
        // sets the value (range from 0 to 255):
        analogWrite(ledPin, fadeValue);         
        // wait for 30 milliseconds to see the dimming effect    
        delay(30);  
      } 
      else {
      // fade in from min to max in increments of 5 points:
      for(int fadeValue = 20 ; fadeValue <= 255; fadeValue +=5) { 
        // sets the value (range from 0 to 255):
        analogWrite(ledPin, fadeValue);         
        // wait for 30 milliseconds to see the dimming effect    
        delay(30);  
      }
    
  
}


void loop(void)
{ 
  Backlight();
}

Gruß,
Tobias

Hi Tobias,

danke für die bereinigung der }. Leider ist es immer noch so das er wieder von vorne anfängt zu dimmen, obwohl der LDR abgedeckt ist....

Probier mal bitte diesen code, und werf nen Blick in den Serial Monitor @ 9600 Baud

int ledPin = 9;      // LED connected to digital pin 9
int analogPin = 0;   // LDR connected to analog pin 0
int val = 0;         // variable to store the read value


void setup(void)
{
  pinMode(ledPin, OUTPUT);   // sets the pin as output
  Serial.begin(9600);
}


void Backlight()
{
  val = analogRead(analogPin);   // read the input pin 0 - 1023
    if (val >600) {
			Serial.println("Licht an!");
		  for(int fadeValue = 255 ; fadeValue >= 20; fadeValue -=5) { 
			// sets the value (range from 0 to 255):
			analogWrite(ledPin, fadeValue);         
			// wait for 30 milliseconds to see the dimming effect    
			delay(30);  
		  } 
	  }
      else 
	  {
			Serial.println("Licht aus!");
			// fade in from min to max in increments of 5 points:
		  for(int fadeValue = 20 ; fadeValue <= 255; fadeValue +=5) { 
			// sets the value (range from 0 to 255):
			analogWrite(ledPin, fadeValue);         
			// wait for 30 milliseconds to see the dimming effect    
			delay(30);  
		  }
	  }
}


void loop(void)
{ 
  Backlight();
}

Das Problem ist, dass du bei jedem Loop Durchgang eine deiner for Schleifen durchläufst und dadurch den fadein/fadeout Prozess startest. Die Leuchtstärke der LED sollte sich aber nur einmal nach dem Wechsel des Werts des LDR von über 600 zu unter 600 bzw umgekehrt ändern.

Du kannst dies mit zwei Status Variablen (Flag) lösen, in denen du speicherst, ob der fadein/fadeout schon durchgeführt wurde.

boolean fadeInSchonDurchgefuehrt = false
boolean fadeOutSchonDurchgefuehrt = false


void Backlight()
{
  Analog Pin einlesen
  
  if (val >600) {
    if (fadeInSchonDurchgefuehrt == false) {
      fadein der LED durchführen
      fadeInSchonDurchgefuehrt = true
      fadeOutSchonDurchgefuehrt = false
    }
  } else {
    if (fadeOutSchonDurchgefuehrt == false) {
      fadeout der LED durchführen
      fadeOutSchonDurchgefuehrt = true
      fadeInSchonDurchgefuehrt = false
    }  
  }  
}

Du hast dein Problem schon richtig erkannt!
Jedes mal wenn der die IF durchläuft stellt er fest das der Lichtwert zb unter 600 ist und er wird dann jedesmal die Led auf 255 schalten und runter dimmen.

Du mußt deinen Wert FadeValue global deklarieren.
Also schon vor der Setup zb int FadeValue=255
Und dann in den schleifen nicht die Startwerte vorgeben.
For (fadevalue; fadevalue <= 20 …
So wird er als startwert immer den nehmen mit dem du als letztes geendet bist.

Was noch vielleicht wichtig währe ist eine Hysterese ein zu bauen.
Also beide zweige der Helligkeit mit Ifs machen.
Und erst hell zu dimmen wenn der wert zb unter 550 ist und erst dunkel zu dimmen wenn der wert über 650 ist.
Weil sonst kann es dir passieren das er im Grenzbereich die ganze zeit hoch und runter dimmt.
Auch wichtig ist dafür zu sorgen das sich led und sensor nicht gegenseitig beeinflussen.

Edit:
Die variante von thewknd geht natürlich auch.
wenn du die anfangswerte der schleife aber nicht vor gibst ist das garnicht nötig.
Er würde zar immer faden wollen zählt aber nur von 255 bis 255 hoch oder eben von 20 bis 20 runter.

Der Code wenn er Werte über bzw unter 600 liest jedesmal ein Fade aus. Du mußt bei einem erfolgten Fade dies in einer Variablen zwischenspeichern. und keinen Änderung an der LED-intensität vornehmen.
Des weiteren habe ich eine kleine Hysterese eingebaut (den richtigen Wert mußt Du noch experimentel ermitteln) damit wenn der LDR genau bei 600 ist nicht durch keine Schwandkungen in der A-D Konversion das Licht dauerns an -bzw aus geht.

void Backlight()
{
  val = analogRead(analogPin);   // read the input pin 0 - 1023
    if (val >600 && LEDon =0)
 	{
	Serial.println("Licht an!");
        for(int fadeValue = 255 ; fadeValue >= 20; fadeValue -=5)
		{ 
		analogWrite(ledPin, fadeValue);         
		delay(30);  
		 } 
          LEDon=1;
	  }
 if (val <=550 && LEDon =1) {
	  {
	  Serial.println("Licht aus!");
	  for(int fadeValue = 20 ; fadeValue <= 255; fadeValue +=5)
		{ 
		analogWrite(ledPin, fadeValue);         
		delay(30);  
		}
	   LEDon=0;
	  }
}

Hmm alle wollen eine zusätzliche Variable nehmen.
Ist meine variante mit der globalen helligkeitsvariable nicht so gut?
Wenn Ja, warum?

MueThoS:
Die variante von thewknd geht natürlich auch.
wenn du die anfangswerte der schleife aber nicht vor gibst ist das garnicht nötig.
Er würde zar immer faden wollen zählt aber nur von 255 bis 255 hoch oder eben von 20 bis 20 runter.

Und sparst damit etwas Speicherplatz.

Der Code ist für mich mit einer zusätzlichen Variable einfacher zu lesen.

ht81: In deinem Code wird die LED bei über 600 gedimmt und bei unter 600 die Leuchtstärke der LED erhöht

MueThoS:
Hmm alle wollen eine zusätzliche Variable nehmen.
Ist meine variante mit der globalen helligkeitsvariable nicht so gut?
Wenn Ja, warum?

Hatte bei der Erstellung meiner Antwort Deine Antwort nicht gesehen.
Wo hast Du das geschrieben?

Du dachtest bei der If-Anweisung an:

 if (val >600 && fadeValue = 20)

Das funktioniert solange mit delay in der Fade-Schleife gearbeitet wird.
Wenn Du es auf millis() umschreibst damit der Kode nicht in der Fade-Schleife festhängt fonktioniert Deine Version nicht mehr.

Ich würde bei der Messung der Helligkeit einen Mittelwert über die letzten 2 bis 5 Minuten bilden damit zB ein Scheinwerfer eines vorbeifahrenden Autos oder ähnliches nicht sofort das Licht aussschalten. Die wirkliche Notwendigkeit diese Maßnahme kann ich aber nicht abschätzen da ich die Installation bzw Situation nicht kenne.

Viele grüße Uwe

Hallo zusammen,

erstmal herzlichen Dank für die tollen Antworten. Das mit dem zwischenspeichern macht sinn...so im nach hinein betrachtet... :blush:

Ich werde später die Codes mal ausprobieren. Das mit der Hysterese macht ebenfalls sinn, daran habe ich auch nicht gedacht. Im Endeffekt soll später ein Display anstelle der LED kommen um das Backlight Abends zu dimmen. Ich baue wohl den 1 Mio.sten Datenlogger inkl. Ethernet.

Ich versuche heute Abend den Code einzuflegen und werde wieder Berichten. Danke

uwefed:

MueThoS:
Hmm alle wollen eine zusätzliche Variable nehmen.
Ist meine variante mit der globalen helligkeitsvariable nicht so gut?
Wenn Ja, warum?

Hatte bei der Erstellung meiner Antwort Deine Antwort nicht gesehen.
Wo hast Du das geschrieben?

Du dachtest bei der If-Anweisung an:

 if (val >600 && fadeValue = 20)

Das funktioniert solange mit delay in der Fade-Schleife gearbeitet wird.
Wenn Du es auf millis() umschreibst damit der Kode nicht in der Fade-Schleife festhängt fonktioniert Deine Version nicht mehr.

Ich würde bei der Messung der Helligkeit einen Mittelwert über die letzten 2 bis 5 Minuten bilden damit zB ein Scheinwerfer eines vorbeifahrenden Autos oder ähnliches nicht sofort das Licht aussschalten. Die wirkliche Notwendigkeit diese Maßnahme kann ich aber nicht abschätzen da ich die Installation bzw Situation nicht kenne.

Viele grüße Uwe

Nein, nicht bei der IF sondern in der FOR:
anstatt:

for(int fadeValue = 255 ; fadeValue >= 20; fadeValue -=5)

dies:

for( fadeValue ; fadeValue >= 20; fadeValue -=5)

und das fadeValue global mit int deklarieren.

Wenn die LED zuletzt hoch gedimmt wurde also auf 255 steht wird sie beim nächsten durchlauf zwar auch hoch gedimmt aber
von 255 (alter wert) auf 255 was faktisch ja keine Änderung ist.
Steigt der Lichtwert würde die andere IF in kraft treten und es würde mit dem alten Wert also 255 runter gedimmt werden.
oder geht das nicht?

Also ich habe bisher nur 1 ausprobiert. Der Code von MueThos (for( fadeValue ; fadeValue >= 20; fadeValue -=5)) funktioniert zwar, jedoch wird beim Starten des Controllers (Nach Hardreset) 2 mal hochgedimmt und dann funktioniert der Code. Was genau passiert da das dieses Phänomen auftritt? Wie kann man es debuggen?

@ Uwe: Dein Code wollte ich probieren. Jedoch bekomme ich einen Compiler Fehler wegen LEDon da dieses nicht deklaiert ist. Ich weiß aber nicht wo und wie ich dies machen soll? Habe es mit Int und Float probiert hat aber nix gebracht....

Poste mal deinen Code.
Bitte mit Tags versehen: oben gibt's einen Button mit # drauf.

Variable Deklarieren musst du auch bei meiner Variante!
Ansonsten kannst du ganz oben
boolean LEDon;
für Uwes Lösung.
Bei meiner solltest du oben schreiben
int fadeValue = 255; wenn du mit LED an starten willst ansonsten int fadeValue = 20;

Aber wie gesagt zeig mal deinen code

Hallo MueThoS,

habe den Code nochmals durch den Compiler gejagt, jetzt scheint es zu gehen. Aber Trotzdem hier mal mein Code inkl. Hysterese:

int ledPin = 9;      // LED connected to digital pin 9
int analogPin = 0;   // potentiometer connected to analog pin 3
int val = 0;         // variable to store the read value
int fadeValue = 200;



void setup(void)
{
  pinMode(ledPin, OUTPUT);   // sets the pin as output
}


void Backlight()
{
  val = analogRead(analogPin);   // read the input pin

  {
    if (val >600) {
      // fade in from min to max in increments of 5 points:
      for(fadeValue ; fadeValue >= 20; fadeValue -=5) { 
        // sets the value (range from 0 to 255):
        analogWrite(ledPin, fadeValue);         
        // wait for 30 milliseconds to see the dimming effect    
        delay(30);  
      } 
    }
    if (val <500) {
      // fade in from min to max in increments of 5 points:
      for(fadeValue ; fadeValue <= 200; fadeValue +=5) { 
        // sets the value (range from 0 to 255):
        analogWrite(ledPin, fadeValue);         
        // wait for 30 milliseconds to see the dimming effect    
        delay(30);  
      }
    }
  }
}


void loop(void)
{ 
  Backlight();
}

ht81:
Hallo MueThoS,

habe den Code nochmals durch den Compiler gejagt, jetzt scheint es zu gehen. Aber Trotzdem hier mal mein Code inkl. Hysterese:

int ledPin = 9;      // LED connected to digital pin 9

int analogPin = 0;   // potentiometer connected to analog pin 3
int val = 0;         // variable to store the read value
int fadeValue = 200;

void setup(void)
{
  pinMode(ledPin, OUTPUT);   // sets the pin as output
}

void Backlight()
{
  val = analogRead(analogPin);   // read the input pin

{    <---------------------------------------- nicht nötig
    if (val >600) {
      // fade in from min to max in increments of 5 points:
      for(fadeValue ; fadeValue >= 20; fadeValue -=5) {
        // sets the value (range from 0 to 255):
        analogWrite(ledPin, fadeValue);         
        // wait for 30 milliseconds to see the dimming effect   
        delay(30); 
      }
    }
    if (val <500) {
      // fade in from min to max in increments of 5 points:
      for(fadeValue ; fadeValue <= 200; fadeValue +=5) {
        // sets the value (range from 0 to 255):
        analogWrite(ledPin, fadeValue);         
        // wait for 30 milliseconds to see the dimming effect   
        delay(30); 
      }
    }
  }  <------------------------------------- dann auch nicht nötig
}

void loop(void)
{
  Backlight();
}

Zwei Klammern sind unnötig.

Hallo MueThoS,

danke habe ich korregiert. Code scheint jetzt zu funktionieren.

Danke nochmals an alle.

ht81:
@ Uwe: Dein Code wollte ich probieren. Jedoch bekomme ich einen Compiler Fehler wegen LEDon da dieses nicht deklaiert ist. Ich weiß aber nicht wo und wie ich dies machen soll? Habe es mit Int und Float probiert hat aber nix gebracht....

Lieber ht81

Etwas Einsatz braucht es schon von Deiner Seite. Mein Codeschnipsel ist ein Beispiel damit Du die Logik verstehst, nicht ein vorgekauter Sketch.
Jede Variable muß deklariert werden. Entweder am Anfang außerhalb jeder Funktion oder innerhalb der Funktion wenn sie nur innerhalb dieser Funktion gelten soll.

Einfach am Anfang zwischen die int
int LEDon = 0;
einfügen.

Arbeite auch einige Tutorials durch damit Du wenigstens die Basis von C erlernst.

Grüße Uwe

Hallo Uwe,

danke nochmals für dein Feedback. Ja ich habe Einsatz gezeigt (wie bereits schon geschrieben) und habe es ja auch mit Int und Float versucht. Wobei mir jetzt der Fehler bewusst wird: Ich habe wohl Int statt int genommen. Deswegen auch der Compiler Fehler?!

Ich gelobe Besserung.

ht81:
Hallo Uwe,
danke nochmals für dein Feedback. Ja ich habe Einsatz gezeigt (wie bereits schon geschrieben) und habe es ja auch mit Int und Float versucht. Wobei mir jetzt der Fehler bewusst wird: Ich habe wohl Int statt int genommen. Deswegen auch der Compiler Fehler?!

Entschuldige, da hatte ich Dich falsch verstanden. :wink: :wink:

Alle Funktionen, Variablennamen und Schlüsselörter sind key-sensitive, daß heißt auch die Groß-Kleinschreibung jedes Buchstabens ist wichtig.
"Int" ist nicht das gleiche wie "int".
Dir wird aufgefallen sein daß im Editor des IDE "int" mit oranger Farbe dargestellt wird und "Int" nicht. Das ist eine kleine Hilfe.

Als Variable für diesen Zweck (LEDon) würde ich niemals eine float Typ verwenden da dieser Rundungsfehler hat. Ein Wert 1 könnte als 0,999999 dargestellt werden.

Grüße Uwe