LED Kerzenlicht mit Auto Aus

Hallo Zusammen,

ich habe mir da ein kleines Projekt in den Kopf gesetzt, das eigentlich eher in die kalte Jahreszeit gehört, aber erst jetzt ein wenig Zeit dafür vorhanden ist.

Ich möchte gerne ein paar meiner Kerzen gegen LED Versionen austauschen (wie man sie für ein paar Euro aus sämtlichen Märkten kennt)

Allerdings soll neben dem klassischen flackern auch die Möglichkeit vorhanden sein, das die Kerze nach z.B 4 Stunden aus geht. Ein weiteres Addon wäre dann noch, das die Kerze nach einem weiteren Delay wieder von alleine angeht.
Also z.B so, das ich den MC um 18 Uhr einschalte, das Flackerlichtprogramm läuft dann für 4 Stunden und um 22 Uhr geht es aus, danach läuft ein Delay von 20 Stunden und damit geht es um 18 Uhr wieder an.

Ist das soweit mit dem Arduino ohne RTC möglich?

Als Code Schnipsel für das Flackern habe ich das bereits gefunden:

#define PIN_LED1_YELLOW 11

void setup()
{
    pinMode(PIN_LED1_YELLOW, OUTPUT);
}

void loop()
{
    analogWrite(PIN_LED1_YELLOW, random(10, 255));
    delay(25);
}

Vielleicht könnt Ihr mir ja Tips geben, wie ich zu dem passenden Ergebnis kommen kann.
Denn ich weißt nicht, wie ich den MC dazu bringen kann, dass ich er weiß, dass nach 4 Stunden (also 14400000ms) das Programm beendend hat und die LED ausgeht.

Ich muss dazu sagen das ich absoluter Neuling und für jeden Hinweis dankbar bin!

Naja, eher sehr ungenau.

Was aber gehen würde, das man mit jedem “manuellen” einschalten intern wieder von vorn anfängt zu zählen.
Also manuell ein → 4 Stunden an → 20 Stunden aus → 4 Stunden an → xx Stunden aus → manuell ein → 4 Stunden an …
Je nach Genauigkeit könnte das schon ne Handvoll Tage gehen…

Aber wenn Du evtl. ne Versorgungspannung brauchst, macht die RTC nichts mehr aus.

Also das Ziel wäre es später mit einem Arduino pro Mini und 2-3 Batterien bzw. 18650 Akku zu betreiben (je nach Version des pro Mini)

Alle paar Tage den Arduino zu resetten fände ich jetzt nicht das Problem :slight_smile:

Ich denke es würde mir schon weiterhelfen, wenn mir jemand sagen könnte, wie ich das flicker “Programm” nur eine gewisse Zeit ablaufen lassen kann, allerdings verwende ich den ersten delay ja für die Schnelligkeit des Flackerns. Also kann ich das ja nicht benutzen um nach Xms das Licht ausgehen zu lassen…

Na nichts leichter als das…
z.B. BlinkwithoutDelay - Die Nachtwächtererklärung

Wenn Du mir sagst, wie Du das ganze startest?
Batterie rein? oder mit nem Eingangspin?

Ich hab mal was getackert.
Erklärt sich von selbst.

const byte PIN_LED1_YELLOW = 11;
const byte switchPIN1 = 10;
enum {aus, ein};
bool anaus = aus;
unsigned long startmillisEin = 0;
const unsigned long bouncemillis = 20;
const unsigned long einzeit = 4UL * 60 * 60 * 1000; // Stunden*Minuten*Sekunden*millis

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start...."));

  pinMode(PIN_LED1_YELLOW, OUTPUT);
  pinMode(switchPIN1, INPUT_PULLUP);
}

void loop()
{
  if (!digitalRead(switchPIN1)                       // Taste gedrückt?
      && (millis() - startmillisEin > bouncemillis)) // Bouncetime abgelaufen?
  {
    startmillisEin = millis();                       // Merke Zeit
    if (anaus == aus)                              // wenn aus
    {
      anaus = ein; // merke neu an
    }
    else
    {
      anaus = aus; // Wenn nicht merke neu aus
    }
  }

  if ((anaus == ein) && (millis() - startmillisEin > einzeit))
  {
    anaus = aus;
  }

  if ((millis() % 25 == 0) && (anaus == ein))
  {
    analogWrite(PIN_LED1_YELLOW, random(10, 255));
  }
}

Hallo,
Wenn Du Wlan zur und Internet hast könntest auch eine NTP Uhrzeit nehmen. Geht auch recht einfach mit einem ESP.

