Forum: Mikrocontroller und Digitale Elektronik Betriebszeit erfassen


von Helper (Gast)


Lesenswert?

Hallo Forum

Folgende Situation:
Ich habe hier eine Schaltung, welche einen Schrittmotor ansteuert. Der 
Schrittmotor ist pro Tag ca. 2-3 mal im Einsatz, immer für rund 10 
Minuten. Genau diese Betriebszeit von rund 30 Minuten täglich soll 
gemessen werden.

Für die Speicherung der Betriebszeit habe ich an ein EEPROM gedacht, das 
dürfte ja nicht all zu schwer sein.

Was mir im moment eher den Kopf zerbricht, bzw. wobei ich nicht ganz 
sicher bin ich die Erzeugung einer "Referenz"zeit.

Mein uC wird mit einem externen Quarz betrieben, 40 MHz. Denke nicht 
dass es sonderlich schlau wäre, die Zeit direkt aus dem uC berechnen zu 
lassen. (Oder vielleicht doch?)

Gibt es irgendwelche Standards wie sowas gemacht wird?

Vielen dank für die Hilfe

von Karl H. (kbuchegg)


Lesenswert?

Helper schrieb:

> Mein uC wird mit einem externen Quarz betrieben, 40 MHz. Denke nicht
> dass es sonderlich schlau wäre, die Zeit direkt aus dem uC berechnen zu
> lassen.

Warum nicht?

Auf wiviele Mykrosekunden (millionstel Sekunden) genau musst du denn die 
Zeit kennen?
Mit einem Quarz bist du recht einfach bei weniger als 100 ppm (parts per 
million). Ob dein Quarz also tatsächlich 40 Millionen Schwingungen pro 
Sekunde macht oder ob es doch 40 Millionen und 56 sind, kann man also 
ohne nachzumessen nicht so genau sagen.
Aber summier dir das doch mal auf, wie lange es bei deinen Daten dauert 
(30 Minuten am Tag), bis sich dieser Fehler im schlimmsten Fall auf 1 
Sekunde addiert.
Wenn der Quarz arg daneben ist (kommt vor), dann kann man auch noch ein 
paar Tagen die tatsächliche Quarzfrequenz aus der Abweichung 
zurückrechnen und im Programm berücksichtigen.

Oder brauchst du die Zeit Atomuhr-genau auf tausendstel Nanosekunden 
genau?

von Helper (Gast)


Lesenswert?

Werde das mal durchrechnen...

Wie würde man das rein Software technisch am saubersten lösen? Vermute 
mal Timer wäre da die schlauste Variante oder?

Wie sieht es dann aus, wenn der uC regelmässig ein UART Interrupt 
aufgelösst bekommt? Stellt das irgendwelche Probleme bezüglich der 
Interrupts für den Timer? Dürfte bei den neueren uC's alles lösbar sein 
mit diesen Interrupt Prioritätslevel oder?

von Schlumpf (Gast)


Lesenswert?

Rechnen wir mal:

30 Min Messdauer pro Tag = 1800 Sekunden.
Fehler des 100ppm-Quarzes = 1800s *100 / 1.000.000 = 180ms.

Macht also ca 1s Fehler in 5-6 Tagen.

Falls du damit nicht leben kannst, nimm einfach einen besseren Quarz 
oder Quarzoszilator.

von Karl H. (kbuchegg)


Lesenswert?

Helper schrieb:
> Werde das mal durchrechnen...
>
> Wie würde man das rein Software technisch am saubersten lösen? Vermute
> mal Timer wäre da die schlauste Variante oder?

Natürlich.
Sobald in einer Aufgabenstellung das Wort 'Zeit' vorkommt, kann man 
seinen Allerwertesten darauf verwetten, dass der vernünftigste 
Lösungsweg über einen Timer führt.

> Wie sieht es dann aus, wenn der uC regelmässig ein UART Interrupt
> aufgelösst bekommt? Stellt das irgendwelche Probleme bezüglich der
> Interrupts für den Timer?

