简体   繁体   English

ESP32上的Web服务器:如何自动更新和显示服务器的传感器值?

[英]Web server on ESP32: How to update and display sensor values from the server automatically?

I have a web server on an ESP32 and a homepage on that server. 我在ESP32上有一个Web服务器,在该服务器上有一个主页。 I would like to update sensor values on the homepage every x seconds automatically (without user input). 我想每隔x秒自动更新主页上的传感器值(无需用户输入)。 I cannot access the file system. 我无法访问文件系统。

The sensor is directly connected to the ESP32. 传感器直接连接到ESP32。 The sensor values are in my C program, stored in variables and updated regularly. 传感器值在我的C程序中,存储在变量中并定期更新。 Variables are global for easier use. 变量是全局的,以便于使用。

I thought about Ajax (I have no experience), but all examples and methods I can find use a file to load data from (in the 'url'-part of XMLHttpRequest().open(...url....)). 我想到了Ajax(我没有经验),但我能找到的所有示例和方法都使用一个文件来加载数据(在XMLHttpRequest()的'url'部分.open(... url ....) )。 I have no file but only strings in which my HTML and Javascript code is generated and sent to the client. 我没有文件,只有生成我的HTML和Javascript代码并发送到客户端的字符串。

I have no idea how to update my values and hope for some help. 我不知道如何更新我的价值观并希望得到一些帮助。

I thought about trying something like the examples from w3schools, but I don't know how to get the values in there: 我想过尝试类似于w3schools的例子,但我不知道如何获得那些值:

Example from another page (I don't use this code - I cannot use files!) 来自另一个页面的示例(我不使用此代码 - 我无法使用文件!)

function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("demo").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "ajax_info.txt", true);
  xhttp.send();
}

Here is some code from my C program on the ESP: 这是我在ESP上的C程序的一些代码:

HTML-String: HTML字符串:

String html_document() {
  String sHTML;
  sHTML = "<!doctype html>";
  sHTML +="<html>";
  sHTML +="<html lang=\"de\">";
  /***************** head ****************/
  sHTML +="<head>";
  /****** avoid favicon requests **  ** <link rel=\"shortcut icon\" href=\"data:image/x-icon;,\" type=\"image/x-icon\"> **/
  sHTML +="<link rel=\"icon\" href=\"data:;base64,iVBORw0KGgo=\"> ";
  sHTML +="<meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">";
  //Anpassung an Viewport für unterschiedliche Devices
  /***************** title ***************/
  sHTML +="<title>LetsgoING IoT</title>";
  sHTML +="<style>h1{display: flex; flex-flow: row wrap; justify-content: center;} </style>";
  sHTML +="<style>h1{ color: green;}</style>";
  sHTML +="<style>h2{display: flex; flex-flow: row wrap; justify-content: center;} </style>";
  sHTML +="<style>h2{ color: blue;}</style>";
  sHTML +="<style>h5{display: flex; flex-flow: row wrap; justify-content: center;} </style>";
  sHTML +="<style>p{display: flex; flex-flow: row wrap; justify-content: center; margin-bottom: 3%;} </style>";
  sHTML +="<style>p1{display: flex; flex-flow: row wrap; justify-content: center; margin-bottom: 0%;} </style>";
  sHTML +="<style>p2{display: flex; flex-flow: row wrap; justify-content: center; margin-bottom: 0%;} </style>";
  sHTML +="</head>";
  /***************** body ****************/
  sHTML+= "<body>";   //onload=\"window.setInterval(updateDiv, 15000);\"
  sHTML+= "<h1>LetsgoING</h1>";
  sHTML+= "<h2>Internet der Dinge</h2>";
  sHTML+= "<p1><a style=\"width:38%;\"></a><a style=\"width:20%;color: green\">LED ein</a> <a style=\"width:15%;\" href=\"LEDON\"><button> EIN </button></a> </a><a style=\"width:27%;\"> </a></p1>";
  sHTML+= "<p><a style=\"width:38%;\"></a><a style=\"width:20%;color: red\"  >LED aus</a> <a style=\"width:15%\"; href=\"LEDOFF\"><button>AUS</button></a><a style=\"width:27%;\"> </a></p>";
  sHTML+= "<h5>RGB-LED PWM-Werte</h5>";
  sHTML+= "<form><p2>";
  sHTML+= "<a style=\"width:38%;\"></a> <a style=\"width:20%;color: red\"> Rot</a>  <a style=\"width:15%;\" ><input name=\"rot\" type=\"number\" min=\"0\" max=\"255\" step=\"1\" value=\"80\" ></a><a style=\"width:27%;\"> </a>";
  sHTML+= "<a style=\"width:38%;\"></a> <a style=\"width:20%;color: green\">Grün</a><a style=\"width:15%;\" ><input name=\"gruen\" type=\"number\" min=\"0\" max=\"255\" step=\"1\" value=\"80\"></a><a style=\"width:27%;\"> </a>";
  sHTML+= "<a style=\"width:38%;\"></a> <a style=\"width:20%;color: blue\">Blau</a> <a style=\"width:15%;\" ><input name=\"blau\" type=\"number\" min=\"0\" max=\"255\" step=\"1\" value=\"80\"></a><a style=\"width:27%;\"> </a>";
  sHTML+= "</p2>";
  sHTML+= "<p><a style=\"width:38%;\"></a> <a style=\"width:20%;\">         </a>   <label style=\"width:15%;\" ><input type=\"submit\" value=\"senden\"></label><a style=\"width:27%;\"></a></p>";
  sHTML+= "</form>";
  sHTML+= "<h5>analoger Schwellwert</h5>";
  sHTML+= "<form><p2><a style=\"width:38%;\"></a> <a style=\"width:20%;\"> <input name=\"schwell\" type=\"number\" min=\"0\" max=\"1024\" step=\"10\" value=\"300\"> </a> <a style=\"width:15%;\"><input type=\"submit\" value=\"senden\"></a><a style=\"width:27%;\"> </a></p2>";
  //sHTML+= "<p><a style=\"width:28%;\"></a> <a style=\"width:30%;\">         </a>   <label style=\"width:15%;\" ><input type=\"submit\" value=\"senden\"></label><a style=\"width:27%;\"></a></p>";
  sHTML+= "</form>";
  sHTML+= "<h5>PWM-Wert</h5>";
  sHTML+= "<form><p2><a style=\"width:38%;\"></a> <a style=\"width:20%;\"> <input name=\"pwm\" type=\"number\" min=\"0\" max=\"255\" step=\"1\" value=\"0\"> </a> <a style=\"width:15%;\"><input type=\"submit\" value=\"senden\"></a><a style=\"width:27%;\"> </a></p2>";
  sHTML+= "</form>";
  sHTML+= "<h5>Messwerte</h5>";
  sHTML+="<p><a style=\"width:38%;\"></a> <p3 id=\"an1\"; style=\"width:20%;\" href=\"anlg1\">#-Wert-#</p3><a style=\"width:22%;\">Analoger Pin 36   </a><a style=\"width:20%;\"></a></p>";
  sHTML+="<p><a style=\"width:38%;\"></a> <p3 id=\"an2\"; style=\"width:20%;\">#-Wert-#</p3><a style=\"width:22%;\">Analoger Pin 39   </a><a style=\"width:20%;\"></a></p>";
  sHTML+="<p><a style=\"width:38%;\"></a> <p3 id=\"dig\"; style=\"width:20%;\">#-Wert-#</p3><a style=\"width:22%;\">Digitaler Pin 5   </a><a style=\"width:20%;\"></a></p>";
  sHTML+= "</body>";
  sHTML+= "</html>";
  return sHTML;
}

