赞
踩
(如有更新,见原文:https://blog.iyatt.com/?p=11891)
ESP32 买了快三个月了,当时用 Arduino IDE 配置好了开发环境,之后就开始吃灰。最近想起来,打算做个可以联网对时的时钟,所以开始学习探索了。
/** * WiFi 连接程序 * 启动后自动尝试连接设置的 WiFi * 如果连接失败,最多尝试 20 次 * 连接成功后可以短接 GND 和 D15 引脚使 WiFi 连接断开 */ #include <WiFi.h> const char* ssid = "IYATT-yx_2.4GHz"; // WiFi 名 const char* password = "esp32test"; // 密码 int pin = 15; // D15 引脚用于控制断开 WiFi int state = false; // 引脚状态 void setup() { Serial.begin(115200); delay(500); pinMode(pin, INPUT_PULLUP); Serial.println(); Serial.print("[WiFi] 尝试连接到 "); Serial.println(ssid); WiFi.begin(ssid, password); // 失败尝试重连 int try_delay = 1000; // 尝试间隔延时 int number_of_tries = 20; // 尝试次数 while (true) { // 检查 WiFi 连接状态 switch(WiFi.status()) { case WL_NO_SSID_AVAIL: { Serial.println("[WiFi] 没有找到 SSID"); break; } case WL_CONNECT_FAILED: { Serial.print("[WiFi] 失败 - WiFi 未连接! 原因:"); return; } case WL_CONNECTION_LOST: { Serial.println("[WiFi] 连接丢失"); break; } case WL_SCAN_COMPLETED: { Serial.println("[WiFi] 扫描已完成"); break; } case WL_CONNECTED: { Serial.println("[WiFi] 已连接!"); Serial.print("[WiFi] IP 地址:"); Serial.println(WiFi.localIP()); return; } case WL_DISCONNECTED: { Serial.println("[WiFi] 连接已断开"); break; } default: { Serial.print("[WiFi] WiFi 状态:"); Serial.println(WiFi.status()); break; } } delay(try_delay); if(number_of_tries <= 0) { Serial.print("[WiFi] 连接 WiFi 失败!"); WiFi.disconnect(); return; } else { --number_of_tries; } } } void loop() { state = digitalRead(pin); if (state == LOW) { Serial.println("[WiFi] 正在断开连接!"); if(WiFi.disconnect(true, false)) { Serial.println("[WiFi] 已断开连接"); } delay(1000); } }
这里方便测试我就使用电脑上的 Python 运行 http 模块作为服务器端,下面是一个简易的 html 网页
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>hello</title>
</head>
<body>
<h1>你好,世界!</h1>
</body>
</html>
命名保存为 index.html 文件
然后在这个文件所在的路径运行 http 服务(8080 端口)
python -m http.server 8080
同一局域网下的手机可以访问这个网页(电脑IP:8080 ),服务器这边就没啥问题了
然后是 ESP32 的代码
/** * GET 请求实现 */ #include <WiFi.h> #include <WiFiMulti.h> WiFiMulti WiFiMulti; // 创建一个多 WiFi 实例,可以连接多个 WiFi void setup() { Serial.begin(115200); delay(10); WiFiMulti.addAP("IYATT-yx_2.4GHz", "esp32test"); // 首先连接到一个 WiFi,分别是名字和密码 Serial.println(); Serial.println(); Serial.print("等待 WiFi 连接...... "); while(WiFiMulti.run() != WL_CONNECTED) // 连接失败时重试 { Serial.print("."); delay(1000); } Serial.println(""); Serial.println("WiFi 已连接"); Serial.println("IP 地址: "); Serial.println(WiFi.localIP()); delay(500); } void loop() { const char * host = "192.168.1.249"; // 服务器地址 const uint16_t port = 8080; // 服务器端口 Serial.print("正在连接到 "); Serial.println(host); WiFiClient client; // 用于创建 TCP 连接 if (!client.connect(host, port)) // 连接服务器 { Serial.println("连接失败!"); Serial.println("5 秒后重试......"); delay(5000); return; } client.print("GET /index.html HTTP/1.1\n\n"); // 发送 GET 请求,获取 index.html 文件 int maxloops = 0; // 等待服务器返回数据 while (!client.available() && maxloops < 1000) { ++maxloops; delay(1); } if (client.available() > 0) // 如果有数据返回 { String response = client.readString(); Serial.println("服务器返回的内容:"); Serial.println(response); } else { Serial.println("连接超时"); } Serial.println("正在关闭连接。"); client.stop(); Serial.println("等待 5 秒后重试......"); delay(5000); }
运行后可以看到串口输出了请求到的内容
Python 这边也会显示 ESP32 的请求记录
源码
#include <WiFi.h> #include <NTP.h> const char * ssid = "IYATT-yx_2.4GHz"; const char * password = "esp32test"; WiFiUDP wifi_udp; NTP ntp(wifi_udp); void setup() { const char * ntp_server = "ntp.aliyun.com"; // NTP 服务器,默认的感觉应该不如国内的稳定 Serial.begin(115200); delay(100); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { Serial.println("正在尝试连接 WiFi ......"); delay(1000); } Serial.println("WiFi 已连接"); ntp.isDST(false); // 禁止夏令时 ntp.timeZone(8); // 北京时间 ntp.begin(ntp_server); Serial.println("开始同步时间:"); } void loop() { ntp.update(); Serial.println(ntp.formattedTime("%Y.%m.%d %A %T")); // 格式化规则同 strftime delay(1000); }
前面探索 NTP 时间同步的时候不知道 ESP32 内部有系统时间,也不知道官方有提供时间同步功能。本来的计划是 ESP32 还要外接一个实时时钟模块,结果在查阅资料的时候发现官方文档说内部有系统时间,那就大大地简化了。不过因为没有独立电源供电,一旦外接电源断开时钟就会丢失,而实时时钟模块自身是可以使用外部电池供电维持走时。
#include <WiFi.h> void setup() { const char * ssid = "IYATT-yx_2.4GHz"; const char * password = "esp32test"; const char * ntp_server = "ntp.aliyun.com"; // NTP 服务器 const int gmt_offset = 8 * 60 * 60; // UTC/GMT+8,东 8 时区偏移量,单位秒 const int daylight_offset = 0; // 夏令时偏移值,单位秒 Serial.begin(115200); delay(1000); // 设置时区 setenv("TZ", "CST-8", 1); // TZ 是时区环境变量,CST-8 是中国标准时间,1 表示覆盖旧值 tzset(); // 作用时区变量 // 连接 WiFi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { Serial.println("正在尝试连接 WiFi ......"); delay(1000); } Serial.println("WiFi 已连接"); delay(1000); // 同步时间 configTime(gmt_offset, daylight_offset, ntp_server); Serial.println("完成时间同步"); delay(2000); } void loop() { time_t now = 0; struct tm time_info; char strftime_buf[64] = {'\0'}; time(&now); localtime_r(&now, &time_info); strftime(strftime_buf, sizeof(strftime_buf), "%Y.%m.%d %A %T", &time_info); Serial.println(strftime_buf); delay(1000); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。