ESP8266模块三种低功耗睡眠模式

面向读者群体

  • ❤️ 电子物联网专业同学,想针对硬件功能构造简单的服务器,不需要学习专业的服务器开发知识 ❤️
  • ❤️ 业余爱好物联网开发者,有简单技术基础,想针对硬件功能构造简单的服务器❤️

技术要求

  • HTMLCSSJavaScript基础更好,当然也没事,就直接运行实例代码学习

专栏介绍

  • 通过简短5天时间的渐进式学习NodeJs,可以了解到基本的服务开发概念,同时可以学习到npm、内置核心API(FS文件系统操作、HTTP服务器、Express框架等等),最终能够完成基本的web开发,而且能够部署到公网访问。

学习交流群

  • NodeJs物联网五天入门学习之旅(搜索:729040020

🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝

1.前言

在很多运用场景中我们都是直接采用适配器供电(usb供电、直插电源供电等等),一般不会考虑到供电问题。

但当我们开始考虑电池供电给esp模块或者功耗消耗问题的时候,为了节省更多的电量或者待机更久的时候,就必须要考虑实际应用。

而这个问题的唯一解决思路就是如何结合实际情况来使用esp模块的睡眠模式(sleep mode)。

睡眠模式:简单一点来说就是睡着了,那各项身体机能整体能量消耗就变低了。最经典的案例就是我们经常看到的科幻世界里面的冰封人。
而在esp中,各项身体机能会包括:wifi系统时钟cpurtc等等,当然最狠的还是连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() {
}

参考资料

  • 10
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
MyBatis是一个开源的持久化框架,可以帮助我们将数据从数据库中读取出来,然后转换为Java对象,并将Java对象写入数据库中。 在C#中使用MyBatis,需要先安装MyBatis.Net库,然后在项目中引用该库。接着,我们需要创建一个配置文件,用于配置MyBatis的数据库连接信息、SQL语句等。在配置文件中,我们需要指定一个别名,用于在程序中引用这个配置文件。 接下来,我们需要创建一个映射文件,用于将数据库中的数据映射为Java对象。在映射文件中,我们需要定义一个 resultMap,用于定义Java对象与数据库表之间的关系。我们还需要定义一个 SQL 语句,用于从数据库中读取数据,并将其转换为Java对象。 在程序中,我们需要创建一个 SqlSession 对象,用于执行SQL语句。我们可以通过SqlSession对象调用selectOne、selectList、update、delete等方法,来执行SQL语句,并将结果转换为Java对象或者操作数据库。 下面是一个简单的示例,展示了如何在C#中使用MyBatis: 1. 安装MyBatis.Net库 在Visual Studio中,选择“工具”-“NuGet包管理器”-“程序包管理器控制台”,然后输入以下命令: ``` Install-Package MyBatisNet ``` 2. 创建配置文件 在项目中创建一个名为“SqlMapConfig.xml”的文件,用于配置数据库连接信息、SQL语句等。以下是一个示例配置文件: ``` xml <?xml version="1.0" encoding="utf-8" ?> <sqlMapConfig> <database> <provider name="SqlServer" connectionString="Data Source=localhost;Initial Catalog=mydatabase;User ID=myuser;Password=mypassword;" /> </database> <sqlMap> <map resource="MyMapper.xml"/> </sqlMap> </sqlMapConfig> ``` 其中,provider元素用于指定数据库类型和连接字符串,map元素用于指定映射文件路径。 3. 创建映射文件 在项目中创建一个名为“MyMapper.xml”的文件,用于将数据库中的数据映射为Java对象。以下是一个示例映射文件: ``` xml <?xml version="1.0" encoding="utf-8" ?> <sqlMap namespace="MyMapper"> <resultMap id="MyResultMap" class="MyClass"> <result property="id" column="id"/> <result property="name" column="name"/> </resultMap> <select id="selectById" resultMap="MyResultMap"> SELECT * FROM mytable WHERE id=#id# </select> </sqlMap> ``` 其中,resultMap元素用于定义Java对象与数据库表之间的关系,select元素用于定义SQL语句。 4. 在程序中使用MyBatis 在程序中,我们需要创建一个 SqlSession 对象,用于执行SQL语句。以下是一个示例代码: ``` csharp using IBatisNet.DataMapper; using IBatisNet.DataMapper.Configuration; using IBatisNet.DataMapper.Configuration.Files; // 创建配置文件 DomSqlMapBuilder builder = new DomSqlMapBuilder(); ISqlMapper sqlMapper = builder.Configure(@"SqlMapConfig.xml"); // 执行SQL语句 MyClass obj = sqlMapper.QueryForObject<MyClass>("MyMapper.selectById", new { id = 1 }); ``` 以上是一个简单的示例,展示了如何在C#中使用MyBatis。实际上,MyBatis还有很多其他的用法和功能,需要我们在实际开发中去探索和使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

单片机菜鸟爱学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值