ESP32 - Webserver - Variablen auf Website Anzeigen lassen (und ändern)

Hallo.
Es ist schon eine weile her das ich mich hier gemledet habe da meine Projekte sonst hin bekommen hab.

Projekt:
Es soll der Taupunkt der Innen und Außen Temperatur bestimmt werden und entsprechend gelüftet werden.
Den Code habe ich schon als Basis am Laufen.

Als nächstes soll der ESP32 ins W-Lan Netz integriert werden.
Das habe ich auch schon hin bekommen.

Mein Problem ist, wie ich es schaffe im ersten Schritt die Werte der Temperatur, Taupunkt, Luftfeuchte und Schaltzustand des Lüfter überhaupt anzeigen zu lassen.

Optional:

  • Werte Live anzeigen
  • Manuelles schalten des Lüfter via Web
  • Anpassen von Variablen (Schalthysterese, etc) via Web

Ich habe mir schon das eine oder andere Video angeschaut aber wirklich schlau bin ich nicht daraus geworden, da es wohl x verschiedene Varianten und unter Varianten gibt.
Welche "Style CSS", "XML", "Java Script", "Ajax" enthalten in verschiedensten varianten.

Mit HTML habe ich mich vor vielen jahren beschäftigt aber viel ist nicht mehr vorhanden.

Es muss nicht grafisch hübsch sein oder sonstiges, einfach technisch funktionell

Mir fehlt im Moment der richtig Ansatz was man für sein Projekt braucht, wie es Strukturiert sein muss und nach was ich suchen sollte um weiter zu kommen.

Ich danke hier schon mal allen die sich die Mühe machen zu Antworten und zu helfen

Gruß
Micha

Technik in verwendung
1X ESP32
2x BME 280 (I2C)
2x Fets (test / ansteuerung leds)

feuchtV1

/* LUFTFEUCHTIGKEIT BME280 BEGINN */
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

Adafruit_BME280 bme1;                                         //I2C 0x76
Adafruit_BME280 bme2;                                         //I2C 0x77

float             temp1                      = 0;             //Einlesen der aktuellen werte
float             humi1                      = 0;             //Einlesen der aktuellen werte
float             temp1val                   = 0;             //Berechnung nach "X" Messung (100mal messen und aufaddieren und danach durch 100 teilern)
float             humi1val                   = 0;             //Berechnung nach "X" Messung (100mal messen und aufaddieren und danach durch 100 teilern)
float             tautemp1                   = 0;             //Berechnung der Tau Temperatur (a * t) / (b + t) + log(h / 100)
float             temp2                      = 0;             //Einlesen der aktuellen werte
float             humi2                      = 0;             //Einlesen der aktuellen werte
float             temp2val                   = 0;             //Berechnung nach "X" Messung (100mal messen und aufaddieren und danach durch 100 teilern)
float             humi2val                   = 0;             //Berechnung nach "X" Messung (100mal messen und aufaddieren und danach durch 100 teilern)
float             tautemp2                   = 0;             //Berechnung der Tau Temperatur (a * t) / (b + t) + log(h / 100)
float             a                          = 17.271;        //Zur Taupunktberechnung nötig
float             b                          = 237.7;         //Zur Taupunktberechnung nötig

unsigned long     BMEcurrentMillis           = 0;             //Variable zum einlesen der aktuellen Zeit (Laufzeit)
unsigned long     BMEpreviousMillis          = 0;             //Variable zum Vergleich der aktuellen zeit mit der vergangen Zeit zur erfassung der Zeitlichen differenz

unsigned long     SchaltverCurrentMillis     = 0;
unsigned long     SchaltverpreviousMillis    = 0;
unsigned          schaltver                  = 500;

float             tautemphysterese           = 0;             //Hysterese Wert ab dem die Lueftung an oder ab geschaltet werden soll
unsigned int      hysteresepinval            = 0;             //Einlesen der Spannung am Hysterese Pin (Poti)
unsigned int      messinterval               = 100;           //Alle "X" millisekunden eine Messing
unsigned int      messcounter                = 0;             //Menge der Messung die durchgeführt worden sind für die IF anweisung zur berechnung des druchscnitts

//Pin Belegungen
const int         steuerung1pin              = 32;            //Pin Zur Ansteuerung des 1ten MosFets. MosFet steuert Relais 1
const int         steuerung2pin              = 33;            //Pin Zut Ansteuerung des 2ten MosFets. MosFet steuert Relais 2
const int         hysteresepin               = 34;            //Pin an dem der Poti für die Hysterese angeschlossen ist