Deine UART legt ja nicht den µC für Stunden lahm. Dann kommt ein Timer 
Interrupt halt mal ein paar µs zu spät. Was aber nichts macht, denn der 
nächste kommt unabhängig davon dann wieder zum richtigen akkumulativen 
Zeitpunkt. D.h. deine Uhr 'hinkt' vielleicht kurzfristig um deine 
kleinste Zeiteinheit mal nach, holt das aber gleich darauf wieder auf. 
Ist deine kleinste Zeiteinheit eine Tausendstel Sekunde (für einen µC 
immer noch eine halbe Ewigkeit), dann ist die akkumulierte Zeit 
vielleicht mal etwas hinten, mit dem nächsten Timer Tick stimmt aber 
alles wieder, weil ja der Timer unabhängig vor sich hin tickt.
Es ist im Grunde wie eine Uhr die an der Wand hängt und die nur einen 
Sekundenzeiger hat (wodurch die regelmässig hinsehen musst um keine 
Minute zu verpassen). Nur weil du mal kurz keine Zeit hast aufs 
Zifferblatt zu sehen, verlierst du ja deswegen keine Zeit. Die Uhr läuft 
ja trotzdem unabhängig davon weiter, egal ob du Zeit hast aufs 
Zifferblatt zu sehen oder nicht. Erwischt du die Uhr nicht exakt im 
Zeitpunkt an dem der Sekundenzeiger auf 0 steht, dann erwischt du ihn 
eben bei 5 Sekunden das nächste mal. Deine Minuten hinken dann diese 5 
Sekunden lang hinten nach. Aber den nächsten 0-Durchgang kriegst du 
wieder zeitgerecht mit, so dass in Summe deine Minutenzählerei stimmt. 
Problematisch wird es erst, wenn du tatsächlich mal keine ganze Minute 
Zeit hast, auf die Uhr zu sehen und du 2 0-Durchgänge hintereinander 
verpasst. Aber diesen Fall hast du ja in einem µC nicht bzw. den kann 
man ganz leicht vermeiden. Unter anderem auch deshalb, weil die Dinger 
(die µC) eben so sauschnell sind, dass sie ~30 Millionen Instruktionen 
pro Sekunde abarbeiten können. Das holen eines Bytes von der UART und 
die Verarbeitung davon dauern vielleicht 100 bis 200 Takte. Damit bleibt 
ein erkleklicher Anteil an Instruktionen pro Sekunde übrig, selbst wenn 
die andere Seite der UART eine richtige QUasselstrippe ist.

von Philipp (Gast)


Lesenswert?

Was Karl Heinz sagt, ist absolut richtig!!!
Wenn du dennoch eine sehr genaue Zeit angabe brauchst kannst du eine RTC 
nehemn gibt es bis genauigkeiten <10ppm. Unterscheidet sich jedoch nicht 
sehr von einem guten Quarz. Vorteil du kannst gleichzeitig abspeichern 
wann (Datum Uhrzeit...) der Schrittmotor gelaufen ist. Weiterer Vorteil, 
ist unabhängig von Quarz und dementsprechend kann die genauigkeit der 
Zeit bei größeren Stückzahlen aus dem Design heruas garantiert werden.
Nachteil: Zusätzliches IC, Stromverbrauch, Platzverbrauch...
Hast du zugang zum Internet???
Dann würde ich es mittels SNTP lösen.

von Helper (Gast)


Lesenswert?

Schlumpf schrieb:
> Macht also ca 1s Fehler in 5-6 Tagen.
>
> Falls du damit nicht leben kannst, nimm einfach einen besseren Quarz
> oder Quarzoszilator.

Ich denke, damit komme ich gaaanz knapp klar. :P
Ne im ernst, reicht locker. Vielen dank für die Rechnung. :)

Karl Heinz schrieb:
> Natürlich.
> Sobald in einer Aufgabenstellung das Wort 'Zeit' vorkommt, kann man
> seinen Allerwertesten darauf verwetten, dass der vernünftigste
> Lösungsweg über einen Timer führt.

Sehr gut, dann lag ich da ja schonmal richtig.

Karl Heinz schrieb:
> Dann kommt ein Timer
> Interrupt halt mal ein paar µs zu spät

Okay. Verstehe ich das also richtig:
Wenn der uC gerade die Interrupt Routine für den UART abarbeitet und 
während dem ein Timerinterrupt auftritt, dann wird der Timerinterrupt 
direkt nach dem UART Interrupt ausgeführt, der Wert des Timers 
allerdings unabhängig von der abarbeitung der ISR bereits wieder weiter 
zählt?

Würde also heissen wenn z.B. jede Sekunde der Imter überläuft spielt es 
keine Rolle wann in der darauffolgenden Sekunde der Interrupt ausgelösst 
wird, der Timer zählt automatisch jede Sekunde wieder von 0?

Oder meintest du damit nur, dass die Abarbeitung der UART ISR so schnell 
sein sollte, dass es nicht ins Gewicht fällt?

(Spielt für meine Anwendung eigentlich keine Rolle mehr, meine UART ISR 
ist bestimmt kurz genug, ist gerade eher generelles Interesse).

von jemand (Gast)


Lesenswert?

Karl Heinz schrieb:
> Mykrosekunden

Karl Heinz?

von Helper (Gast)


Lesenswert?

Philipp schrieb:
> Nachteil: Zusätzliches IC, Stromverbrauch, Platzverbrauch...
> Hast du zugang zum Internet???
> Dann würde ich es mittels SNTP lösen.

Platz, Stromverbrauch undsoweiter sind absolut kein Problem. Das ganze 
soll nicht in Serie Produziert werden sondern dient als einmaliges 
Projekt. Von demher stören da paar mA nicht. ;)

