Zisternen Füllstandsüberwachung mittels Drucksensor (RPi3 + I2C Bus)

  • Hallo Zusammen,


    für meine Gartenbewässerung habe ich ein komplettes System aus mehren PIs aufgebaut, die verschiedene Aufgaben übernehmen und
    miteinander kommunizieren.

    Um zu Bestimmen, ob die Bewässerung aus der Zisterne erfolgen kann, oder der Hausanschluss verwendet soll war ein Punkt des Projekts
    den Zisternen-Füllstand zu überwachen.

    Zunächst hatte ich dies über einen Ultraschallsensor realisiert, war aber mit der Genauigkeit unzufrieden, vor allem bei Entfernungen von über einem
    Meter lieferten die Spielzeug sensor schon Abweichungen im Bereich von 20 bis 25cm.

    Also habe ich die Überwachung umgestellt auf eine Wasser-Druck-basierte Überwachung, dies erschien mir die logischste aller Kenngrößen.
    Hier eine Zusammenfassung, zum Ausschneiden und Nachbasteln :)

    Zunächst ein paar Gedanken zur Grundüberlegung:
    - Je nach Standort haben wir ca 1 bar Luftdruck, die täglichen Schwankungen sind vernachlässigbar.
    - Physikalisch gesehen ist das schöne, dass der Wasserdruck auf einen Punkt lediglich von der Höhe der Wassersäule abhängt, völlig egal wieviel liter dies sind, oder wie das Wasser geformt ist.
    - Hier ergibt sich pro 10m Wasser 1 bar Druck.

    - Meine Zisterne hat eine Recht übliche Zylinderform: 2m Durchmesser, 2,17 Höhe (bis Überlauf), das ergibt 6817l Volumen.

    Ich habe mir daher folgenden Drucksensor gekauft, dieser bildet einen Messbereich von 0-30 psi (ca 0 - 2 bar) auf den Bereich 0-5V ab (wenn er mit 5V betrieben wird)
    https://www.amazon.de/gp/product/B07YZKS27T/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&th=1 (Affiliate-Link)


    Da das Rasperry keine analoge Auswertung vornehmen kann, musste zusätzlich ein Analog-Digital-Converter her, habe folgenden gewählt:
    https://www.amazon.de/gp/product/B07DFX9Q4G/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1 (Affiliate-Link)
    (einen weiteren für künftige Spielereien)


    Aufbau
    Der Sensor ansich ist Wasserdicht, auch der Stecker wirkt optisch wasserdicht. Da das Teil jedoch mit ganzen 20cm Kabel geliefert wird, musste ich zwangsläufig etwas anbauen.
    Ich habe den Sensor also in eine herumliegende Klemmbox gebaut, mit Reste vom Pool-Kleber fixiert und das Gehäuse dann mit Kunstharz ausgegossen um a.) den Auftrieb zu entfernen und b) das ganze einfach 100% abzudichten.

    Das Kabel zum PI bzw. zum Analog-Digital-Converter ist etwa 5-Meter lang, stellt aber in der Praxis kein Problem dar, trotz der geringen Spannungen. Selbst wenn die Spannung hierdurch verfälscht werden würde, ist das egal, denn mich interessiert nicht, ob da unten jetzt 1.2bar oder 1.165bar herrschen - mich interessiert nur das delta zwischen "Voll" und "Leer".


    So sieht das vergoßene Gehäuse Gehäuse aus



    Links neben dem PI ist der Mini-Analog-Digital-Converter


    Auswertung & Programmierung

    Für den Betrieb der PIs verwende ich Java (Beruf Software-Entwickler) und die fs-based Steuerung des PIs.
    Zwar gibt es tolle, fertige Libraries, ich erfinde das Rad aber manchmal gerne neu - denn ich bin der Meinung, wenn man es 100% selbst gemacht hat, hat man es verstanden und kann dann ganz anders mit Fehlern umgehen.

    Betrieben mit 5V und folgender Konfiguration des Wandlers:

    Code
    i2cset -y 1 0x48 0x01 0x0342 w
                                 ^ ein Wort schreiben
                            ^----- Zu schreibende Konfiguration, siehe unten.
                       ^---------- In Register 1 schreiben
                  ^--------------- Gerät an Adresse 0x48 beschreiben
              ^------------------- I2C BUS 1 verwenden 
            ^--------------------- yes, keine Bestätigung
    ^----------------------------- Serienmäßiges Programm um I2C Befehle zu senden.


    Die Konfiguration für den Wandler ist sehr umfangreich (näheres ist im Datenblatt zu finden: https://www.ti.com/lit/gpn/ads1115) , der Wert "0x0342" hat folgende Effekte, zu beachten ist, dass die Werte in der Form 0xLSBMSB übertragen werden müssen:




    Wichtigste Eckdaten:
    - Betrieb 0 > egal, nur relevant für Betrieb.
    - Multiplexer 100 > AINP = AIN0 and AINN = GND (Ich möchte Eingang 0 vs GND messen)

    - Verstärkung 001 > +/-4,096V

    - Modus 0 > Kontinuirliche Messung.
    - Sampling Rate 000 > 8 Messungen pro Sekunde - das reicht völlig aus und je mehr, desto stärker die Varianz der Messwerte.

    - Kom. Mode > 0 , traditionell.
    - Alert stuff: brauchen wir nicht, deaktivieren -> Die letzte 11.


    Damit konnte ich für meinen Anwendungsfall folgende Werte ermitteln:


    Es ergibt sich beim Wandler "125 micro-Volt pro digit".

    Code
    Beschreibung    Spannung Sensor    Anzeige AD-Wandler
    Zisterne leer   0,70788V           5663
    Zisterne voll   1,10113V           8809

    Der Bereich des Sensors (0-2bar, 0-5V) ist damit natürlich nicht sehr sinnvoll ausgenutzt - Mein Messbereich ist wie erwähnt ca 1-1.2 bar.
    Dennoch ergibt sich hier ein delta von 3146 digits, die sich bequem und hinreichend genau auf 0-100% umrechnen lassen.

    Die Auswertung schwankt bei unveränderten Bedingungen etwa um +/- 20 digits. Auf den Bereich von 3146 digits bezogen bedeuted das,
    es ergibt sich ein Fehler von +/- 0,6357% - und auf das Volumen von 6817l bezogen, entspricht das +/- 43,3 Liter.

    Aber ich denke damit kann man leben.


    Damit die Zisternen-Füllstands-Anzeige nicht permanent schwankt, bilde ich immer den Durchschnitt über die letzten 60 Sekunden Messwerte. Das funktioniert ganz gut und ist hinreichend schnell in der Reaktion.

    Auslesung der Werte erfolgt im übrigen über das Tool "i2cget":


    Code
    i2cget -y 1 0x48 0x00 w


    Anmerkung hierzu: Auch das Ergebnis der Auslesung ist in der Form 0xLSBMSB, das habe ich für diese Sensor-Klasse einfach hardcoded, bsp:




    Jo, das wars im Prinzip soweit. Auf Programmierung und Co gehe ich jetzt nicht im Detail ein, da hier jeder eigene Vorlieben hat.
    Wer aber konkrete Fragen hat, wie ich was in Java gemacht habe, kann mir diese natürlich gerne stellen.


    Die PIs werden noch vom Gira-Homeserver ausgelesen und dort findet auch die "Benutzerfreundliche" Anzeige und Steuerung statt:

    Sensor auf Tauchstation:



    Sensor an der Luft (aka "Zisterne leer")


    Edited 2 times, last by dognose ().

  • Auswertung & Programmierung

    Für den Betrieb der PIs verwende ich Java (Beruf Software-Entwickler) und die fs-based Steuerung des PIs.
    Zwar gibt es tolle, fertige Libraries, ich erfinde das Rad aber manchmal gerne neu - denn ich bin der Meinung, wenn man es 100% selbst gemacht hat, hat man es verstanden und kann dann ganz anders mit Fehlern umgehen.

    Da bin ich einer von sehr wenigen, die da voll bei Dir sind...



    Beste Grüsse


    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    • Icon-Tutorials (IDE: Geany) - GPIO-Library - µController-Programmierung in Icon! - ser. Devices - kein Support per PM / Konversation

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • Kleiner Nachtrag hierzu:


    Da wir demnächst in den Urlaub fahren und es bei uns schon ewig nicht geregnet hat, habe ich die Zisterne mal mit 6500 liter Leitungswasser gefüllt.
    Das reicht den Urlaub über und ich kann den Hausanschluss abdrehen. (Software is noch a bisserl "jung", nicht, dass da nachher was 24/7 läuft weil irgendwo ne Nullpointer-Exception auftritt.)


    Dabei habe ich aber gemerkt, dass der Messwert doch stark temperaturabhängig zu sein scheint. Ich denke mal, dass die gesamt 6-8m Kupferleitung, die dann im kalten oder warmen Wasser sind bei werten von 0.5 bis 1.1 Volt doch einen signifikanten impact in Sachen Widerstand haben.


    Daher habe ich das ganze mal noch Software-Seitig etwas optimiert:


    Das System lernt ohnehin neue Min- und Max- Werte automatisch, allerdings bislang nur expandierend. Das habe ich nun noch wie folgt optimiert:


    automatische 0-Punkt-Kalibrierung:

    Die Tauchpumpe hat natürlich einen Trockenlaufschutz, wenn Sie kein Wasser mehr zieht schält Sie ab. Während des Bewässerns überwache ich die Durchflussmenge pro "zu bewässerndem Bereich" - und wenn einer da nichts mehr geliefert hat, kann ich sagen "Zisterne is leer" - In dem Fall resete ich den Nullpunkt der Füllstandsüberwachung. (Die Bewässerung würde dann für die nächste Sektion auf "Hausanschluss" umschalten)


    automatische MAX-Punkt-Kalibrierung:
    Idealer Weise werde ich hier ggf. noch einen Schwimmschalter o.ä. verbauen, sodass ich bei "Voll" den maximalen Messwert der Füllstandsüberwachung automatisch kalibrieren kann. Auf die schnelle fehlte mir da die Zeit, leider kein "Freies" Adernpaar mehr in der Zisterne, müsste ich nochmal buddeln.


    Daher habe ich die automatische Max-Wert Kalibrierung derzeit rein Software-Seitig und wie folgt gelöst:

    Wenn mein Regensensor beginnt Regen zu erfassen, wird alle 30 Minuten der aktuelle Füllstandswert (Digits) gespeichert. Zeitgleich werte ich den Zustand im Vergleich zu vorherigem Speicherpunkt aus, wenn es tatsächlich "signifikant" regnet (hier habe ich mal 3mm / h angesetzt, das muss ich noch beäugen):


    - ist der Aktuelle Messwert immer noch +/-5% des gespeicherten Messwerts ist, setze ich diesen Wert als neues Maximum. (Annahme: Zisterne ist voll, Wasser fließt halt durch)

    - Ist der aktuelle Messwert höher als der gespeicherte Wert, passiert nichts. (Dann war die Zisterne beim 1ten Messwert nicht voll, der Zweite liegt folglich höher.)


    Das ist nicht ganz optimal, aber bis ich dafür einen dedizierten Sensor platziert habe ist es das beste, was ich aus den vorhandenen Messwerten ableiten kann.