Zeitschaltuhr mit manuellem Ein/Aus Schalter

etwas weiters ausgeführt wie man c lösen könnte

/*
   Timer - Proof of Concept

   https://forum.arduino.cc/t/zeitschaltuhr-mit-manuellem-ein-aus-schalter/688003

   Timer in struct array
   persist in EEPROM
   read from EEPROM
   act according stored timers

   by noiasca

   2021-07-21   
*/

#include <EEPROM.h>

struct Timer {
  bool active;      // is the timer running
  byte startHH;     // start hour
  byte startMM;     // start minute
  byte finishHH;    // finish hour
  byte finishMM;    // finish minute
} timer[5];

const byte addrTimer = 0;  // EEPROM start addresss for timer array


void testChangeValues()
{
  timer[0].active = false;
  timer[0].startHH = 0;
  timer[0].startMM = 0;
  timer[0].finishHH = 0;
  timer[0].finishMM = 0;
  timer[1].active = true;
  timer[1].startHH = 0;
  timer[1].startMM = 1;
  timer[1].finishHH = 0;
  timer[1].finishMM = 2;
  timer[2].active = true;
  timer[2].startHH = 0;
  timer[2].startMM = 2;
  timer[2].finishHH = 0;
  timer[2].finishMM = 3;
  timer[3].active = true;
  timer[3].startHH = 11;
  timer[3].startMM = 0;
  timer[3].finishHH = 11;
  timer[3].finishMM = 30;
  timer[4].active = true;
  timer[4].startHH = 22;
  timer[4].startMM = 0;
  timer[4].finishHH = 22;
  timer[4].finishMM = 30;
  EEPROM.put(addrTimer, timer);
}

void debugTimer()
{
  // Ausgabe aller Werte
  for (size_t i = 0; i < sizeof(timer) / sizeof(timer[0]); i++)
  {
    Serial.print(F("timer ")); Serial.println(i);
    Serial.print(F(" active ")); Serial.println(timer[i].active);
    Serial.print(F(" start  ")); Serial.print(timer[i].startHH); Serial.print(":"); Serial.println(timer[i].startMM);
    Serial.print(F(" finish ")); Serial.print(timer[i].finishHH); Serial.print(":"); Serial.println(timer[i].finishMM);
  }
}


void runAutomatic()
{
  uint32_t currentMillis = millis();
  byte hh = currentMillis / 1000 / 60 / 24;       // simulate HH
  byte mm = currentMillis / 1000 / 60  % 60000UL; // simulate MM
  static byte previousMM = 255;
  if (previousMM != mm)   // run automatic only once a minute
  {
    Serial.print(F("Current Time ")); Serial.print(hh); Serial.print(":"); Serial.println(mm);
    
    for (size_t i = 0; i < sizeof(timer) / sizeof(timer[0]); i++)
    {
      if (timer[i].active && timer[i].startHH == hh && timer[i].startMM == mm)
      {
        Serial.print(F("ON timer ")); Serial.println(i);
      }
      else if (!timer[i].active)                                               // only debug
      {
        Serial.print(F("not active timer ")); Serial.println(i);
      }
      else                                                                     // only debug
      {
        Serial.print(F("no fitting starttime timer ")); Serial.println(i);
      }

      if (timer[i].active && timer[i].finishHH == hh && timer[i].finishMM == mm)
      {
        Serial.print(F("OFF timer ")); Serial.println(i);
      }
    }
    previousMM = mm;
  }
}

void setup() {
  Serial.begin(115200);
 // testChangeValues();  // einmal um Werte ins EEPROM zu bekommen

  EEPROM.get(addrTimer, timer);
  debugTimer();

}

void loop() {
  // put your main code here, to run repeatedly:
  runAutomatic();

}

testChangeValues soll dir nur zeigen, wie man Werte im struct verändert. Außerdem brauchte ich das einmal um Werte im EEPROM zu haben.

EEPROM speichern in das struct ist ein EINZEILER. Mit put werden wie bei update nur veränderte Werte geschrieben.

Ebenso

EEPROM auslesen in das struct ist ein EINZEILER.

debugTimer zeigt dir wie man auf die Werte im struct zugreift

runAutomatic ... ich hab mir HH / MM einfach aus den millis gemacht, der Sketch muss also ein paar Minuten laufen damit du siehst das was passiert. Wichtig erscheint mir, du hast Minuten-Timer, also braucht die Automatik nur einmal pro Minute laufen. Daher das static previousMM

