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 服务器:如何自动更新和显示来自服务器的传感器值? 的相关文章

  • 关闭 Godot 中的游戏

    我正在使用 Godot 创建网页游戏 为了关闭游戏 我尝试使用 get tree quit 如果我在 IDE 上使用它 它就可以工作 当我在我的服务器上尝试它时 导出项目后 它不起作用 我确信导出设置没问题 我怎样才能关闭游戏 并且 如何添
  • 使用javascript向url添加哈希而不滚动页面?

    在不滚动页面的情况下向 url 添加哈希 使用 JavaScript 我打开页面 我向下滚动 我单击添加哈希的链接 可能带有值 test 示例 http www example com test http www example com t
  • 使用 ES6 静态函数时,我得到“没有这样的方法”

    我正在尝试为我在 React Native 中工作的项目创建一个包含静态函数的 utils 类 我读到了如何在 StackOverFlow 中创建静态函数question https stackoverflow com questions
  • 元素上的框阴影行为

    Update 在我提交错误报告后 https bugs chromium org p chromium issues detail id 763337 https bugs chromium org p chromium issues de
  • 检测 iPad Safari 用户的最佳方法

    添加用于检测 iPad Safari 用户的代码的最佳方法是什么 我的意思是我们应该使用 1 CSS 通过链接媒体 2 JS 通过navigator对象 我听说使用用户代理字符串并不是检测 iPad 的最佳方法 因为存在不一致的情况 请建议
  • 如何在javascript中删除一组表情符号中的最后一个表情符号?

    假设我的字符串中有 3 个表情符号 字符串中没有任何空格或除表情符号之外的任何其他字符 如何删除javascript中最后一个表情符号 下面的答案不使用任何特殊的包并安全地删除最后一个表情符号 function safeEmojiBacks
  • Javascript - 对父母调用 super 父母?

    我在 Odoo 中定义了当前自定义 javascript 视图的扩展 openerp account move journal test function instance var t instance web t lt instance
  • XMLHttpRequest、jQuery.ajax、jQuery.post、jQuery.get 之间有什么区别

    我如何找出最适合某种情况的方法 有人可以提供一些例子来了解功能和性能方面的差异吗 XMLHttpRequest是原始浏览器对象 jQuery 将其包装成更可用和简化的形式以及跨浏览器一致的功能 jQuery ajax是 jQuery 中的通
  • 如何保存包含框架/iframe 的完整 html 页面?

    在网页抓取期间 我想将当前页面的 html 保存到文件中以供以后调试 browser html在大多数情况下有帮助 但是当页面包含 iframe frame 时 它 的内容不会返回browser html 我必须用类似的东西单独得到它bro
  • JavaScript:嵌套循环?

    我想实现这样的动画 序列 动画以循环开始 想象一下car从 x1 移动到 x2 然后暂停 1 秒 然后再次播放动画 想象一下car从 x2 移动到 x3 等 the car循环是通过向汽车左侧添加 1px 来实现的 值 但我无法弄清楚嵌套循
  • 主干集合排序

    我制作了我的第一个主干应用程序 但在集合排序方面遇到了一些问题 使用这个后 var SortedFriends MyFriends sortBy function friend return friend get uid console l
  • HTML5 画布将颜色应用于形状重叠的图像

    我将此图像绘制到 HTML5 画布上 我想做的就是只给它的一部分应用颜色 我想要应用颜色的部分由以下覆盖图像定义 所以 基本上 我想通过叠加来指导我的着色 因此 在覆盖像素与主图像像素相遇的地方 我应该在主图像上应用颜色 至少我认为它是这样
  • TinyMCE:将 CSS 类属性与 formatselect-dropdown 格式结合使用

    我想定制格式 http wiki moxiecode com index php TinyMCE Configuration theme advanced blockformats在 TinyMCE 中格式选择下拉菜单 http wiki
  • 如何在javascript中设置从数据库输入的最大数量?

    我希望根据数据库中的数量设置 输入类型 数字 中输入的最大数量 目前 我正在尝试让它在数据最大的基础上工作 然后再尝试从数据库中获取最大值 但它似乎无法工作 之前已经在这里问过 但我仍然无法理解 在 php javascript 中设置数据
  • 如何缩放到高图中的特定点

    Highmaps highcharts 是一个 javascript jquery 适配器 可在浏览器等中呈现地图 我有一张突出显示单个国家 地区的地图 但是 世界 地图的比例如此之大 因此我想在将地图加载到相关国家 地区后进行放大 看看
  • Escape String - 在 Javascript 中输出rails字符串[重复]

    这个问题在这里已经有答案了 我正在尝试将字符串值分配给 erb 文件中的 javascript 对象 如下所示 var data name 问题是 如果name is Tom s small ears 的输出data name将会Tom x
  • 为什么 [].push([]) 返回 1? [复制]

    这个问题在这里已经有答案了 为什么这会返回 1 push outputs 1 push 返回数组的新长度 one push two returns 2 array length is 2 one two push something ret
  • RemoveEventListener 在 Firefox 版本 58 中不起作用

    但它在 Chrome 中有效 这是我的 UI EventBus 代码 原型 addEventListener方法是一样的 只不过remove换成了add UI EventBus removeEventListener function ob
  • 将响应式网格布局转换为 Plotly Dash

    我是一个非常活跃的 Dash 用户 我开始发现 Dash 使用中存在很多限制 并且我意识到有关如何将组件转换为 Dash 的信息 内容绝对有限 并且示例过时且非常简单 并且我对 Javascript 或 React 几乎没有任何了解 我完全
  • CSS 未使用 req.params 或其他内容加载

    我对节点 表达等非常陌生 我制作了一个博客应用程序 但遇到了问题 我正在使用 mongoose node express 和 ejs 当我打电话时 router get posts function req res Post find fu

随机推荐

  • 如何在 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 程序中 存储在变量中并定期更新 变量是全局的 以