NEWS
Füllstandsmessung per Pegelsonde.
-
@BastelKlaus sagte in Füllstandsmessung per Pegelsonde.:
@Eisbaeeer Danke für dein Angebot!
@opossum Ich bin da noch über was gestolpert, verstehe aber nicht was er da macht.
Was meinst Du damit, kannst gern fragen.
-
@opossum
im letzten post schreibt er das er es gelöst hat.
Ich wollte das erst mal so testen was da für Werte raus kommen, aber ich bekomm ja noch nicht mal die Formel rein, seine ist zu lang (....*100)
aber wenn ich nicht versteh was er da berechnet ist es auch schon fast egal. -
Ein Freund von mir will sich die andere Formel mal anschauen, ich kümmer mich jetzt erst mal um die Hardware.
Das wird meine erste selbst gelötete Platine. -
Einen liegenden Tank habe ich auch, siehe https://homematic-forum.de/forum/viewtopic.php?p=328133&sid=c9889fdb7499abc6e015d80692f97910#p328133 .
Und die Formel hatte ich schon lange zuvor, als ich noch mit dem Maßstab arbeitete, hergeleitet und auch in xls implementiert. Die Herleitung war damals noch schneller als Suchen. Im obigen Post (bzw. Folgepost) ist das auch kurz beschrieben:"Die Umrechnung von Füllstandshöhe auf Volumen hängt von der Tankform ab. Im meinem Fall eines liegenden Erdtanks kann aus der Füllhöhe der Füllquerschnitt berechnet werden. Stichwort Fläche des Kreissegments, s. https://de.wikipedia.org/wiki/Kreissegment hier die vierte Formel, Fläche in Abhängigkeit vom Druchmesser und der Füllhöhe. Die ESP8266 können den arccos rechnen, die Resultate stimmen mit einer XLS-Referenzberechnung überein. Nach Multiplikation mit der lichten Tanklänge erhält man das Füllvolumen ohne Berücksichtigung der Klöpperböden."
Wie beschrieben verwende ich die vierte Formel mit dem arccos(h). Die enthält alles, was wir kennen: Radius (bzw. Durchmesser) und Höhe vom Grund zum Flüssigkeitsspiegel (= Sehne)
Die Abbildung in Wikipedia einfach auf den Kopf stellen, dann wird es klar was das mit dem Tank zu tun hat.
https://de.wikipedia.org/wiki/Kreissegment#/media/Datei:Circular_segment.svgIm ESP8266 - Arduino-Code sieht das bei mir dann so aus:
void calculateInventory() { currentLevel = deltaPressure / cfg.fluidDensity + cfg.levelOffset; if (currentLevel > maxLevel) { currentLevel = maxLevel; if (currentLevel > maxLevel * 1.3) measError = 1; return; } // Meas error -> stop, no further calculation else measError = 0; // calculation for a cylindrical tank, horizontally oriented, Kloepperboden not regarded currentInventory = (pow(cfg.tankRadiusReal, 2) * acos(1 - currentLevel / cfg.tankRadiusReal) - sqrt( 2 * cfg.tankRadiusReal * currentLevel - pow(currentLevel, 2)) * (cfg.tankRadiusReal - currentLevel)) / 1000 * cfg.tankLengthReal; quantityToOrder = cfg.maxCapacity_90percent - currentInventory; } // end calculate inventory
Also die Formel stumpf und ohne Optimierung reingeklopft. Wird bei mir auch nur einmal pro Nacht gemessen und gerechnet.
Alle Variablen, die "cfg." davor haben, sind Teil eines Konfigurations-Structs, welches ich im EEPROM halte und persistent verstellen kann.Dabei bedeuten:
- quantityToOrder: Zu bestellende Ölmenge. Dabei ist in meinem Fall (Erdtank) zu beachten, daß der Tank nicht mehr als 90% befüllt werden darf. Das regelt die eingebaute (thermische) Füllstandssonde, die an das Tankfahrzeug angeschlossen wird.
- tankRadiusReal=79.00 - lichter Radius des Tanks in cm
- tankLengthReal=502.75 - lichte Länge des Tanks in cm
- maxCapacity_90percent=9472.00 - Max erlabte Fuellmenge bis zur 90Prozent Abschaltung
- fluidDensity=0.86 - Dichte des Mediums, Heizoel =0,86
- levelOffset=9.80 - Level-Offet in cm. >0 wenn Perlsonde höher als realer Tankgrund. Bei Euch wäre das die Höhe des Drucksensors über Grund
Wie schon andernorts hier im Thread erwähnt: Die Sache schnurrt bei mir jetzt schon >3 Jahre und bei der letzten Füllung wurde der Tankwagen durch die eingebaute Abschaltsonde exakt bei der bestellten Füllmenge angehalten. Auf den Liter genau bei einem 10.000 Liter Tank. War sicher auch Zufall dabei (Der Tankwagen hätte auch einen Tag früher oder später kommen können), aber die Genauigkeit ist sicher ausreichend. Trotz des in meinem Fall "windigen" (=pneumatischen) Verfahrens.
-
@klassisch
Danke für deinen Hinweis.
Hättest du die letzten Beiträge genauer gelesen, geht es mir eher drum die Berechnung in EspEasy umzusetzen oder in IoBroker.
Deine Formel ist mir, zugegeben durch Wiki bekannt und auch umsetzbar.
Für EspEasy wäre es nötig, die Berechnung mit einer Polynomial Funktion 5. Grades zu machen, da hier acos nicht verfügbar ist.
Alles nicht so Wild.Frohe Weihnachten.
-
@BastelKlaus Die Beiträge hatte ich gelese, aber EspEasy ist mir nicht geläufig. Als mir das zur Kenntnis kam, war ich schon weitgehend durch.
Es wurde ja auch überlegt, da Ganze in Arduino für ESP8266 umzusetzen - zumindest hatte ich das so verstanden.Zur Reihenentwicklung von arccos findet sich hier etwas https://mathepedia.de/Arkussinus_und_Arkuskosinus.html . Die Fehler bei 5. Grad und Argumenten im Intervall [-1, 1] habe ich nicht allerdings noch nicht gerechnet.
-
Seit gestern ist die Version 1.4 auf Github verfügbar. Ich habe ein Array eingefügt, welches die Meßdaten glättet und beruhigt.
Grüße Eisbaeeer -
Hallo Eisbaeeer,
habe die neue Version ausprobiert.
Läuft ganz gut, aber ich mußte die Zeile 311 von
percent = fuel * 0.132;
auf
percent = (fuel * dichte) / 10;
Danach zeigte das LCD Display die richtige Prozentzahl an.
Grüße
Manfred -
@Beowolf uups. Kann sein, dass ich da noch nen Bug drin hab. War gestern auch ein Schnellschuß mit andauernden Störungen von extern
-
Was mich auch wundert, ist aber nicht so schlimm, ich habe jetzt nach ca. 5 Minuten eine "Uptime von 66 Tagen und 16 Minuten."
-
@Beowolf Ja, da scheint auch noch ein Bug drin zu sein. Die Anzeige passt das noch nicht. Eventuell hab ich das noch eine falsche variablen Definition.
-
Hallöchen - lese schon ne ganze Weile mit - die Bautieile sind im Zulauf - mir fehlt noch die Sonde und das Ethernet-Shield. Ich habe mal versucht den Nano zu flashen und bekomme das hier:
avrdude: Version 6.3-20190619 Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/ Copyright (c) 2007-2014 Joerg Wunsch System wide configuration file is "/home/lutz/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf" User configuration file is "/home/lutz/.avrduderc" User configuration file does not exist or is not a regular file, skipping Using Port : /dev/ttyUSB0 Using Programmer : arduino Overriding Baud Rate : 57600 AVR Part : ATmega328P Chip Erase delay : 9000 us PAGEL : PD7 BS2 : PC2 RESET disposition : dedicated RETRY pulse : SCK serial program mode : yes parallel program mode : yes Timeout : 200 StabDelay : 100 CmdexeDelay : 25 SyncLoops : 32 ByteDelay : 0 PollIndex : 3 PollValue : 0x53 Memory Detail : Block Poll Page Polled Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- --------- eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00 calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00 signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00 Programmer Type : Arduino Description : Arduino Hardware Version: 2 Firmware Version: 1.16 Vtarget : 0.0 V Varef : 0.0 V Oscillator : Off SCK period : 0.1 us avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.00s avrdude: Device signature = 0x1e950f (probably m328p) avrdude: reading input file "/tmp/arduino_build_243251/Zisterne.ino.hex" avrdude: writing flash (29122 bytes): Writing | ################################################## | 100% 8.48s avrdude: 29122 bytes of flash written avrdude: verifying flash memory against /tmp/arduino_build_243251/Zisterne.ino.hex: avrdude: load data flash data from input file /tmp/arduino_build_243251/Zisterne.ino.hex: avrdude: input file /tmp/arduino_build_243251/Zisterne.ino.hex contains 29122 bytes avrdude: reading on-chip flash data: Reading | ################################################## | 100% 6.53s avrdude: verifying ... Beim Hochladen des Sketches ist ein Fehler aufgetreten avrdude: verification error, first mismatch at byte 0x7000 0xff != 0x19 avrdude: verification error; content mismatch avrdude done. Thank you.
Wenn man den Fehler googelt kommt ein Hinweis auf "zu groß" - welche Größe hat denndas binary bei euch? sind ggfls. die gebundenen Libs zu dick?
-
@ltathome Hast du das über die IDE hochgeladen? Siehr mir so aus, als ob du die compilierte Datei direkt hochlädst?
-
@Eisbaeeer Ja - ich hatte zwischenzeitlich auch den Bootloader nochmal neu gebraten, weil ich sicher gehen wollte, dass optiboot drauf ist (kleiner).
Im Moment hab ich das gelöst, indem ich per #ifndef HAS_DISPLAY... die ganzen Serial-Ausgaben und Aufrufe abgeklemmt habe.
Der Sketch ist aktuell bei mir jetzt 28428 Bytes groß bis 0x7000 = 28672 habe ich also noch gut 200 Bytes platz...
-
@ltathome Ich habe noch ein wenig experimentiert mit dem Code:
wenn man die Ermittlung der Uptime z.B. so macht und das Zusammenbauen des Strings nicht doppelt (an mehreren Stellen), dann kommt man mit der Code-Size runter (Fragmente):
... int secs = 0, mins = 0, hours = 0; int days = 0; char uptime[25]; ... void set_uptime() { secs++; secs = secs % 60; if (secs == 0) { mins++; mins = mins % 60; if (mins == 0) { hours++; hours = hours % 24; if (hours == 0) { days++; days = days % 10000; // Nach 9999 Tagen zurück auf 0 (das sind 27 Jahre....) } } } sprintf(uptime, "%4dd %2dh %2dm", days, hours, mins); } ... // System /* String upsum; upsum = String(days); upsum = String(upsum + "d "); upsum = String(upsum + hours); upsum = String(upsum + "h "); upsum = String(upsum + mins); upsum = String(upsum + "m"); upsum.toCharArray(buff, 25); */ client.publish("Zisterne/Uptime", uptime);
-
@ltathome machst du einen pull-request?
-
@Eisbaeeer kann ich gerne machen, wenn man mir sagt wie - bisher habe ich auschließlich gecloned. Damit ich mit meinen sonstigen Anpassungen (4-zeiliges Display) den Stand nicht verhunze, setz ich das nochmal ganz sauber separat auf.
-
@ltathome
Wäre cool. Du könntest z.B. über#define 4rowdisplay // 4x20 display oder 2x16 display
#if 4rowdisplay
... Code für 4 zeiliges Display
#endif
#if 2rowdisplay
... Code für 2 zeiliges Display
#endif
Das ganze konfigurierbar machen.
Einen Pull-request machst du ganz einfach aus dem fork heraus. Da gibt es einen Button.
Ich kann dir da gerne behilflich sein.
Gruß EisbaeeerP.S. du kannst den Stand gar nicht verhundsen. Erstens muss ich den pull-request vorher bestätigen und zweitens gibt es in github eine versionierung. Also nur zu!
-
@Eisbaeeer said in Füllstandsmessung per Pegelsonde.:
na dann ....Ich hätte den Code für 4x20 fertig. Ich sehe da noch ein Problem - aber vllt. liegt das auch an meiner Unwissenheit....
Ich habe dein Repo gecloned, in der IDE Zisterne.ino geöffnet - und dann mosert die IDE, dass sie gerne ein Verzeichnis "Zisterne" hätte, legt das Verzeichnis an und schiebt das File darein, der anschließende Compile mosert dann über ein fehlendes progress.h, was ich dadurch gelöst habe, dass ich das ebenfalls in den Ordner "zisterne" verschoben habe.
Dies nur als Vorwarnung - welchen Button meinst du? was ist jetzt das korrekte vorgehen? und sollen wir das "irgendwie" per Chat lösen? wir spammen hier den Thread voll....
-
Das wäre die Version mit den Anpassungen (jetzt korrigiert):