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

2024-03-02

我在 ESP32 上有一个网络服务器,在该服务器上有一个主页。我想每隔 x 秒自动更新主页上的传感器值(无需用户输入)。我无法访问文件系统。

该传感器直接连接到 ESP32。传感器值位于我的 C 程序中,存储在变量中并定期更新。变量是全局的,以便于使用。

我考虑过 Ajax(我没有经验),但是我能找到的所有示例和方法都使用文件来加载数据(在 XMLHttpRequest().open(...url...) 的“url”部分) )。我没有文件,只有字符串,在其中生成 HTML 和 Javascript 代码并将其发送到客户端。

我不知道如何更新我的价值观,希望得到一些帮助。

我想过尝试类似 w3schools 的示例,但我不知道如何获取其中的值:

另一个页面的示例(我不使用此代码 - 我无法使用文件!)

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

以下是我在 ESP 上的 C 程序的一些代码:

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

以下是更新值并创建 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:

最简单的方法是通过将其添加到来要求页面每 5 秒刷新一次<head>:

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

然后改变你的sHTML字符串来连接全局变量的值。每次页面刷新时,它都会(应该)重建 html 并返回最新值。

Option 2:

您可以使用 ajax 检索最新值,然后经常更新显示数据的网页的一小部分。

这里发生的情况是,您将 ESP32 设置为提供第二个 URL,该 URL 仅以 json 对象的形式返回最新值。然后这些值被注入到页面中,覆盖旧的。

首先在中添加 jQuery 的链接<head>:

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

In the <body> add spans用 ids 来保存要更新的值。就像是:

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>";

创建sHTML对于以下 javascript,每 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>

当你检测到字符串时/sensors in sHTMLRequest您想要返回以下 json 格式:

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

目前,我对您的设置还不够了解,无法提供更多建议,但这些链接有望对 C 代码有所帮助:http://www.iotsharing.com/2017/05/how-to-turn-esp32-into-web-server.html http://www.iotsharing.com/2017/05/how-to-turn-esp32-into-web-server.html & http://randomnerdtutorials.com/esp32-web-server-arduino-ide/ http://randomnerdtutorials.com/esp32-web-server-arduino-ide/

