Zisterne 4.0 + Nextion Display ohne Internet / WLAN Router (UPD)
In diesem Beitrag geht es um einen Füllstandsanzeige für eine Zisterne, Brunnen oder einen Wassertank. Sicher gibt es noch viele weitere Anwendungsgebiete.
Das besondere an diesem Projekt ist, man kann es überall einsetzten wo kein WLAN / Internet zur Verfügung steht. Wie zum Beispiel abgelegene Gartenanlagen oder ähnliches.
Es werden hier 2 ESP8266 Boards benötigt, dass eine Board fungiert als Sender und das andere Board als Empfänger. Die Ausgabe wird über ein Nextion Display 3.5 Zoll realisiert. Als Übertragungprotokoll wird UPD verwendet.
Das Empfängerboard wird normal mit Stromversorgt. Das Senderboard kann hier mit einem Akku betrieben werden. Beim Lolin D1 mini Pro v2 ist die Ladeelektronik mit auf der Platine. Wenn hier eine Spannungquelle an den USB Port angeschlossen wird, wird der Akku geladen.
Alternativ kann auch der D1 mini Pro v1 verwendet werden. Hier muss dann das Batterie Schield mit genutzt werden.
Was wird für das Projekt benötigt.
1. Installation ESP8266 in der Arduino IDE
Welche Bauteile werden benötigt.
Der Sender sendet 3 Datenpacket. 1. die Batteriespannung, 2. die Nummer der letzten Messung und 3. die Messdaten vom Ultraschallsensor.
Der Empfänger empfängt die Daten und teilt sie auf zur Weitergabe an das Nextion Display.
#include
#include
#include
#ifndef STASSID
#define STASSID "WIFI_UPD_R"
#define STAPSK "123456789+"
#endif
IPAddress ip(192, 168, 10, 10);
IPAddress gateway(192, 168, 10, 1);
IPAddress subnet(255, 255, 255, 0);
unsigned int sendPort = 9500;
int trigger = 2;
int echo = 4;
long dauer = 0;
int counter = 0;
unsigned int raw = 0;
float batt = 0.0;
long wasser = 0;
const int sleepSeconds = 2000;
WiFiUDP Udp;
void setup() {
pinMode(A0, INPUT);
Serial.begin(115200);
pinMode(trigger, OUTPUT);
pinMode(echo, INPUT);
WiFi.mode(WIFI_STA);
WiFi.config(ip, gateway, subnet);
WiFi.begin(STASSID, STAPSK);
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(500);
}
Serial.print("Connected! IP address: ");
Serial.println(WiFi.localIP());
Serial.printf("UDP server on port %d\n", sendPort);
Udp.begin(sendPort);
}
void batt_status()
{
raw = analogRead(A0);
batt = raw / 1023.0;
batt = batt * 4.2;
}
void zeit()
{
counter++;
EEPROM.write(1, counter);
Serial.println(counter);
if (counter >= 21)
{
counter = 0;
EEPROM.write(1, counter);
EEPROM.commit();
EEPROM.end();
ESP.reset();
}
}
void loop() {
EEPROM.begin(512);
counter = EEPROM.read(1);
batt_status();
zeit();
digitalWrite(trigger, LOW);
delay(5);
digitalWrite(trigger, HIGH);
delay(10);
digitalWrite(trigger, LOW);
dauer = pulseIn(echo, HIGH);
wasser = (dauer / 2) / 29.1;
for (int i=0; i <= 3; i++){
Udp.beginPacket(gateway, sendPort);
Udp.write("Batterie:");
Udp.print(batt);
Udp.write(";count:");
Udp.print(counter);
Udp.write(";wasser:");
Udp.print(wasser);
Udp.endPacket();
delay(1000);
}
EEPROM.commit();
EEPROM.end();
delay(3000);
ESP.deepSleep(sleepSeconds * 1000000);
}
#include
#include
#include
#ifndef STASSID
#define STASSID "WIFI_UPD_R"
#define STAPSK "123456789+"
#endif
IPAddress ip(192, 168, 10, 10);
IPAddress gateway(192, 168, 10, 1);
IPAddress subnet(255, 255, 255, 0);
unsigned int sendPort = 9500;
// Ultraschallsensor
int trigger = 2;
int echo = 4;
long dauer = 0;
// Zähler für die Messreihe
int counter = 0;
// Variablen für die Batterie und dem Wasserstand
unsigned int raw = 0;
float batt = 0.0;
long wasser = 0;
// Zeit für den DeepSleep in Sekunden
const int sleepSeconds = 2000;
WiFiUDP Udp;
void setup() {
pinMode(A0, INPUT);
Serial.begin(115200);
pinMode(trigger, OUTPUT);
pinMode(echo, INPUT);
WiFi.mode(WIFI_STA);
WiFi.config(ip, gateway, subnet);
WiFi.begin(STASSID, STAPSK);
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(500);
}
Serial.print("Connected! IP address: ");
Serial.println(WiFi.localIP());
Serial.printf("UDP server on port %d\n", sendPort);
Udp.begin(sendPort);
}
void batt_status()
{
raw = analogRead(A0);
batt = raw / 1023.0;
batt = batt * 4.2;
}
void zeit()
{
counter++;
EEPROM.write(1, counter);
if (counter >= 21)
{
counter = 0;
EEPROM.write(1, counter);
EEPROM.commit();
EEPROM.end();
ESP.reset();
}
}
void loop() {
// EEPROM Starten
EEPROM.begin(512);
// Zähler aus dem EEPROM lesen
counter = EEPROM.read(1);
batt_status();
zeit();
// Ultraschallmessung
digitalWrite(trigger, LOW);
delay(5);
digitalWrite(trigger, HIGH);
delay(10);
digitalWrite(trigger, LOW);
dauer = pulseIn(echo, HIGH);
wasser = (dauer / 2) / 29.1;
// Daten werden gesendet, zur sicherheit 3x im ein Sekundenabstand
for (int i=0; i <= 3; i++){
Udp.beginPacket(gateway, sendPort);
Udp.write("Batterie:");
Udp.print(batt);
Udp.write(";count:");
Udp.print(counter);
Udp.write(";wasser:");
Udp.print(wasser);
Udp.endPacket();
delay(1000);
}
// EEPROM schließen
EEPROM.commit();
EEPROM.end();
delay(3000);
// deepSleep ausführen
ESP.deepSleep(sleepSeconds * 1000000);
}
#include
#include
#include
#ifndef APSSID
#define APSSID "WIFI_UPD_R"
#define APPSK "123456789+"
#endif
SoftwareSerial nextion(12, 13); // RX, TX
IPAddress ip(192, 168, 10, 1);
IPAddress gateway(192, 168, 10, 10);
IPAddress subnet(255, 255, 255, 0);
unsigned int recivePort = 9500;
// buffers für Empfangene Daten
char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; //buffer to hold incoming packet,
char * values[3];
char * buf[3];
float batt;
unsigned int w_stand_txt;
unsigned int w_stand;
WiFiUDP Udp;
void setup() {
nextion.begin(9600);
Serial.begin(115200);
Serial.println();
Serial.print("Configuring access point...");
WiFi.softAPConfig(ip, gateway, subnet);
WiFi.softAP(APSSID, APPSK);
delay(500);
Serial.print("AP IP address: ");
Serial.println(WiFi.softAPIP());
Serial.printf("UDP server on port %d\n", recivePort);
Udp.begin(recivePort);
nextion.print("p0.pic=");
nextion.print(0);
sendTOdisplay();
}
void sendTOdisplay()
{
nextion.write(0xFF);
nextion.write(0xFF);
nextion.write(0xFF);
}
void loop() {
String cmd;
cmd += "\"";
// sind Daten vorhanden, lese ein packet
int packetSize = Udp.parsePacket();
if (packetSize) {
// lese das packet in packetBufffer
int n = Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
packetBuffer[n] = 0;
//Empfangene Daten zerlegen
char* ptr = strtok(packetBuffer, ";");
for (byte i = 0; i < sizeof(values) / sizeof(values[0]); i++)
{
values[i] = ptr;
ptr = strtok(NULL, ";");
}
buf[0] = strtok(values[0], ":");
batt = atof(strtok(NULL, ":")); //Batterie Wert
buf[1] = strtok(values[1], ":");
buf[2] = strtok(NULL, ":"); // Counter
buf[3] = strtok(values[2], ":");
w_stand_txt = atof(strtok(NULL, ":")); // Messwert Ultraschallsensor
//Daten an das Display senden
nextion.print("batterie.txt=" + cmd + batt);
nextion.print(" V" + cmd);
sendTOdisplay();
nextion.print("zeit.txt=" + cmd + buf[2] + cmd);
sendTOdisplay();
nextion.print("w_stand.txt=" + cmd + w_stand_txt + cmd);
sendTOdisplay();
w_stand = w_stand_txt * 0.1666667; // Berechnung für die Seule
w_stand = 100 - w_stand; // Berechnung für die Seule
nextion.print("wstand.val=");
nextion.print(w_stand);
sendTOdisplay();
if (batt >= 3.8 && batt <= 4.1)
{
nextion.print("p0.pic=");
nextion.print(4);
sendTOdisplay();
}
if (batt >= 3.5 && batt <= 3.8)
{
nextion.print("p0.pic=");
nextion.print(3);
sendTOdisplay();
}
if (batt >= 3.3 && batt <= 3.5)
{
nextion.print("p0.pic=");
nextion.print(2);
sendTOdisplay();
}
if (batt >= 0 && batt <= 3.3)
{
nextion.print("p0.pic=");
nextion.print(1);
sendTOdisplay();
}
delay(100);
}
}
#include
#include
#include
#ifndef APSSID
#define APSSID "WIFI_UPD_R"
#define APPSK "123456789+"
#endif
SoftwareSerial nextion(12, 13); // RX, TX
IPAddress ip(192, 168, 10, 1);
IPAddress gateway(192, 168, 10, 10);
IPAddress subnet(255, 255, 255, 0);
unsigned int recivePort = 9500;
// buffers für Empfangene Daten
char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; //buffer to hold incoming packet,
char * values[3];
char * buf[3];
float batt;
unsigned int w_stand_txt;
unsigned int w_stand;
WiFiUDP Udp;
void setup() {
nextion.begin(9600);
Serial.begin(115200);
Serial.println();
Serial.print("Configuring access point...");
WiFi.softAPConfig(ip, gateway, subnet);
WiFi.softAP(APSSID, APPSK);
delay(500);
Serial.print("AP IP address: ");
Serial.println(WiFi.softAPIP());
Serial.printf("UDP server on port %d\n", recivePort);
Udp.begin(recivePort);
// Nextion Display Batterie Bild auf leer setzen.
nextion.print("p0.pic=");
nextion.print(0);
sendTOdisplay();
}
// sind Daten vorhanden, lese ein packet
int packetSize = Udp.parsePacket();
if (packetSize) {
// lese das packet in packetBufffer
int n = Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
packetBuffer[n] = 0;
//Empfangene Daten zerlegen
char* ptr = strtok(packetBuffer, ";");
for (byte i = 0; i < sizeof(values) / sizeof(values[0]); i++)
{
values[i] = ptr;
ptr = strtok(NULL, ";");
}
buf[0] = strtok(values[0], ":");
batt = atof(strtok(NULL, ":")); //Batterie Wert
buf[1] = strtok(values[1], ":");
buf[2] = strtok(NULL, ":"); // Counter
buf[3] = strtok(values[2], ":");
w_stand_txt = atof(strtok(NULL, ":")); // Messwert Ultraschallsensor
//Daten an das Display senden
nextion.print("batterie.txt=" + cmd + batt);
nextion.print(" V" + cmd);
sendTOdisplay();
nextion.print("zeit.txt=" + cmd + buf[2] + cmd);
sendTOdisplay();
nextion.print("w_stand.txt=" + cmd + w_stand_txt + cmd);
sendTOdisplay();
w_stand = w_stand_txt * 0.1666667; // Berechnung für die Seule
w_stand = 100 - w_stand; // Berechnung für die Seule
nextion.print("wstand.val=");
nextion.print(w_stand);
sendTOdisplay();
if (batt >= 3.8 && batt <= 4.1)
{
nextion.print("p0.pic=");
nextion.print(4);
sendTOdisplay();
}
if (batt >= 3.5 && batt <= 3.8)
{
nextion.print("p0.pic=");
nextion.print(3);
sendTOdisplay();
}
if (batt >= 3.3 && batt <= 3.5)
{
nextion.print("p0.pic=");
nextion.print(2);
sendTOdisplay();
}
if (batt >= 0 && batt <= 3.3)
{
nextion.print("p0.pic=");
nextion.print(1);
sendTOdisplay();
}
delay(100);
}
Wie wird das Programm auf das Nextion Display geladen?
Hier könnt Ihr euch den Sketch runterladen.
Wenn Ihr hier mit einem Akku arbeitet dann nach dem ausfstecken noch einmal den Reset Knopft drücken.
Sicherlich kann die ein oder andere Stelle noch verbessert werden. Ich hoffe es ist alles soweit verständich. Wenn Ihr fragen habe schickt mir einfach ein Mail. Ich versuche Sie zeitnah zu beantworden.
Weitere Beträge zum Thema Füllstand:
Zisterne 3.0 Web Server + SPIFFS
In meinem ersten Beitrag für die Zisterne (Wasserstandsmessung), verwende ich Batterie Bilder für den Füllstand der Zisterne. Hier werde ich immer wieder gefragt wie die Bilder angezeigt werden können.
Zisterne Füllstandsanzeige 2.0 mit Wemos Lolin32 + MySQL Datenbank
Es handelt sich hier um eine Abänderung von meiner 1. Zisternen Überwachung, den Beitrag dazu findet Ihr hier. In der 2. Version werden die Daten
Zisterne Füllstandsanzeige
Wasserstand einer Zisterne mit einem Wemos D1 mini überwachen. Hier zeige ich euch wir Ihr mit einem Wemos den Wasserstand einer Zisterne überwachen könnt.Ich habe