LED Fade in and out

Guten Abend,

ich verzweifle schon seit Tagen an meinem Code, LED über zwei Trigger (digitalRead) zu steuern.

Projekt: LED Steuerung fürs Auto (mit Fade effekt).

Ziel: Trigger1 (Innenraumlicht = LED 100%) // Trigger2 (Standlicht = LED 30%)

Innenraumlicht hat prio über Standlicht.

Wenn Innenraumlicht dann gehen die LED langsam an auf 100%. Ist dann auch noch Standlicht an bleibt es bei 100%, wenn Innenraumlicht aus geht, soll die LED auf 30% runter. Geht wieder Innenraum an, wieder 100%. Wenn beide aus dann vom letzten Stand auf 0%.

Der Code:

#define ledAT 3 // Außentür LED
#define ledIT 5 // Innentür LED
#define ledFR 6 // Fußraum LED
#define ledTA 9 // Türablage LED

#define triggerIL 2 // Trigger Innenraumlicht
#define triggerSL 4 // Trigger Standlicht

int statusIL = 0;
int statuslastIL = 0;
int statusSL = 0;
int statuslastSL = 0;
int helligkeit = 0;
int lasthelligkeit = 0;

void setup() {
  pinMode(triggerIL, INPUT);
  pinMode(triggerSL, INPUT);
  Serial.begin(9600);
}

void setled(int i) {
  helligkeit = i;
  Serial.println(helligkeit);
  if (helligkeit < lasthelligkeit) {
    for (lasthelligkeit; lasthelligkeit <= helligkeit; helligkeit = helligkeit - 1) {
    analogWrite(ledAT, helligkeit);
    analogWrite(ledIT, helligkeit);
    analogWrite(ledTA, helligkeit);
    analogWrite(ledFR, helligkeit);
    delay(20);
    lasthelligkeit = helligkeit;
     Serial.println("1");
    }
  }
  if (helligkeit > lasthelligkeit) {
    for (lasthelligkeit; lasthelligkeit >= helligkeit; helligkeit = helligkeit + 1) {
    analogWrite(ledAT, helligkeit);
    analogWrite(ledIT, helligkeit);
    analogWrite(ledTA, helligkeit);
    analogWrite(ledFR, helligkeit);
    delay(20);
    lasthelligkeit = helligkeit;
    Serial.println("2");
    }
  }
}


void loop() {
  statusIL = digitalRead(triggerIL);
  statusSL = digitalRead(triggerSL);

  if ((statusIL != statuslastIL) || (statusSL != statuslastSL)) {
    if ((statusIL == LOW) && (statusSL == HIGH)) {
        setled(50);
    } 
    if ((statusIL == LOW) && (statusSL == LOW)) {
        setled(0);
    }
    if ((statusIL == HIGH) && (statusSL == HIGH)) {
        setled(255);
    }
    if ((statusIL == HIGH) && (statusSL == LOW)) {
        setled(255);
    }
     statuslastIL = statusIL;
     statuslastSL = statusSL;
}
}

Ich hoffe jemand findet das Problem.
Problem: LEDs wechseln nicht den Status wenn die Trigger unterschiedlich agieren.

Gruß Daniel

Hallo,

Ich hoffe jemand findet das Problem.

durchaus :slight_smile:

Schalte einmal in der IDE alle Warnungen ein.
Datei > Voreinstellungen > Compiler-Warnungen > "ALLE"
Dort kannste gleich noch "Zeilennummern anzeigen" und "Codefaltung" aktivieren. Finde ich sehr hilfreich.

Dann drückste nochmal auf Kompilerung und schaust dir die Warnungen der for Schleifen an.

Vielleicht findest du damit schon selbst das Problem.

Und das hier

helligkeit = helligkeit + 1
// besser so schreiben
helligkeit++

Dann solltest du schon sehen was an den Argumenten bzw. Bedingungen falsch ist. :wink:

Projekt: LED Steuerung fürs Auto

Ist das eine zulässige Modification?

