LED Kerzenlicht mit Auto Aus

Mein Code sieht dann momentan so aus:

const byte LED_YELLOW = 11;                             // Setzte Pin 11 auf die LED
unsigned long startmillisEin = 0;                       // Setzte die Startzeit auf 0ms
const unsigned long einzeit = 4UL * 60 * 60 * 1000;     // Stunden*Minuten*Sekunden*millis


void setup()
{
  pinMode(LED_YELLOW, OUTPUT);                          // Sage dem MC das Pin 11 ein Ausgang ist
}

void loop()
{
  if (millis() - startmillisEin < einzeit)              // Wenn millis - 0ms kleiner als Einzeit
  {
    if (millis() % 55 == 0)                             // dann rechne millis durch 55% und vergleiche mit 0 (flackern)
    {
      analogWrite(LED_YELLOW, random(10, 255));         // passt der Vergleich lasse die LED zwischen 10 und 255 flackern
    }
  }
  else
  {
     if (millis() - startmillisEin >= einzeit)          // Wenn millis - 0ms größer oder gleich Einzeit,
     {
      analogWrite(LED_YELLOW, random(0));               // dann schalte die LED aus
     }
  }
}

allerdings funktioniert das ganze nicht so wie ich dachte… Wenn ich die Einzeit auf ein paar Sekunden setzte, funktioniert das auch soweit und nach den Sekunden geht das Licht aus. Wenn ich das ganz aber auf mehrere Sekunden setzte (z.B 60s) oder sogar Minuten, Stunden…
geht das Licht nicht mehr aus.

Hab ich das falsch verstanden? Könnt Ihr noch Hinweis geben? Oder muss ich die Zeit irgendwo speichern, wie im Blink without delay Beispiel?

VG

Mach mal daraus nur:

{
   digitalWrite(LED_YELLOW, LOW);               // dann schalte die LED aus
  }

Das hört sich nach eben genau dem Effekt an, der erfolgt, wenn UL auf der rechten Seite nicht mitgenommen wird.
Wenn Du 4UL aus der Berechnung löscht… Mache das UL hinter die 1000, dann sollte es funktinieren.

Vielen Dank!

Funktioniert! (wusste nicht, das ich das so einfach schreiben kann)

Auf den Trichter kam ich nicht, jetzt wo es hinzugefügt wurde, klappt es auch bei mehr Sekunden, Stunden muss ich noch testen, aber ich bin zuversichtlich (Es wurde mir aber zu keiner Zeit eine Fehlermeldung ausgegeben, daher bin ich bei dem kleinen Wert davon ausgegangen das es nicht nötig wäre…)

Wenn ich die LED jetzt statt einfach nur aus, für 20h aus schalten möchte, muss ich die Zeit irgendwo speichern oder? Sodass der MC nach den 20 Stunden weiß, das er wieder mit 4 Stunden LED ein anfangen soll.

Die habe ich mir direkt abgespeichert und werde Sie mal langsam durch “arbeiten” :slight_smile:

Ja. Weil das kein Fehler ist.
Es gibt aber eine Warnmeldung, das der Bereich, den Du mit Deiner Berechnung abdecken möchstest nicht in die Variable passt, mit der auf der rechten Seite gerechnet wird.
Solange, wie Du NICHTS angibst, wird mit INT gerechnet.
Wie der Wertebereich ist, dazu liest Du ja noch… :wink:

Die Warnungen solltest Du einschalten unter DATEI - VOREINSTELLUNEGEN - Da den Haken machen mindestens bei Kompiler und alle auswählen.

Ja.
Und weil Du so lernwillig bist:

// Forensketch basiert auf:
// https://forum.arduino.cc/t/led-kerzenlicht-mit-auto-aus/854849/21
// https://forum.arduino.cc/t/led-kerzenlicht-mit-auto-aus/854849/22

const byte LED_YELLOW = 11;                             // Setzte Pin 11 auf die LED
unsigned long startmillisEin = 0;                       // Setzte die Startzeit auf 0ms
const unsigned long einzeit = 4UL * 60 * 60 * 1000;     // Stunden*Minuten*Sekunden*millis
const unsigned long zwanzigstundenaus = 10000;          // HIER ZEIT EINTRAGEN, DIE AUS SEIN SOLL

