Durchschnitt einer Variable berechnen

mpe86at

Level-1
Beiträge
26
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen.

Mal eine kurze Frage:
Wie würdet ihr den Durchschnitt einer Variable über eine fortlaufende Zeit berechnen.
Min/Max ist ja kein Problem, aber für den Durchschnitt habe ich keine "Speicherschonende" Lösung parat.

Mein erster Ansatz war folgender:
Code:
L     "DB_TIC2406_01".TempIst
L     "DB_TIC2406_01".ZwischenWert
+D
T     "DB_TIC2406_01".ZwischenWert

L     "DB_TIC2406_01".Counter
L     1
+D
T     "DB_TIC2406_01".Counter

L     "DB_TIC2406_01".ZwischenWert
L     "DB_TIC2406_01".Counter
/D
T     "DB_TIC2406_01".TempDS

Aber mit dieser Variante würde ich sehr schnell in den Overflow der Variablen kommen.
Hat irgend jemand einen besseren Vorschlag?

Danke schon mal im Voraus
lg, Michael
 
Ich mach das immer so:
40% vom alten Wert + 60% vom neuen Wert:

Code:
L "DB_TIC2406_01".LetzterWert
DTR
L 4.000000e-001
*R
T #Zwischenwert_R1

L "DB_TIC2406_01.TempIst
DTR
L 6.000000e-001
*R
T #Zwischenwert_R2

L #Zwischenwert_R1
L #Zwischenwert_R2
+R

TRUNC
T "DB_TIC2406_01".LetzterWert

Falls du die Daten in deinem DB in Real abspeicherst, braucht du die DTR und TRUNC-Funktionen nicht zu nutzen.
So mache ich das immer und das klappt ganz gut :)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke für die Antwort.

Aber ich denke nicht, dass das für mich nutzbar ist. Denn ich brauche den genauen Durchschnitt der Temperatur über einen variablen Zeitraum. Einmal sind das 100s und ein anderes mal eine Stunde.

Dein Beispiel ist aber eher eine Glättung der Variable und nicht der Durchschnitt. Oder?

lg, Michael
 
Jain. Es berechnet auch schon den Durchschnitt. Aber halt immer. Über bestimmte Zeiträume geht das natürlich nicht (stand im übrigen in deinem 1. Post nicht drin).
Wenn du das aber mal in einer Excel-Tabelle nachstellst, wirst du sehen, das zum Durchschnitt Abweichungen erst ab der 2. Kommastelle auftreten.
Mit dem Verschieben der Prozente (50/50 oder 30/70) kann man das "Verhalten" auch bissel anpassen. Aber einer bestimmten Prozent-Zahl wird es dann kein
Durchschnitt mehr sondern geht dann wirklich in Richtung Glättung.
Wenn man es genauer braucht, dann wird es wohl Speicherhungrig nur gehen.
 
Wie schnell ändert sich denn deine Temperatur?

Ich kann mir nicht vorstellen dass du nach einem Zyklus schon wieder einen neuen Wert aufnehmen musst weil du eine signifikante Änderung hast.
Wenn du nur alle 10s einen Wert brauchst kannst du dir ein FIFO über 360 Werte aufbauen...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie schnell ändert sich denn deine Temperatur?

Ich kann mir nicht vorstellen dass du nach einem Zyklus schon wieder einen neuen Wert aufnehmen musst weil du eine signifikante Änderung hast.
Wenn du nur alle 10s einen Wert brauchst kannst du dir ein FIFO über 360 Werte aufbauen...

Hallo zusammen.

Min/Max ist ja kein Problem, aber für den Durchschnitt habe ich keine "Speicherschonende" Lösung parat.

Das wäre auch mein Vorschlag, aber nicht sein Ziel :)
 
Hallo zusammen.

Mal eine kurze Frage:
Wie würdet ihr den Durchschnitt einer Variable über eine fortlaufende Zeit berechnen.
Min/Max ist ja kein Problem, aber für den Durchschnitt habe ich keine "Speicherschonende" Lösung parat.

Mein erster Ansatz war folgender:
Code:
L     "DB_TIC2406_01".TempIst
L     "DB_TIC2406_01".ZwischenWert
+D
T     "DB_TIC2406_01".ZwischenWert

L     "DB_TIC2406_01".Counter
L     1
+D
T     "DB_TIC2406_01".Counter

L     "DB_TIC2406_01".ZwischenWert
L     "DB_TIC2406_01".Counter
/D
T     "DB_TIC2406_01".TempDS

Aber mit dieser Variante würde ich sehr schnell in den Overflow der Variablen kommen.
Hat irgend jemand einen besseren Vorschlag?

Danke schon mal im Voraus
lg, Michael

Du könntest auch den Gleitender Mittelwert berechnen, somit musst nicht durch den Divisor die Aanzhal der Stützpunkte begrenzen.

Also


Neuer_Mittelwert = ( ( n - 1 ) * alter_Mittelwert + Messwert ) / n


10 12 14 12 15 12 13 ...