/* LUFTFEUCHTIGKEIT BME280 ENDE */

/******************************************************************************/

/* WIFI WEBSERVER BEGINN */

#include <WiFi.h>                           // Load Wi-Fi library

const char* ssid = "test1234";                  // Replace with your network credentials
const char* password = "12345678";          // Replace with your network credentials
unsigned long currentTime = millis();
unsigned long previousTime = 0;
unsigned long timeoutTime = 2000;

WiFiServer server(80);                      // Set web server port number to 80

String header;                              // Variable to store the HTTP request
/* WIFI WEBSERVER ENDE */




void setup() {
  /* DEBUG SERIAL */
  Serial.begin(115200);
  /* DEBUG SERIAL */

  /******************************************************************************************/

  /* LUFTFEUCHTIGKEIT BME280 BEGINN */
  //Pin defniftionen input / output
  pinMode(hysteresepin, INPUT);
  pinMode(steuerung1pin, OUTPUT);
  pinMode(steuerung2pin, OUTPUT);



  //Test ob die BME280 korrekt bzw überhaupt angeschlossen sind
  Serial.println(F("BME280 test"));
  bool status1;
  status1 = bme1.begin(0x76);
  if (!status1) {
    Serial.println("Could not find a valid BME280 sensor, check wiring! BME 1");
    while (1);
  }
  bool status2;
  status2 = bme2.begin(0x77);
  if (!status1) {
    Serial.println("Could not find a valid BME280 sensor, check wiring! BME 2");
    while (1);
  }
  Serial.println();
  /* LUFTFEUCHTIGKEIT BME280 ENDE */

  /****************************************************************************************/


  /* WIFI WEBSERVER BEGINN */
    // Connect to Wi-Fi network with SSID and password
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    }
    // Print local IP address and start web server
    Serial.println("");
    Serial.println("WiFi connected.");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    server.begin();
  /* WIFI WEBSERVER ENDE */

}


void loop()
{
  taupunkt();
  websrv();
}

Taupunkt

void taupunkt()
{

  BMEcurrentMillis = millis();

  if (BMEcurrentMillis - BMEpreviousMillis >= messinterval && messcounter < 100)
  {
    //BME280 Sensor 1 Temperatur und Luftfeuchtigkeit einlesen
    temp1 = bme1.readTemperature();
    humi1 = bme1.readHumidity();

    temp1val = temp1val + temp1;
    humi1val = humi1val + humi1;




    //BME280 Sensor 2 Temperatur und Luftfeuchtigkeit einlesen
    temp2 = bme2.readTemperature();
    humi2 = bme2.readHumidity();

    temp2val = temp2val + temp2;
    humi2val = humi2val + humi2;


    messcounter++;

    BMEpreviousMillis = BMEcurrentMillis;

  //Serial.println(messcounter);
  //Serial.println(temp1val);
  //Serial.println(humi1val);
  //Serial.println(temp2val);
  //Serial.println(humi2val);


    

  }
  
  if (messcounter >= 100)
  {
    temp1 = temp1val / messcounter;
    humi1 = humi1val / messcounter;
    temp2 = temp2val / messcounter;
    humi2 = humi2val / messcounter;


    //Sensor 1 Taupunkt Berechnung
    tautemp1 = (a * temp1) / (b + temp1) + log(humi1 / 100);

    //Sensor 2 Taupunkt Berechnung
    tautemp2 = (a * temp2) / (b + temp2) + log(humi2 / 100);


    Serial.print("temp1: ");
    Serial.println(temp1);
    Serial.print("humi1: ");
    Serial.println(humi1);
    Serial.print("tautemp1: ");
    Serial.println(tautemp1);

    Serial.print("temp2: ");
    Serial.println(temp2);
    Serial.print("humi2: ");
    Serial.println(humi2);
    Serial.print("tautemp2: ");
    Serial.println(tautemp2);
  }


  //Feuchte Luft aus dem Keller ins Freie Blasen

  SchaltverCurrentMillis = millis();


  if (temp1 - tautemp1 <= tautemphysterese && messcounter >= 100)
  {
    digitalWrite(steuerung1pin, HIGH);

    messcounter = 0;
    temp1val = 0;
    humi1val = 0;
    temp2val = 0;
    humi2val = 0;
    Serial.println("Steuerung An");
  }
  else if (temp1 - tautemp1 > tautemphysterese + 5 && messcounter >= 100)
  {
    digitalWrite(steuerung1pin, LOW);

    messcounter = 0;
    temp1val = 0;
    humi1val = 0;
    temp2val = 0;
    humi2val = 0;
    Serial.println("Steuerung Aus");
  }
}

