ESP8266模块睡眠模式
面向读者群体
- ❤️ 电子物联网专业同学,想针对硬件功能构造简单的服务器,不需要学习专业的服务器开发知识 ❤️
- ❤️ 业余爱好物联网开发者,有简单技术基础,想针对硬件功能构造简单的服务器❤️
技术要求
- 有HTML、CSS、JavaScript基础更好,当然也没事,就直接运行实例代码学习
专栏介绍
- 通过简短5天时间的渐进式学习NodeJs,可以了解到基本的服务开发概念,同时可以学习到npm、内置核心API(FS文件系统操作、HTTP服务器、Express框架等等),最终能够完成基本的web开发,而且能够部署到公网访问。
学习交流群
- NodeJs物联网五天入门学习之旅(搜索:
729040020
)🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝
1.前言
在很多运用场景中我们都是直接采用适配器供电(usb供电、直插电源供电等等),一般不会考虑到供电问题。
但当我们开始考虑电池供电
给esp模块或者功耗消耗
问题的时候,为了节省更多的电量或者待机更久的时候,就必须要考虑实际应用。
而这个问题的唯一解决思路就是如何结合实际情况来使用esp模块的睡眠模式
(sleep mode)。
睡眠模式:简单一点来说就是睡着了,那各项身体机能整体能量消耗就变低了。最经典的案例就是我们经常看到的科幻世界里面的冰封人。
而在esp中,各项身体机能会包括:wifi
、系统时钟
、cpu
、rtc
等等,当然最狠的还是连cpu都停止运行了。
2.睡眠模式
在esp中,有三种不同的睡眠模式:
modem sleep
调制解调器睡眠模式
对人来说,把手头上的工作停下来休息一下
light sleep
轻度睡眠模式
对人来说,我眯眼10分钟
deep sleep
深度睡眠模式
对人来说,我先睡个8小时,不到点别叫我
从左到右其实就是逐步加强睡眠效果,主要就是关注电流变化 15mA->0.4mA->20uA
(当然这是一个概念值,实际上不一定是这个确定值,我们关注的是变化趋势)。
我们可以看到共同点就是:
三种睡眠模式下wifi功能都是关闭
的,如果我们的场景是持续需要网络功能的场景估计是不合适的。但是非常适合于间隔时间做一些操作的场景,比如每隔一段时间检测环境数据、开关门等等
2.1 modem sleep —— 调制解调器睡眠模式
2.1.1`使用场景
当不需要持续保持wifi连接时,且应用程序需要保持运行的状态下,又想减少功耗
2.1.2 核心代码
通过 WiFi.forceSleepBegin
关闭wifi,和通过 WiFi.forceSleepWake
启用wifi。
WiFi.forceSleepBegin(); // Wifi off
doAny();
WiFi.forceSleepWake(); // Wifi on
- 需要进入睡眠模式时 使用第一条语句 WiFi.forceSleepBegin
- 需要唤醒时,使用第二条语句 WiFi.forceSleepWake。
- 可以在loop中使用。
2.1.3 测试代码
/**
* Demo:
* modem sleep
*/
#include <ESP8266WiFi.h>
//以下三个定义为调试定义
#define DebugBegin(baud_rate) Serial.begin(baud_rate)
#define DebugPrintln(message) Serial.println(message)
#define DebugPrint(message) Serial.print(message)
const char* AP_SSID = "TP-LINK_5344"; // XXXXXX -- 使用时请修改为当前你的 wifi ssid
const char* AP_PSK = "xxxx"; // XXXXXX -- 使用时请修改为当前你的 wifi 密码
const unsigned long BAUD_RATE = 115200;// serial connection speed
//声明一下函数
void initBasic(void);
void initWifi(void);
void setup(void) {
initBasic();
}
void loop(void) {
// 连接wifi
initWifi();
Serial.println("Going to sleep now");
WiFi.forceSleepBegin(); // Wifi Off
delay(1000*10); // sleep for 10 seconds
WiFi.forceSleepWake(); // Wifi On
Serial.println("Wake up");
}
/**
* 初始化基础功能:波特率
*/
void initBasic(){
DebugBegin(BAUD_RATE);
}
/**
* 初始化wifi模块:工作模式 连接网络
*/
void initWifi(){
WiFi.mode(WIFI_STA);
WiFi.begin(AP_SSID, AP_PSK);
DebugPrintln("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
DebugPrint(".");
}
DebugPrintln("");
DebugPrint("Connected to ");
DebugPrintln(AP_SSID);
DebugPrint("IP address: ");
DebugPrintln(WiFi.localIP());
}
2.2 light sleep —— 轻度睡眠模式
2.2.1`使用场景
wifi、系统时钟停止了,rtc还在运行,cpu处于pending状态。
功耗上比modem sleep 更好。
2.2.2 核心代码
void light_sleep(){
wifi_station_disconnect();
wifi_set_opmode_current(NULL_MODE);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); // set sleep type, the above posters wifi_set_sleep_type() didnt seem to work for me although it did let me compile and upload with no errors
wifi_fpm_open(); // Enables force sleep
gpio_pin_wakeup_enable(GPIO_ID_PIN(2), GPIO_PIN_INTR_LOLEVEL); // GPIO_ID_PIN(2) corresponds to GPIO2 on ESP8266-01 , GPIO_PIN_INTR_LOLEVEL for a logic low, can also do other interrupts, see gpio.h above
wifi_fpm_do_sleep(0xFFFFFFF); // Sleep for longest possible time
}
- 设置的睡眠时间是最长的时间,一方面唤醒通过按钮将GPIO2 接地(手动按下按键提前唤醒),另一方面可以通过调整睡眠时间来闹钟醒来。
- 唤醒后就是做自己本来的逻辑操作。
2.2.3 测试代码
/**
* Demo:
* light sleep
*/
#include <ESP8266WiFi.h>
//以下三个定义为调试定义
#define DebugBegin(baud_rate) Serial.begin(baud_rate)
#define DebugPrintln(message) Serial.println(message)
#define DebugPrint(message) Serial.print(message)
const char* AP_SSID = "TP-LINK_5344"; // XXXXXX -- 使用时请修改为当前你的 wifi ssid
const char* AP_PSK = "xxxx"; // XXXXXX -- 使用时请修改为当前你的 wifi 密码
const unsigned long BAUD_RATE = 115200;// serial connection speed
//声明一下函数
void initBasic(void);
void initWifi(void);
void setup(void) {
initBasic();
}
void loop(void) {
// 连接wifi
initWifi();
Serial.println("Going to sleep now");
// 睡眠
light_sleep();
delay(50000);
Serial.println("Wake up");
}
/**
* 初始化基础功能:波特率
*/
void initBasic(){
DebugBegin(BAUD_RATE);
}
/**
* 初始化wifi模块:工作模式 连接网络
*/
void initWifi(){
WiFi.mode(WIFI_STA);
WiFi.begin(AP_SSID, AP_PSK);
DebugPrintln("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
DebugPrint(".");
}
DebugPrintln("");
DebugPrint("Connected to ");
DebugPrintln(AP_SSID);
DebugPrint("IP address: ");
DebugPrintln(WiFi.localIP());
}
void light_sleep(){
wifi_station_disconnect();
wifi_set_opmode_current(NULL_MODE);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); // set sleep type, the above posters wifi_set_sleep_type() didnt seem to work for me although it did let me compile and upload with no errors
wifi_fpm_open(); // Enables force sleep
gpio_pin_wakeup_enable(GPIO_ID_PIN(2), GPIO_PIN_INTR_LOLEVEL); // GPIO_ID_PIN(2) corresponds to GPIO2 on ESP8266-01 , GPIO_PIN_INTR_LOLEVEL for a logic low, can also do other interrupts, see gpio.h above
wifi_fpm_do_sleep(0xFFFFFFF); // Sleep for longest possible time
}
2.3 deep sleep —— 深度睡眠模式
2.3.1`使用场景
wifi、系统时钟停止了,rtc还在运行,cpu也处于停止运行状态。
功耗上比light sleep 更好。
对于耗电有要求,而且发送数值不频繁 可以使用睡眠模式,里面原有程序数据在深度睡眠模式将都不执行。相当于关机,只是还保持一个rtc简单定时。
这种方式下的唤醒需要使用到RST引脚来唤醒(因为睡过头了,得重启)。而触发方式有两种:
定时触发唤醒
(每隔一段时间系统自动触发rst信号)外界触发条件唤醒
(人工干预手动触发rst信号)
两种方式的核心api都是 ESP.deepSleep
2.3.2 核心代码
- 定时触发唤醒
将GPIO16 与RST连接
// 使esp模块进入深度睡眠模式 30s.
// 30s达到后 GPIO16进行唤醒
// 最多睡眠时长4,294,967,295 µs 也就是大概71分钟
ESP.deepSleep(30e6); //(单位us)
- 外界触发条件唤醒
让rst引脚接入到一个gnd电平有效的按键上
ESP.deepSleep(0); // 进行长时间的深度睡眠状态
当按钮按下 RST有低电平信号,将进行唤醒,唤醒后执行到这条语句将再次睡眠直到下一次按钮按下。
2.3.3 测试代码
/**
* Demo:
* deep sleep
*/
#include <ESP8266WiFi.h>
void setup() {
Serial.begin(115200);
Serial.setTimeout(2000);
// Wait for serial to initialize.
while(!Serial) { }
// Deep sleep mode for 30 seconds, the ESP8266 wakes up by itself when GPIO 16 (D0 in NodeMCU board) is connected to the RESET pin
//Serial.println("I'm awake, but I'm going into deep sleep mode for 30 seconds");
//ESP.deepSleep(30e6);
// Deep sleep mode until RESET pin is connected to a LOW signal (for example pushbutton or magnetic reed switch)
Serial.println("I'm awake, but I'm going into deep sleep mode until RESET pin is connected to a LOW signal");
ESP.deepSleep(0);
}
void loop() {
}
参考资料