Beim letzten Starkregen (welcher in Deutschland ja verheerende Schäden angerichtet hat) kam auch bei uns die Kanalisation nicht mehr mit. Gott sei Dank gab es nicht so große Probleme wie anderswo, aber unsere Zisterne ist übergelaufen und dadurch ist mein Sensor in der Zisterne abgesoffen.
Interessanterweise läuft der ESP8266 noch problemlos, aber die Messung liefert Mondwerte.
Das war mal wieder der Startschuss die Sensorik erneut zu ändern… Jetzt steige ich auf einen Drucksensor um, der mir einen Strom zwischen 4mA und 20mA liefert (je nach Wasserstand). Das ganze nennt sich Stromschleife. Das ist für mich erstmal neuDas scheint in der Industrie durchaus üblich zu sein, da Störeinflüsse minimiert werden. Wiki sagt dazu folgendes: https://de.wikipedia.org/wiki/Stromschnittstelle
Mein Plan ist Elektronik und Sensor wieder zu trennen. Der Sensor wird in der Zisterne versenkt, die Elektronik kommt ins Pumpenhaus.
Zunächst also einmal einen Stromsensor (China-Ware) besorgt. Der hatte auch direkt ein passend langes Kabel und macht trotz zweifelhafter Herkunft einen vernünftigen und wertigen Eindruck.
Doch wie bringt man einem ESP8266 bei Strom zu messen? Sicher gibt es viele Möglichkeiten, doch ich entscheide mich ganz simpel für einen (passenden) Widerstand, an dem die gewünschte Spannung abfällt.
Wir erinnern uns kurz zurück an die Schule: Da war mal was das hieß “U = I * R”
Und ich möchte das an meinem ADC, wenn der Sensor 20mA liefert eine Spannung von 3.3V anliegt. Das ist die Betriebsspannung meines ESP8266.
Das heißt: R = 3,3V / 0,020A = 165 Ohm -> Ich nehme also einen 150 Ohm Widerstand.
Bei minimaler und maximaler Wassertiefe (= Stromfluss) ergeben sich dann folgende Spannungen.
V = 0,004A * 150 Ohm = 0,6V (minimal)
V = 0,020A * 150 Ohm = 3,0V (maximal)
Das passt also, auch wenn ich nicht den ganzen Messbereich des ADC ausschöpfe!
Jetzt möchte ich den µC noch gegen Spannungen die größer als VCC (=3,3V) + 0.6V sind schützen und den Strom auf unter 0,1mA bringen. Kann ja immer mal passieren das irgendwo ein Kurzschluss entsteht oder beim Aufbau Kabel vertauscht werden.
R= (24V-(3,3V+0,6V)) / 0,0009A = 22333 Ohm -> Ich nehme also einen 27k Widerstand.
So sieht die modifizierte Schaltung nun aus:
Jetzt schaut man sich den Schaltplan an und denkt: Ok, R2 = 27kOhm, das ist also der Schutzwiderstand.
Aber sollte R3 lt. Berechnung nicht 150 Ohm sein? Warum steht im Schaltplan 50 Ohm?
Das liegt daran, das ich in die Falle meines ESP-Moduls getappt bin. Nachdem ich das so gebaut hatte und der ADC irgendwie nichts sinnvolles gemessen hat, habe ich etwas Datenblätter gewälzt und festgestellt, das die “rohen” ESP-Module – wie ich sie verwende – einen Spannungsbereich am ADC von 0-1V erwarten (trotz 3,3V Betriebsspannung). Es gibt Module da ist direkt ein Spannungsteiler eingebaut, bei meinem nackten Modul aber nicht.
Also nochmal neu gerechnet:
R = 1.0V / 0,020A = 50 Ohm -> Ich nehme also einen 51 Ohm Widerstand.
Der Schutzwiderstand bleibt gleich.
Proberechnung:
V = 0,004A * 50 Ohm = 0,2V (minimal)
V = 0,020A * 50 Ohm = 1,0V (maximal) (hier liefert der ADC dann den Wert 1023)
Dann sieht man eine zweite Spannungsquelle im Schaltplan. Das liegt daran, das der Sensor 24V benötigt. Dazu nutze ich einen simplen Step-Up-Wandler, der aus den 5V vom Netzteil 24V macht. Um nicht unnötig Strom zu verbrauchen schalte ich den Step-Up-Wandler über einen Transistor vor der Messung an. Als Transistor habe ich das genommen was noch so rumlag. Da kaum Ströme fließen sollte jeder NPN Transistor gehen. Wichtig ist nur, das er bei den 3,3V des digitalen Ausgangs komplett durchschaltet.
Ich habe dann die bestehende Schaltung auf der vorhandenen Lochrasterplatine entsprechend erweitert.
Man sieht meine geliebte (aber sehr labile) Wurfverkabelung, mit der ich quasi immer arbeite. 😉
Im Hintergrund ist der USB->Seriell Konverter zu sehen (zum Programmieren) und vorne links, unter der Platine ist der Step-Up-Wandler. Die Platine ist jetzt durch das aus- und einlöten diverser Bauteile ganz schön verbraten, aber muss ja auch keinen Schönheitspreis gewinnen.
Ordentlich verpackt in eine Abzweigdose die rumlag sieht es dann so aus.
Wie man sieht habe ich das Kabel vom Sensor mit einem Hohlstecker versehen, damit ich die Elektronik für Wartungszwecke leicht vom Sensor trennen kann.
Jetzt fehlt noch der angepasste Arduino Sketch:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
const int sensorEnable = 15; // PIN für den Transistor zum aktivieren des Step-Up-Wandlers
const byte sensorPin = A0; // ADC für den sensor
const uint16_t resistor = 51; // Eingesetzter Pull-Down Widerstand
const int maxAdcWennVoll = 472; // Prozentuale Umrechnung
ESP8266WebServer server(80); // Webserver
WiFiClient client;
void setup() {
Serial.begin(115200);
IPAddress ip(192, 168, X, Y);
IPAddress gateway(192, 168, X, Z);
IPAddress subnet(255, 255, 255, 0);
WiFi.config(ip, gateway, subnet);
WiFi.begin("**netzwerk**", "**geheim**");
Serial.print("Connecting");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("Connected, IP address: ");
Serial.println(WiFi.localIP());
server.on("/", handle_normal);
server.on("/hs", handle_hs);
server.on("/hs/1", handle_hs);
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("http server startet");
pinMode(sensorEnable, OUTPUT);
digitalWrite(sensorEnable, LOW);
pinMode(sensorPin, INPUT);
}
void loop() {
server.handleClient();
}
void handle_NotFound(){
server.send(404, "text/plain", "Not found");
}
void handle_normal() {
Serial.println("handle /");
long pressure = measurePressure();
long percent = pressure * 100 / maxAdcWennVoll; //umrechnen auf prozent
String msg = String("<!DOCTYPE html><html>") +
"<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" +
"<link rel=\"icon\" href=\"data:,\">" +
"<body><h1>Zisterne Measusement Server</h1>" +
"<p>Use get parameter hs for homeserver</p>" +
"<p>Exampe: /hs/1</p>" +
"<br><br><p>Current pressure: " + String(pressure) + "</p>" +
"<br><br><p>Current percent: " + String(percent) + "</p>" +
"</body></html>\r\n" ;
server.send(200, "text/html", msg);
}
void handle_hs() {
Serial.println("handle /hs");
long pressure = measurePressure();
long percent = pressure * 100 / maxAdcWennVoll; //umrechnen auf prozent
String msg = String("D=" + String(percent) + "\r\n");
server.send(200, "text/html", msg);
}
int measurePressure() {
Serial.println("setting 24v on");
digitalWrite(sensorEnable, HIGH);
delay(5*1000); //auf sensor warten
Serial.println("start measuring");
int myValue = doMeasure();
Serial.println("done measuring");
Serial.println("setting 24v off");
digitalWrite(sensorEnable, LOW);
return myValue;
}
int32_t doMeasure() {
float minAdc = 0.004 * resistor * 1024;
float maxAdc = 0.020 * resistor * 1024;
int adc = 0;
for (byte i = 0; i < 3; i++)
{
int m = analogRead(sensorPin);
Serial.println("adc" + String(m));
adc += m;
delay(10);
}
adc = adc / 3;
int32_t value = (adc - minAdc) * int32_t(1023) / (maxAdc - minAdc);
if (value > 1023) value = 1023;
else if (value < 0) value = 0;
return value;
}
Ich hoffe das diese Version jetzt rebust genug ist und der China-Sensor auch ein paar Jahre durchhält.