Zisterne 3.0 Web Server + SPIFFS

68 Kommentare
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.

Da nicht jeder eine Webseite besitzt oder sich extra dafür eine anschaffen will (Kostet ja auch Geld), hab ich hier eine andere Lösung für euch.


Inhaltsverzeichnis

  1. Installation ESP8266 in der Arduino IDE
  2. Filesystem Uploader Plugin (SPIFFS)
  3. Installation der Librarys
  4. Welche Bauteile werden benötigt.
  5. Schema
  6. Der Programmcode
  7. Der HTML Code
  8. Der CSS Code
  9. Upload Code und Datein


Der ESP8266 egal welche Version, haben einen Speicherplatz auf dem Chip wo man Daten ablegen und abrufen kann. Könne Ihr hier nachlesen. https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html

Das werden wir hier benutzen um die Bilder und die HTML Seite dort abzulegen.

|--------------|-------|---------------|--|--|--|--|--|
^              ^       ^               ^     ^
Sketch    OTA update   File system   EEPROM  WiFi config (SDK)

Board Flash chip size, bytes File system size, bytes
Generic module 512k 64k, 128k
Generic module 1M 64k, 128k, 256k, 512k
Generic module 2M 1M
Generic module 4M 1M, 2M, 3M
Adafruit HUZZAH 4M 1M, 2M, 3M
ESPresso Lite 1.0 4M 1M, 2M, 3M
ESPresso Lite 2.0 4M 1M, 2M, 3M
NodeMCU 0.9 4M 1M, 2M, 3M
NodeMCU 1.0 4M 1M, 2M, 3M
Olimex MOD-WIFI-ESP8266(-DEV) 2M 1M
SparkFun Thing 512k 64k
SweetPea ESP-210 4M 1M, 2M, 3M
WeMos D1 R1, R2 & mini 4M 1M, 2M, 3M
ESPDuino 4M 1M, 2M, 3M
WiFiduino 4M 1M, 2M, 3M


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.



2. Filesystem Uploader Plugin (SPIFFS)

Mit diesem Plugin können Daten bequem per Knopfdrück auf den EPS8266 (SPIFFS) geladen werden.Zunächst müsst Ihr euch das Plugin von Github herunterladen. https://github.com/esp8266/arduino-esp8266fs-plugin/releases/tag/0.5.0

Den Inhalt der ZIP Datei kopiert ihr in den Tools Ordner.
C:\Program Files (x86)\Arduino\tools
oder in diesen, das ist egal.
C:\Users\???\Documents\Arduino\tools

Wenn das erledigt ist müsst Ihr die Arduino IDE neu starten. Dann sollte das Plugin hier angezeigt werden.




3. Installation der Librarys

Ihr braucht hier die Librarys ESPAsyncWebServer und ESPAsyncTCP.

ESPAsyncWebServer


ESPAsyncTCP


Die Zip Datei entpackt Ihr in den Library Ordner C:\Users\???\Documents\Arduino\libraries jenachdem wo er bei euch liegt.

ODER / ALTERNATIV

Die Import Funktion der Arduino IDE nutzen.




Welche Bauteile werden benötigt.

Beim ESP spielt es keine Rolle welches Modell genommen wird.

1x D1 mini ESP8266 ESP-12 - https://ap-url.de/d1mini
1x Ultraschallentfernungsmesser AJ-SR04M / JSN-SR04T Wasserdicht - https://ap-url.de/jsnsr04t



Schema

Alternativ zu der 5 Volt Spannungsversorgung kann auch die 3,3 Volt genommen werden. Der D1 mini verträgt nur 3,3 Volt an den Eingängen. Der Ultraschallsensor gibt aber keine 5 Volt am Echo Ausgang raus.

Der Programmcode

#include <esp8266wifi.h>
#include <espasynctcp.h>
#include <espasyncwebserver.h>
#include <fs.h>

const char* ssid = "DEIN WLAN";
const char* password = "DEIN PASSWORT";

AsyncWebServer server(80);

char* Bild = "";

