ich habe ein Problem wo ich mir schon eine ganze Weile den Kopf zerbreche und irgendwie nicht weiter komme.
Ich habe hier einen Niederschlagssensor der mir die aktuelle Niederschlagsmenge in mm/min als mA ausgibt. Das erfassen des Wertes ist nicht das Problem.
Jetzt habe ich zwar den aktuellen Wert der Niederschlagsmenge, nur würde ich es toll finden das ich dann am Ende des Tages/Regens eine Statistik habe, wo ich sehen kann wie viel Niederschlag im laufe des Tages runtergekommen ist.
Wie würdet ihr da weiter vorgehen? Ich denke mal nicht das diese Berechnung auf dem Controller, in meinem Fall ein ESP32, stattfinden kann. Deshalb übertrage ich den aktuellen Messwert auch schon per mqtt an meinen Broker im lokalen Netzwerk.
Laut meinem Verständniss müsste ich ja irgendwie, um so genau wie möglich zu werden, einem sekündlichen Mittelwert bilden aus dem dann einen Minütlichen und das dann irgendwie mit timestamp in eine Datenbank schreiben, damit ich daraus dann später meine Statistik erstellen kann.
Das hört sich für mich aber nach einer verdammt grossen Menge an Daten an. Gibt es da vielleicht einen eleganteren Weg den ich übersehe?
Der ESP32 ist schon sehr leistungsfähig und kann diese kleine Berechnung sicher erledigen. Wenn du die Daten schon im ESP32 zur Verfügung hast, dann einfach damit rechnen, das schafft der schon.
wenn du jede Minute einen Wert abfragen kannst
kannst du den ganzen Tag (also 60 x 24 = 1440 mal) den erhaltenen Wert einfach zu deinem Tageszähler/heute dazuzählen - dann hast du bis um Mitternacht deine Niederschlagsmenge.
Um Mitternacht kopierst du dir den heute Wert in eine variable Gestern und
setzt deinen heute Zähler auf null und fängst somit wieder von vorne an.
Dann weist du wie viel Niederschlag heute war - wie viel Gestern den ganzen Tag war.
Der "aktuelle" Niederschlagswert, ist die Niederschlagsmenge in mm/min die der Sensor gerade in nahezu Echtzeit ausgibt. Es ist ein Analoger Wert zwischen 4 und 20mA den ich mit Hilfe einer kleinen Schaltung in eine Spannung umwandle und diese dann am ADC messe und auswerte.
Hier ist mein Code, habe die ganze Netzwerk Geschichte eingekürzt.
Ich frage den Wert kontinuierlich ab, habe dadurch mehrere Messwerte in der Sekunde die ich dann noch filtere, da der analoge Wert doch sehr am Rauschen ist.
Ich müsste mir die Daten einer ganzen Minute speichern und daraus den Mittelwert bilden, und da weiß ich nicht ob der ESP das lange mitmachen wird, da da ja doch einiges zusammenkommen dürfte.
bau dir einen ein Minuten timer und speichere es dir einmal in der minute weg
pseudo code
static uint32_t previousMillis = 0;
uint32_t currentMillis=millis();
if (currentMillis - previousMillis>60000UL)
{
heute += niederschlag;
previousMillis=currentMillis();
Serial.println("... und merken...");
}
wie du zum "niederschlag" kommst ist doch egal bzw. das kannst machen wie du willst.
Entweder nimmst einen aktuellen Wert (der soll ja mm/min sein) oder deinen schon vorhanden Mittelwert.
Ich muss mal versuchen ob es der ESP schafft mir einen Mittelwert aus einer Minute zu errechnen.
Ich kann nicht einfach jede Minuten den Wert abspeichern. Dieser schwankt natürlich innerhalb einer Minute sehr stark da es nie so konstant regnet. der Wert von dem Sensor gibt den Wert an, wie es wäre wenn es exakt eine Minute so weiter regnen würde. (Das is aber natürlich nie der Fall) Deshalb muss ich mir wohl einen Mittelwert aus der letzten Minute erstellen.
Kenne mich mit C leider nicht so besonders gut aus, gibt es "flexible" Arrays in C?
Oder muss man die Grösse des Arrays zwingend immer vorher wissen? Ich weiß natürlich nicht genau wie viele Messwerte in einer Minute zusammenkommen.
du machst ja schon allerlei smooth, median , map ... ich mein auf einen gültigen Wert wirst doch hoffentlich kommen... sonst hats ja sowieso was mit deinem Sensor (oder deiner Programmlogik)
Ich bin mir sicher, der ESP32 kann das, daher ist eher die Frage, ob Du das kannst.
Programmiert wird in C++ und ich kann mir nicht vorstellen, wozu flexible Felder notwendig wären.
Du scheinst eine Art Durchflußsensor zu haben. Den fragst Du beispielsweise jede Sekunde ab. Den Wert addierst Du zu einer Minuten-Summe, die Du nach 60 Messungen durch 60 teilst, dann hast Du den Niederschlag der letzten Minute. Diesen Wert kannst Du dann 1440 mal zur Tages-Summe addieren, die Du dann an das Netzwerk überträgst.
Das benötigt eine Handvoll Variablen, kein flexibles Feld.
Natürlich kannst Du auch häufiger messen und mehr Informationen an das Netzwerk übertragen, das benötigt dann eben ein paar mehr Variablen, aber immer noch kein flexibles Feld.
Ich komme ja auf einen gültigen Wert, aber nicht auf einen Wert der für eine komplette Minute gültig ist. Mit dem ganzen Sketch komme ich auf ca. 420 werte die Sekunde. Da jetzt einfach jede Minuten einen Wert von zu nehmen wäre nicht repräsentativ für die letzte Minute.
Vielleicht sollte ich den Sketch erstmal umbauen und das ganze erstmal auf 2-4 Messungen die Sekunde reduzieren. Dann hätte ich nur ca. 250 Werte aus den ich ein Mittelwert bilden muss.
Ja, auf die Idee, dass ich den Sensor eventuell einfach weniger abfrage bin ich auch gerade gekommen. Das macht die Sache auf jeden Fall um einiges einfacher.
Ich werde einfach nochmal von ganz vorne anfangen.
Egal wie häufig Du abfragst, Du solltest es in einem festen Zeitraster tun. Wenn Du dann n Messungen machst, benötigst Du kein Feld mit n Elementen, sondern nur eine Summe, die Du nach den n Messungen durch n teilst.
Also mache jede Sekunde einen Wert in einen Ringpuffer und bilde am Ende der Minute einen Durchschnitt. (60 Werte)
Addiere jede Minute in einen Stundenwert. Macht 24 Stundenwerte. Die in einem Array am Ende des Tages zusammenaddiert, dann hast Du:
letzte Minute, letzte Stunde, letze 24 Stunden, letzten Tag.
Wenn Du willst auch noch 31 Tage.
Das sind dann insgesamt irgendwo um die 125 Werte.
Für jeden Wert 4 Byte.
Da lacht sich der ESP drüber eher tot, als Du den vollschreibst.
Es gibt den Variablentyp unsigned long. Der kann Zahlen bis 2 hoch 32 = 4.294.967.296
Wenn du in einer Variable vom Typ unsigned long die 12-bit-AD-Wandler.Meßwerte aufsummierst
dann kannst du da 12 bit = 2 hoch 12 = 4096
4.294.967.296 / 4096 = 1.048.576 eine Million Messwerte addieren bevor die Zahl zu groß wird.
Das heißt du könntest die Messwerte bei hoher Geschwindigkeit aufaddieren und dann durch die Anzahl Meßwerte teilen.
Dabei ist wichtig, dass die Messungen über einen präzise konstant gehaltenen Zeitraum aufsummiert werden oder du musst die Mikrosekunden zum Meßstart und Meßende mit erfassen. Dann ist eine präzise Berechnung mm/min möglich.
Die Mikrosekunden werden auch in Variablen vom Typ unsigend long gespeichert
Die Berechnung wird mit hochskalierten Integerwerten präziser als wenn man variablen vom Typ float verwendet.
Beispiel:
Originalwert 0,04593
mit der Zahl 1 Million hochskalierter Wert 45930,000000
Das Komma wurde durch die Multiplikation mit 1.000.000 um 6 Stellen nach links verschoben.
vgs