websrv


void websrv()
{
  WiFiClient client = server.available();   // Listen for incoming clients

  if (client) {                             // If a new client connects,
    currentTime = millis();
    previousTime = currentTime;
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected() && currentTime - previousTime <= timeoutTime) {  // loop while the client's connected
      currentTime = millis();
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();



            // Web Page Heading       

                        // Display the HTML web page
                        client.println("<!DOCTYPE html><html>");
                        client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
                        client.println("<body><table border=2 align=center>");
                        client.println("<caption align=top><b><u>Wetterdaten</u></b><br></caption>");
                        client.println("<tr>");
                        client.println("<th>Sensor</th>");
                        client.println("<th>Temperatur</th>");
                        client.println("<th>Feuchtigkeit</th>");
                        client.println("<th>Taupunkt</th>");
                        client.println("<th>Hysterese</th>");
                        client.println("<th>Einschalt Temp</th>");
                        client.println("<th>Ausschalt Temp</th>");
                        client.println("<th>Luefter Status</th>");
                        client.println("</tr>");
                        client.println("<tr align=center>");
                        client.println("<td>Innen</td>");
                        client.println("<td>22Grad</td>");
                        client.println("<td>48%</td>");
                        client.println("<td>18Grad</td>");
                        client.println("<td>" + tautemp1 "</td>");
                        client.println("<td>20Grad</td>");
                        client.println("<td>24Grad</td>");
                        client.println("<td rowspan=2>Aus</td>");
                        client.println("</tr>");
                        client.println("<tr align=center>");
                        client.println("<td>Aussen</td>");
                        client.println("<td>22Grad</td>");
                        client.println("<td>48%</td>");
                        client.println("<td>18Grad</td>");
                        client.println("<td>4Grad</td>");
                        client.println("<td>20Grad</td>");
                        client.println("<td>24Grad</td>");
                        client.println("</tr>");
                        client.println("</table>");
                        client.println("</body></html>");
        
            client.println("</body></html>");

            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

Ich empfehle Dir, die Beispiele zum ESP32-Webserver anzuschauen, die mit dem ESP32-Core geliefert werden. Die Webserver-Lib nimmt dir einiges ab, was Du händisch machst.
Ohne HTML, CSS und Javascript wird es wohl nichts werden.
Anstelle von AJAX würde ich Dir die Fetch-Api empfehlen, die ist einfacher.
Die statischen HTML-, CSS- und JS-Dateien ins SPIFFS legen und die Inhalte mit Fetch füllen. Beispiele dazu findest Du bei Fips.

Gruß Tommy

vereinfacht gesagt müsstest du dort wo du heute den fixtext ausgibst:

halt die jeweilige Variable ausgeben:

client.print("<td>");
client.print(temp1);
client.println("Grad</td>");

damit sich das ohne reload aktualisiert, brauchst du das bereits angesprochene Fetch API und ein wenig markup auf der Seite damit das JavaScript in die Seite reinfindet.

Auch wurde dir schon empfohlen den webserver / HelloServer als Ausgangsbasis zu verwenden.

Wenn dir zum Einstieg die Fips Seiten zu Umfangreich sind, versuch mal meinen Sketch von
https://werner.rothschopf.net/microcontroller/202108_esp_generic_webserver_en.htm

Da gibts zwar viele Tabs mit verschiedenen Konfigurationen aber fang einfach mal mit Board 1 = config1.h an - der Sketch sollte in einem Ruck auf den ESP32 ladbar sein und funktionieren nach dem du die Credentials im Haupttab richtig gestellt hast.

Zwischen die beide Zeilen

schreib noch dazu

client.println("<head><META HTTP-EQUIV=\"refresh\" CONTENT=\"6\"></head>")

die 6 bedeutet das die Seite alle 6 Sekunden neu geladen wird, ist nicht fein aber funktioniert.
Wen Du das durch hast beschäftige sich mit den vorschlagen von @noiasca , @Tommy56, ist leichter als Du denkst. Habe auch mit client.print angefangen :wink: für mehr als par Zeilen anzeigen ist das nicht zu haben.

Gruß Bernhard

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.