Betriebsstundenzähler

Hi Leute

Ich habe schon einen sehr umfangreichen Sketch gebaut. Dieser beinhaltet die Ansteuerung eines Touchscreen (inkl. Sleeptimer, Helligkeitsregelung usw.), eine Pumpensteuerung, 3 Temperaturmessungen, einen selbst gebauten Regler (auch mit Hilfe des Forums hier) für eine Differenztemperatursteuerung usw.

Das einzige, was ich jetzt noch gerne machen möchte, wäre ein Betriebsstundenzähler.

Soll so ablaufen.

Sobald die Pumpe eingeschaltet wird, soll die Zeit laufen, wenn die Pumpe stoppt soll sie wieder angehalten werden. Sobald wieder eingeschaltet wird, soll die Zeit weiterläufen.
Ich komme einfach nicht darauf, wie ich das machen sollte.
Zuerst fiel mir natürlich millis ein.
Dazu könnte ich den Einschaltzeitpunkt und den Ausschaltzeitpunkt merken und dann die Differenz bilden und zu einer gemerkten Zeit dazuaddieren. Schön und gut, aber wenn die Pumpe gerade läuft, wird der Zählerstatus ja nicht geändert, da ja erst die Differenz gebildet wird, wenn die Pumpe wieder ausgeschaltet wird..

Weiters möchte ich diese Zeit einmal am Tag gerne in den EEPROM schreiben

Ich hoffe, ihr könnt mir dabei helfen

LG

Schön und gut, aber wenn die Pumpe gerade läuft, wird der Zählerstatus ja nicht geändert, da ja erst die Differenz gebildet wird, wenn die Pumpe wieder ausgeschaltet wird..

Und wieso ist ein Problem?

Du kannst den Gesamt-Zähler beim Ausschalten aktualisieren. Das reicht doch. Und dann vielleicht jedesmal um Mitternacht im EEPROM speichern.

arduino_89:
Dazu könnte ich den Einschaltzeitpunkt und den Ausschaltzeitpunkt merken und dann die Differenz bilden und zu einer gemerkten Zeit dazuaddieren. Schön und gut, aber wenn die Pumpe gerade läuft, wird der Zählerstatus ja nicht geändert, da ja erst die Differenz gebildet wird, wenn die Pumpe wieder ausgeschaltet wird..

Weiters möchte ich diese Zeit einmal am Tag gerne in den EEPROM schreiben

Du kannst die Betriebszeit genau so von einem zum nächsten Durchlauf der loop-Funktion um 0, 1 oder 2 Millisekunden weiterzählen, oder je nachdem wie lange ein Durchlauf der loop-Funktion dauert.

Dass Du die Betriebszeit aus der Differenz von Aus- und Einschaltzeit bildest, ist nicht in Stein gemeißelt, sondern wenn Du der Programmierer bist, kannst Du es Dir frei aussuchen, was Du programmierst.

In der Steuerungstechnik macht man so was in einem Zeit-OB

Kannst ja beim Arduino z.B. alle Sekunden ein Unterprogramm aufrufen. In dem addierst du zu einer 32Bit-Zahl immer eins dazu, wenn die Pumpe läuft. Dann hast du einen Betriebssekundenzähler. Kannst du dann ja /3600 teilen und hast die Betriebsstunden.
Selbst wenn die Pumpe dauernd läuft, reicht der Zähler, wenn ich richtig gerechnet habe, ca 130 Jahre

Wenns nicht so genau gehen muss, kann man z.B. auch alle 10 Sekunden aufrufen. Hängt davon ab, wie lange und wie oft du deine Pumpe schaltest.

Serenifly:
Und wieso ist ein Problem?

Du kannst den Gesamt-Zähler beim Ausschalten aktualisieren. Das reicht doch. Und dann vielleicht jedesmal um Mitternacht im EEPROM speichern.

Grundsätzlich wäre es kein Problem, da hast du Recht. Aber ich will es einfach so haben, dass er "sofort" aktualisiert wird. Gibt sonst keinen Grund, hat also so gesehen keine Relevanz.