void setup()
{
  pinMode(LED_YELLOW, OUTPUT);                          // Sage dem MC das Pin 11 ein Ausgang ist
}

void loop()
{
  if (millis() - startmillisEin < einzeit)              // Wenn millis - 0ms kleiner als Einzeit
  {
    if (millis() % 55 == 0)                             // dann rechne millis durch 55% und vergleiche mit 0 (flackern)
    {
      analogWrite(LED_YELLOW, random(10, 255));         // passt der Vergleich lasse die LED zwischen 10 und 255 flackern
    }
  }
  else
  {
    digitalWrite(LED_YELLOW, LOW);                      // dann schalte die LED aus
    ausmillis = millis();                               // Merke Zeit wann ausgeschaltet
  }

  if (millis() - ausmillis >= zwanzigstundenaus)        // ist auschaltzeit um
  {
    startmillisEin = millis();                          // fang von vorn an
  }
}

Der muss natürlich noch deklariert werden… sorry.
Das wärs dann IMHO:

// Forensketch basiert auf:
// https://forum.arduino.cc/t/led-kerzenlicht-mit-auto-aus/854849/21
// https://forum.arduino.cc/t/led-kerzenlicht-mit-auto-aus/854849/22
// ungetestet - unkompiliert
const byte LED_YELLOW = 11;                             // Setzte Pin 11 auf die LED
unsigned long startmillisEin = 0;                       // Setzte die Startzeit auf 0ms
const unsigned long einzeit = 4UL * 60 * 60 * 1000;     // Stunden*Minuten*Sekunden*millis
const unsigned long zwanzigstundenaus = 10000;          // HIER ZEIT EINTRAGEN, DIE AUS SEIN SOLL
unsigned long ausmillis = 0;

void setup()
{
  pinMode(LED_YELLOW, OUTPUT);                          // Sage dem MC das Pin 11 ein Ausgang ist
}

void loop()
{
  if (millis() - startmillisEin < einzeit)              // Wenn millis - 0ms kleiner als Einzeit
  {
    ausmillis = millis();                               // Weil nicht aus, zurücksetzen...
    if (millis() % 55 == 0)                             // dann rechne millis durch 55% und vergleiche mit 0 (flackern)
    {
      analogWrite(LED_YELLOW, random(10, 255));         // passt der Vergleich lasse die LED zwischen 10 und 255 flackern
    }
  }
  else
  {
    digitalWrite(LED_YELLOW, LOW);                      // dann schalte die LED aus
    ausmillis = millis();                               // Merke Zeit wann ausgeschaltet
  }

  if (millis() - ausmillis >= zwanzigstundenaus)        // ist auschaltzeit um
  {
    startmillisEin = millis();                          // fang von vorn an
  }
}

hmm,

also so ganz einleuchten tuts mir noch nicht…
Funktionieren leider auch nicht, oder übersehe ich etwas?

Ja, das habe ich nach deinem ersten Post schon gemacht, da wurde aber auch keine Warnung ausgegeben…
image

habe die Ein Zeit für den Test auf 3000UL und die Aus Zeit auf 10000UL gesetzt. Also müsste die LED 3 Sekunden an und 10 Sekunden aus, danach wieder 3 Sekunden an sein usw. oder?

Eigentlich sind von dir ja alle Zeilen schon codiert, oder ich habs noch nicht verstanden, auch möglich… :smiley:

Edit, habe dich als Antworten vergessen, weiß gerade nicht wie ich das bei einem editierbaren Beitrag machen kann… sorry

Ja.
Wenn es richtig ist.
Ich hab gestern vermutlich auch ne Zeile zuviel drin gehabt.
Hier getestet mit dem Seriellen Monitor - und für gut befunden.


