Spitzenwert erfassen aber wie?

Hallo,

die Erfassung der mittleren Windgeschwindigkeit pro 10 Minuten habe ich schon gelöst.

Bei der Erfassung des Spitzenwertes stehe ich auf dem Schlauch.

Definition des DWD:
Windspitze ist die Bezeichnung für die höchste momentane Windgeschwindigkeit (höchster 3-Sekunden-Mittelwert der Geschwindigkeit) in einem willkürlich festgelegten Zeitraum (z. B. Windspitze des Tages, der letzten Stunde, der letzten 10 Minuten).

Ich habe pro Sekunde 3-5 Werte in vWind.
Das heißt ich muss den Durchschnitt aus den 9-15 Werten mit den 9-15 Werten,
die um einen Wert weiter sind, vergleichen.
Dabei sind immer Werte für 3s zu berücksichtigen.
Ein gleichmäßige Messung ist nicht möglich, weil der Arduino noch andere Aufgaben hat.
Ich dachte da evtl. an einen Zeitstempel pro Wert.

Das habe ich schon.
Hier wird nur immer der neue Wert mit dem zuletzt höchsten Wert verglichen.

float vWind10Min[6];                                        //durchschnitliche Windgeschwindigkeit für 6x10Min pro Stunde (vWind / 1,9 = km/h)
float vWindSpitze[6];                                       //Windspitzenwerte 6 für je 10Min
unsigned long vWindAdd = 0;
int cndW = 0;                                               //Anzahl der Windmessungen
void WindLog(){
  static byte vMin10Alt;
  static boolean bNeustart = true;
  byte vMin10 = vMin / 10;                                  //Dekade der aktuellen Stunde
  if(bNeustart == true){
    Serial.println("WindLog");
    vMin10Alt = vMin10; 
    bNeustart = false;
  }
  if(vMin10Alt != vMin10){                                  //hat sich die Dekade geändert
    vWind10Min[vMin10Alt] = float(vWindAdd / cndW);         //Durchschnitt berechnen
    WindAusgabe();  //test
    vWindSpitze[vMin10] = vWind;                            //ersten Wert speichern
    vWindAdd = vWind;                                       //ersten Wert speichern
    cndW = 1;                                               //Zähler zurück setzen
    vMin10Alt = vMin10;                                     //aktuellen Dekade speichern
  } else{ 
    vWindAdd = vWindAdd + vWind;                            //Werte addieren
    cndW++;                                                 //Messungen zählen  
    if(vWindSpitze[vMin10] < vWind) vWindSpitze[vMin10] = vWind;   //Spitzenwert aktualisieren    
  }
}
void WindAusgabe(){   //test
  Serial<<vStd<<":"<<vMin<<endl;
  Serial<<"cndW        "<<cndW<<endl;
  Serial<<"vWindAdd    "<<vWindAdd<<endl;
  Serial<<"vWind10Min  "<<vWind10Min[0]<<" "<<vWind10Min[1]<<" "<<vWind10Min[2]<<" "<<vWind10Min[3]<<" "<<vWind10Min[4]<<" "<<vWind10Min[5]<<endl;
  Serial<<"vWindSpitze "<<vWindSpitze[0]<<" "<<vWindSpitze[1]<<" "<<vWindSpitze[2]<<" "<<vWindSpitze[3]<<" "<<vWindSpitze[4]<<" "<<vWindSpitze[5]<<endl;
}

Hi

Du hast 3...5 Werte pro Sekunde - also hat der Arduino dafür wohl Zeit.
Diese Messwerte gibt'st Du einem 'gleitenem Mittelwert' und bekommst eben Diesen für die letzten 3...5 Sekunden zurück.
Das prüfst Du bei jedem Messwert, Den Du erhältst und dort einträgst.

Wo ist Dein Problem?

MfG

PS: Kann mich irren, aber komplett sieht der Sketch nicht aus

Das habe ich jetzt nicht verstanden???

Hallo,

wenn der Max Wert aus den Rohdaten stammen soll, führst du diese nicht nur deiner Mittelwert Funktion zu sondern auch der MAX() Funktion. max() - Arduino Reference
Diesen Max Wert löscht du dann nach Zeitraum x und lässt ihn erneut kontinuierlich ermitteln.
So habe ich das Problem jedenfalls verstanden.

Wenn ich die Definition richtig interpretiere, dann sollst Du innerhalb von 3 Sekunden messen (z.B. je Sekunde 1 Wert) und daraus den Mittelwert bilden.

also Mittel = Summe der 3 Werte durch 3. Danach Summe wieder auf 0. Dadurch sparst Du den Speicherplatz für Arrays zur Mittelwertberechnung.