jurs:
Du kannst die Betriebszeit genau so von einem zum nächsten Durchlauf der loop-Funktion um 0, 1 oder 2 Millisekunden weiterzählen, oder je nachdem wie lange ein Durchlauf der loop-Funktion dauert.

Das verstehe ich leider nicht so wirklich.

jurs:
Dass Du die Betriebszeit aus der Differenz von Aus- und Einschaltzeit bildest, ist nicht in Stein gemeißelt, sondern wenn Du der Programmierer bist, kannst Du es Dir frei aussuchen, was Du programmierst.

Das ist mir klar, daher habe ich mich ans Forum gemeldet. Das war ja nur ein Denkansatz von mir, wie es eventuell gehen könnte. Nicht mehr und nicht weniger

hk007:
In der Steuerungstechnik macht man so was in einem Zeit-OB

Kannst ja beim Arduino z.B. alle Sekunden ein Unterprogramm aufrufen. In dem addierst du zu einer 32Bit-Zahl immer eins dazu, wenn die Pumpe läuft. Dann hast du einen Betriebssekundenzähler. Kannst du dann ja /3600 teilen und hast die Betriebsstunden.
Selbst wenn die Pumpe dauernd läuft, reicht der Zähler, wenn ich richtig gerechnet habe, ca 130 Jahre

Wenns nicht so genau gehen muss, kann man z.B. auch alle 10 Sekunden aufrufen. Hängt davon ab, wie lange und wie oft du deine Pumpe schaltest.

Dieser Vorschlag gefällt mir am Besten. Ich glaube so werde ich es machen. Ich hoffe nur, dass dann der Arduino nicht zu sehr ausgelastet ist, dass er auf Touchscreen Eingaben fast nicht mehr reagiert. Hab schon mehrerer solcher Abfragen laufen. Muss ich mal ausprobieren.

Aber eine Frage bleibt dann weiterhin. Wie kann ich diese Zahl in den EEPROM speichern? Ich habe mal nachgesehen, eine 4 Byte Variable wäre z.B. long. Diese Zahl müsste ich also in 4 Teile zerlegen, ich weiß aber nicht wie ich das mache. Kenne nur den Trick mit lowbyte und highbyte, was ich hier ja nicht anwenden kann. Jetzt fällt mir gerade ein, ich könnte die Sekunden ja in Stunden umrechnen und diese Zahl als Int Zahl speichern?!?
um diesen Wert dann alle 24h zu speichern, könnte ich ja mit der millis abfrage arbeiten und dann diese zahl mit "letzten merker zahl + 24h (86400000ms)" vergleichen und dann speichern oder?

Übrigens, laut meiner Recherche kann z.B. long 2^31-1 als Zahlenwert speichern, dass wären dann ca. 68 Tage wenn die Pumpe 24h am Tag laufen sollte.

Dir ist aber schon klar, daß ein fertiger Betriebsstundenzähler weniger kostet als ein Arduino: Amazon.de : betriebsstundenzähler

arduino_89:
Aber eine Frage bleibt dann weiterhin. Wie kann ich diese Zahl in den EEPROM speichern? Ich habe mal nachgesehen, eine 4 Byte Variable wäre z.B. long.

Hi,
hab mir mal mit Hilfe des Forums zwei Treiber fürs Speichern und Lesen einer Long geschrieben:

//==================================================================
unsigned long Eeprom_Read_LongInt (unsigned int addr)
{
      unsigned long result;
      byte *ptr = (byte *)&result;
      byte i;
      for (i=0;i<4;i++)
          *(ptr+3-i)=EEPROM.read(addr++);
      return result;
}
//==================================================================
void Eeprom_Write_LongInt (unsigned int addr,unsigned long data)
{
      byte *ptr= (byte *)&data;
      byte i;
      for (i=0;i<4;i++)
            EEPROM.write(addr++,*(ptr+3-i));
}
//==================================================================

arduino_89:
Übrigens, laut meiner Recherche kann z.B. long 2^31-1 als Zahlenwert speichern, dass wären dann ca. 68 Tage wenn die Pumpe 24h am Tag laufen sollte.