Heinz

Der Plan wäre für den allgemeinen Start einen Schalter, damit ich die Batterie nicht abklemmen muss, also mit dem wird der MC gestartet

WOW! Danke! Das meiste verstehe ich!
Aber warum hast du hinter der 4 “UL” geschrieben? Das Netz hilft mir nur bedingt weiter, da einige sagen man kann es weglassen und andere nicht?

Ich probiere das gleich mal aus :slight_smile:

Hi,

wie viel Strom braucht so ein ESP denn? Hat da einer Erfahrung mit? Läuft der dann nur auf seiner eigenen Batterie, oder greift diese nur wenn der Arduino aus ist?
Denn ich vermute so WLAN ESP verbraucht schon mehr Strom oder?

Das Ziel wäre ja ohne extra Spannungsversorgung nur per Batterie oder Akku einige Tage laufen zu lassen. Obwohl ein RTC mittlerweile ja auch fast nichts mehr kostet

das UL hinter einer Zahl bedeutet, dass sie zwingend als „unsigned long“ behandelt wird.

Gruß

Gregor

PS:

Ja, klar, die Kosten sind nicht so wild. Denke aber daran, dass es Arbeit nach sich zieht.

Vielen Dank!

Ja mehr Verdrahtung und Programmierung, damit wäre dann aber theoretisch eine Kombination aus dem Code von my_xy_projekt und meiner Ursprünglichen Idee, das er automatisch an/aus geht machbar oder?

Ja, mit einer RTC könntest Du es tatsächlich von der Uhrzeit abhängig machen, was wann wie lange läuft. Aber wenn es Dir nicht darauf ankommt, es sekundengenau steuern/programmieren zu können, kannst Du auch mit millis() - also mit „Bordmitteln“ - arbeiten. Die Genauigkeit ist nicht so grottenschlecht, wie manche meinen. Es wird ja wohl kaum etwas in die Luft fliegen, wenn die Chose fünf Minuten früher oder später wieder ausgeht.
Sollte es Dir auf möglichst hohe Ganggenauigkeit ankommen, machst Du halt einen Probelauf und misst, ob millis(3600000) genau eine Stunde dauert und korrigierst entsprechend.

Gruß

Gregor

Das ist keine Sache über die man im Netz abstimmen kann!
Es ist kein Mehrheitsentscheid.

Dann könnte mein SwitchPin zum starten entfallen.
[edit]
sieht dann in der Kurzfassung so aus:

const byte PIN_LED1_YELLOW = 11;
unsigned long startmillisEin = 0;
const unsigned long einzeit = 4UL * 60 * 60 * 1000; // Stunden*Minuten*Sekunden*millis

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start...."));
  pinMode(PIN_LED1_YELLOW, OUTPUT);
}

void loop()
{
  if (millis() - startmillisEin < einzeit)
  {
    if (millis() % 25 == 0)
    {
      analogWrite(PIN_LED1_YELLOW, random(10, 255));
    }
  }
}

[/edit]

Ja, kann man. Dann stimmt aber das gewollte Ergebnis nicht mehr.

Du wirst sogar darauf hingewiesen.
Dazu musst Du Dir das anzeigen lassen.
Unter DATEI-VOREINSTELLUNGEN so einstellen:
grafik
Und dann einfach nur kompilieren - geht ganz trocken, brauchst nicht hochladen.

Die Warnung solltest Du dann nehmen und danach suchen.

Das sieht bei mir mittlerweile so aus:


#include <CombieTypeMangling.h> // Teil der CombieLib
using namespace Combie::Millis;


const Millis bouncemillis {20_ms};
const Millis einzeit      {4_hr}; 
const Millis interval     {0.33_dy}; 

Suchtipp: “user defined literals C++”

Cool, danke für die Tipps!

Habe ich direkt mal angepasst und ausprobiert…

Leider klappt das mit dem Code noch nicht ganz, nach Ablauf der Zeit, bleibt die LED an, statt aus.
Denn es fehlt ja auch noch der “aus” Code oder?

Wenn ich danach suche, wird mir ne ganze Menge angezeigt… Gibt es irgendwo eine Auflistung was und wie ich das genau einsetze? Und wo bekomme ich die Bibliothek her?

Es gibt sowas, wie absichtlich nicht zu Ende und fertig ausgelieferten Code.
Ja! Das war beabsichtigt.
Was hast Du aus dem Schnipsel rausgelesen?