int trigger = 12;
int echo = 13;
long dauer = 0;

long entfernung = 0;
long Liter = 0;

//Berechnung der Liter für die Webseite
String getLiter() {
  digitalWrite(trigger, LOW);
  delay(5);
  digitalWrite(trigger, HIGH);
  delay(10);
  digitalWrite(trigger, LOW);
  dauer = pulseIn(echo, HIGH);
  // Prüfen ob Messwert zwischen 200cm und 0cm liegt
  entfernung = (dauer / 2) / 29.1;
    if (entfernung >= 200 || entfernung <= 0)
  {
    entfernung = 0;
  }
  else
  {
    Liter = 199 - entfernung;
    Liter = Liter * 84.7457;
  }
  Serial.println(Liter);
  return String(Liter);
}

//Auswertung wann welches Bild angezeigt werden soll
String getBild() {
  if (Liter >= 0 && Liter <= 1833)
  {
    Bild = "/bat_emty.jpg";
  }
  else if (Liter >= 1833 && Liter <= 3666)
  {
    Bild = "/bat_1.jpg";
  }
  else if (Liter >= 3666 && Liter <= 5500)
  {
    Bild = "/bat_2.jpg";
  }
  else if (Liter >= 5500 && Liter <= 7332)
  {
    Bild = "/bat_3.jpg";
  }
  else if (Liter >= 7332 && Liter <= 9165)
  {
    Bild = "/bat_4.jpg";
  }
  else if (Liter >= 9165 && Liter <= 16000)
  {
    Bild = "/bat_full.jpg";
  }
  Serial.println(Bild);
  return String(Bild);
}


// Platzhalter im HTML Code
String colldata(const String& var) {
  Serial.println(var);
  if (var == "LITER") {
    return getLiter();
  }
}

void setup() {
  Serial.begin(115200);

  // Starte SPIFFS
  if (!SPIFFS.begin()) {
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }
  pinMode(trigger, OUTPUT);
  pinMode(echo, INPUT);
  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // Print Local IP Address
  Serial.println(WiFi.localIP());

  // Webseite Laden
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "/index.html", String(), false, colldata);
  });

  // CSS Datei Laden
  server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "/style.css", "text/css");
  });

  // Liter an Webseite übergeben
  server.on("/Liter", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/plain", getLiter().c_str());
  });
  // Bild an Webseite übergeben
  server.on("/bat", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, getBild().c_str(), "image/jpg");
  });

  // Start server
  server.begin();
}

void loop() {

}

Funktionsweise

Als erstes werden die Librarys inkludiert.

#include &>t;ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <FS.h>

Für das WLAN werden die Zugangsdaten benötigt und der Web Server wird mit dem Port 80 erstellt.

const char* ssid = "DEIN WLAN";
const char* password = "DEIN PASSWORT";

AsyncWebServer server(80);

Definieren der Variablen (char, int und long). char* Bild  speichert die Bildinformation, int trigger und echo sind für den Ultraschallsensor Zuständig. Der long entfernung gibt den die gemessene Entfernung des Ultraschallsensors wieder und der long Liter ist für die Berechnung der Literzahl da.

char* Bild = "";

int trigger = 12;
int echo = 13;
long dauer = 0;

long entfernung = 0;
long Liter = 0;

Die Berechnung des Volumen:

Hier werden 2 Funktionen erstellt (getLiter und getBild) die einmal den Sensorwert als LONG zurück gibt und einmal den Bildname als CHAR zurück gibt.

//Berechnung der Liter für die Webseite
String getLiter() {
  digitalWrite(trigger, LOW);
  delay(5);
  digitalWrite(trigger, HIGH);
  delay(10);
  digitalWrite(trigger, LOW);
  dauer = pulseIn(echo, HIGH);
  // Prüfen ob Messwert zwischen 200cm und 0cm liegt
  entfernung = (dauer / 2) / 29.1;
    if (entfernung >= 200 || entfernung <= 0)
  {
    entfernung = 0;
  }
  else
  {
    Liter = 199 - entfernung;
    Liter = Liter * 84.7457;
  }
  Serial.println(Liter);
  return String(Liter);
}

