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
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
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
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.