Loop: 环:

void loop() {
  if (millis() - startTime >= 2000) {
    startTime = millis();
    /* Check if a client has connected */
    client = server.available();
    if (!client){
      return;
    }
    /*Wait for the client to send data */
    Serial.println("neuer Client verbunden------------------------------");
    /*Count requests: */
    request_counter ++;
    unsigned long clTimeout = millis()+250;
    while(!client.available() && (millis()<clTimeout) ) {
      delay(1);
    }
    /***  publish Homepage ***/
    client.print(html_document());
    /* Read the first line of the clients request string "sHTML" until carriage return \r */
    sHTMLRequest = client.readStringUntil('\r');
    #ifdef DEBUGMODE
    Serial.println("Antwort: ");
    Serial.println(sHTMLRequest);
    #endif
    client.flush();
    /* stop client, if request is empty */
    if(sHTMLRequest=="") {
      Serial.println("Leere Anfrage! - client gestoppt");
      client.stop();
      return;
    }
    #ifdef DEBUGMODE
    Serial.println("Antwort2: ");
    Serial.println(sHTMLRequest);
    Serial.println ("---------");
    Serial.print("DEBUG: Remote IP - Address : ");
    for (int i = 0; i < 3; i++) {
      Serial.print( client.remoteIP()[i]);
      Serial.print(".");
    }
    Serial.println(client.remoteIP()[3]);
    Serial.print("Seitenaufrufe: ");
    Serial.println(request_counter);
    Serial.println ("---------");
    #endif
    /**** call event handler **********/
    eventHandler();
    #ifdef DEBUGMODE
    Serial.println("Zugewiesene PWM-Werte");
    Serial.print("rot: ");
    Serial.println(rot);
    Serial.print("gruen: ");
    Serial.println(gruen);
    Serial.print("blau: ");
    Serial.println(blau);
    #endif
    /* write PWM values for colors to channels*/
    ledcWrite(1, rot);
    ledcWrite(2, gruen);
    ledcWrite(3, blau);
    #ifdef DEBUGMODE
    Serial.println(analog1);
    #endif
  }
  UpdateValues();
}