Meine Zisterne fast 10000 Liter. Die 199 cm ist die Enfternung vom Sensor bis zum Boden der Zisterne. Jetzt brauchen wir den Multiplikator, die 100% Füllstand sind bei mir bei 118 cm erreicht, also 10000/118=84,7457.
Das ist nun der Multiplikator aus der Sketch.
    Liter = 199 - entfernung;
    Liter = Liter * 84.7457;



Die Funktion colldata() weist dem Platzhalter in der HTML Datei (%LITER%) den Wert zu.

// Platzhalter im HTML Code
String colldata(const String& var) {
  Serial.println(var);
  if (var == "LITER") {
    return getLiter();
  }
}

Mit den server.on Befehle werden die Daten wie index.html, style.css und die Werte in die Weitseite gepackt und auf dem SPIFFS gelesen.
Man könnte jetzt die Daten auch einzeln abrufen wie zu Beispiel http://ipadresse/Liter dann bekommt man hier die Literzahl angezeigt.

// Webseite Laden
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
  request->send(SPIFFS, "/index.html", String(), false, colldata);
});

// CSS Datei Laden
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest * request) {
  request->send(SPIFFS, "/style.css", "text/css");
});

// Liter an Webseite übergeben
server.on("/Liter", HTTP_GET, [](AsyncWebServerRequest * request) {
  request->send_P(200, "text/plain", getLiter().c_str());
});
// Bild an Webseite übergeben
server.on("/bat", HTTP_GET, [](AsyncWebServerRequest * request) {
  request->send(SPIFFS, getBild().c_str(), "image/jpg");
});



Der HTML Code

<!DOCTYPE html>
<!--
Projekt Details im Blog https://arduino-projekte.info
-->
<html>
<head>
<title>Zisterne 3.0</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="refresh" content="5">
<link rel="icon" href="data:,">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<h1>Zisterne 3.0</h1>
<p>
<span id="Liter">%LITER%</span>
<span>Liter</span>
</p>
<p><img src="/bat"></p>
</body>
</html>

Die Webseite wird über die IP Adresse des EPS8266 aufgerufen. Diese könnt Ihr über den Seriellen Monitor abrufen, oder über euren WLAN Router.



Hier könnt Ihr einstellen in welchen Intervall die Webseite aktualisiert werden soll. In diesem Fall sind es 5 sekunden.

<meta http-equiv="refresh" content="5">

Der %LITER% dient hier als Platzhalter und wird vom ESP8266 über den Sketch beschrieben. Hier wird die Liter Anzahl übergeben. Der "/bat" ist ebenfalls der Char String der dann von ESP beschrieben und das Bild (Batterie) übergeben wird.

<p><span id="Liter">%LITER%</span>
    <span class="label">Liter</span>
</p>
<p><img decoding="async" src="data:image/svg+xml,%3Csvg%20xmlns='http://
www.w3.org/2000/svg'%20viewBox='0%200%200%200'%3E%3C/svg%3E" data-lazy-src="/bat"><noscript><img decoding="async" src="/bat"></noscript></p>



Der CSS Code

CSS wird verwenden um Webseite von der Darstellung zu verändern. Alles was Schriftarten, Schriftgörßen, Farben und so weiter angeht.

/***
  Projekt Details im Blog https://arduino-projekte.info
***/
html {
  font-family: Arial;
  display: inline-block;
  margin: 0px auto;
  text-align: center;
}
h1 {
  font-size: 40px;
  color: #4054b2;
}
p {
  font-size: 30px;
}
.label {
  font-size: 30px;
  vertical-align:middle;
  padding-bottom: 5px;
}



Upload Code und Datein

  • Sketch -> Sketch Ordner anzeigen, und erstellte einen Ordner Names data. In diese Ordner packt Ihr eure Daten wie Bilder, HTML und CSS Datein.
  • Werkzeuge -> Board, wählt euer ESP8266 Board aus was Ihr benutzt.
  • Dann geht Ihr auf Werkzeuge -> Flash size and select 4M (FS:1MB) es kann hier auch stehen 4M (1M SPIFFS).

