Alles über Arduino und Co.

suche
Generic filters

Zisterne 4.0 + Nextion Display ohne Internet / WLAN Router (UPD)

Zisterne 4.0 + Nextion Display ohne Internet / WLAN Router (UPD)

Was wird für das Projekt benötigt.

1. Installation ESP8266 in der Arduino IDE

Um den EPS8266 in der Arduino IDE verwenden zu können, muss dieser erst installiert werden. Wie das geht habe ich in diesem Blogbeitrag schon einmal erklärt.

Welche Bauteile werden benötigt.

Funktionsweise

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.

Wenn die Externe Antenne verwendet werden soll muss der Widerstand umgelötet werden oder einfach einen Lötklecks über die Pads ziehen.

Sender Sketch

Um die Batteriefunktion  (Messung) nutzen zu können müsst Ihr am D1 mini pro v2.0 oder dem D1 Lipo Battery Shield. Je nachdem was Ihr verwendet das Lotpad auf der Rückseite verbinden.
				
					#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <EEPROM.h>

#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);
}
				
			

Funktionsweise

				
					#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <EEPROM.h>
				
			
Als erstes werden die Librarys (Bibliotheken) inkludiert.
				
					#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;
				
			
WLAN Daten um auf den Empfänger zugriff zu bekommen. IP Adressen und festlegen auf welchen UDP Port gesendet wird.
				
					// 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;
				
			
Definieren der Signale und Variablen.
				
					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);
}
				
			
Im Setupteil brauch ich glaub ich nicht viel zu sagen. Hier werden die Ausgangspin, Eingangspins und das WLAN gestartet.
				
					void batt_status()
{
  raw = analogRead(A0);
  batt = raw / 1023.0;
  batt = batt * 4.2;
}
				
			
Routine für das Batterie messen, der Wert wird in “batt” gespeichert.
				
					void zeit()
{
  counter++;
  EEPROM.write(1, counter);
  if (counter >= 21)
  {
    counter = 0;
    EEPROM.write(1, counter);
    EEPROM.commit();
    EEPROM.end();
    ESP.reset();
  }
}
				
			
Routine für den Zähler. Dieser dient nur dazu um zu pürfen ob die Messung funktioniert hat. Hier kann man sicher auch eine andere Möglichekeit wählen. Der Zähler zählt bis 20 und fängt dann wieder von vorne an. Der Zähler wird im EEPROM gespeichert, damit er nach dem DeepSleep / Ausschalten wieder zur verfügung steht. Der ESP wird nach den 20 Messwerten 1x Resetet.
				
					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);
}
				
			
Routine für den Zähler. Dieser dient nur dazu um zu pürfen ob die Messung funktioniert hat. Hier kann man sicher auch eine andere Möglichekeit wählen. Der Zähler zählt bis 20 und fängt dann wieder von vorne an.

Empfänger Sketch

				
					#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <SoftwareSerial.h>

#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);
  }
}
				
			

Funktionsweise

				
					#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <SoftwareSerial.h>
				
			
Als erstes werden die Librarys (Bibliotheken) inkludiert.
				
					#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;
				
			
WLAN Daten für den eigenen Access Point. IP Adressen und festlegen auf welchen UDP Port empfangen wird. Der SoftwareSerial legt fest wo die RX/TX Leitungen für das Display liegen.
				
					// 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;
				
			
Definieren der Variablen.
				
					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();
}
				
			
Serielle Schnittstellen, WLAN und das UDP werden gestartet.
				
					  // 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
				
			
Im LOOP Teil werden hier die Datenpakete empfangen und in 3 Werte zerlegt.
				
					    //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);
  }

				
			
Im Anschluss werden die Werte an das Display übertragen.

Wie wird das Programm auf das Nextion Display geladen?

Ihr packt die brunnen.tft Datei auf eine Micro SD Karte und steckt diese in das Display. Dann das Display mit Spannung versorgen und der Upload wird gestartet. Nach dem Upload das Display wieder von der Spannung trennen und nach dem nächsten Verbinden ist das Programm aktiv.

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 mit Wemos messen

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

Weiterlesen »

Letzte Aktualisierung am 30.07.2021 / Affiliate Links / Bilder von der Amazon Product Advertising API