Bei 2^31 hast du auch ein Vorzeichen. brauchst du aber nicht. Also unsigned long verwenden.
Und deine Rechnung kann ich nicht so ganz nachvollziehen.
2^32 /60sek/60min/24h/365Tage --> 136,2 Jahre. (Schaltjahre nicht berücksichtigt)

arduino_89:
Aber eine Frage bleibt dann weiterhin. Wie kann ich diese Zahl in den EEPROM speichern? Ich habe mal nachgesehen, eine 4 Byte Variable wäre z.B. long. Diese Zahl müsste ich also in 4 Teile zerlegen, ich weiß aber nicht wie ich das mache.

Viel zu umständlich:
Dafür gibts hier im Forum fertige Funktionen:

#include <EEPROM.h>


void EEPromSave(byte* wert, int numbytes, int eprom_offset)
{
  // input:
  // wert: pointer to byte array which holds the value to save
  // numbytes: number of bytes to be saved
  // eprom_offset: offset in EEPROM for saving bytes
  // output: void (nothing)
  for (int i=0;i<numbytes;i++)
    EEPROM.write(eprom_offset+i, wert[i]);
}

void EEPromLoad(byte* wert, int numbytes, int eprom_offset)
{
  // input:
  // wert: pointer to byte array which takes the loaded value
  // numbytes: number of bytes to be loaded
  // eprom_offset: offset in EEPROM for loading bytes
  // output: void (nothing)
  for (int i=0;i<numbytes;i++)
    wert[i] = EEPROM.read(eprom_offset+i);
}


#define FLOATSAVEOFFSET 100

  byte myByteVar;
  int myIntVar;
  float myFloatVar;
  

void setup()
{
  Serial.begin(115200);
  
  EEPromLoad((byte*) &myByteVar, 1, 10);  // Wert von Adresse 10+1 aus EEProm holen.
  EEPromLoad((byte*) &myIntVar, 2, 11);  // Wert von Adresse 11+2 aus EEProm holen.
  EEPromLoad((byte*) &myFloatVar, 4, 13);  // Wert von Adresse 13+4 aus EEProm holen.
  Serial.print("Werte im EEProm Durchlauf: \t");
  Serial.print("myByteVar: \t");Serial.print(myByteVar);
  Serial.print("\tmyIntVar: \t");Serial.print(myIntVar);
  Serial.print("\tmyFloatVar: \t");Serial.println(myFloatVar);

  myByteVar += 7;      // Wert verändern.
  myIntVar = (myIntVar +5) * 2.5;  // Wert verändern.
  myFloatVar = (myFloatVar +5) * 1.47;  // Wert verändern.
  
  EEPromSave((byte*) &myByteVar, 1, 10);  // Wert von Adresse 10+1 in EEProm Speichern.
  EEPromSave((byte*) &myIntVar, 2, 11);  // Wert von Adresse 11+2 in EEProm Speichern.
  EEPromSave((byte*) &myFloatVar, 4, 13);  // Wert von Adresse 13+4 in EEPromSpeichern.
    
}

void loop()
{
}

Auf diese Weise kannst du auch ganze Arrays oder Structs mit einem Befehl abspeichern.

Wenn du dir die Mühe machst, den Überlauf von Hand zu bearbeiten, dann kannst du beliebig lange Zahlen erzeugen.

arduino_89:
Ich hoffe nur, dass dann der Arduino nicht zu sehr ausgelastet ist, dass er auf Touchscreen Eingaben fast nicht mehr reagiert. Hab schon mehrerer solcher Abfragen laufen. Muss ich mal ausprobieren.

Das glaub ich eher nicht. Alle Sekunden zu einer Zahl eins dazu addieren, ist doch nichts.
Kommt darauf an, wie du es programmiert hast.

ich habe es mal für eine "Zeitschaltuhr" so gemacht:

void loop(){
// Aufruf des Unterprogrammes alle Sekunden
  if ((long) (millis() - IntSub) >=0) {
  SubSec ();
  IntSub += 1000;
  }
...

und dann ich der SubSec() die Aktionen reingeschrieben, die alle Sekunden durchgeführt werden. Also in deinem Fall: "Betriebssekundenzähler ++"

arduino_89:
Ich hoffe nur, dass dann der Arduino nicht zu sehr ausgelastet ist, dass er auf Touchscreen Eingaben fast nicht mehr reagiert.

So lahm bist du mit 16MHz nun auch nicht. Du musst das alles nur so programmieren, dass deine Funktionen nur kurz was machen und dann nach loop() zurückkehren. Und nicht irgendwo warten bis ein Ereignis eingetreten ist.

arduino_89:
Das verstehe ich leider nicht so wirklich.

Anbei ein Betriebssekundenzähler, der Betriebssekunden an einem digitalen Pin zählt. Und zwar erfolgt die Fortschreibung direkt während der Pin eingeschaltet (im Beispiel HIGH) ist.

Das Beispielprogramm zählt die Einschaltzeit an der Pin-13 LED, deren Einschaltdauer durch eine Zufallsschaltung alle 5 bis 15 Sekunden abwechselnd ein und aus geschaltet wird.

Gezählt und zurückgeliefert werden millisekundengenau "ganze Einschaltsekunden", Bruchteile von Sekunden fallen weg, sobald ausgeschaltet wird.

unsigned long countSeconds(byte pin)
{
  static unsigned long lastRun;
  static unsigned long onCounter;
  static unsigned long milliRest;
  long now=millis();
  milliRest+= now-lastRun;
  if (digitalRead(pin))
  {
    while (milliRest>=1000)
    {
      onCounter++;
      milliRest-=1000;
    }
  }
  else milliRest=0;
  lastRun=now;
  return onCounter;
}

byte motorPin=13;
int zufallsSchaltdauer;


void setup() {
  Serial.begin(9600);
  pinMode(motorPin,OUTPUT);
  zufallsSchaltdauer=5000+random(10000);
}

unsigned long letzteSchaltung;

void loop() {
  if (millis()-letzteSchaltung>=zufallsSchaltdauer) // Hier wird das Umschalten gesteuert
  {
    digitalWrite(motorPin,!digitalRead(motorPin)); 
    zufallsSchaltdauer=5000+random(10000); // neue ZufallsSchaltdauer
    letzteSchaltung=millis();
  }
  Serial.print("Ein [s]: ");
  Serial.println(countSeconds(motorPin)); // Hier wird die Einschaltdauer gemessen und angezeigt
}

Hallo

Ich habe für mein Aquarium Heizstab der mittels Temperatursensor über den Arduino gesteuert wird
ein Betriebsstundenzähler geschrieben der ein mal am Tag die Sekunden ins EEPROM schreiben.

// BetriebsstundenzaehlerEEPROMex.ino
#include <Time.h>
#include <EEPROMex.h>


#define Heizung 20		//Pinbelegung Heizung


unsigned int Startsikunden;
unsigned int Betriebssikunden;
unsigned int Betriebssikunden_Tag;
unsigned long Betriebssikunden_EEPROM;


int Status_Heizung;
int Status_Heizung_Zeit = 1;


void setup()
{
  pinMode(Heizung, OUTPUT);	//Heizung
}

void loop()
{
  Status_Heizung = digitalRead(Heizung);
  if(Status_Heizung == HIGH && Status_Heizung_Zeit == true)
  {
    Status_Heizung_Zeit = 0;

    Startsikunden = elapsedSecsToday(now());		// Verstrichene Sekunden seit Beginn des Tages
  }
  
  if(Status_Heizung = LOW && Status_Heizung_Zeit == false)
  {
    Betriebssikunden = elapsedSecsToday(now()) - Startsikunden;

    Betriebssikunden_Tag = Betriebssikunden_Tag + Betriebssikunden;

    Status_Heizung_Zeit = 1;
  }
  
  if(elapsedSecsToday(now()) == 0)
  {
  	Betriebssikunden_EEPROM = EEPROM.readLong(10);

  	Betriebssikunden_EEPROM = Betriebssikunden_EEPROM + Betriebssikunden_Tag;

    EEPROM.updateLong(10, Betriebssikunden_EEPROM);

    Betriebssikunden_Tag = 0;
  }
}

Ja ist mir klar, abgesehen davon, dass mein Arduino günstiger war, als die dort angebotenen Betriebsstundenzähler, möchte ich das selbst auf meinem Arduino realisieren. Man kann immer wieder fertige Produkte kaufen. Dann brauche ich aber auch keinen Arduino. Ich möchte das so programieren wie ich will und nicht was fertiges kaufen, sonst hätte ich das ja gemacht.

hk007:
Hi,
hab mir mal mit Hilfe des Forums zwei Treiber fürs Speichern und Lesen einer Long geschrieben:

//==================================================================

unsigned long Eeprom_Read_LongInt (unsigned int addr)
{
     unsigned long result;
     byte *ptr = (byte *)&result;
     byte i;
     for (i=0;i<4;i++)
         *(ptr+3-i)=EEPROM.read(addr++);
     return result;
}
//==================================================================
void Eeprom_Write_LongInt (unsigned int addr,unsigned long data)
{
     byte *ptr= (byte )&data;
     byte i;
     for (i=0;i<4;i++)
           EEPROM.write(addr++,
(ptr+3-i));
}
//==================================================================

Danke für den Treiber, ich habe zwar nicht diesen ausprobiert, da für mich der nächste (den ich gleich nochmal zitiere) besser gefallen hat und für mich verständlicher war

hk007:
Bei 2^31 hast du auch ein Vorzeichen. brauchst du aber nicht. Also unsigned long verwenden.
Und deine Rechnung kann ich nicht so ganz nachvollziehen.
2^32 /60sek/60min/24h/365Tage --> 136,2 Jahre. (Schaltjahre nicht berücksichtigt)

ok, ich habe nicht die unsigned long variable herangezogen, sondern die long variable. Dadurch habe ich mit 2^31 gerechnet und kam daher auf ein anderes Ergebnis.
Mit 2^32 stimmt deine Rechnung natürlich schon.
Werde auch diese Variable für meinen Zähler verwenden. Ich hoffe allerdings, dass es kein Problem gibt, wenn millis aus dem Ruder läuft (overflow). Sonst muss ich halt hin und wieder mal den Reset Knopf drücken, damit es dazu nicht kommt

Vielen Dank für deine Beiträge :slight_smile:

guntherb:
Viel zu umständlich:
Dafür gibts hier im Forum fertige Funktionen:

Auf diese Weise kannst du auch ganze Arrays oder Structs mit einem Befehl abspeichern.

Wenn du dir die Mühe machst, den Überlauf von Hand zu bearbeiten, dann kannst du beliebig lange Zahlen erzeugen.

Danke auch dir sehr für diesen Beitrag. Habe deine Schnipsel schon in meinen Code eingebaut und es funktioniert perfekt. Habe damit eine Highscore Seite auf meinem Display gebastelt. Hoch und Tiefstwerte werden damit in den EEProm geschrieben (alles float Variablen). Und das für alle 3 Sensoren. Hatte ich gerade eben alles eingebaut und funktioniert perfekt :slight_smile:

Den letzten Satz habe ich allerdings nicht ganz verstanden. Wann sollte der Überlauf auftreten? Wenn meine Zahl mehr als die 4 Bytes beansprucht? Habe übrigens die "float" Variante gewählt, und daher 4 Bytes ausgewählt, was bei unsigned long ja auch passen wird. Eine höhere Variable habe ich auf die schnelle nicht gefunden, aber unsigned long reicht für meine Zwecke locker.

hk007:
Das glaub ich eher nicht. Alle Sekunden zu einer Zahl eins dazu addieren, ist doch nichts.
Kommt darauf an, wie du es programmiert hast.

ich habe es mal für eine "Zeitschaltuhr" so gemacht:

void loop(){

// Aufruf des Unterprogrammes alle Sekunden
 if ((long) (millis() - IntSub) >=0) {
 SubSec ();
 IntSub += 1000;
 }
...



und dann ich der SubSec() die Aktionen reingeschrieben, die alle Sekunden durchgeführt werden. Also in deinem Fall: "Betriebssekundenzähler ++"

Danke auch dir. Ich habe schon diverse "Unterprogramme" geschrieben mit einer If - Schleife die alle 1000ms aufgerufen wird. Deine Variante ist zwar ähnlich aber nicht gleich.
Kannst du mir das kurz erklären?
was soll in dem Teil (long) drinnstehen? meine Variable für den Stundenzähler?
was passiert da: (long) (millis....) ? Damit meine ich was mit den werten long und den wert als ergebnis in der zweiten klammer?
die Funktion SubSec(); kenne ich noch nicht, muss ich mal nachlesen
IntSub += 1000 ist wohl der Intervall oder? und die Variable intsub muss als int zahl deklariert werden oder?

Serenifly:
So lahm bist du mit 16MHz nun auch nicht. Du musst das alles nur so programmieren, dass deine Funktionen nur kurz was machen und dann nach loop() zurückkehren. Und nicht irgendwo warten bis ein Ereignis eingetreten ist.

Ok gut, also sollte das kein Problem sein. Mein Sketch wartet nirgends (delay kommt nicht vor, außer bei einer Touchscreen Eingabe, damit die Eingabe nicht 2 mal sofort ausgeführt wird). Von dem her sollte also alles kein Problem sein. Danke auch dir für den Hinweis

jurs:
Anbei ein Betriebssekundenzähler, der Betriebssekunden an einem digitalen Pin zählt. Und zwar erfolgt die Fortschreibung direkt während der Pin eingeschaltet (im Beispiel HIGH) ist.

Das Beispielprogramm zählt die Einschaltzeit an der Pin-13 LED, deren Einschaltdauer durch eine Zufallsschaltung alle 5 bis 15 Sekunden abwechselnd ein und aus geschaltet wird.

Gezählt und zurückgeliefert werden millisekundengenau "ganze Einschaltsekunden", Bruchteile von Sekunden fallen weg, sobald ausgeschaltet wird.

unsigned long countSeconds(byte pin)

{
 static unsigned long lastRun;
 static unsigned long onCounter;
 static unsigned long milliRest;
 long now=millis();
 milliRest+= now-lastRun;
 if (digitalRead(pin))
 {
   while (milliRest>=1000)
   {
     onCounter++;
     milliRest-=1000;
   }
 }
 else milliRest=0;
 lastRun=now;
 return onCounter;
}

byte motorPin=13;
int zufallsSchaltdauer;

void setup() {
 Serial.begin(9600);
 pinMode(motorPin,OUTPUT);
 zufallsSchaltdauer=5000+random(10000);
}

unsigned long letzteSchaltung;

void loop() {
 if (millis()-letzteSchaltung>=zufallsSchaltdauer) // Hier wird das Umschalten gesteuert
 {
   digitalWrite(motorPin,!digitalRead(motorPin));
   zufallsSchaltdauer=5000+random(10000); // neue ZufallsSchaltdauer
   letzteSchaltung=millis();
 }
 Serial.print("Ein [s]: ");
 Serial.println(countSeconds(motorPin)); // Hier wird die Einschaltdauer gemessen und angezeigt
}

Auch dir schonmal im Vorraus ein großes Dankeschön.
So halbwegs verstehe ich deinen code schon. Muss ich mir aber noch genau anschauen, werde dir dann darauf nochmal gezielt zurückschreiben.
Nur eine Frage zwischendurch. Dein sketch prüft ob ein digitalpin high oder low ist. Funktioniert das auch, wenn ich den pin über den Arduino high bzw. low schalte? Also quasi könnte ich dann den Digital Pin überprüfen, wo mein Relais hängt, an dem die Pumpe angeschlossen ist? Dieser wird ja über den Arduino nach best. Kriterien ein und ausgeschaltet?

Ingo79:
Hallo

Ich habe für mein Aquarium Heizstab der mittels Temperatursensor über den Arduino gesteuert wird
ein Betriebsstundenzähler geschrieben der ein mal am Tag die Sekunden ins EEPROM schreiben

Auch dir ein großes Danke. Das kommt meinen Fall ja schon sehr nahe. Ich habe gesehen du verwendest die Time Library? Hast du eine RTC angeschlossen?
Ich wollte auch meine RTC anschließen, allerdings habe ich keine pins mehr frei darfür :confused:
Display, Touchscreen, Temp.-Sensoren, Relais ist schon ziemlich viel bei mir.
Deinen Sketch selbst muss ich mir auch nochmal genauer ansehen, allerdings verwendest du die time library und wenn die nur mit der rtc geht, dann kann ich es leider nicht direkt verwenden.

Abschließend möchte ich nochmal allen danken, die mir dabei geholfen haben und weiterhin helfen :))