Wenn der Sketch erfolgreich hochgeladen wurde, müssen nun noch die Daten auf den SPIFFS geladen werden.

Dateisystem für SPIFFS upload.

Um das Upload Tool für das SPIFFS nutzen zu kommen müssen die Daten (Bilder, HTML-Datein usw.) im Sketch Ordern mit abgelegt werden. Dazu im Sketch Ordner eine Ordner Names data erstellen und dort die Daten ablegen.

Sketch Ordner

Data Ordner


Werkzeug -> ESP8266 Sketch Data Uoload


Wichtig Ihr müsst etwas warten bis die Daten hochgeladen sind. Wenn im Ausgabefenster die 100% angezeigt werden ist er noch nicht fertig. Ihr muss auf das "Leaving... Hard resetting via RTS pin..." warten.

noch nicht fertig
fertig



Hier könnt Ihr euch den Sketch runterladen.

Download Sketch + Data (30kb .zip)


Folgende Bauteile wurden verwendet:

1x D1 mini ESP8266 ESP-12 - https://ap-url.de/d1mini
1x Ultraschallentfernungsmesser AJ-SR04M / JSN-SR04T Wasserdicht - https://ap-url.de/jsnsr04t
ESP8266 Projekte ultraschallsensor Zisterne Füllstandsanzeige

68 Kommentare

Ich habe jetzt mal noch versucht folgenden Sketch hochzuladen
#include <ESP8266WiFi.h>
void setup(){
Serial.begin(115200);
delay(500);

Serial.println();
Serial.print("MAC: ");
Serial.println(WiFi.macAddress());

}
void loop(){}

Habe dabei eingestellt “All Flesch Contents” zu löschen.

Im Seriellen Monitor bringt er jetzt aber weiterhin “Connecting to Wifi…”
Jetzt stelle ich mir die Frage: Kann es sein, dass die alten Programmzeilen nicht gelöscht werden?

Flo-B

Upload funktioniert jetzt einwandfrei.
Wenn ich den Seriellen Monitor öffne bekomme ich aber nichts angezeigt – auch wenn ich auf 115200 Baud umstelle.
Und in meiner FritzBox wird es auch nicht angezeigt?
Hat jemand eine Erklärung dafür?

Flo-B

Ich musste den Port noch auswählen :-)

https://heise.cloudimg.io/width/2000/q75.png-lossy-75.webp-lossy-75.foil1/www-heise-de_/tipps-tricks/imgs/96/2/4/7/1/1/0/4/arduinoport-45cfc2e32fb4af4b.png

Flo-B

Ich glaube das lässt sich nicht aufspielen.

Flo-B

Hallo Markus,

wenn die “dauer” immer null ist, stimmt bestimmt mit dem Sensor was nicht. Versuch doch mal den Sketch um zu sehen ob der Sensor funktioniert.

Du musst gucken an welchen Pin Echo und Trigger ist und anpassen.
Was ist mit Jumper gemeint? Das Board hat ja keine Jumper.

Gruß
Tobias

int trigger = 12; // D6
int echo = 13; // D7
long dauer=0;

long entfernung=0;

void setup() {
Serial.begin(9600);
pinMode(trigger,OUTPUT);
pinMode(echo,INPUT);
}

void loop() {

digitalWrite(trigger, LOW);
delayMicroseconds(2);
digitalWrite(trigger, HIGH);
delayMicroseconds(10);
digitalWrite(trigger, LOW);
dauer=pulseIn(echo,HIGH);
entfernung=(dauer/2)/29.1;

if(entfernung>=500||entfernung<=0)
{
Serial.println(“Kein Messwert”);
}
else
{
Serial.print(entfernung);
Serial.println(" cm");
}
delay(1000);
}

arduino projekte

Hinterlassen Sie einen Kommentar

Bitte beachten Sie, dass Kommentare vor der Veröffentlichung genehmigt werden müssen.