• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
MKT-porter
博客园    首页    新随笔    联系   管理    订阅  订阅
esp8266 网页画压力数据图,双按键控制报警,串口接收json数据解析
 

 

 

1串口等待数据

2建立wifi

3数据给网页

 

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>                // 文件系统库
#include <ArduinoJson.h>
#include <SoftwareSerial.h>    // 软串口库

const char *ssid = "ESP8266_Hotspot";    // 热点名称
const char *password = "love123456";      // 热点密码

ESP8266WebServer server(80);  // 创建 HTTP 服务器,监听端口 80

bool alarmState = false;  // 默认报警器关闭
float pressure = 100.0;  // 假设压力值为 1013 hPa

#define BEEPER_PIN  D4    // 假设蜂鸣器连接在引脚3

// 创建软串口,使用 D1 和 D2 引脚
SoftwareSerial softSerial(D1, D2);//D1 为 RX, D2 为 TX

void setup() {
  Serial.begin(9600);  // 启动串口调试
  softSerial.begin(9600);  // 启动软串口,波特率为 9600

  // 初始化文件系统
  if (!SPIFFS.begin()) {
    Serial.println("SPIFFS 初始化失败!");
    return;
  }

  // 设置为热点模式
  WiFi.softAP(ssid, password);
  Serial.println("Hotspot created");
  Serial.print("IP Address: ");
  Serial.println(WiFi.softAPIP());  // 打印热点 IP 地址

 // 设置蜂鸣器引脚为输出
  pinMode(BEEPER_PIN, OUTPUT);
  digitalWrite(BEEPER_PIN, HIGH);  // 关闭蜂鸣器


  // 设置根目录的请求处理函数,返回 HTML 文件
  server.on("/", HTTP_GET, handleRoot);
  server.on("/data", HTTP_GET, handleData); // 用于动态数据访问
  server.on("/chart.js", HTTP_GET, handleChartJS); // 修改为 /chart.js 路由
  server.on("/control-alarm", HTTP_GET, handleControlAlarm); // 控制报警器
  server.begin();

  Serial.println("esp3-交互网页模块开启 ");
}

void loop() {
  server.handleClient();  // 处理网页请求

  // 检查软串口是否有数据
  if (softSerial.available()) {
    String jsonData = softSerial.readStringUntil('\n');  // 读取一行数据

    // 解析 JSON 数据
    StaticJsonDocument<200> doc;
    DeserializationError error = deserializeJson(doc, jsonData);

    if (!error) {
      // 提取压力和报警状态
      pressure = doc["pressure"];
      alarmState = doc["alarm"];
      Serial.print("esp3交互网页模块- 压力: ");
      Serial.println(pressure);
      Serial.print("报警状态: ");
      
      if(pressure>240){
          alarmState="开启";    
          digitalWrite(BEEPER_PIN, LOW);  // 启动蜂鸣器 
        }
        else{
          alarmState="关闭";   // alarmState="开启"; 
          digitalWrite(BEEPER_PIN, HIGH);  // 启动蜂鸣器 
      }
      Serial.println(alarmState );
      
    } else {
      Serial.println("JSON 解析失败!");
    }
  }
}

void handleRoot() {
  // 从 SPIFFS 中读取 HTML 文件
  File file = SPIFFS.open("/index.html", "r");
  if (!file) {
    server.send(404, "text/plain", "File not found");
    return;
  }

  server.streamFile(file, "text/html");  // 返回 HTML 文件
  file.close();
}

void handleChartJS() {
  // 从 SPIFFS 中读取 Chart.js 文件
  File file = SPIFFS.open("/chart.js", "r");  // 这里读取 /chart.js 文件
  if (!file) {
    server.send(404, "text/plain", "File not found");
    return;
  }

  server.streamFile(file, "application/javascript");  // 返回 Chart.js 文件
  file.close();
}

void handleData() {
  // 构造 JSON 响应
  String jsonResponse = "{\"pressure\": " + String(pressure) + ", \"alarm\": " + (alarmState ? "true" : "false") + "}";

  server.send(200, "application/json", jsonResponse);  // 返回 JSON 数据
}

void handleControlAlarm() {
  String state = server.arg("state");  // 获取控制参数

  if (state == "on") {
    alarmState = true;
    // 通过软串口将控制命令发送出去
    Serial.println("ALARM_ON");
    Serial.println("报警器已开启");
     alarmState="开启"; 
    digitalWrite(BEEPER_PIN, LOW);  // 启动蜂鸣器
  } else if (state == "off") {
    alarmState = false;
    // 通过软串口将控制命令发送出去
    Serial.println("ALARM_OFF");
    Serial.println("报警器已关闭");
     alarmState="关闭";   
    digitalWrite(BEEPER_PIN, HIGH);  // 关闭蜂鸣器
  }

  // 返回 JSON 响应
  String jsonResponse =String() + "{\"success\": \""+ alarmState +"\"}";
  server.send(200, "application/json", jsonResponse);  // 返回控制成功的响应
}

  

 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>实时压力与报警数据</title>
  <script src="/chart.js"></script>
  <script>
    var chart;
    var dataPoints = [];  // 存储压力数据的数组
    var labels = [];      // 存储时间标签的数组

    // 创建并更新图表的函数
    function createChart() {
      chart = new Chart(document.getElementById("myChart").getContext("2d"), {
        type: 'line',
        data: {
          labels: labels,
          datasets: [{
            label: '压力值',
            data: dataPoints,
            borderColor: 'rgba(75, 192, 192, 1)',
            fill: false
          }]
        },
        options: {
          scales: {
            y: {
              beginAtZero: true
            }
          }
        }
      });
    }

    // 更新图表数据
    function updateChartData(newData) {
      // 限制数据点数量为12个
      if (dataPoints.length >= 12) {
        dataPoints.shift();  // 移除第一个元素(最旧的点)
        labels.shift();      // 移除第一个标签
      }

      // 将新数据添加到数组中
      dataPoints.push(newData.pressure);
      labels.push(new Date().toLocaleTimeString());

      // 更新图表
      chart.update();
    }

    // 从 ESP 获取数据
    function fetchData() {
      fetch('/data')
        .then(response => response.json())
        .then(data => {
          document.getElementById("pressure").innerHTML = "压力: " + data.pressure + " hPa";
          document.getElementById("alarm").innerHTML = "报警: " + data.alarm;

          // 更新图表数据
          updateChartData(data);
        });
    }

    setInterval(fetchData, 2000);  // 每 2 秒更新一次数据

    window.onload = function() {
      createChart();  // 页面加载时创建图表
    };
  </script>
</head>
<body>
  <h1>实时压力与报警数据</h1>
  <p id="pressure">压力: 1013 hPa</p>
  <p id="alarm">报警: 正常</p>
      <!-- 折线图 -->
  <canvas id="myChart" width="400" height="200"></canvas>

      <!-- 控制报警器的按钮  -->
      <div id="alarm-control">
        <button class="button" onclick="controlAlarm('on')">开启报警</button>
        <button class="button" onclick="controlAlarm('off')">关闭报警</button>
      </div>
     

      <script>
        // 控制报警器的函数
        function controlAlarm(state) {
          fetch(`/control-alarm?state=${state}`)
            .then(response => response.json())
            .then(data => {
              if (state === 'on') {
                document.getElementById("alarm").innerHTML = "报警: 开启";
              } else {
                document.getElementById("alarm").innerHTML = "报警: 正常";
              }
            });
        }
      </script>
</body>
</html>

  

 

posted on 2025-03-01 01:31  MKT-porter  阅读(50)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3