Musste jetzt den Code nochmals etwas kürzen da ich schon die Speichergrenzen sehr sehr nahe gekommen bin und dabei hat der Arduino schonmal aufgehört zu arbeiten. Sketch Größe war dabei 31.982 Bytes (max 32.256)
War wohl kein RAM Overflow oder?
Jetzt bin ich wieder bei 30.878 Bytes (von einem Maximum von 32.256 Bytes), da geht sich hoffentlich der Betriebsstundenzähler noch aus.

Hallo

Ich stelle die time library über ein Unix Zeitstempel aus dem Internet. Du braust keine RTC. Wie stellst du den deine Uhr oder was benutzt du als zeit Angabe?

Hi

Ok verstehe. Ich stelle meine Uhr im Arduino gar nicht, da ich sie nicht zwingend benötige. Meine Pumpensteuerung hängt alleine von den Temperaturen ab. Eventuell baue ich noch eine Zeit ein, um vl. eine Statistik zu führen, müsste diese dann über das Display einstellbar machen, da ich wie gesagt die RTC nicht einsetzen kann. Eventuell mache ich dass dann aber erst mit dem großen Bruder des Arduino Uno's

arduino_89:
Danke auch dir. Ich habe schon diverse "Unterprogramme" geschrieben mit einer If - Schleife die alle 1000ms aufgerufen wird. Deine Variante ist zwar ähnlich aber nicht gleich.
Kannst du mir das kurz erklären?
was soll in dem Teil (long) drinnstehen? meine Variable für den Stundenzähler?
was passiert da: (long) (millis....) ? Damit meine ich was mit den werten long und den wert als ergebnis in der zweiten klammer?
die Funktion SubSec(); kenne ich noch nicht, muss ich mal nachlesen
IntSub += 1000 ist wohl der Intervall oder? und die Variable intsub muss als int zahl deklariert werden oder?

  • Der Code ist hier geklaut. Ist aber recht gut beschrieben, warum es so gemacht wird (Stichwort Rollover nach 49 Tagen)
  • SubSec() wirst du im Internet nicht viel finden. :wink: Ist ein Unterprogramm, das ich alle Sekunden aufrufe. --> Sub=Subroutine; Sec= alle Sekunden. Hier könntest du z.B. deinen Betriebssekundenzähler um eins erhöhen.
  • intsub ist keine Integer, sondern eine unsigned long. (Siehe Link). Das int hier soll für mich ein Hinweis auf einen Interrupt sein. (Jeder hat so seine eigene Gedankenstruktur)
  • IntSub += 1000. Ja, hier erhöhe ich die Zielzeit um 1000ms