Die Frage ist: Was macht der Schnipsel?
Wenn Du Die Frage richtig beantwortest, dann kommst Du selbst drauf, was wo wie ergänzt werden muss.
Wenn Dir dazu das Codeschreiben fehlt, wird das gerne nachgeholt, aber Du musst die Logik dahinter verstehen und nicht stur abschreiben.

find ich gut^^

Also ich habe folgendes aus dem Code bis jetzt verstanden. (verzeiht wenn ich die Begriffe noch nicht ganz drauf habe):

const byte, sage ich dem MC das Pin 11 die gelbe LED ist, damit ich im Code später immer gelbe LED statt “11” schreiben kann

unsigned long startmillisEin, hiermit setzte ich die Start Sekunden auf Null, damit die if Schleife direkt nach dem starten des MC anfängt zu zählen

const unsigned long, hier deklariere ich die Einzeit die 4h betragen soll

Im void setup starte ich den seriellen Monitor und mit dem (F(“Start…”)) gebe ich nicht nur “Start…” im seriellen Monitor aus, sondern sage dem MC mit dem “F” dass er die Werte in den Flash-Speicher schreiben soll, statt in den RAM. (Weil dieser bei mehreren seriellem Schreiben schnell vollläuft?)
Was mir nicht ganz klar ist, wieso ich das hier brauche, oder ist das nur zu Veranschaulichung?

pinMode, hier sage ich mit MC das meine gelbe LED an Port 11 ein Ausgang ist

Im Void Loop läuft nun das eigentliche Programm immer wieder “durch”
Ich starte mit einer If Abfrage bei der ich den internen millis (Counter?) minus der Startzeit (0ms) rechne und dieser muss kleiner als die einzeit (4h) sein.
Darin kommt dann noch eine If Abfrage die bei Bestätigung (was ja die ersten 4h nach dem Einschalten der Fall ist) die Geschwindigkeit des flackerns einstellt. (diesen Part habe ich nicht ganz verstanden, die 55 entscheiden über die Geschwindigkeit, aber warum % und gleich 0?)
Und in dieser If Schleife wird dann die LED per random Befehl zwischen 10 und 255 an und aus geschaltet.

Was aufjedenfall noch fehlt wäre der Aus Befehl und wie der MC erkennt, das die 4 Stunden nun abgelaufen sind.
Also muss noch das “LED Aus” deklariert werden und in der if Schleife muss ein else hinzukommen oder?

Habe ich das soweit einigermaßen verstanden? Dann versuche ich nachher mal ob ich das irgendwie hinbekomme.

Ich auch - andere hätten den Satz als Angriff auf ihre Person gesehen…
ok

Das kommt daher, das ich das als Vorlage bereits integriert habe.
Ich mache vieles trocken ohne Aufbau und lasse mir dann z.B. nur die PIN-Stati auf dem SerMon ausgeben, anstatt ne LED oder nen Relais anzubauen.
Ja, es ist nur zur Veranschaulichung drin geblieben.

Bis hierhin alles schick.
Du hast also jetzt den Start und die Laufzeit festgelegt.(*)
Die Bedingung ist solange erfüllt, wie die Laufzeit nicht abgelaufen ist. In dieser Zeit flackerts:

Das erklär ich mal:
das %-Zeichen bedeutet MODULO. Das heisst, es ist eigentlich eine reine Division, aber Du siehst nur den ganzzahligen Rest und nicht das was vor dem Komma stünde.
30/25=1 Rest 5
50/25=1 Rest 0 Katsumi hat recht: 50/25=2 Rest 0 :wink:
Und immer, wenn der Vergleich stimmt, das der Rest 0 ist, sind 25ms abgelaufen.
Das ist hier unkritisch, wenn das nicht klappt und bei einem Durchlauf einmal die 0 nicht “erwischt” wird.

Damit vermeide ich aber, das das gesamte Konstrukt wie in Deinem Ursprungscode für 25ms durch das Delay() stehen bleibt.

Naja, den Ablauf der 4 Stunden hast Du ja, Siehe oben mein (*) da ist dann schluss ist mit Flackern.
Bis dahin war die Bedingung erfüllt.
Jetzt musst Du an entsprechender Stelle nur abfragen, ob die Bedingung nicht erfüllt ist und dort das LEDchen aus machen.

IF (Bedingung erfüllt)
flackern
ELSE
nicht flackern.

Kleine Nachtlektüre fürs Kopfkissen:
https://www.arduinoforum.de/code-referenz Da das pdf runterladen - liest sich gut weg; nicht auswendig lernen, es reicht zu wissen, wo was steht :wink:

Na dann.