Grüße Uwe

Doc_Arduino:
Hallo,
durchaus :slight_smile:

Schalte einmal in der IDE alle Warnungen ein.
Datei > Voreinstellungen > Compiler-Warnungen > "ALLE"
Dort kannste gleich noch "Zeilennummern anzeigen" und "Codefaltung" aktivieren. Finde ich sehr hilfreich.

Dann drückste nochmal auf Kompilerung und schaust dir die Warnungen der for Schleifen an.

Vielleicht findest du damit schon selbst das Problem.

Und das hier

helligkeit = helligkeit + 1

// besser so schreiben
helligkeit++




Dann solltest du schon sehen was an den Argumenten bzw. Bedingungen falsch ist. ;)

Habe das mit "helligkeit++" angepasst.

Habe den Fehler gesehen:

warning: statement has no effect [-Wunused-value]

Habe es herausgefunden:

Nun habe ich das Problem, dass die LEDs immer wieder von 0 auf max springen, sobald einmal ein Trigger kam. Ist echt zum Mäuse melken :frowning:

uwefed:
Ist das eine zulässige Modification?

Grüße Uwe

Ist für Innenraum primär gedacht, Features die halt neue Autos haben :slight_smile:

Hallo,

okay, dann zeige bitte den aktuellen Sketch.
Jede kleine Veränderung kann entscheidend sein.

danja95:
Nun habe ich das Problem, dass die LEDs immer wieder von 0 auf max springen, sobald einmal ein Trigger kam.

statte jede IF-Bedingung mit einem entsprechenden Serial.println aus damit du zur Laufzeit siehst, was dein Code macht, dann siehst du vermutlich auch, wodurch das Fehlverhalten entsteht.

Doc_Arduino:
Hallo,

okay, dann zeige bitte den aktuellen Sketch.
Jede kleine Veränderung kann entscheidend sein.

#define ledAT 3 // Außentür LED
#define ledIT 5 // Innentür LED
#define ledFR 6 // Fußraum LED
#define ledTA 9 // Türablage LED

#define triggerIL 2 // Trigger Innenraumlicht
#define triggerSL 4 // Trigger Standlicht

int statusIL = 0;
int statuslastIL = 0;
int statusSL = 0;
int statuslastSL = 0;
int helligkeit = 0;
int lasthelligkeit = 0;

void setup() {
  pinMode(triggerIL, INPUT);
  pinMode(triggerSL, INPUT);
  Serial.begin(9600);
}

void setled(int i) {
  helligkeit = i;
  Serial.println(helligkeit);
  if (helligkeit < lasthelligkeit) {
    for (; helligkeit <= lasthelligkeit; helligkeit--) {
    analogWrite(ledAT, helligkeit);
    analogWrite(ledIT, helligkeit);
    analogWrite(ledTA, helligkeit);
    analogWrite(ledFR, helligkeit);
    delay(20);
    lasthelligkeit = helligkeit;
     Serial.println("1");
    }
  }
  if (helligkeit > lasthelligkeit) {
    for (; helligkeit >= lasthelligkeit; helligkeit++) {
    analogWrite(ledAT, helligkeit);
    analogWrite(ledIT, helligkeit);
    analogWrite(ledTA, helligkeit);
    analogWrite(ledFR, helligkeit);
    delay(20);
    lasthelligkeit = helligkeit;
    Serial.println("2");
    }
  }
}


void loop() {
  statusIL = digitalRead(triggerIL);
  statusSL = digitalRead(triggerSL);

  if ((statusIL != statuslastIL) || (statusSL != statuslastSL)) {
    if ((statusIL == LOW) && (statusSL == HIGH)) {
        setled(50);
    } 
    if ((statusIL == LOW) && (statusSL == LOW)) {
        setled(0);
    }
    if ((statusIL == HIGH) && (statusSL == HIGH)) {
        setled(255);
    }
    if ((statusIL == HIGH) && (statusSL == LOW)) {
        setled(255);
    }
     statuslastIL = statusIL;
     statuslastSL = statusSL;
}
}

