You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为ESP8266图表添加阿姆斯特丹实时时间戳的技术问询

解决ESP8266图表时间戳替换为阿姆斯特丹实时时间的方案

当前代码用millis()生成的时间戳无实际意义,要显示阿姆斯特丹实时时间,核心是通过NTP协议获取网络标准时间,再转换为阿姆斯特丹时区(CET/CEST,UTC+1或UTC+2,自动适配夏令时)。以下是具体实现步骤和修改后的代码:

实现步骤

  • 引入ESP8266自带的WiFiUdp和NTPClient库,无需额外安装
  • 初始化NTP客户端,配置可靠的NTP服务器、时区偏移及同步间隔
  • 编写函数生成格式化的阿姆斯特丹时间字符串(如YYYY-MM-DD HH:MM:SS)
  • 替换原有路由中millis()生成时间的逻辑,改用NTP获取的实际时间

修改后的完整代码

#include <DHT.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiUdp.h>
#include <NTPClient.h>

#define DHTTYPE DHT11
#define DHTPIN 2
DHT dht(DHTPIN, DHTTYPE);
ESP8266WebServer server(80);

// 初始化NTP客户端
WiFiUDP ntpUDP;
// 阿姆斯特丹时区:UTC+1(冬令时)/ UTC+2(夏令时),库自动处理夏令时切换
NTPClient timeClient(ntpUDP, "pool.ntp.org", 3600, 60000); // 3600秒=UTC+1偏移,60000ms=10分钟同步一次

// 生成格式化的阿姆斯特丹时间字符串
String getAmsterdamTime() {
  timeClient.update();
  unsigned long epochTime = timeClient.getEpochTime();
  
  // 转换为本地时间结构体
  struct tm *localTime = gmtime(&epochTime + timeClient.getTimeOffset());
  
  // 格式化时间为YYYY-MM-DD HH:MM:SS格式
  char timeStr[20];
  sprintf(timeStr, "%04d-%02d-%02d %02d:%02d:%02d",
          localTime->tm_year + 1900,
          localTime->tm_mon + 1,
          localTime->tm_mday,
          localTime->tm_hour,
          localTime->tm_min,
          localTime->tm_sec);
  return String(timeStr);
}

void setup() {
  Serial.begin(115200);
  WiFi.begin("SSID", "Password");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");
  
  dht.begin();
  timeClient.begin(); // 启动NTP客户端
  
  server.on("/", []() {
    String html = "<html><body>";
    html += "<style> body{text-align:center; font-family:sans-serif;}#temp,#hum{color:red;}h1{font-size:75px;}.top{margin-top:50px;}</style>";
    html += "<h1 class='top'>Temperatuur: <span id='temp'>Loading...</span> *C</h1>";
    html += "<h1>Luchtvochtigheid <span id='hum'>Loading...</span> %</h1>";
    html += "<script src='https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js'></script>";
    html += "<canvas id='tempChart'></canvas>";
    html += "<canvas id='humChart' style='margin-top:50px;'></canvas>";
    html += "<script>setInterval(function(){fetch('/temp-hum').then(res=>res.text()).then(tempHum=>{let [temp, hum] = tempHum.split(','); document.getElementById('temp').innerHTML=temp; document.getElementById('hum').innerHTML=hum});fetch('/getTempData').then(res => res.json()).then(data => {tempChart.data.labels.push(data.time); tempChart.data.datasets[0].data.push(data.temp); tempChart.update()});fetch('/getHumData').then(res => res.json()).then(data => {humChart.data.labels.push(data.time); humChart.data.datasets[0].data.push(data.hum); humChart.update()})}, 10000);</script>";
    html += "<script>var tempCtx = document.getElementById('tempChart').getContext('2d');var tempChart = new Chart(tempCtx, {type: 'line',data: { labels: [],datasets: [{label: 'Temperature',data: [],borderColor: 'red',fill: false}]},options: {scales: {yAxes: [{scaleLabel: {display: true,labelString: 'Temperature (°C)'}}],xAxes: [{scaleLabel: {display: true,labelString: 'Time'}}]},title: {display: true,text: 'Temperature over time'},legend: {display: true }}});var humCtx = document.getElementById('humChart').getContext('2d');var humChart = new Chart(humCtx, {type: 'line',data:{ labels: [],datasets: [{label: 'Humidity',data: [],borderColor: 'blue',fill: false}]},options: {scales: {yAxes: [{scaleLabel: {display: true,labelString: 'Humidity (%)'}}],xAxes: [{scaleLabel: {display: true,labelString: 'Time'}}]},title: {display: true,text: 'Humidity over time'},legend: {display: true }}})</script>";
    html += "</body></html>";
    server.send(200, "text/html", html);
  });

  server.on("/temp-hum", []() {
    String temp = String(dht.readTemperature());
    String hum = String(dht.readHumidity());
    String tempHum = temp + "," + hum;
    server.send(200, "text/plain", tempHum);
  });

  server.on("/getTempData", []() {
    String time = getAmsterdamTime();
    String temp = String(dht.readTemperature());
    String data = "{\"time\":\""+time+"\",\"temp\":\""+temp+"\"}";
    server.send(200, "application/json", data);
  });
  
  server.on("/getHumData", []() {
    String time = getAmsterdamTime();
    String hum = String(dht.readHumidity());
    String data = "{\"time\":\""+time+"\",\"hum\":\""+hum+"\"}";
    server.send(200, "application/json", data);
  });
  
  server.begin();
  Serial.println("Server started");
}

void loop() {
  server.handleClient();
}

关键说明

  • NTPClient初始化时的3600是UTC到阿姆斯特丹冬令时的偏移秒数,库会自动识别夏令时并追加3600秒(切换为UTC+2)
  • getAmsterdamTime()每次调用会先更新NTP时间,但库内部会按设置的10分钟间隔限制同步频率,避免频繁请求
  • 已替换getTempData和getHumData路由中的millis()调用,改用实际的阿姆斯特丹时间字符串

内容的提问来源于stack exchange,提问作者siebetimmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 07:25:32