如果你使用ESP32WebServer.h from https://github.com/nhatuan84/esp32-webserver https://github.com/nhatuan84/esp32-webserver(见后半部分http://www.iotsharing.com/2017/05/how-to-turn-esp32-into-web-server.html 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}"); 
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • 如何在 VScode 笔记本中激活跨单元格的单词突出显示?

    我在 Visual Studio Code 1 67 0 中使用 Jupyter ipynb 笔记本 当我双击某个单词 区域时 会突出显示该单词 区域的所有出现位置仅在同一个单元格中 对此的设置在settings json file is
  • Javadoc 在 Eclipse 中不可用

    我正在使用面向 Java 开发人员的 Eclipse IDE 版本 Helios 服务版本 2 内部版本号 20110218 0911 我有一个类似的问题堆栈溢出问题 https stackoverflow com questions 69
  • .data 在 pytorch 中还有用吗?

    我是 pytorch 的新手 我读了很多大量使用张量的 pytorch 代码 data成员 但我搜索 data在官方文档和Google中 发现很少 我猜 data包含张量中的数据 但我不知道什么时候需要它 什么时候不需要 data是一个属性
  • Java或C#中工厂设计模式的反思

    我偶然发现了一个词 叫做反思 这是工厂设计模式中常用的功能 我很难理解这个概念 因为我仍在学习如何编程 如何在 C 或 Java 的工厂设计模式中使用反射 谁能给我一个简单的例子 并向我展示您使用反射来实现工厂设计模式的代码 微软提供了这个
  • android 在相机上显示矩形

    您好 我想在相机中显示一个矩形 以便当用户拍摄快照时 只能处理矩形内的区域 知道我该怎么做吗 并且可以通过沿角拖动来调整矩形大小 我没有调用相机应用程序 我正在使用相机 API 您好 我使用本教程解决了问题 see here http ad
  • Android/Java:将任何字符串转换为颜色(十六进制)

    有没有办法像加密 哈希函数一样从 Java Android 中的任何字符串生成颜色 例子 字符串 Home 生成类似 FF1234 的颜色 字符串 Sky 生成类似 00CC33 的颜色 没有随机化 因此 系统将始终为该字符串计算相同的颜色
  • Azure eventhub 多个分区键指向同一分区

    我们正在开发一个多租户应用程序 其中 eventhub 将在不同租户之间共享 我们将在租户之间分配分区 每个租户将在不同的分区上发送消息 我们希望在分区级别对租户进行身份验证 正如 Microsoft 网站上所述 我们根据租户 ID 定义分
  • java swing布局两个组件

    A B
  • getaddrinfo:如果指定了节点名,AI_PASSIVE 以什么方式被忽略?

    引用自规格获取地址信息 http pubs opengroup org onlinepubs 009695399 functions freeaddrinfo html If the AI PASSIVE如果指定了标志 则返回的地址信息应适
  • 检查元素是否包含数组中的任何类

    我有以下要素 div class one two three four five six seven eight div div class one two three four five six seven eight ten div d
  • 如何防止不良项目引用?

    我们使用带有 TFS 的 C 项目作为源代码控制和 CI 构建 我不断发现其他开发人员正在引用来自的程序集 Bin当他们应该使用我们的目录时 目录不正确 Libs文件夹 我们保存第 3 方程序集的地方 作为解决方案构建或 CI 构建 我们也
  • 如何在 vim 中打开旧文件列表中的文件?

    在 vim 中 我可以输入 oldfiles查看我之前编辑过的文件列表 很棒的功能 但现在我想将该列表中的一个或多个文件打开到缓冲区中 我怎样才能做到这一点 一旦您位于列表底部 您应该按 并使用这个 奇怪 的符号发出命令 command l
  • 使用查询范围热切加载相关模型

    说我有一个模型Box其中包含许多小部件 小部件可以是活动的或非活动的 布尔值 这Widget模型有一个可以过滤结果的查询范围 模型 box php class Box extends Eloquent public function wid
  • 在 R 中创建数字同心环递增的矩阵

    我需要在 R 中编写一个函数来创建一个由递增的同心数字环组成的矩阵 该函数的参数是层数 例如 如果 x 3 矩阵将如下所示 1 1 1 1 1 1 2 2 2 1 1 2 3 2 1 1 2 2 2 1 1 1 1 1 1 我不知道该怎么做
  • 在 WooCommerce 电子邮件模板中获取产品名称和描述

    我试图在 WooCommerce 电子邮件模板中发送电子邮件时获取产品描述和产品名称 我能够获取产品 ID order id trim str replace order gt get items 使用此代码 但是当我试图获取它的描述和产品
  • 在 Symfony 应用程序/控制台中启用 Doctrine DBAL 命令

    当使用 Bare Bone Doctrine 和开箱即用的命令行时 有两个命令可用 但在 Symfony 和 Doctrine 中使用时似乎不可用 app console dbal dbal import Import SQL file s
  • MVC3 razor 创建 HtmlButtonExtension 时出错

    我正在尝试使用在我的页面上创建一个自定义 html 按钮this https stackoverflow com questions 5955571 theres no html button public static class Htm
  • oci8、php7 和 Oracle 10.1 兼容性

    我必须从以下版本升级系统php5 6 to php7 2 该系统使用一个oracle 10 1数据库 现在我尝试收集所有信息 但仍然对之间的兼容性感到困惑php oci8 instant client和数据库 我读到 对于 php7 我至少
  • ASCII 码实际上是 7 位还是 8 位?

    我的老师告诉我 ASCII 是一种 8 位字符编码方案 但它仅定义为 0 127 代码 这意味着它可以容纳 7 位 那么难道不能说 ASCII 实际上是一个 7 位代码吗 当说 ASCII 是一个 8 位代码时 我们到底在说什么 ASCII
  • ESP32 上的 Web 服务器:如何自动更新和显示来自服务器的传感器值?

    我在 ESP32 上有一个网络服务器 在该服务器上有一个主页 我想每隔 x 秒自动更新主页上的传感器值 无需用户输入 我无法访问文件系统 该传感器直接连接到 ESP32 传感器值位于我的 C 程序中 存储在变量中并定期更新 变量是全局的 以