# \[Erledigt\] Messwerte auf SD-Karte, Mittelwert bilden

**URL:** <https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732>\
**Category:** Deutsch\
**Created:** [January 12, 2014, 11:21am UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732 "2014-01-12T11:21:15Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [January 12, 2014, 11:21am UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/1 "2014-01-12T11:21:15Z")

</div>

Hallo,

kurz zu mir: ich heiße Jan, bin 14 Jahre alt und komme aus dem Südwesten Deutschlands.  
Als Hobby gestalte ich Webseiten und programmiere "Webanwendungen" in PHP (mit ein bisschen SQL).

Als erstes richtiges Projekt habe ich mir vorgenommen, einen Datenlogger mit dem Arduino UNO, dem Ethernet Shield und dem Datalogging Shield zu konstruieren.  
Das Alles geht schonmal:  
Am UNO hängen verschiedene Sensoren (Ultraschallentfernungssensor, Temperatursensoren, Niederschlagsmesser, ...). Die Uhrzeit bekomme ich von der Uhr auf dem Datalogging Shield. Die Sensoren werden im Sekundentakt ausgelesen und die Werte an einem I²C-Bus Display ausgegeben. Mit einem Drehencoder kann man bestimmen, welcher Sensorwert am Display angezeigt werden soll.

Damit ich die Werte auch schön visualisieren kann müssen sie in meine MySQL-Datenbank. Das habe ich mit so vorgestellt:  
Die Werte werden im Sekundentakt auf die SD-Karte geschrieben (in eine CSV-Datei). Alle 10 Min wird ein Mittelwert, von Werten auf der SD-Karte gebildet und die Mittelwerte werden per Ethernet Shield auf den Webserver geschoben. Danach werden die Werte auf der SD-Karte gelöscht.  
Heißt also, ich messe jede Sekunde, aber übertrage nur 10 Min-Mittelwerte auf den Webserver. Und als Datenablage dient die SD-Karte.

Wie ich Messwerte auf die SD-Karte schreibe ist kein Problem, das Problem ist wie ich die 300 Messwerte von der SD-Karte auslese und den Mittelwert bilde und und anschließend die Messwerte aus der CSV lösche.

Nun meine Frage: Gibt's irgendwo gute Tutorials zum Thema "Lesen von Werten aus einer CSV von SD-Karte" oder hat jemand hier schonmal das Selbe gemacht und noch einen Code parat?

Schonmal Danke für Eure Hilfe!

webworker

---

<div class="post-metadata">

**Author:** ![SkobyMobil](https://avatars.discourse-cdn.com/v4/letter/s/85f322/32.png) [@SkobyMobil](https://forum.arduino.cc/u/SkobyMobil)\
**Post date:** [January 12, 2014, 11:41am UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/2 "2014-01-12T11:41:30Z")

</div>

Hallo,  
ich weiß nicht so recht...  
10 Min messen/ alle Sek sind bei mir 600 Werte pro sensor. Diese Rohdaten würde ich auf SD/Datei schreiben.  
Mittelwert würde ich hochzählen...  
Wert=Wert plus Neuwert. Wenn 600 mal gemacht, Mittelwert bilden, Mittelwert speichern/senden.  
Gruß und Spaß  
Andreas

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [January 12, 2014, 12:02pm UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/3 "2014-01-12T12:02:41Z")

</div>

> SkobyMobil:  
> [...]10 Min messen/ alle Sek sind bei mir 600 Werte pro sensor. [...]

😊 Stimmt ja, ich wollte zuerst 10 Min-Mittelwerte senden, habe mich dann aber doch für 5 Min-Mittelwerte entschieden :), deshalb die 300 Messungen. Die 10 Min-Mittelwerte erzeuge ich dann auf dem Webserver mit PHP.

Ich bin dann mal ein bisschen Testen.... 😉

---

<div class="post-metadata">

**Author:** ![guntherb](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/guntherb/32/215276_2.png) [@guntherb](https://forum.arduino.cc/u/guntherb)\
**Post date:** [January 12, 2014, 12:13pm UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/4 "2014-01-12T12:13:29Z")

</div>

ich würde das ganz anders machen, mittels eines gleitenden Mittelwertes.

Mittelw = (messwert + Mittelw \* 300.0)/301.0; // muß in float gerechnet werden, float Mittelw  
Die Funktion braucht eine Periode zum Einschwingen, aber dann folgt sie dem arithmetischem Mittelwert mit einer Genauigkeit besser 0,1%.

Und du hast den Vorteil dass du immer, zu jedem Zeitpunkt, den Mittelwert hast.  
Die Funktion wrid auch oft als einfacher Filter von Sensorsignalen benutzt. Das ist ein digitaler Tiefpassfilter mit Tau = filterfaktor \* Abtastung (filterfaktor ist hier 300)

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [January 13, 2014, 8:18pm UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/5 "2014-01-13T20:18:56Z")

</div>

Moin,

jede Sekunde messen, um einen 5 ober 10 min Mittelwert zu bilden? Is dies nicht zu stressig für Prozessor/ Karte? Bei einem Zyklus von 10 oder 30 sec wird die 'Mittelwertlast' um einiges geringer, damit wäre doch 'mehr Luft zum Atmen' für andere Prozesse?

Wie sieht dies mit den Schreibzyklen auf die Karte aus? Wenn dort weniger Traffic ist, dann würde die doch länger halten, oder?

Greetz Linpo

---

<div class="post-metadata">

**Author:** ![guntherb](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/guntherb/32/215276_2.png) [@guntherb](https://forum.arduino.cc/u/guntherb)\
**Post date:** [January 14, 2014, 6:45am UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/6 "2014-01-14T06:45:57Z")

</div>

Wenn man das mit dem dem digitalen Tiefpass macht, wie oben beschrieben, dann hat du jede Sekunde diese eine Codezeile auszuführen und brauchst gar keine SD-Karte, weil du als zusätzlichen Speicher nur einen Float-Wert brauchst.

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [January 14, 2014, 5:00pm UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/7 "2014-01-14T17:00:34Z")

</div>

Hallo,

danke für Eure Anworten. Ich habe mich jetzt für einen gleitenden Mittelwert entschieden, da es der SD-Karte bestimmt nicht gut tut, wenn sie jede Sekunde 365 Tage im Jahr beschrieben wird. Der ausschlaggebende Grund ist aber der, dass es viel zu aufwändig wäre, die Werte danach wieder auszuwerten und zu mitteln - für mich als Anfänger jedenfalls!

Gruß  
webworker

---

<div class="post-metadata">

**Author:** ![Doc\_Arduino](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/doc_arduino/32/215810_2.png) [@Doc\_Arduino](https://forum.arduino.cc/u/Doc_Arduino)\
**Post date:** [January 14, 2014, 8:14pm UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/8 "2014-01-14T20:14:45Z")

</div>

Hallo,

> guntherb:  
> ich würde das ganz anders machen, mittels eines gleitenden Mittelwertes.
> 
> Mittelw = (messwert + Mittelw \* 300.0)/301.0; // muß in float gerechnet werden, float Mittelw  
> Die Funktion braucht eine Periode zum Einschwingen, aber dann folgt sie dem arithmetischem Mittelwert mit einer Genauigkeit besser 0,1%.
> 
> Und du hast den Vorteil dass du immer, zu jedem Zeitpunkt, den Mittelwert hast.  
> Die Funktion wrid auch oft als einfacher Filter von Sensorsignalen benutzt. Das ist ein digitaler Tiefpassfilter mit Tau = filterfaktor \* Abtastung (filterfaktor ist hier 300)

Deine Mittelwertbildungsmethode finde ich gut und wollte ich gleich ausprobieren. Leider erhalte ich nur Werte in Größenordnung 2,67. Es müßten jedoch Werte um 21 herauskommen.

Dein Filterfaktor 300 (bzw. meine 10) gibt doch an mit wievielen Meßwerten gemittelt werden soll. Oder?  
Außerdem ist mir nicht klar, wie stets der aktuelle Mittelwert ermittelt werden soll. Es wird nirgends ein frischer Wert hinzugenommen **und gleichzeitig** ein alter Wert (älteste) rausgenommen. Man benötigt dazu doch bestimmt eine Schleife zum neuen Wert rein, ältester raus, mit den verbliebenen Werten den Mittelwert bilden, Spiel von vorn.

```arduino
//  Arduino Mega 2560

// Deklaration der Funktionen, übernimmt die Arduino IDE selbst
// unsigned int read_MAX6675();
  
//  Arduino Mega 2560

// Port-Pins definieren
int    MAX_CS = 24;              // Arduino Pin, SPI ChipSelect, 1. MAX6675
int    MAX_SO  = 26;              // Arduino Pin, SPI Datenleitung
int    MAX_CLK = 28;           // Arduino Pin, SPI Clockleitung

unsigned int value = 0;

// Deklaration Datentypen und Variablen
unsigned int Temp = 0;   // Zwischenspeicher
float Mittelwert = 0;

void setup() {

  Serial.begin(9600); 

  pinMode(MAX_CS, OUTPUT);
  pinMode(MAX_SO, INPUT);
  pinMode(MAX_CLK, OUTPUT);
  
  digitalWrite(MAX_CS, HIGH);              // Ruhezustand
  digitalWrite(MAX_CLK, LOW);              // Ruhezustand
  
}

void loop() {
  
  delay(1000);
  
  Temp = read_MAX6675();
  
  Mittelwert = (Temp + Mittelwert * 10) / 11 / 4.0;
     
  // Temp = read_MAX6675()/4.0;    // Roh-Temperaturwert durch 4 (wegen °C) vom MAX6675 einlesen
  
Serial.println(Mittelwert,2);
  

}

// -----------------------------------------------------------------------------------------------------	 
// Der MAX6675 wird ausgelesen und der 12-Bit-Wert zurückgegeben ********
unsigned int read_MAX6675 ()
{
  int i;
  unsigned int data;
  data = 0;
  digitalWrite(MAX_CS, LOW);            // CS=Low
  for(i=0;i<16;i++)
    {
    delayMicroseconds(1);            // warte 100us
    digitalWrite(MAX_CLK,HIGH); // SCK=High
    delayMicroseconds(1); // warte 100us
    // data = ((data<<1) | MAX_SO); // schiebe nach links und lies SO
    data = ((data<<1) | digitalRead(MAX_SO)); // schiebe nach links und lies SO
    digitalWrite(MAX_CLK, LOW); // SCK=Low
    }
  delayMicroseconds(1); 	
  digitalWrite(MAX_CS, HIGH);        // CS=High
  delayMicroseconds(1); // warte 100us
  return (data>>3); // gib 12-Bit Wert zurück
}

```

Zur Zeit bilde ich mit 10 Werten immer einen neuen Mittelwert.

```arduino
  for(int i=0 ; i<10; i++)
    {  
    delay(220);                          // 220ms Wartezeit vorm erneuten auslesen
    value = value + read_MAX6675();      // Temperaturwert vom MAX6675 einlesen
    }
    Mittelwert = value / 10 / 4.0;
    value = 0;

```

---

<div class="post-metadata">

**Author:** ![guntherb](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/guntherb/32/215276_2.png) [@guntherb](https://forum.arduino.cc/u/guntherb)\
**Post date:** [January 15, 2014, 8:44am UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/9 "2014-01-15T08:44:10Z")

</div>

ohne das jetzt überprüfen zu können, vermute ich , dass dein Fehler in dieser Zeile zu suchen ist:

Mittelwert = (Temp + Mittelwert \* 10) / 11 / 4.0;

das muß heißen:  
Mittelwert = (Temp + Mittelwert \* 10.0) / 11.0 / 4.0;  
Sonst werden die Berechnungen in int ausgeführt.

Nachtrag:  
Noch ein Fehler. Du mußt den Rohwert umrechnen, nicht den Mittelwert. So vermischt du beides.  
Mittelwert = (Temp /4.0 + Mittelwert \* 10.0) / 11.0;

---

<div class="post-metadata">

**Author:** ![Doc\_Arduino](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/doc_arduino/32/215810_2.png) [@Doc\_Arduino](https://forum.arduino.cc/u/Doc_Arduino)\
**Post date:** [January 15, 2014, 9:31am UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/10 "2014-01-15T09:31:09Z")

</div>

Hallo,

eigentlich möchte ich solange wie möglich mit den Rohwerten rechnen, sprich Ganzzahlen, um Rundungsfehler durch float zu vermeiden. Deshalb dachte ich mir, rechnest erst zum Schluss den Durchschnitt der Rohwerte in float um.

Edit:  
Ich habe das in Excel nachgebaut. 3. Formel scheint zu stimmen.  
Mir ist aber nachwievor nicht klar wie in der Formel alte Messwerte herausgenommen werden. Es wird doch nur immer ein neuer Wert hinzuaddiert. Laut meinem Verständnis driftet der ständig neu ermittelte Wert stetig ab. Man muß doch vorher eine Schleifen bauen wo immer die letzten x Messwerte enthalten sind und damit wird gemittelt. 🙄

---

<div class="post-metadata">

**Author:** ![guntherb](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/guntherb/32/215276_2.png) [@guntherb](https://forum.arduino.cc/u/guntherb)\
**Post date:** [January 15, 2014, 11:30am UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/11 "2014-01-15T11:30:16Z")

</div>

> Doc\_Arduino:  
> Hallo,  
> eigentlich möchte ich solange wie möglich mit den Rohwerten rechnen, sprich Ganzzahlen, um Rundungsfehler durch float zu vermeiden. Deshalb dachte ich mir, rechnest erst zum Schluss den Durchschnitt der Rohwerte in float um.

Nein, das funktioniert nicht.  
Du mußt das so sehen:  
du nimmst jedes mal 1/11 tel des neue Wertes und 10/11 tel des alten Mittelwertes und bildest damit den neuen Mittelwert.  
Das funktioniert nur komplett mit float.  
Aber dein Hauptfehler war das "/4" an falscher Stelle.

> Doc\_Arduino:  
> Mir ist aber nachwievor nicht klar wie in der Formel alte Messwerte herausgenommen werden. Es wird doch nur immer ein neuer Wert hinzuaddiert. Laut meinem Verständnis driftet der ständig neu ermittelte Wert stetig ab. Man muß doch vorher eine Schleifen bauen wo immer die letzten x Messwerte enthalten sind und damit wird gemittelt. 🙄

Das funktioniert ungefähr so:  
Nehmen wir mal als Faktor nur 1 an.  
Also: "Mittelwert = (Temp/4.0 + Mittelwert \* 1.0) / 2.0;" (Nur damit es sich schöner erklären läßt)  
Bei jedem Zyklus nimmst du also die Hälte der aktuellen Temperatur und die Hälfte des alten Mittelwertes und addierst die zum neuen Mittelwert.  
Nehmen nun einen Messwert und beobachten seine Wertigkeit vonZyklus zu Zyklus.

1. Durchlauf: Mein Messwert (nennen wir ihn Otto) wird halbiert und mit der Hälfte des Mittelwertes addiert zum neuen Mittelwert. Im neuen Mittelwert steckt Otto nun zur Hälfte drin (50% des Mittelwertes werde von Otto bestimmt.
2. Durchlauf: ein neuer Messwert kommt, der alte Mittelwert wird wieder halbiert. Damit auch Otto. Im neuen Mittelwert steckt Otto nun nur noch zu einem Viertel drin.
3. Durchlauf: wieder ein neuer Meßwert. Der Mittelwert wird halbiet und die WErtigkeit von Otto sinkt auf 1/8 tel.  
Beim nächsten Durchlauf auf e 1/16 tel, dann 1/32tel usw.

Der Anteil von Otto (als Stellvertreter für alle vergangenen Meßwerte) im Ergebnis wrid immer kleiner, bis er keine Rolle mehr spielt. Er muß also nicht rausfallen, er verschwindet irgenwann in der Bedeutunglosigkeit.

Das ganze ist einfach nur ein digitaler Tiefpass. Er verhält sich genau so wie ein RC-Glied in der Hardware.

Nachtrag:  
Ich habe auch mal versucht, das ganze mit long int zu rechnen, in dem ich die Werte um 16-bit geshiftet habe (also \*32768), aber es hilft nix. Der Wert konvergiert nicht. Es muß float sein.  
Andererseits ist die Rechenzeit auch nicht so groß. Ich habs nicht mehr im Kopf, aber einen Wert aufs LCD-Display zu schreiben dauert länger.

---

<div class="post-metadata">

**Author:** ![Doc\_Arduino](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/doc_arduino/32/215810_2.png) [@Doc\_Arduino](https://forum.arduino.cc/u/Doc_Arduino)\
**Post date:** [January 15, 2014, 1:06pm UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/12 "2014-01-15T13:06:27Z")

</div>

Hallo,

ich glaube 🙄 ich habe es jetzt verstanden. Das bedeutet aber auch, dass man nicht sagen kann, man hat immer den Mittelwert der letzten x Messwerte. Sondern man hat den Mittelwert aller jemals gesammelten Messwerte. Ist das so richtig ausgedrückt oder immer noch falsch verstanden?

Das wiederum würde bedeuten, ab einer Anzahl x gesammelter Messwerte macht das keinen Sinn mehr, weil der Einfluss eines neues Wertes auch immer bedeutungsloser wird. Wie die Ladekurve eines Kondensators. Ich hoffe das Bsp. ist passend. Ab 5x Tau kann man den Versuch beenden. Die Ladespannung ist praktisch erreicht, alles weitere bis zu 100% Ladespannung würde ewig und 3 Tage dauern.

Nur die Wirkung vom Filterfaktor ist mir noch nicht klar. Denn auch wenn man mit 2 beginnt, halbiert sich der Einfluss immer weiter.

Ich dachte ich kann damit meine starre Mittelwertbildung beschleunigen und immer die letzten 10 aktuellsten Messwerte mitteln. Aktuell messe ich 10x und bilde dann erst davon den Mittelwert. Ich dachte ich kann mit dem gleitenden Mittelwert immer mit den letzten 10 aktuellen Werte sofort den neuen Durchschnitt bilden und muß nicht erst warten bis ich erneute 10x hintereinander gemessen habe.

---

<div class="post-metadata">

**Author:** ![jurs](https://avatars.discourse-cdn.com/v4/letter/j/43a26b/32.png) [@jurs](https://forum.arduino.cc/u/jurs)\
**Post date:** [January 15, 2014, 1:34pm UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/13 "2014-01-15T13:34:31Z")

</div>

> Doc\_Arduino:  
> Nur die Wirkung vom Filterfaktor ist mir noch nicht klar. Denn auch wenn man mit 2 beginnt, halbiert sich der Einfluss immer weiter.

Korrekt. Die "exponentielle Glättung" führt zu einem gewichteten Mittelwert, bei dem neuere Messwerte eine höhere Gewichtung haben als ältere, d.h. nicht alle Werte werden gleich gewichtet, sondern neuere Werte tragen stärker zum Mittelwert bei als ältere Werte.

Deshalb kann man die exponentielle Glättung auch endlos weiterlaufen lassen: Je älter ein eingerechneter Wert ist, desto geringer ist sein Beitrag zum Mittelwert, bis hin zur völligen Bedeutungslosigkeit.

Ein "arithmetisches Mittel" bekommst Du durch "exponentielle Glättung" jedenfalls nicht heraus.

Falls Du Deine Werte für irgendwelche meteorologischen Auswertungen verwenden möchtest, ist Dein gesamter Ansatz, was an Daten dauerhaft gespeichert wird, übrigens nicht meteorologisch korrekt und widerspricht den Grundsätzen der Wetterdatenerfassung. Ich gehe also mal davon aus, dass es nicht um die Auswertung meteorologischer Daten nach den üblichen meteorologischen Standards gehen soll.

---

<div class="post-metadata">

**Author:** ![guntherb](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/guntherb/32/215276_2.png) [@guntherb](https://forum.arduino.cc/u/guntherb)\
**Post date:** [January 15, 2014, 1:48pm UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/14 "2014-01-15T13:48:49Z")

</div>

> Doc\_Arduino:  
> ich glaube 🙄 ich habe es jetzt verstanden. Das bedeutet aber auch, dass man nicht sagen kann, man hat immer den Mittelwert der letzten x Messwerte. Sondern man hat den Mittelwert aller jemals gesammelten Messwerte. Ist das so richtig ausgedrückt oder immer noch falsch verstanden?

Leider noch nicht ganz.

> dass man nicht sagen kann, man hat immer den Mittelwert der letzten x Messwerte.

Das ist richtig.

> Sondern man hat den Mittelwert aller jemals gesammelten Messwerte

Das ist falsch.

Du hast keinen Mittelwert im reinen mathematischen Sinn. (Aber ich denke, den brauchst du auch nicht.)  
mathematisch sieht das ganze etwa so aus:  
m = Mittelwert  
x1 = aktueller Messwert  
x2 = letzer Messwert  
x3 = vorletzer Messwert  
x4 = vorvorletzer Messwert  
...

m = 1/2 \* X1 + 1/4_x2 + 1/8 \* x3 \* 1/16 x4 + 1/32x5 + 1/64_x6 + 1/128\*x6 ....  
Für Filterfaktor 2.  
Du siehst, dass schon der Messwert, der 6 Messungen zurückliegt, fast nicht mehr eingeht.

Für höhere Filterfaktoren nimmt das natürlich viel langsamer ab.

Ich habe dir mal ein Excel-datei zum spielen angehängt.

[Tiefpassfilter\_digital.xlsx](https://forum.arduino.cc/uploads/short-url/sodMnorHgDT76AZcBsSs4M4hqiY.xlsx) (29 KB)

---

<div class="post-metadata">

**Author:** ![Doc\_Arduino](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/doc_arduino/32/215810_2.png) [@Doc\_Arduino](https://forum.arduino.cc/u/Doc_Arduino)\
**Post date:** [January 15, 2014, 4:55pm UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/15 "2014-01-15T16:55:01Z")

</div>

Hallo,

Dank der vielen Erklärungen und tollen Exceltabelle 🙂 bin ich mir sicher das jetzt verstanden zu haben. Manchmal drängelt sich zwar noch die geistige Vorstellung eines notwendigen Schieberegisters ins Hirn, dann muß ich Eure Erklärungen wieder lesen und der Nebel verzieht sich wieder. 😉

Der Filterfaktor entspricht Tau, auf die Kondensatorladekurve bezogen, und nach mindestens 5x Tau erhalte ich Mittelwerte die praktisch meinen Meßwert entsprechen, solange der sich nicht ändert. Diese Erklärung laut meinem Verständnis sollte stimmen. 🙄

Vielleicht gehe ich an mein "Meßproblem" auch etwas falsch ran. Mag sein. Ich lese ja mittels MAX6675 Temperaturen ein. Diese schwanken jedoch hin und wieder in 0.25°C Sprüngen. Raumtemp. laut Fühler nicht konstant, sondern zwischen 23.25 und 24.00 schwankend. Jetzt dachte ich spontan, als ich diesen Thread hier las, ich könnte es mit der Methode schön mitteln und erhalte konstante Werte. Aber selbst mit Filterfaktor 20 schwankt die 1. Kommastelle doch für mich zu oft. Wenn ich nur mit einer Kommastelle anzeigen lasse. Ich brauche also noch eine Art Hysterese.

Jetzt denke ich mir, ich komme besser, wenn ich die Viertel-Kommawerte (0.25, 0.50, 0.75) separat auswerte und nur auf halbe °C anzeigen lasse. Das sollte stabil werden.

Die gleitende Mittelwertbildung kann ich ja dennoch verwenden um eine leichte Trägheit reinzubekommen. Dann muß ich nicht wie sonst gemacht wird sturr 10x aufaddieren und teilen für einen einzigen Mittelwert, sondern bekomme bei jeden Durchgang einen neuen Mittelwert. Nach der "Wartezeit" von 5x Filterfaktor.

Habe das obige vorhin in Code umgesetzt. Filterfaktor mir Poti veränderbar.

```cpp
//  Arduino Mega 2560

// Deklaration der Funktionen, übernimmt die Arduino IDE selbst
// unsigned int read_MAX6675();
  
//  Arduino Mega 2560

// Port-Pins definieren
int    MAX_CS = 24;              // Arduino Pin, SPI ChipSelect, 1. MAX6675
int    MAX_SO  = 26;              // Arduino Pin, SPI Datenleitung
int    MAX_CLK = 28;           // Arduino Pin, SPI Clockleitung

// Deklaration Datentypen und Variablen
int Poti = 0;                    // Eingang A0
int Filterfaktor = 1;
float Teiler = 2.0;

unsigned int value = 0;

unsigned int Temp = 0;	
float Mittelwert = 0;
float actual = 0;

void setup() {

  Serial.begin(9600); 
 
  pinMode(MAX_CS, OUTPUT);
  pinMode(MAX_SO, INPUT);
  pinMode(MAX_CLK, OUTPUT);
  
  digitalWrite(MAX_CS, HIGH);              // Ruhezustand
  digitalWrite(MAX_CLK, LOW);              // Ruhezustand
    
}

void loop() {
  
  delay(1000);
  Filterfaktor = analogRead(Poti)/8;        // lese analog Pin A0 ein und Begrenzung auf 128
  if(Filterfaktor == 0) Filterfaktor = 1;  // wenn A0 = 0, dann setze es auf 1 (Mindestwert)
  Teiler = Filterfaktor + 1;                // Teiler immer eins größer wie Filterfaktor
  Temp = read_MAX6675();
  actual = Temp / 4.0;
  Serial.print(Filterfaktor);
  Serial.print("  ");
  Serial.print(actual,2);                  // aktueller Meßwert von A0
  Serial.print("  ");
  Mittelwert = (Temp/4.0 + Mittelwert * Filterfaktor) / Teiler;
  Serial.println(Mittelwert,1);            // gleitender Mittelwert

}

// -----------------------------------------------------------------------------------------------------	 
// Der MAX6675 wird ausgelesen und der 12-Bit-Wert zurückgegeben ********
unsigned int read_MAX6675 ()
{
  int i;
  unsigned int data;
  data = 0;
  digitalWrite(MAX_CS, LOW);            // CS=Low
  for(i=0;i<16;i++)
    {
    delayMicroseconds(1);            // warte 100us
    digitalWrite(MAX_CLK,HIGH); // SCK=High
    delayMicroseconds(1); // warte 100us
    // data = ((data<<1) | MAX_SO); // schiebe nach links und lies SO
    data = ((data<<1) | digitalRead(MAX_SO)); // schiebe nach links und lies SO
    digitalWrite(MAX_CLK, LOW); // SCK=Low
    }
  delayMicroseconds(1); 	
  digitalWrite(MAX_CS, HIGH);        // CS=High
  delayMicroseconds(1); // warte 100us
  return (data>>3); // gib 12-Bit Wert zurück
}

```

---

<div class="post-metadata">

**Author:** ![guntherb](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/guntherb/32/215276_2.png) [@guntherb](https://forum.arduino.cc/u/guntherb)\
**Post date:** [January 16, 2014, 6:49am UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/16 "2014-01-16T06:49:02Z")

</div>

> Doc\_Arduino:  
> Der Filterfaktor entspricht Tau, auf die Kondensatorladekurve bezogen, und nach mindestens 5x Tau erhalte ich Mittelwerte die praktisch meinen Meßwert entsprechen, solange der sich nicht ändert. Diese Erklärung laut meinem Verständnis sollte stimmen. 🙄

Richtig!  
Jetzt hast Du's! 🙂

Die Temperaturschwankungen müssen nicht an deiner Messtechnik liegen. Was für Thermoelemente hast du denn? Thermoelemente sind teilweise so schnell, dass sie wirklich auf die kleinste Änderung reagieren. Ich habe ein professionelles Messgerät mit Thermoelementen, und da ist es auch so, dass es reicht wenn jemand nur durchs Zimmer geht, dass das reicht um 1°-2° Temperturänderung hervorzurufen.  
Du mußt dir die Frage andersrum stellen: Wie schnell ändert sich die Temperatur, die du messen willst?  
Wenn es wirklich die Raumtemperatur ist, dann kannst du meiner Meinung nach Zeitkonstanten von 10-20min ansetzen.  
Oder einen Sensor nehmen, der thermisch träger ist, einen mit größerer Masse, aber das ist auch nichts anderes als ein Tiefpass.

---

<div class="post-metadata">

**Author:** ![Doc\_Arduino](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/doc_arduino/32/215810_2.png) [@Doc\_Arduino](https://forum.arduino.cc/u/Doc_Arduino)\
**Post date:** [January 16, 2014, 1:39pm UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/17 "2014-01-16T13:39:10Z")

</div>

Hallo,

ich messe mit einem K-Typ an einem MAX6675. Der reagiert wirklich extrem schnell auf Berührung. Das ein Luftzug ausreicht wußte ich noch nicht. Nie darüber nachgedacht. Ich dachte immer eine Raumtemperatur ist immer sehr konstant solange alle Fenster und Türen zu sind. Ich werde die Ausgabe auf halbe °C umstellen. Dann sind die normalen Schwankungen weg.

Ich bedanke mich jedenfalls für Deine/Eure Geduld mit den Erklärungen. Hat mir richtig weitergeholfen.

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [May 6, 2021, 12:59pm UTC](https://forum.arduino.cc/t/erledigt-messwerte-auf-sd-karte-mittelwert-bilden/204732/18 "2021-05-06T12:59:01Z")

</div>