ok, ich habe nicht die unsigned long variable herangezogen, sondern die long variable. Dadurch habe ich mit 2^31 gerechnet und kam daher auf ein anderes Ergebnis.

Auch mit 2^31 stimmt deine Rechnung nicht, bzw. hast du Tage mit Jahre verwechselt. Nur so nebenbei.... :wink:

arduino_89:
Den letzten Satz habe ich allerdings nicht ganz verstanden. Wann sollte der Überlauf auftreten? Wenn meine Zahl mehr als die 4 Bytes beansprucht? Habe übrigens die "float" Variante gewählt, und daher 4 Bytes ausgewählt, was bei unsigned long ja auch passen wird. Eine höhere Variable habe ich auf die schnelle nicht gefunden, aber unsigned long reicht für meine Zwecke locker.

Das mit dem Überlauf hat nichts mit dem EEprom zu tun, sonder nur damit dass du eventuell grössere Zahlen als unsigned long brauchst. wenn du über 0xFFFFFFFF hinaus gehst, dann da bekommst du einen Überlauf auf 0x00000000.
Wenn du diesen Überlauf in deinen Rechnungen abfängst und in eine zweite Variable umleitest, dann kannst du Zahlen bis 2^64 darstellen.

Aber das Problem hast du ja inzwischen anders gelöst.