Dann mal hier noch ein Wurf von mir.
Frage an den TO: ich könnte Dir das auch mit dem Aufbau via Array anbieten, aber das mache ich nur, wenn die lib für die RTC ausgetauscht wird und Du das ganze rechnen nicht mitmachst, sondern die Werte aus der lib nimmst. :wink:

@my_xy_projekt ...sehr gerne sofern es funktioniert ....und da bin ich mir sicher :slightly_smiling_face:.....müsste ich nur wissen welche lib ich verwenden soll

@noiasca ....die die Memanggil RTC3231 Library habe ich irgend wann mal aus dem Netz geholt.....weiss aber nicht mehr woher.

Na dann...
Richte Dich auf neu bauen ein.
Timelib und rtc1307 von Paul Stoffregen
Letztere funktioniert auch mit einer 3231, da alles was die Uhr angeht gleich ist. Nur die Zusatzfunktionen der 3231 gehen damit nicht. Benutzt Du nicht, also sorglos.

Wenn Du einen ersten Einblick bekommen willst, dann lies einfach mal kurz ein meinem aktuellen Lieblingsteil...
Angefangen mit der Uhr und deren Tücken mit der DSlib, die ihr alle benutzt....

und das FolgePost.
Und dann ab Serielle Datenstring vom Computer im Adruino Mega einlesen und aufteilen - #143 by my_xy_projekt
Und ab #151 zeige ich auch wie man die stellen kann. Wobei das eher Dein kleinstes Übel ist.

Paul sein Original:

Ich habe die nur inhaltlich umgeschrieben mit deutschen Angaben. -> findest Du im ersten Link oben.
Die Example der time.lib einfach mal durchgehen...
(Ich weiss nicht genau, ob die ds3231 lib vorher gelöscht werden muss....)

Hallo my_xy_projekt,

habe deiner Conversation mit benziner leider nicht ganz folgen können.

Bei mir ist es so, dass ich neben den Tastenbelegungen und den Regensensor eine einfach Zeitschaltuhr mit 4 verschiedenen Timereinstellungen aufgebaut habe.

Nur das der Timer offenbar nicht richtig zählt.

Nun habe ich die Bibliotheken die du vorgeschlagen hast in den Code eingebunden und bekomme prompt folgende Fehlermeldung:


A.00.ino (18.6 KB)

Fehlermeldung ist klar - aber bitte keine Fotos. Das ist nicht schick, wenn man das auf kleinen Displays liest.

Gib mal nur Deinen neuen Code.
Der bemängelt die fehlende lib. Ich will nur sehen, ob und wie Du Dich da rantastest.

...sorry werde mich daran halten.

Den Code habe ich angehangen.

Ja - sorry.
Aehm..
Möchtest Du Dich darauf einlassen etwas neues zu bauen? - Ich habe das in #64 schon mal angesprochen, das Du Dich darauf einlassen müsstest.
Damit ist dann ein Umbau ausgeschlossen, Es wird ein Neubau - und Du musst mitmachen.

Das fängt damit an, die timelib und die dc1307 von Paul Stoffregen runterzuladen und dort wenigstens das TimeRTC-Example zum laufen zu bekommen.

Wenn das geht, baue ich mit Dir die Alarmierung in ein Array.

Guten Morgen,

ja gerne, nur ich bin mich nicht sicher ob ich es mit meinen beschränkten Kenntnissen hin bekomme.

Die timelib und die dc1307 von Paul Stoffregen habe ich bereits herunter geladen und eingebunden.
Am WE (ich denke morgen Abend) werde ich versuchen gem. deiner Konversation mit Benziner das TimeRTC-Example aufzubauen.

ich habe dir in Beitrag #60 drei Tipps gegeben. Hast du irgendwas davon ausprobiert?

Hallo noiasca,

leider noch nicht, da ich eine recht stressige Woche hinter mir habe ......kennt bestimmt jeder ....die Woche vor dem Sommerurlaub :slight_smile: .....my-xy und ich haben in der Vergangenheit recht erfolgreich das Projekt vorangetrieben und möchte mich vorrangig darauf konzentrieren.
Ich bin aber für deine konstruktiven Beiträge sehr dankbar. Es kann einen nur schlauer machen.

:vulcan_salute:

Hallo my-xy,

ich habe versucht die Uhr gem. Dialog zwischen dir und Benziner aufzubauen, leider bekomme ich folgenden Fehler:

Blockquote
E:\Gartenbewässerung\Arduino-210722\UHR\UHR\UHR.ino: In function 'void setup()':
UHR:25:13: error: no matching function for call to 'LiquidCrystal_I2C::begin()'
In file included from E:\Gartenbewässerung\Arduino-210722\UHR\UHR\UHR.ino:9:0:
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:58:8: note: candidate: void LiquidCrystal_I2C::begin(uint8_t, uint8_t, uint8_t)
void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS );
^~~~~
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:58:8: note: candidate expects 3 arguments, 0 provided
exit status 1
no matching function for call to 'LiquidCrystal_I2C::begin()'

Den Code habe ich angehangen
UHR.ino (1.1 KB)

Da muss bei Dir vermutlich lcd.init(); stehen.
(Die erste Zahl ist die betreffende Zeile)

Die Ausgabe sieht auf den ersten Blick nicht schlecht aus - ich kanns momentan nur kompilieren und das macht es.

Da siehst Du dann auch, das Du das ganze selber rechnen nicht brauchst.

...so jetzt läuft es durch, dennoch bekomme ich folgenden Fehler:

Blockquote
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp: In member function 'void LiquidCrystal_I2C::begin(uint8_t, uint8_t, uint8_t)':
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp:66:39: warning: unused parameter 'cols' [-Wunused-parameter]
void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
^~~~
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp: In member function 'void LiquidCrystal_I2C::setDelay(int, int)':
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp:307:39: warning: unused parameter 'cmdDelay' [-Wunused-parameter]
void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {}
^~~~~~~~
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp:307:52: warning: unused parameter 'charDelay' [-Wunused-parameter]
void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {}
^~~~~~~~~
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp: In member function 'uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t)':
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp:310:50: warning: unused parameter 'graphtype' [-Wunused-parameter]
uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype){return 0;}
^~~~~~~~~
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp: In member function 'void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t, uint8_t, uint8_t, uint8_t)':
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp:311:55: warning: unused parameter 'row' [-Wunused-parameter]
void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){}
^~~
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp:311:68: warning: unused parameter 'column' [-Wunused-parameter]
void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){}
^~~~~~
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp:311:84: warning: unused parameter 'len' [-Wunused-parameter]
void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){}
^~~
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp:311:98: warning: unused parameter 'pixel_col_end' [-Wunused-parameter]
void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){}
^~~~~~~~~~~~~
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp: In member function 'void LiquidCrystal_I2C::draw_vertical_graph(uint8_t, uint8_t, uint8_t, uint8_t)':
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp:312:53: warning: unused parameter 'row' [-Wunused-parameter]
void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){}
^~~
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp:312:66: warning: unused parameter 'column' [-Wunused-parameter]
void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){}
^~~~~~
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp:312:82: warning: unused parameter 'len' [-Wunused-parameter]
void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){}
^~~
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp:312:96: warning: unused parameter 'pixel_row_end' [-Wunused-parameter]
void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){}
^~~~~~~~~~~~~
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp: In member function 'void LiquidCrystal_I2C::setContrast(uint8_t)':
C:\Users\VB\Documents\Arduino\libraries\LiquidCrystal_I2C\LiquidCrystal_I2C.cpp:313:45: warning: unused parameter 'new_val' [-Wunused-parameter]
void LiquidCrystal_I2C::setContrast(uint8_t new_val){}
^~~~~~~

Siehe Code:
UHR-01.ino (1.1 KB)

Lerne zwischen warning und error zu unterscheiden.
Du solltest aber auch die Ursache von warnings beseitigen. unused parameter sagt, dass Du einen Wert übergibst, den aber nicht benutzt, die Übergasbe nach Ansicht des Kompilers also sinnlos ist.

Gruß Tommy

Grundsätzlich ja.

Sieht mir hier aber so aus als kämen die alle aus der Library. Ich lasse das dann meist so oder verwende eine andere (wenn verfügbar).

vielen Dank für deinen Hinweis.

Habe vorhin das Board angeschlossen und den Code übertragen.

Dabei sind weder Warnungen noch Error Meldungen ausgegeben worden. :thinking:

Hallo my_xy,

habe den code (siehe Anhang) um die Tasten erweitert.

ist das so in Ordnung?

UHR-02.ino (1.3 KB)

Geht das stellen der Uhr? Ja - Dann ist es schick.
Mal sehen, ob ich morgen an Hardware komme. Dannkomm ich mit einem Array-Angebot.

Beste Grüße