/**** reads pin values **/
void UpdateValues() {
  analog1 = analogRead(pinAnalog1);
  analog2 = analogRead(pinAnalog2);
  DigiOut = digitalRead(LEDpin);
}

Here's the function that updates the values and creates the JSON string: 这是更新值并创建JSON字符串的函数:

void UpdateValues() {
  analog1 = analogRead(pinAnalog1);
  analog2 = analogRead(pinAnalog2);
  DigiOut = digitalRead(LEDpin);
  String strJson;
  strJson = "(200,\"application/json\",\"{\"pin36\": ";
  strJson+=analog1;
  strJson+=", \"pin39\":";
  strJson+= analog2;
  strJson+=", \"pin5\": ";
  strJson+=DigiOut;
  strJson+="}\")";
  server.print(strJson);
}

Option 1 : 选项1

The simplest way is to ask the page refresh itself every 5 seconds by adding this to <head> : 最简单的方法是通过将此页面添加到<head>来每隔5秒刷新一次页面:

sHTML +="<meta http-equiv=\"refresh\" content=\"5\">";

Then change your sHTML string to concatenate the values of your global variables. 然后更改sHTML字符串以连接全局变量的值。 Each time the page refreshes it will (should) rebuild the html and return the latest values. 每次刷新页面时,它都会(应该)重建html并返回最新值。

Option 2 : 选项2

You could use ajax to retrieve the latest values, and then frequently update the small section of the webpage that shows the data. 您可以使用ajax检索最新值,然后经常更新显示数据的网页的小部分。

What happens here is you set up your ESP32 to provide a second URL, one that returns just the latest values as a json object. 这里发生的是你设置你的ESP32以提供第二个URL,一个只返回最新值作为json对象的URL。 The values are then injected into the page, overwriting the old. 然后将值注入页面,覆盖旧的。

First add a link to jQuery in the <head> : 首先在<head>添加一个指向jQuery的链接:

sHTML +="<script src=\"https://code.jquery.com/jquery-3.2.1.min.js\"></script>";

In the <body> add spans with ids to hold the values to be updated. <body>添加带有id的spans以保存要更新的值。 Something like: 就像是:

sHTML+= "<h5>Messwerte</h5>";
sHTML+="<p>Analoger Pin 36</p>&nbsp;<span id='pin36'></span>";
sHTML+="<p>Analoger Pin 39</p>&nbsp;<span id='pin39'></span>";
sHTML+="<p>Analoger Pin 5</p>&nbsp;<span id='pin5'></span>";

Create the sHTML for the following javascript that makes an ajax request every 5 seconds, and updates the latest values in the browser: 为以下javascript创建sHTML ,每隔5秒发出一次ajax请求,并更新浏览器中的最新值:

<script>
  $(function() {

    // request data every 5 seconds
    setInterval(requestData, 5000);

    function requestData() {

      // ajax request for latest sensor data
      $.get("/sensors")
        .done(function(data) {

          console.log(data);  // debugging - remove when satisfied

          if (data) { // if the returned data is not null, update the values
            $("#pin36").text(data.pin36);
            $("#pin39").text(data.pin39);
            $("#pin5").text(data.pin5);
          } else { // a problem occurred
            $("#pin36").text("?");
            $("#pin39").text("?");
            $("#pin5").text("?");
          }
        }).fail(function() {
          console.log("The was a problem retrieving the data.");
        });
    }

  });
</script>

When you detect the string /sensors in sHTMLRequest you want to return the following json format: 当您在sHTMLRequest检测到字符串/sensors ,您希望返回以下json格式:

{"pin36": 5.2, "pin39": 0.322, "pin5": 1}

At this point I don't know enough about your setup to advise too much further, but these links should hopefully assist with the C code: http://www.iotsharing.com/2017/05/how-to-turn-esp32-into-web-server.html & http://randomnerdtutorials.com/esp32-web-server-arduino-ide/ 在这一点上,我不太了解您的设置,以进一步建议,但这些链接应该有助于C代码: http//www.iotsharing.com/2017/05/how-to-turn-esp32 -into-web-server.htmlhttp://randomnerdtutorials.com/esp32-web-server-arduino-ide/

If you use ESP32WebServer.h from https://github.com/nhatuan84/esp32-webserver (see second half of http://www.iotsharing.com/2017/05/how-to-turn-esp32-into-web-server.html for more details), you can use something like: 如果您使用来自https://github.com/nhatuan84/esp32-webserver的 ESP32WebServer.h (请参阅http://www.iotsharing.com/2017/05/how-to-turn-esp32-into-web的下半部分-server.html了解更多详情),您可以使用以下内容:

server.on("/sensors", handleSensorData);

with

/* this callback will be invoked when user request "/sensors" */
void handleSensorData() {
  /* server responds 200 with a json payload */
  /* although preferably concatenate your real sensor data here */
  server.send(200, "application/json", "{\"pin36\": 5.2, \"pin39\": 0.322, \"pin5\": 1}"); 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM