一、功能需求
实现一个简单的功能:
让 ESP32 每天在固定的时间 自动打开电源(通电),到了设定时间后自动关闭电源(断电)。
比如:
- 每天早上 7:00 自动打开电源
- 每天晚上 17:00 自动关闭电源
这样就不用手动操作了。
开始前需要掌握的知识
面包版
我们在学习使用单片机的时候,电路是必须要用到的,而面包版和杜邦线就非常适合搭建电路
面板版的分为窄条和宽条,面板包的外观如下图所式
窄条,外观的结构和功能如下
窄条上下两行之间电不连通。每 5 个插孔为一组,标注 + 的窄条一般接电源,- 接地。
宽条,外观的结构和功能如下
宽条上下两行之间电连通,左右不连通,每 5 个插孔为一组
杜邦线
杜邦线是一种用于电子制作中连接模块和板子的导线
杜邦线的线有线头为公线,无线头为母线
杜邦线的分类
名称 | 用法 |
---|---|
公对公(♂-♂) | 接两个母座(比如两个排针) |
公对母(♂-♀) | 一头插排针,一头接传感器 |
母对母(♀-♀) | 接两个模块,或模块和传感器 |
LED
LED(Light Emitting Diode) 发光二极管 是一种能将电转换为光能的电子元器件,它具有单向导电性。
LED 是一个 二极管,具有方向性:
- 阳极(长脚):接电源正极(VCC)
- 阴极(短脚):接地(GND)
只有电流从正极流向负极时才会发光。
名称 | 数值范围 | 说明 |
---|---|---|
最小点亮电流 | ≈ 3mA | 一般来说 3mA 就能点亮 LED,但亮度较低 |
推荐电流 | 5mA ~ 15mA | 常用范围,亮度适中且不会损伤 LED |
最大安全电流 | 20mA | 超过此值可能会缩短寿命甚至烧毁,通常不推荐长时间使用 |
导通压降 | ≈ 1.7V | 发光时的两端电压(红色 LED 典型值) |
点亮一个LED灯
名称 |
---|
LED |
1kΩ 电阻 |
面包板 |
杜邦线 |
功能如何实现?
ESP32 是一个联网的芯片,我们用它来:
- ESP32 连上 Wi-Fi,自动从网络上获取准确的时间;
- 你设置好“几点通电、几点断电”;
- 每分钟 ESP32 会查看一次当前时间;
- 到了设定时间,它就通过一个引脚输出 高电平(接通电源控制开关,比如继电器);
- 超过那个时间,它就输出 低电平,断开电源。
需要的设备
- ✅ 一块 ESP32 开发板
- ✅ 一个 继电器模块(用来控制电的开和关)
- ✅ 一块 面包板(方便连接各个模块)
- ✅ 若干 杜邦线(用来连接 ESP32 和继电器)
- ✅ 三个 LED灯
- ✅ 一条 USB 数据线(用于连接电脑上传程序)
- ✅ 电源适配器(用于 ESP32 或继电器供电)
⚠️ 注意:控制220V电器,一定要查看继电器支持的电压,开发阶段可以使用低压设备进行测试
主要功能逻辑
主要引脚说明
ESP32 引脚编号 | 功能说明 |
---|---|
GPIO 12 | 启动检测指示灯(程序启动时点亮) |
GPIO 13 | Wi-Fi 连接成功指示灯 |
GPIO 14 | 控制电源开关(控制继电器) |
GND | 地线 |
3.3V 或 5V | 电源 |
完整代码
#include <WiFi.h>
#include "time.h"
#define LED_ESP32_BOOT 12 // esp32 启动检测
#define LED_WIFI_SUCCESS 13 // wifi 连接成功 led 灯
#define LED_POWER_ON 14 // 定时开始时间
// wifi 设置
const char* ssid = "yunzhi";
const char* password = "yunzhi.club";
// 设置时区
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 8 * 3600; // 东八区 (北京时间)
const int daylightOffset_sec = 0;
// 开灯时间:07:00
const int ON_HOUR = 21;
const int ON_MIN = 57;
// 关灯时间:17:00
const int OFF_HOUR = 22;
const int OFF_MIN = 20;
void setup() {
Serial.begin(9600);
initPinMode();
WiFi.disconnect(true);
WiFi.begin(ssid, password);
Serial.print("正在连接 Wi-Fi");
// 检测是否连接 wifi 成功
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("连接成功");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
digitalWrite(LED_ESP32_BOOT, HIGH);
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
}
void loop() {
struct tm timeinfo;
if (getLocalTime(&timeinfo)) {
int hour = timeinfo.tm_hour;
int min = timeinfo.tm_min;
Serial.printf("当前时间: %02d:%02d\n", hour, min);
if (isInTimeRange(hour, min)) {
Serial.println("开始时间");
digitalWrite(LED_14, HIGH);
} else {
Serial.println("关闭时间");
digitalWrite(LED_14, LOW);
}
}
delay(60 * 1000);
}
bool isInTimeRange(int hour, int min) {
int current = hour * 60 + min;
int onTime = ON_HOUR * 60 + ON_MIN;
int offTime = OFF_HOUR * 60 + OFF_MIN;
Serial.printf("当前 totalMin: %d, 开始 onTime: %d, 关闭 offTime: %d\n", current, onTime, offTime);
return current >= onTime && current < offTime;
}
void initPinMode() {
pinMode(LED_12,OUTPUT);
pinMode(LED_13,OUTPUT);
pinMode(LED_14,OUTPUT);
digitalWrite(LED_ESP32_BOOT, HIGH);
}
常量定义与配置信息
#define LED_ESP32_BOOT 12 // esp32 启动检测
#define LED_WIFI_SUCCESS 13 // wifi 连接成功 led 灯
#define LED_POWER_ON 14 // 是否通电
定义三个 GPIO 引脚,用于不同状态下的 LED 指示。
const char* ssid = "yunzhi";
const char* password = "yunzhi.club";
设置 Wi-Fi SSID 和密码。
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 8 * 3600; // 东八区
const int daylightOffset_sec = 0;
配置 NTP 服务器与时区,适用于中国(UTC+8)。
const int ON_HOUR = 7;
const int ON_MIN = 0;
const int OFF_HOUR = 17;
const int OFF_MIN = 0;
设置控制通电的时间段为 7:00 到 17:00。
初始化函数
Serial.begin(9600);
pinMode(LED_ESP32_BOOT,OUTPUT);
pinMode(LED_WIFI_SUCCESS,OUTPUT);
pinMode(LED_POWER_ON,OUTPUT);
digitalWrite(LED_ESP32_BOOT, HIGH); // 点亮 LED_ESP32_BOOT 代表程已启动
启动串口,波特率为 9600,用于调试输出;设置三个 LED 引脚为输出模式;点亮 LED_ESP32_BOOT 代码程序已经启动
WiFi.disconnect(true); // 确保断开之前的连接
WiFi.begin(ssid, password); // 启动 Wi-Fi 连接
Serial.print("正在连接 Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
等待连接成功;
每 500ms 打印一个点来表示正在尝试连接。
Serial.println("连接成功");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
digitalWrite(LED_WIFI_SUCCESS, HIGH); // Wi-Fi 连接成功,点亮 LED_13
连接成功后打印 IP;
点亮 LED_WIFI_SUCCESS 作为指示
主循环
void loop() {
struct tm timeinfo;
if (getLocalTime(&timeinfo)) {
int hour = timeinfo.tm_hour;
int min = timeinfo.tm_min;
Serial.printf("当前时间: %02d:%02d\n", hour, min);
if (isInTimeRange(hour, min)) {
digitalWrite(LED_POWER_ON, HIGH);
} else {
digitalWrite(LED_POWER_ON, LOW);
}
}
delay(60 * 1000);
}
判断时间范围函数 isInTimeRange
bool isInTimeRange(int hour, int min) {
int current = hour * 60 + min;
int onTime = ON_HOUR * 60 + ON_MIN;
int offTime = OFF_HOUR * 60 + OFF_MIN;
Serial.printf("当前 totalMin: %d, 开始 onTime: %d, 关闭 offTime: %d\n", current, onTime, offTime);
return current >= onTime && current < offTime;
}
- 将时间全部转化为分钟数来进行比较;
- 如果当前分钟数在开始和结束时间之间,返回true;
补充说明
“wokwi-relay-module” 是 Wokwi 平台(一个专注于 Arduino、ESP32 等开发板模拟器)的一个虚拟继电器模块,用来模拟实际中的继电器(relay)工作方式,常用于控制大功率设备如灯、电机等。
当 IN 为高电平时,继电器吸合,NO 与 COM 导通。
当 IN 为低电平时,继电器释放,NC 与 COM 导通。
参考地址
https://docs.geeksman.com/esp32/Arduino/01.esp32-arduino-intr...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。