Zugang zum Internet wäre vorhanden, überschreitet dann allerdings 
langsam mein Wissen. Müsste ich mich mal einlesen und schauen wie 
kompliziert das ganze ist, denke aber ich bleibe bei der Variante mit 
dem uC.

von Karl H. (kbuchegg)


Lesenswert?

Helper schrieb:

> Okay. Verstehe ich das also richtig:
> Wenn der uC gerade die Interrupt Routine für den UART abarbeitet und
> während dem ein Timerinterrupt auftritt, dann wird der Timerinterrupt
> direkt nach dem UART Interrupt ausgeführt, der Wert des Timers
> allerdings unabhängig von der abarbeitung der ISR bereits wieder weiter
> zählt?


Exakt.

> Würde also heissen wenn z.B. jede Sekunde der Imter überläuft spielt es
> keine Rolle wann in der darauffolgenden Sekunde der Interrupt ausgelösst
> wird, der Timer zählt automatisch jede Sekunde wieder von 0?

Genau

> Oder meintest du damit nur, dass die Abarbeitung der UART ISR so schnell
> sein sollte, dass es nicht ins Gewicht fällt?

Ich weiß nicht, welche Vorstellungen du davon hast, wie lange so etwas 
dauert. Was macht man denn in einer UART-ISR? Man holt sich das Zeichen, 
macht vielleicht noch ein paar kurze Chzecks auf Gültigkeit, speichert 
das empfangene Zeichen vielleicht noch in einem Buffer, tja. das wars 
dann aber auch schon. Recht viel mehr als 10 bis 20µs gehen da auf 
keinen Fall drauf. Und da hab ich bei 40Mhz schon großzügig geschätzt.
Im Vergleich zu der einen kompletten Sekunde (die du angenommen hast) 
also praktisch nichts. Und nach dieser Zeit sind die Interrupts wieder 
freigegeben, so dass der 1 Timer-Interrupt der zwischenzeitlich 
möglicherweise angefallen ist, jetzt (mit 20µs Verspätung) nachgeholt 
wird. Der Timer ist zwischendurch ja sowieso weiter gelaufen, so dass 
auf lange Sicht nichts verloren gegangen ist.

von Dietrich L. (dietrichl)


Lesenswert?

Karl Heinz schrieb:
> Deine UART legt ja nicht den µC für Stunden lahm. Dann kommt ein Timer
> Interrupt halt mal ein paar µs zu spät.

... was natürlich voraussetzt, dass die UART-Interruptroutine 
'ordentlich' geschrieben ist (d.h. ohne Warteschleifen) und der Timer 
ebenso 'ordentlich' arbeitet (d.h. der Timer hardwaremäßig frei läuft 
ohne Laden oder Resetten in der Interruptroutine).

Gruß Dietrich

von Philipp (Gast)


Lesenswert?

Eine ISR sollte prinzipiell so geschrieben werden, dass sie 
schnellstmöglich wieder verlassen wird. In jedem System unabhängig von 
den Anforderungen. Alles andere ist in meinen Augen ein unsauberer 
Programmierstiel

von Schlumpf (Gast)


Lesenswert?

Den Timer machst du als rundlaufenden Timer. Das heißt, es ist dann 
nichts anderes, als ein Hardware-Zähler im Prozessor, dem es völlig 
schnuppe ist, was deine Software gerade macht. Der Zähle einfach immer 
von einem Startwert bis 0x00 runter, löst einen Interrupt aus und fängt 
wieder von vorne an.
Ist deine SW gerade mit einem andern IRQ beschäftigt, so kann z.B. der 
Timer-Interrupt direkt im Anschluss an den anderen IRQ bearbeitet 
werden.

Zeitlich sieht das dann so aus
1
Timer        ------|----------|----------|----------|----------|---- 
2
Software Uhr ------1----------2--------------3------4----------5----
3
xy-IRQ       ---------------------------AKTIV-----------------------

von Helper (Gast)


Lesenswert?

Vielen lieben Dank für all die super schnellen und tollen Antworten!

Das mit dem ISR programmieren ist mir bekannt, dafür sorge ich schon 
dass der Code so klein wie möglich sein wird.

Vielen dank analle!

von Karl H. (kbuchegg)


Lesenswert?

Helper schrieb:
> Vielen lieben Dank für all die super schnellen und tollen Antworten!
>
> Das mit dem ISR programmieren ist mir bekannt, dafür sorge ich schon
> dass der Code so klein wie möglich sein wird.

Ja, aber Achtung:

so klein wie möglich bedeutet nicht, das man gar nichts machen darf.

zb wird man das hochzählen einer Uhr (Hundertstel, Sekunden, Minuten, 
Stunden) zur Gänze in der ISR machen und sich nicht nur 1 Flag setzen 
und das Hochzählen der Hauptschleife überlassen. So eine Uhr betrachtet 
man als 1 Einheit die als Einheit hochgezählt wird und nur aus 
technischen Gründen in Sekunden und Minuten zerfällt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.