Wenn ich jeweils 3 Messwerte zusammenfasse, um die Mittelwerte zu berechnen, dann hab ich
( 10 + 12 + 14 ) / 3 = 36 / 3 = 12
( 12 + 14 + 12 ) / 3 = 38 / 3 = 12.666
( 14 + 12 + 15 ) / 3 = 41 / 3 = 13.666
( 12 + 15 + 12 ) / 3 = 39 / 3 = 13
( 15 + 12 + 13 ) / 3 = 40 / 3 = 13.333

und damit man das so rechnen kann, muss man immer die letzten 2 Messungen vorrätig halten. Bei 3 Werten geht das, bei 2000 Werten mag das ein Problem sein.
Man kanns aber auch anders machen. Da 12 der Mittelwert war, der bei der ersten Messung rausgekommen ist, kann ich den nächsten Mittelwert berechnen,
indem ich anstelle ( 12 + 14 + 12 ) / 3 einfach den zuletzt bekannten Mittelwert anstelle der ersten beiden (gemerkten) Messwerte einsetze
( 12 + 12 + 12 ) / 3 = 36 / 3 = 12 und analog das ganze mit den anderen jeweils neue dazugekommenen Messwerten

10 12 14 12 15 12 13

4. Messung: ( 12 + 12 + 12 ) / 3 = 36 / 3 = 12
5. Messung: ( 12 + 12 + 15 ) / 3 = 39 / 3 = 13
6. Messung: ( 13 + 13 + 12 ) / 3 = 38 / 3 = 12.666
7. Messung: ( 12.666 + 12.666 + 13 ) / 3 = 38.332 / 3 = 12.777
8. Messung: ( 12.777 + 12.777 + 10 ) / 3 = 35.554 / 3 = 11.851

Was fällt auf? Zunächst mal hinkt der Mittelwert etwas hinterher. Er reagiert nicht mehr so schnell auf die Änderung des Messwertes, wie das Original.
Daher auch 'gleitend' - weil er dem tatsächlichen Zahlenwert hinterhergleitet.
Wenn der Messwert sich auf einen Zahlenwert stabilisert, 'gleitet' der Mittelwert an diesen Wert heran.
 
Hallo zusammen.

Danke für die verschiedenen Lösungsansätze.

Ich denke, dass ich alle 10s einen Wert aufnehme und einen FIFO mache und über diesen werde ich dann den Mittelwert rechnen.

Danke für die Hilfe.

lg, Michael
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@TE:
dein eigener Ansatz ist natürlich am Präzisesten - gleichzeitig aber auch der Ansatz, der nicht besonders Resourcen- und CPU-Leistung-schonend ist.
Ich persönlich halte es bei so etwas mit dem von Krumnix genannten Weg - nur mit einer anderen Wichtung - bei mir "neuer Mittelwert := (10 * letzter Mittelwert + neuer Messwert) / 11". Man kann das aber beliebig variieren - denk mal drüber nach ...

Gruß
Larry
 
@TE:
dein eigener Ansatz ist natürlich am Präzisesten - gleichzeitig aber auch der Ansatz, der nicht besonders Resourcen- und CPU-Leistung-schonend ist.
Ich persönlich halte es bei so etwas mit dem von Krumnix genannten Weg - nur mit einer anderen Wichtung - bei mir "neuer Mittelwert := (10 * letzter Mittelwert + neuer Messwert) / 11". Man kann das aber beliebig variieren - denk mal drüber nach ...

Gruß
Larry

ja ja, die Wichtung....

der Vorteil dieses Ansatzes ist es ja auch, dass relativ schnell und rescourenschonend die Glättung verändert werden kann. Wenn du mal schnell auf "neuer Mittelwert := (100000 * letzter Mittelwert + neuer Messwert) / 100001" umstellen willst ist das auch kein Problem. Bei der FIFO-Variante macht das dann schon richtig Spaß.
 
Das du ein FIFO nennst, bedeutet das du den Durchschnitt über ein "Laufende Fenster" von den Zeit berechnen willst, oder ?
Die Antworten bis jetzt sind verschiedene Arten von Filterung.
Wenn du eine wahre Mittelwert benötigst, dann genügt es nicht mit eine Filterung (umgekehrt, ein Mittelwert kann als Filterung verwendet werden.).
Wenn du jede 10 s bis max 1 std, die Werte speicherst, dann wird das zu 360 INTs = 720 bytes, oder 360 REALs = 1440 bytes.
Eine Speicherschonende Ansatz wäre es ins mehrere FIFOs zu verteilen. Z.B. Erste FIFO hat 30 Register (= insgesamt 300 sek. = 30 INTs (*) = 60 Bytes). Den Mittelwert von diese FIFO wird in eine Weitere FIFO gespeichert mit z.B. 12 Register (= insgesamt 300x12 sek = 3600 sek = 1 Std. = 12 REALS = 48 Bytes). Den Speicherbedarf wird dann 60+48 bytes = 108 bytes. Nicht schlimm.

*: Erste FIFO kann die Rohwerte von den Analogeingang speichern, das sind INTs.

edit: Diese Verfahren ist auch nicht 100% genau. Jeden 300 sek. wird den Durchschnitt von 3600 sek. berechnet. In den Zwischenzeit wird den Durchschnitt zwischen 3300-3599 sek. berechnet.
 
Zuletzt bearbeitet:
Zurück
Oben