Willkommen zurück zum zweiten Teil der Serie „Tiefbrunnenpumpen Steuerung“.
Im heutigen Blogbeitrag wollen wir die im ersten Teil verwendeten Klappschwimmschalter durch einen Ultraschall Sensor ersetzen. Der geneigte Leser mag sich nun vielleicht fragen, wozu das gut sein soll! Hierfür gibt es mehrere Gründe.
Der erste Grund ist, dass die Befestigung des Schwimmers bei vielen Klappschwimmschaltern aus einem Teflon Band oder einem Kunststoff Band besteht. Die dauerhafte mechanische Belastung durch das Heben und Senken des Schwimmkörpers führt dazu, dass diese mit der Zeit brüchig wird und irgendwann reißt. Passiert dies unbemerkt, z.B. beim oberen Schalter, so haben wir keinen „Sensor“ mehr, der uns mitteilt, wenn das Fass vollgelaufen ist – die Tiefbrunnenpumpe pumpt dann weiter Wasser in das Fass und es läuft über. Ein Wasserschaden wäre der Fall!
Der zweite Grund ist, und diesen finde ich persönlich viel wichtiger, dass wir unter Verwendung der Klappschwimmschalter nicht wissen können, wie viel Wasser sich aktuell im Fass befindet. Plant man also, demnächst den Garten zu bewässern oder den Fischteich aufzufüllen, benötigt man also eventuell mehr Wasser, als vorhanden ist. Das am Fass angeschlossene Hauswasserwerk zieht mehr Wasser aus dem Fass ab, als die Tiefbrunnenpumpe fördert. Folglich könnte das Fass unbemerkt schnell leer laufen.
Hier hilft uns der Ultraschall Sensor. Mit ihm können wir den Wasserpegel im Fass bis auf einen Zentimeter genau messen. Damit und mit den Maßen des Fasses können wir den Füllstand berechnen.
Der Ultraschall Sensor
Der Ultraschall Sensor besteht aus einem Sende-Modul (40kHz Signal), einem Empfänger-Modul (im Prinzip ein Mikro) und einem Kontroll-Chip. Ausgelöst wird die Messung, wenn am Trigger Pin für mind. 10µs eine LOW-HIGH-LOW Flanke anliegt. Dann sendet das Sende-Modul acht kurze Ultraschall Impulse und liefert über den Echo Pin ein HIGH Signal für die Dauer des reflektierten Signals. Dieses Signal müssen wir dann in eine Entfernung umrechnen.
Bei der Schallgeschwindigkeit müssen wir beachten, dass diese von der Umgebungstemperatur abhängig ist. Daher muss zum Grundwert der Schallgeschwinditkeit noch eine Temperaturkorrektur hinzugefügt werden. Daraus ergibt sich dann für 20°C eine Schallgeschwindigkeit von:
331,5 m/s + (0,6 * 20) = 343,5m/s
Da unser Signal aber nicht in Metern pro Sekunden gemessen wird, sondern in cm pro µs, müssen wir die Schallgeschwindigkeit noch von m/s in cm/µs umrechnen. Dies erfolgt, in dem wir den Wert von 343,5m/s zunächst durch 1000^2 dividieren und anschließend mit 100 multiplizieren:
343,5m/s / 1000^2 * 100 = 0,03435cm/µs
Die Entfernungsmessung über die Laufzeit des Signals erfolgt nach folgender Formel:
Distanz = (Schallgeschwindigkeit in cm/µs) * Signalzeit / 2
Die Laufzeit muss durch zwei geteilt werden, da das Signal ja einen Hin- und eine Rückweg hat – es wird ja reflektiert.
Die Formel zum Berechnen des Füllstandes und der Wassermenge
Das Volumen des Fasses können wir über das Volumen für Zylinder berechnen. Dabei müssen wir ein wenig idealisieren, da das Fass kein reiner Zylinder ist, sondern im unteren und oberen Bereich leicht nach innen hin abfällt. Dies ist aber für uns vernachlässigbar.
Das Fass hat folgende Maße: Höhe (h) = 98cm, Durchmesser (d) = 57cm. Das Volumen ergibt sich wie folgt:
V = (d/2)^2 * 3,141 * h = 250025,1705 cm^3 = 250L
Im Programm berechnen wir dann über folgende Formel zunächst die Füllstandhöhe in Prozent:
waterLevel = (1-(gemesseneDistanz/Fasshöhe))*100;
Daraus leiten wir dann später (für den dritten Teil dieser Serie) die tatsächlich vorhandene Wassermenge ab:
waterQuantity = waterLevel * 250 / 100;
Der Schaltungsaufbau auf dem Breadboard
Betrachten wir den Breadboard Aufbau, so fällt auf, dass nicht nur die Klappschwimmschalter verschwunden sind, sondern neben dem Ultraschall Sensor noch ein Bauteil hinzugekommen ist: ein Logic Level Converter. Dieser ist notwendig, da die GPIO Pins des ESP32 nur mit 3,3V angesteuert werden dürfen. Da der Ultraschallsensor aber mit 5V arbeitet, müssen wir die Spannungspegel des Sensors auf das Niveau des ESP32 bringen. Dies übernimmt der Logic Level Converter für uns.
Der Logic Level Converter
Bei dem hier verwendeten Logic Level Converter handelt es sich um einen 8-kanäligen bi-direktionalen Converter. Soll heißen, er kann bis zu acht Signale gleichzeitig von A nach B oder von B nach A wandeln. Die Beschaltung ist in unserem Fall sehr einfach:
VA | 3.3V |
OE | 3.3V (Output Enabled) |
VB | 5V |
GND | GND (Masse) |
A1 | GPIO21 (Trigger Signal des Ultraschall Sensors) |
A2 | GPIO22 (Echo Signal des Ultraschall Sensors) |
B1 | Trigger Pin des Ultraschall Sensors |
B2 | Echo Pin des Ultraschall Sensors |
Alternative zum Logic Level Converter
Alternativ zum Logic Level Converter, solltet ihr keinen zur Verfügung haben, könnt ihr auch einen Spannungsteiler verwenden. Ein Spannungsteiler ist, simpel gesprochen, eine Reihenschaltung von Widerständen. Im einfachsten Fall, wie dem unseren, besteht diese Reihenschaltung aus zwei Widerständen. Die Widerstände werden so gewählt, dass die Spannung zwischen dem ersten und zweiten Widerstand auf 1/3 zu 2/3 aufgeteilt wird. Exemplarisch ein Breadboard Aufbau.
Die Spannungsversorgung des Breadboard liefert 5V, so wie es der Ultraschall Sensor auch tun würde. Das Verhältnis der Widerstände, hier ein 10k und ein 22k Widerstand, ist ca. 1/3 zu 2/3. Messen wir die Spannung am zweiten Widerstand (gelbe Leitung), so bekommen wir ca. 3.4V. Damit können wir bedenkenlos auf die GPIO Pins des ESP32 gehen.
Der Sketch
// 2020-03-02 Brunnenpumpe V2
// (c) Markus Pohle @Creative Commons BY-NC-SA
// https://en.wikipedia.org/wiki/File:Cc-by-nc-sa_icon.svg
//
// Brunnenpumpen Steuerung mittels Ultraschall-Sensor
const int relayPin = 23;
const int triggerPin = 22;
const int echoPin = 21;
const int barrelHeight = 98;
int pumpActive = 0;
float waterLevel = 0;
void setup() {
// Serial.begin(115200);
pinMode(relayPin, OUTPUT);
// PIN-Modes
pinMode(triggerPin, OUTPUT);
pinMode(echoPin, INPUT);
digitalWrite(triggerPin, HIGH);
}
float distance() {
float d = 0;
long t = 0;
noInterrupts();
digitalWrite(triggerPin, LOW);
delayMicroseconds(3);
digitalWrite(triggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(triggerPin, LOW);
t = pulseIn(echoPin, HIGH);
d = (t/2) * 0.03435;
interrupts();
return(d);
}
void loop() {
waterLevel = (1-(distance()/barrelHeight))*100;
if (!pumpActive && (waterLevel <= 15) ) {
pumpActive = 1;
}
if (pumpActive && (waterLevel >= 92) ) {
pumpActive = 0;
}
// Serial.println(waterLevel);
// vor der nächsten Messung warten wir eine Sekunde
delay (1000);
if (pumpActive) {
digitalWrite(relayPin, HIGH);
} else {
digitalWrite(relayPin, LOW);
}
}
Der Sketch unterscheidet sich nicht sonderlich viel vom Sketch des ersten Teils. Wir definieren wieder einige Konstanten (die GPIO Pins) und Variablen. In der setup() Routine definieren den Relay Pin als OUTPUT, das gleiche gilt für den Trigger Pin. Den Echo Pin definieren wir als INPUT (wir wollen ja das ECHO Signal des Ultraschall Sensors darüber einlesen).
Interessant ist dann noch das eigentliche Messen. Hierzu deaktivieren wir zunächst die Interrupts des ESP32 – sicher ist sicher. Dann ziehen wir den Trigger Pin für 3µs auf LOW, anschließend für 10µs auf HIGH und danach wieder auf LOW. Dies löst beim Ultraschall Sensor die Messung aus, dessen Ergebnis wir dann über den ECHO Pin auslesen können. Nachdem die Messung (und die Berechnung der Entfernung) abgeschlossen ist, schalten wir die Interrupts wieder ein.
In der loop() Schleife führen wir dann die Distanzmessung aus (Besonderheit hier bei unserer Formel: wir bestimmen anhand des gemessenen Abstands zu wie viel Prozent das Fass gefüllt ist). Über zwei if Abfragen zum zuvor berechneten Füllstand legen wir dann fest, ob das Relay geschaltet werden muss oder nicht.
Das Sensor Gehäuse
Wenn wir so weit sind, dass wir die Schaltung zur Steuerung der Tiefbrunnenpumpe verbauen, müssen wir uns auch Gedanken über ein Gehäuse für den Ultraschall Sensor machen. Dieser wird ja innerhalb des Fasses mittig auf die Unterseite des Fassdeckels montiert werden müssen, damit er vernünftig messen kann. Daher habe ich mittels TinkerCAD ein passgenaues Gehäuse für den Sensor erstellt.
Verschraubt werden Gehäusekörper und Deckel mittels M3 Gewinde-Schrauben und Muttern. Damit diese gut ins Gehäuse eingesetzt werden können, habe ich hier bereits entsprechende Aufnahmen direkt beim Erstellen der CAD Vorlage vorgesehen. Die Mutter wird dabei mit leichtem Druck in die vorgesehene Öffnung gepresst. Dies bietet den Vorteil, dass man beim Eindrehen der Schraube die Mutter nicht mehr kontern muss, da sie sich nicht mehr mitdrehen kann.
Die .stl Dateien zum Slicen für den 3D Druck finden sich hier…
Viel Spaß beim Nachbauen
Markus Pohle