// Forensketch basiert auf:
// https://forum.arduino.cc/t/led-kerzenlicht-mit-auto-aus/854849/21
// https://forum.arduino.cc/t/led-kerzenlicht-mit-auto-aus/854849/22
// ungetestet - unkompiliert
const byte LED_YELLOW = 11;                             // Setzte Pin 11 auf die LED
unsigned long startmillisEin = 0;                       // Setzte die Startzeit auf 0ms
const unsigned long einzeit = 3000;                    // Einzeit
const unsigned long zwanzigstundenaus = 10000;          // HIER ZEIT EINTRAGEN, DIE AUS SEIN SOLL
unsigned long ausmillis = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  pinMode(LED_YELLOW, OUTPUT);                          // Sage dem MC das Pin 11 ein Ausgang ist
}

void loop()
{
  if (millis() - startmillisEin < einzeit)              // Wenn millis - 0ms kleiner als Einzeit
  {
    ausmillis = millis();                               // Weil nicht aus, zurücksetzen...
    if (millis() % 55 == 0)                             // dann rechne millis durch 55% und vergleiche mit 0 (flackern)
    {
      ausmillis = millis();                             // Merke Zeit / für Zeitpunkt ausschalten
      analogWrite(LED_YELLOW, random(10, 255));         // passt der Vergleich lasse die LED zwischen 10 und 255 flackern
    }
  }
  else
  {
    digitalWrite(LED_YELLOW, LOW);                      // dann schalte die LED aus
    Serial.println(F("Ende EinZeit"));
  }

  if (millis() - ausmillis >= zwanzigstundenaus)        // ist auschaltzeit um
  {
    startmillisEin = millis();                          // fang von vorn an
    Serial.println(F("Ende AusZeit"));
  }
}

Zur Frage:

Hier die Antwort aus der IDE, wenn der UL nicht deklariert ist:

ino:7:38: warning: integer overflow in expression [-Woverflow]

 const unsigned long einzeit = 4*60*60*1000;                    // Einzeit

                               ~~~~~~~^~~~~

Diese Warnung bekommst Du auch, wenn die Berechnung größer als ein INT wird. Musst nur in dem kleinen schwarzen Fenster hochscrollen.

Bitte korrigieren. Das verwirrt sonst.
50/25=2

Gruß, Jürgen

1 Like

vielen lieben Dank für deine Hilfe!!

Der Code sieht nun wie folgt aus und funktioniert auch:

/*
 * Forensketch basiert auf:
 * https://forum.arduino.cc/t/led-kerzenlicht-mit-auto-aus/854849/22
 * https://forum.arduino.cc/t/led-kerzenlicht-mit-auto-aus/854849/28
 * Kompiliert und gestestet!
*/
const byte LED_YELLOW = 11;                             // Setzte Pin 11 auf die LED
unsigned long startmillisEin = 0;                       // Setzte die Startzeit auf 0ms
const unsigned long einzeit = 4UL * 60 * 60 * 1000;     // Einzeit Stunden*Minuten*Sekunden*Millisekunden
const unsigned long auszeit = 20UL * 60 * 60 * 3000;    // Auszeit Stunden*Minuten*Sekunden*Millisekunden
unsigned long ausmillis = 0;

void setup()
{
  pinMode(LED_YELLOW, OUTPUT);                          // Sage dem MC das Pin 11 ein Ausgang ist
}

void loop()
{
  if (millis() - startmillisEin < einzeit)              // Wenn millis - 0ms kleiner als Einzeit
  {
    ausmillis = millis();                               // Weil nicht aus, zurücksetzen...
    if (millis() % 55 == 0)                             // dann rechne millis durch 55% und vergleiche mit 0 (flackern)
    {
      ausmillis = millis();                             // Merke Zeit / für Zeitpunkt ausschalten
      analogWrite(LED_YELLOW, random(10, 255));         // passt der Vergleich lasse die LED zwischen 10 und 255 flackern
    }
  }
  else
  {
    digitalWrite(LED_YELLOW, LOW);                      // dann schalte die LED aus
  }

  if (millis() - ausmillis >= auszeit)                  // ist auschaltzeit um
  {
    startmillisEin = millis();                          // fang von vorn an
  }
}

Ich löte den Schaltkreis nun mal fertig und werde das ganze testen, mal sehen wie genau das nach 1-2 Tagen noch ist. Sollte ich damit überhaupt nicht zufrieden sein, kann ich mich ja immer noch für eine RTC entscheiden.

Ich werde aufjedenfall berichten :slight_smile:

Ja, freu ich mich drauf…

Wenn Du noch was probieren willst:

const byte LED_YELLOW = 11;                             // Setzte Pin 11 auf die LED
unsigned long startmillisEin = 0;                       // Setzte die Startzeit auf 0ms
const unsigned long einzeit = 4UL * 60 * 60 * 1000;     // Einzeit Stunden*Minuten*Sekunden*Millisekunden
const unsigned long auszeit = 20UL * 60 * 60 * 3000;    // Auszeit Stunden*Minuten*Sekunden*Millisekunden
unsigned long tikmillis = 0;

enum {aus, ein};
unsigned int stat=ein;

void setup()
{
  pinMode(LED_YELLOW, OUTPUT);                          // Sage dem MC das Pin 11 ein Ausgang ist
}

void loop()
{
  switch (stat)
  {
    case ein:
      if (millis() % 55 == 0)                           // dann rechne millis durch 55% und vergleiche mit 0 (flackern)
      {
        analogWrite(LED_YELLOW, random(10, 255));       // passt der Vergleich lasse die LED zwischen 10 und 255 flackern
      }
      if (millis() - tikmillis > einzeit)               // Wenn Einzeit abgelaufen
      {
        tikmillis = millis();
        stat = aus;
      }
    case aus:
      digitalWrite(LED_YELLOW, LOW);                    // dann schalte die LED aus
      if (millis() - tikmillis >= auszeit)              // ist auschaltzeit um
      {
        tikmillis = millis();                           // fang von vorn an
        stat = ein;
      }
  }
}

Hi,

nun habe ich das ganze entsprechend der Vorstellung ablaufen lassen und habe mich gewundert, warum der MC nach 20std nicht wieder anschaltet…
Nach einem genaueren Blick in den Code habe ich dann auch den eigenen Fehler entdeckt…
Statt der * 1000 habe ich noch vom testen zuvor *3000 stehen gehabt, dadurch wird die Zahl natürlich deutlich größer und ich kann lange warten…

Also das ganze abgeändert und nochmal testen… :slight_smile:

Melde mich

Edit:

Wollte den Code gerne editieren und entsprechend durchstreichen, sowie richtig hinschreiben, finde aber nicht die richtige Tastenkombi dafür…
Gibt es da eine Liste für?

Code in Codetags lässt sich nicht durchstreichen.
Ist nicht weiter schlimm - und ehrlich gesagt auch besser so, denn später Lesende werden dem Thread von oben nach unten folgen. Wenn oben Code durchgestrichen ist, muss erstmal gesucht werden warum.

Ansonsten… Nicht wirklich…
… schon einiges rausgefunden.
https://forum.arduino.cc/t/ot-lose-sammlung-forum-tipps-tricks/849120/60

Ah okay, das wusste ich so nicht.

Danke^^

Hi,

ich habe das ganze nun einige Tage lang getestet, mit einem Arduino Uno und auch mit einem Arduino Pro Mini, angeschlossen an einem 18650 Akku und kann mit Freuden sagen, das alles genau so klappt, wie ich mir das vorgestellt habe^^
Die Zeitverschiebung nach hinten (also nach mehreren Tagen) ist nur minimal und soll mich nicht weiter stören, wenns zuweit verschoben ist, starte ich den Arduino einfach kurz neu.

Vorallem hat mich aber der minimale Stromverbrauch überrascht und der Pro Mini angeschlossen per Lade-/Enlademodul am 18650 Akku hält nun schon gut 10 Tage non Stop!

Doch noch besser finde ich den klasse SUpport und die Hilfestellungen die Ihr mir gegeben habt und mich langsam an das Thema herangeführt habt!
Ich werde mich definitiv weiter mit dem Arduino beschädftigen und mal schauen was man noch so alles schönes damit basteln kann. :slight_smile:

Nun zu der 2. Code Variante (getestet habe ich ihn noch nicht)
Wo liegt der große Unterschied zu Variante 1? Klar, andere Variablen usw. aber was noch?
Oder ist es einfach eine andere Möglichkeit die Situation zu lösen?

Nimm beide loops - drucke sie aus und lege sie nebeneinander.
Beste Grüße und Danke fürs Feedback!