Diesen vergleichst Du dann mit dem bisherigen Maximalwert (initial=0). Ist der neue Wert größer, wird er der neue Maximalwert.
Nach Ablauf des Messintervalls (10 min, Stunde, ...) wird der jeweilige Maximalwert wieder auf 0 gesetzt.

Das wäre in meinen Augen der einfachste Ablauf. Das kann man schön mit millis() für die Sekundenabstände und das Messintervall abhandeln.

Ich denke 3-5 Werte pro Sekunde ist zu viel, so schnell ändert der Windmesser seinen Wert nicht signifikant.

Gruß Tommy

Hallo,

ich habe es jetzt folgendermaßen gelöst.
Es wird jetzt nach jeder Messung der Wert mit Zeitstempel gespeichert.
Aus diesen Werten werden dann alle Werte gemittelt die jünger 3s sind und
mit dem alten Spitzenwert verglichen.

Auf diese Weise müsste die Definition des DWD eingehalten sein.
Oder ist jemand anderer Meinung?

float vWind10Min[6];                                      //durchschnitliche Windgeschwindigkeit für 6x10Min pro Stunde in km/h
float vWindSpitze[6];                                       //Windspitzenwerte 6 für je 10Min in km/h
unsigned long vWindAdd = 0;
int cndW = 0, cndMaxW = 0;                                  //Anzahl der Windmessungen
uint32_t vWindMaxTime[10];                                  //Zeitstempel zu vWindMaxWert
uint8_t vWindMaxWert[10];                                   //Windwerte für Maxwertermittlung
float vWindSpiSchnitt= 0.0;                               //Windspitzenwert in km/h
void WindStatistik(){
  static byte vMin10Alt;
  static boolean bNeustart = false;
  byte vMin10 = vMin / 10;                                  //Dekade der Stunde
  if(bNeustart == false){
    Serial.println("WindStatistik");
    vMin10Alt = vMin10; 
    bNeustart = true;
  }
  if(vMin10Alt != vMin10){                                  //hat sich die Dekade geändert
    vWind10Min[vMin10Alt] = (float)vWindAdd / cndW / 1.9;   //Durchschnitt berechnen und in km/h
    WindAusgabe();  //test
    vWindSpitze[vMin10] = 0;                                //Spitzenwert der aktuellen Dekade löschen
    vWindAdd = vWind;                                       //ersten Wert speichern
    cndW = 1;                                               //Zähler zurück setzen
    vMin10Alt = vMin10;                                     //aktuellen Wert der Dekade speichern
  } else{ 
    vWindAdd = vWindAdd + vWind;                            //Werte addieren
    cndW++;                                                 //Messungen zählen   
    vWindMaxTime[cndMaxW] = millis();                       //Zeitstempel
    vWindMaxWert[cndMaxW] = vWind;                          //aktuellen Wert speichern
    cndMaxW++;
    if(cndMaxW > 9) cndMaxW = 0;                            //Zählerüberlauf
    uint32_t vAktTime = millis();                           //aktuelle Zeit  
    uint16_t vWindSumMax = 0;
    int cndWindSumMax = 0;
    for(int i=0;i<10;i++){  
      if(vAktTime - vWindMaxTime[i] < 3000){
        vWindSumMax += vWindMaxWert[i];                     //alle Werte die vor weniger als 3s gemessen wurden addieren
        cndWindSumMax++;                                    //Anzahl der Werte
      }
    }
    vWindSpiSchnitt = (float)vWindSumMax / cndWindSumMax / 1.9;   //Durchschnitt berechnen und in km/h
    if(vWindSpitze[vMin10] < vWindSpiSchnitt) vWindSpitze[vMin10] = vWindSpiSchnitt;   //Spitzenwert aktualisieren 
  }
}
void WindAusgabe(){   //test
  Serial<<vStd<<":"<<vMin<<endl;
  Serial<<"cndW        "<<cndW<<endl;
  Serial<<"vWindAdd    "<<vWindAdd<<endl;
  Serial<<"vWind10Min  "<<vWind10Min[0]<<" "<<vWind10Min[1]<<" "<<vWind10Min[2]<<" "<<vWind10Min[3]<<" "<<vWind10Min[4]<<" "<<vWind10Min[5]<<endl;
  Serial<<"vWindSpitze "<<vWindSpitze[0]<<" "<<vWindSpitze[1]<<" "<<vWindSpitze[2]<<" "<<vWindSpitze[3]<<" "<<vWindSpitze[4]<<" "<<vWindSpitze[5]<<endl;
}