Hallo,
habe Problem mit millis(), in einer " sekunde " fehlen mir zwei Einheiten.
will ein stromzehler bauen mit Arduino im Garten. Angeschlossen sind RTC ,DHT und zwei LCD über I2C.
Sehr warschanlich durch die interrupts dauern die millis() 1000 länger als sekunde
Was soll uns das jetzt sagen? Dass wir uns die Ursache erwürfeln sollen?
Wie meinst Du, wie wir Dir helfen können, ohne Deinen Sketch zu kennen.
Setze Deinen Code bitte in Codetags. (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Naja - da der Arduino nicht als Uhr konzipiert ist, wundert Das wenig.
Wenn Du eine Uhr haben willst, nimmst Du einen Chip, Der auf Genauigkeit getrimmt ist.
Das braucht der Arduino aber nicht, Der ist ein Rechenknecht.
Auch sind 1000 zu 1002 'Ticks' pro Sekunde ein sehr guter Wert - wird sich aber wohl schwer ändern, wenn der Arduino Mal wärmer/kälter ist oder Interrupts gesperrt werden (z.B. durch WS2812B).
Was hast Du vor und wofür brauchst Du Zeiten kleiner als eine Sekunde, Die Dir die RTC ebenfalls ausgeben kann.
MfG
PS: Ich habe eine Uhr laufen, in Der ich noch ca. 700 'Ticks' pro Sekunde bekomme - da der Sekundenzeiger animiert ist und nach einer Sekunde damit halt fertig sein sollte (die nächste Sekunde startet ja dann), nehme ich halt diese 700 (wird laufend angepasst wenn der Wert weiter sinkt) als Sekundenmaß.
fony:
Hallo,
habe Problem mit millis(), in einer " sekunde " fehlen mir zwei Einheiten.
will ein stromzehler bauen mit Arduino im Garten. Angeschlossen sind RTC ,DHT und zwei LCD über I2C.
Sehr warschanlich durch die interrupts dauern die millis() 1000 länger als sekunde
@ my_xy_projekt
wehre ja kein Problem jede µsek die Leistungmessen nur das Problem wurde dadurch nicht behoben,
als alter Aufzugsmonteur , gebe ich nicht auf der armer Arduino mit seinen 16MhZ wird Qualmen aber rechnen so wie ich will
Danke an ALLE
Melde mich wenn "das Ding rechnet" wie ich will
MfG
Bernhard
PS leider kann ich kein Englisch --- großer nachteil
fony:
@ my_xy_projekt
wehre ja kein Problem jede µsek die Leistungmessen nur das Problem wurde dadurch nicht behoben,
als alter Aufzugsmonteur , gebe ich nicht auf der armer Arduino mit seinen 16MhZ wird Qualmen aber rechnen so wie ich will
Danke an ALLE
Melde mich wenn "das Ding rechnet" wie ich will
Ich versteh noch nicht ganz das Problem. Ich bin geneigt zu behaupten, das Du einen Denkfehler hast.
Deinen Sketch hast Du noch immer nicht in Codetags gesetzt.
Du kannst das auch jetzt noch machen. Klicke auf Deiner Ursprungsnachricht auf "modify Message"; markiere den Text, der der Code ist und dann klicke oben auf der linken Seite im Editorfenster auf </>
Und jetzt zu Deiner Logik:
Du gehst das falsch an.
bei jedem Durchlauf schreibst Du den Display neu - vollkommen unsinnig, da Dein Auge das sowieso nicht schafft.
Die Aufgabe ist also:
In jedem Durchlauf von loop() U und I einlesen, P errechnen und aufsummieren.
Und nur jede Sekunde machst Du die Ausgabe auf dem Display.
Schreibe Deinen Code nicht komplett in loop() ; das macht keinen Sinn, ist unproduktiv und erschwert nur das debugen
PS leider kann ich kein Englisch --- großer nachteil
da auch ich nur deutsch kann, sehe ich darin keinen Nachteil.
Texte in Englisch lassen sich mit deepl.com übersetzen.
Wenn die Sprache exotischer wird, kann man sich auch von Google helfen lassen, deepl ist halt weniger datenhungrig ...
Zum Glück hat mein Schul-Englisch zumindest etwas gebracht - ohne deepl wäre ich aber ebenfalls aufgeschmissen - von Chinesisch ganz zu schweigen - hatte Mal einen chinesischen Elektro-Plan (Siebdruck-Presse ... wenn ich mich recht erinnere) - wenn man die Symbole gerafft hat, war's ganz einfach
Keine Kritik! Nur ein Hinweis. Wenn Du den Code vorher einmal mit STRG-T bearbeitest, werden die Einrückungen formatiert. Damit lässt sich der code dann auch besser lesen.
2 LCD's...
Und dann:
if (now.second() <= 5) // Umschalt zeit für LCD
{
auswahl = 1;
}
if (now.second() >= 10)
{
auswahl = 2;
}
if (now.second() > 25)
{
auswahl = 1;
}
if (now.second() > 30)
{
auswahl = 2;
}
if (now.second() > 45)
{
auswahl = 1;
}
if (now.second() > 50)
{
auswahl = 2;
}
switch (auswahl) //Anweisung für umschalten
Warum machst Du sowas?
Switch/Case kann auch 31 ... 45 bzw. 46 ... 50 oder 51 ... 59
Da benötigst Du keinen zusätzlichen Abfrageparameter.
Versuche Deinen Code in einzelne Bereiche zu unterteilen, jenachdem, was da passieren soll und lagere das aus dem loop() aus.
Würde in einer kleineren Einheit (und ohne float) rechnen.
Spannung und Strom sind bekannt oder in Erfahrung zu bekommen.
Beides multipliziert ergibt W (Watt).
Wenn ich Das jede Sekunde mache, habe ich Ws (Watt-Sekunden), Die ich wunderbar aufaddieren kann.
3600Ws=1Wh
Auch lassen sich Divisionen unterbinden, wenn man den Divisor zuvor auf true prüft:
if (Divisor) {
Ergebnis=Dividend/Divisor;
}
Wobei fraglich ist, wo man großartig mit unbekanntem Dividenden dividieren müsste.
Das heißt wenn du Sekunden haben möchtest den Rückgabewert durch 1000 teilen.
Wenn du die RTC verwendest, dann zähle die Hertztakte und mach deine Vergleiche mit denen.
Von der RTC bekommst Du ein Sekunden-Takt.
Intern guckst Du bei JEDEM Takt nach, wie viele millis() seit dem letzten Takt vergangen sind - DAS ist Deine aktuelle Sekunde (bzw. 110% davon - damit Du noch etwas Luft hast).
In Deinem Sketch rechnest Du weiterhin mit millis() - nur Du nimmst nicht die 1000 als 'Dauer einer Sekunde', sondern den ausgemessneen Wert - bei meiner Uhr irgendwas um 700.
Nach 70 0 millis() ist also 1/10tel Sekunde bei mir vorbei - Zeit, für den nächsten Schritt der Animation.
So bin ich mit der Animation fertig, bevor die nächste Sekunde 'zuschlägt' und mir ggf. die 'Zeit' - also meine 700 'Ticks' noch weiter reduziert - weil der Arduino irgend wofür länger brauchte, als vorher - dann sind's halt ab Jetzt nur noch 698 'Ticks', Die ich zur Verfügung habe - dann startet mein 2.ter Schritt eben nicht nach 70 'Ticks', sondern bereits nach 69(komma 8 ... eigentlich).
Die Sekunden sind nur, damit der Arduino 'im Takt' bleibt.
Zusätzlich zum 'Mitzählen' der Sekunden (damit Du die aktuelle Uhrzeit hast), kannst Du alle paar Stunden die Uhrzeit aus der RTC auslesen, um ggf. Ungenauigkeiten auszugleichen.
MfG
Edit
Nachgerechnet und entschieden, eine Null zu streichen - waagerecht
postmaster-ino:
In Deinem Sketch rechnest Du weiterhin mit millis() - nur Du nimmst nicht die 1000 als 'Dauer einer Sekunde', sondern den ausgemessneen Wert - bei meiner Uhr irgendwas um 700.
Nach 700 millis() ist also 1/10tel Sekunde bei mir vorbei
er kann auch das komplette Datum der RTC zyklisch auslesen seine "Zeit" bilden, nach dem Unix Format.
Dann muss er sich nicht um den eingehenden 1s Takt kümmern.
Er muss die RTC Zeiten nicht mit millis vergleichen. Wofür auch?
millis wird nur für einen zyklisch gebremsten Aufruf zum RTC ansteuern benötigt.
Wenn ich etwas aller einer RTC genauen Minute machen möchte und frage die RTC aller ungenauen millis 100ms ab, dann pendelt der Abfragefehler konstant maximal um die 100ms jeder Minute herum. Was ja nun nicht stören sollte für ein Stromzähler.