noiasca:
statte jede IF-Bedingung mit einem entsprechenden Serial.println aus damit du zur Laufzeit siehst, was dein Code macht, dann siehst du vermutlich auch, wodurch das Fehlverhalten entsteht.

Habe ich auch schon Probiert. Siehe Code.

Komme dennoch leider nicht vorran.

Hallo,

habs nochmal angeschaut.

a) deine Bedingungen der for Schleifen sind falsch
b) for Init Bedingung ist global, kann gut gehen, meistens ist das aber Mist und führt zu Kaos, macht man nur äußerst selten
c) analogWrite arbeitet im Wertebereich Byte, du übergibts Wertebereich int und zählst auch in diesem, dass führt zum Bereichsüberlauf was dich jetzt wundern lässt was da passiert

Bsp. dein erstes for

for (; helligkeit <= lasthelligkeit; helligkeit--) {

ich setze als Startbedingung dein setled(50) ein, daraus folgt

for (helligkeit = 50; helligkeit <= lasthelligkeit; helligkeit--) {

ab jetzt dekrementierst du “ohne Ende” bis helligkeit den Wert -32768 hat. Dann springt es auf +32767 und wird wieder fleißig dekrementiert. Und weil du lasthelligkeit immer schön nachziehst mit helligkeit und auf <= vergleichst, hast in meinen Augen eine Endlosschleife und analogWrite spielt mit seinem Byte Wertebereich und dessen Überläufen quasi PingPong.

Ich habe mal die Ausgabe ergänzt die du dir anschauen solltest.

void setled(int i) {
  helligkeit = i;
  Serial.println(helligkeit);
  
  if (helligkeit < lasthelligkeit) {
    for (; helligkeit <= lasthelligkeit; helligkeit--) {
      analogWrite(ledAT, helligkeit);
      analogWrite(ledIT, helligkeit);
      analogWrite(ledTA, helligkeit);
      analogWrite(ledFR, helligkeit);
      delay(20);
      lasthelligkeit = helligkeit;
      Serial.print("mode 1"); Serial.print('\t'); 
      Serial.print(helligkeit);  Serial.print('\t'); 
      Serial.println(lasthelligkeit); 
    }
  }
  
  if (helligkeit > lasthelligkeit) {
    for (; helligkeit >= lasthelligkeit; helligkeit++) {
      analogWrite(ledAT, helligkeit);
      analogWrite(ledIT, helligkeit);
      analogWrite(ledTA, helligkeit);
      analogWrite(ledFR, helligkeit);
      delay(20);
      lasthelligkeit = helligkeit;
      Serial.print("mode 2"); Serial.print('\t'); 
      Serial.print(helligkeit);  Serial.print('\t'); 
      Serial.println(lasthelligkeit); 
    }
  }
}

Ich ändere dir nicht den ganzen Sketch, du sollst selbst drauf kommen. Dann merkt man sich sowas besser.
Wenn du dir das angeschaut hast, änderst du i, helligkeit und lasthelligkeit erstmal in byte ab und schaust dir das erneut an.
Dann sollte sich theoretisch noch nichts groß ändern im optischen Verhalten.
Danach schiebst du das nachziehen “lasthelligkeit = helligkeit” aus der for raus ans Ende der if.
Dann sollte sich etwas tun in die richtige Richtung.

Hallo,

vielleicht noch ein Hinweis wenn ich das richtig überblicke.
helligkeit ist dein SOLL-Wert (Zielwert), also auf den Wert soll das Licht eingestellt werden.
lasthelligkeit ist dein IST-Wert, also der alte Wert von dem du weg willst.

Wie sind deine Taster/Schalter (“Trigger”) angeschlossen?
Gibt es da “Pullup-” oder "Pulldown-Widerstände?

Die for-Schleifen machen wohl nicht was du möchtest.
Weil “for-Schleife ausführen solange”

helligkeit >= lasthelligkeit

und folgende Zeile innerhalb der for-Schleife

lasthelligkeit = helligkeit

zu “interessanten” Ergebnissen führt :slight_smile:

Vielleicht könnte es so besser funktionieren.
Es sind auch ausführliche serielle Ausgaben eingefügt, so kann man sehen, was passiert.
Beachte auch, dass die “TriggerPins” jetzt INPUT_PULLUP sind (und deshalb die “Logik” möglicherweise umgekehrt ist).

#define ledAT 3 // Außentür LED
#define ledIT 5 // Innentür LED
#define ledFR 6 // Fußraum LED
#define ledTA 9 // Türablage LED

#define triggerIL 2 // Trigger Innenraumlicht
#define triggerSL 4 // Trigger Standlicht

int statusIL = 0;
int statuslastIL = 0;
int statusSL = 0;
int statuslastSL = 0;
int helligkeit = 0;

void setup() {
  pinMode(triggerIL, INPUT_PULLUP);
  pinMode(triggerSL, INPUT_PULLUP);
  Serial.begin(9600);
}

void setled(int zielHelligkeit) {
  Serial.print("Ziel: ");
  Serial.println(zielHelligkeit);
  if (helligkeit < zielHelligkeit) {   // aufblenden
    for (int aktHelligkeit = helligkeit; aktHelligkeit <= zielHelligkeit; aktHelligkeit++) {
      analogWrite(ledAT, aktHelligkeit);
      analogWrite(ledIT, aktHelligkeit);
      analogWrite(ledTA, aktHelligkeit);
      analogWrite(ledFR, aktHelligkeit);
      delay(10);
      Serial.println(aktHelligkeit);
    }
    helligkeit = zielHelligkeit;
  }
  if (helligkeit > zielHelligkeit) {   // abblenden
    for (int aktHelligkeit = helligkeit; aktHelligkeit >= zielHelligkeit; aktHelligkeit--) {
      analogWrite(ledAT, aktHelligkeit);
      analogWrite(ledIT, aktHelligkeit);
      analogWrite(ledTA, aktHelligkeit);
      analogWrite(ledFR, aktHelligkeit);
      delay(10);
      Serial.println(aktHelligkeit);
    }
    helligkeit = zielHelligkeit;
  }
}


void loop() {
  statusIL = digitalRead(triggerIL);
  statusSL = digitalRead(triggerSL);

  if ((statusIL != statuslastIL) || (statusSL != statuslastSL)) {
    if ((statusIL == LOW) && (statusSL == HIGH)) {
      setled(50);
    } 
    if ((statusIL == LOW) && (statusSL == LOW)) {
      setled(0);
    }
    if ((statusIL == HIGH) && (statusSL == HIGH)) {
      setled(255);
    }
    if ((statusIL == HIGH) && (statusSL == LOW)) {
      setled(255);
    }
    statuslastIL = statusIL;
    statuslastSL = statusSL;
  }
}

uxomm:
Wie sind deine Taster/Schalter (“Trigger”) angeschlossen?
Gibt es da “Pullup-” oder "Pulldown-Widerstände?

Die for-Schleifen machen wohl nicht was du möchtest.
Weil “for-Schleife ausführen solange”

helligkeit >= lasthelligkeit

und folgende Zeile innerhalb der for-Schleife

lasthelligkeit = helligkeit

zu “interessanten” Ergebnissen führt :slight_smile:

Vielleicht könnte es so besser funktionieren.
Es sind auch ausführliche serielle Ausgaben eingefügt, so kann man sehen, was passiert.
Beachte auch, dass die “TriggerPins” jetzt INPUT_PULLUP sind (und deshalb die “Logik” möglicherweise umgekehrt ist).

#define ledAT 3 // Außentür LED

#define ledIT 5 // Innentür LED
#define ledFR 6 // Fußraum LED
#define ledTA 9 // Türablage LED

#define triggerIL 2 // Trigger Innenraumlicht
#define triggerSL 4 // Trigger Standlicht

int statusIL = 0;
int statuslastIL = 0;
int statusSL = 0;
int statuslastSL = 0;
int helligkeit = 0;

void setup() {
  pinMode(triggerIL, INPUT_PULLUP);
  pinMode(triggerSL, INPUT_PULLUP);
  Serial.begin(9600);
}

void setled(int zielHelligkeit) {
  Serial.print("Ziel: ");
  Serial.println(zielHelligkeit);
  if (helligkeit < zielHelligkeit) {  // aufblenden
    for (int aktHelligkeit = helligkeit; aktHelligkeit <= zielHelligkeit; aktHelligkeit++) {
      analogWrite(ledAT, aktHelligkeit);
      analogWrite(ledIT, aktHelligkeit);
      analogWrite(ledTA, aktHelligkeit);
      analogWrite(ledFR, aktHelligkeit);
      delay(10);
      Serial.println(aktHelligkeit);
    }
    helligkeit = zielHelligkeit;
  }
  if (helligkeit > zielHelligkeit) {  // abblenden
    for (int aktHelligkeit = helligkeit; aktHelligkeit >= zielHelligkeit; aktHelligkeit–) {
      analogWrite(ledAT, aktHelligkeit);
      analogWrite(ledIT, aktHelligkeit);
      analogWrite(ledTA, aktHelligkeit);
      analogWrite(ledFR, aktHelligkeit);
      delay(10);
      Serial.println(aktHelligkeit);
    }
    helligkeit = zielHelligkeit;
  }
}

void loop() {
  statusIL = digitalRead(triggerIL);
  statusSL = digitalRead(triggerSL);

if ((statusIL != statuslastIL) || (statusSL != statuslastSL)) {
    if ((statusIL == LOW) && (statusSL == HIGH)) {
      setled(50);
    }
    if ((statusIL == LOW) && (statusSL == LOW)) {
      setled(0);
    }
    if ((statusIL == HIGH) && (statusSL == HIGH)) {
      setled(255);
    }
    if ((statusIL == HIGH) && (statusSL == LOW)) {
      setled(255);
    }
    statuslastIL = statusIL;
    statuslastSL = statusSL;
  }
}

Ich verbeuge mich vor dir. Es funktioniert nun wie es soll. For Schleifen sind immer ein graus für mich. Ich werde dennoch versuchen es zu verstehen, aber nun habe ich mal ein funktionierendes exampel :slight_smile:

Vielen Dank euch allen für die Hilfe!

FOR, Arduino Reference
Erste Angabe - Startwert
Zweite Angabe - Bedingung
Dritte Angabe - Veränderung
Wenn man Alle weg lässt, hat man eine FOR-Endlos-Schleife - wie immer: per break; abbrechbar.

MfG

Hallo,

Schade. Wertebereich wurde auch nicht korrigiert.
Mein Anliegen war es das du dich nochmal mit der for Schleife und den Operatoren beschäftigst. Danach hatte ich gehofft das du dir deine Aufgabe nochmal genauer anschaust was die eigentlich machen soll. Dann käme man drauf das man keine for Schleifen benötigt. Man muss nur einer kontinuierlich aufgerufenen Funktion den Sollwert übergeben. Diese entscheidet dann was zu tun ist und regelt den Istwert auf den Sollwert.

Kleines Bsp.

byte last = 100;    // oder was auch immer im Byte Bereich

void setup() {
  Serial.begin(9600);
}


void loop()
{
  fading(50);        // oder was auch immer im Byte Bereich
}


void fading(byte soll)
{
  if (soll != last) {                 // ändert sich überhaupt etwas?
    if (soll < last) {                // Licht soll dunkler werden
      last--;
    }
    if (soll > last) {                // Licht soll heller werden
      last++;
    }
    // hier analogWrite(last);
    // delay(20);
    Serial.print(soll); Serial.print('\t'); Serial.println(last);
  }
}

Mach das Beste daraus …