关于esp32的省电模式的WiFi连接
对于ESP32,其作为一款集成了2.4GHz WiFi和蓝牙双模块的单芯片,所有基于wifi和蓝牙开发是学习esp32的重要一环,今天WiFi原理和网络结构 可以点击链接进行详细的了解,这里就不做详细的叙述了,本文重点讲解省电模式下的WiFi是如何连接上路由器的,重点是相关API接口和编程方法的介绍。本文源码地址在:esp-idf/examples/wifi/power_save里。源码完成了对ESP32的低功耗模式的设置,并通过menuconfig将接入点AP的名称和密码赋值给ESP32,使ESP32作为一个站点STA接入到接入点AP(即路由器)中。
PART1:
定义基本参数
/*set the ssid and password via "make menuconfig"*/
#define DEFAULT_SSID CONFIG_WIFI_SSID
#define DEFAULT_PWD CONFIG_WIFI_PASSWORD #if CONFIG_POWER_SAVE_MODEM
#define DEFAULT_PS_MODE WIFI_PS_MODEM
#elif CONFIG_POWER_SAVE_NONE
#define DEFAULT_PS_MODE WIFI_PS_NONE
#else
#define DEFAULT_PS_MODE WIFI_PS_NONE
#endif /*CONFIG_POWER_SAVE_MODEM*/
这里首先将AP端的名称和密码赋值给ESP32,使ESP32可以连接上接入点AP,这里的CONFIG_WIFI_SSID和CONFIG_WIFI_PASSWORD即为路由器端的名称和密码,他们在源码中是看不到的,它们的定义是在Kconfig.projbuild中定义的,我们可以通过make menconfig对其进行赋值。具体操作如下:
选择Example Configuration后
在WIFI SSID和WIFI Password中分别将路由器的名称和密码赋值给ESP32。
(当然,你也可以不通过menucofig而对ESP32直接进行赋值)
紧随其后的便是对ESP32工作模式的设置,同样,其也可以通过menuconfig进行设置。
PART2:
进程打印函数
static const char *TAG = "power_save"; static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START");
ESP_ERROR_CHECK(esp_wifi_connect());
break;
case SYSTEM_EVENT_STA_GOT_IP:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP");
ESP_LOGI(TAG, "got ip:%s\n",
ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED");
ESP_ERROR_CHECK(esp_wifi_connect());
break;
default:
break;
}
return ESP_OK;
}
本部分主要是将ESP32的工作信息,打印出来,对返回的任务通知进行switch分析,如果连接上了,就打印sta_start消息,并再次执行esp_err_t esp_wifi_connect
( void )将ESP32 WiFi站连接到AP,第二次得到返回任务通知SYSTEM_EVENT_STA_GOT_IP,并调用 ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));将数字IP地址转换为十进制点ASCII表示法。,此时显示连接到的AP的IP和MAC地址。
如果没有连接上AP,同样会一直执行esp_err_t esp_wifi_connect
( void ),直到将ESP32 WiFi站连接到AP为止。
PART3:
WIFI设置和耗电设置
/*init wifi as sta and set power save mode*/
static void wifi_power_save(void)
{
tcpip_adapter_init();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
wifi_config_t wifi_config = {
.sta = {
.ssid = DEFAULT_SSID,
.password = DEFAULT_PWD
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG, "esp_wifi_set_ps().");
esp_wifi_set_ps(DEFAULT_PS_MODE);
}
wifi_power_save首先调用 tcpip_adapter_init();函数对底层库的TCP/IP协议进行调用,然后检测esp_event_loop_init是否初始化完成。
之后便是进行wifi的设置,首先用esp_wifi_init(&cfg)对WIFI的内存空间进行设置,初始化WiFi Alloc资源为WiFi驱动,如WiFi控制结构,RX / TX缓冲区,WiFi NVS结构等,此WiFi也启动WiFi任务。(注意;在调用所有其他WiFi API之前,必须先调用此API)
然后设置ESP32 STA或AP的配置。
wifi_config_t wifi_config = {
.sta = {
.ssid = DEFAULT_SSID, //设置要连接的AP的接入点名称和密码
.password = DEFAULT_PWD
},
};
- (注意
- 1.只有当指定的接口被启用时,才能调用这个API,否则API会失败
- 2.对于站配置,bssid_set需要为0; 只有当用户需要检查AP的MAC地址时,才需要1。
- 3. ESP32仅限一个通道,因此在软AP +站模式下,软AP将自动调整其通道与ESP32站的通道相同。)
通过esp_wifi_set_mode(WIFI_MODE_STA)将WiFi操作模式设置为站,软AP或站+软AP,默认模式为软AP模式。
esp_wifi_set_config设置ESP32 STA或AP的配置。
最后通过esp_wifi_start()根据当前配置启动WiFi,
并通过 esp_wifi_set_ps(DEFAULT_PS_MODE);设置当前节电类型。
PART4:
APP_main函数
void app_main()
{
// Initialize NVS
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret ); wifi_power_save();
}
app_main函数主要是对NVS完成基本的初始化操作(关于NVS,可以在ESP32汇总中进行详细了解),保证数据的缓存空间,然后调用 wifi_power_save();函数完成WIFI设置。
PART5:
实验现象
程序烧写完成后,打开minicom,可以看到如下的打印信息
打开windows的cmd(这里笔记本和ESP32接入的是同一个AP),对AP分配的ESP32的IP进行ping操作,观察能否PING通。操作结果如下:
至此,基于省电模式的WIFI链接就设计完成了。
PART6:编程详情
一旦ESP32已经设置了站点配置细节,其中包括SSID和password,我们准备好连接到目标访问点后。 功能 esp_wifi_connect() 将形成的连接。你连接了后ESP32中的任何内容都不会阻塞,同样也不会影响到这个功能。
在一段时间以后,当其实际的连接起来后,我们会看到两个回调事件发生, 首先是 SYSTEM_EVENT_STA_CONNECTED 表明我们有连接到接入点。 第二个事件是 SYSTEM_EVENT_STA_GOT_IP 其表示我们已经被DHCP服务器分配了一个IP地址。只有这样我们才能真正参与通讯。如果我们正在使用静态IP地址,那么我们只会看到连接的事件。
我们从接入点断开连接时,我们将看到一个SYSTEM_EVENT_STA_DISCONNECTED 事件。从先前连接的 断开接入点我们调用esp_wifi_disconnect()完成,
关于与接入点连接的进一步考虑是自动连接的想法。 有一个布尔标志存储在闪存中指示ESP32是否应尝试自动连接到最后一个使用的接入点。 如果设置为true,那么之后在设备启动后,你无需调用任何API函数,它将尝试连接到最后使用的接入点。 这是一个
方便选项,但是我更喜欢关闭。 通常我想在我的设备中进行控制来确定是否自动连接,是否自动连接,我们可以通过调用esp_wifi_set_auto_connect()。
另外,当我们连接到接入点时,我们的设备正在成为一个station。 连接到接入点AP不是自动的,意味着我们现在有一个IP地址。 我们坚持必须从DHCP服务器请求已建立的IP地址。 这可能需要几秒。在某些情况下,我们可以让设备请求特定的IP。 这可以更快的连接时间。 如果我们指定数据,我们也需要提供DNS信息,如果我们需要连接到DNS服务器的名字解析度。
这是分配给我们一个特定IP地址的逻辑片段:
#include <lwip / sockets.h> //我们希望我们的设备拥有的IP地址。
#define DEVICE_IP“192.168.1.99” //我们希望发送数据包的网关地址
//这通常是我们的接入点。
的#define DEVICE_GW “192.168.1 1” //网络掩码规范。
#define DEVICE_NETMASK“255.255.255.0” //我们希望连接的接入点的身份。
#define AP_TARGET_SSID“RASPI3” //我们需要提供给接入点进行授权的密码。
#define AP_TARGET_PASSWORD“password” esp_err_t wifiEventHandler(void * ctx,system_event_t * event)
{
返回ESP_OK;
} //代码片段在这里...
nvs_flash_init();
tcpip_adapter_init(); tcpip_adap ter_dhcpc_stop(TCPIP_ADAPTER_IF_STA);
tcpip_adapter_ip_info_t ipInfo; inet_pton(AF_INET,DEVICE_IP,&ipInfo.ip);
inet_pton(AF_INET,DEVICE_GW,&ipInfo.gw);
inet_pton(AF_INET,DEVICE_NETMASK,&ipInfo.netmask);
tcpip_ada pter_set_ip_info(TCPIP_ADAPTER_IF_STA,&ipInfo); ESP_ERROR_CHECK(esp_event_loop_init(wifiEventHandler,NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_ST ORAGE_RAM));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
wifi_config_t sta_config = {
.sta = {
.ssid = AP_TARGET_SSID,
.password = AP_TARGET_PASSWORD,
.bssid_set =
}
};
ESP_ERROR_CHECK(esp_wifi_set_config(WI FI_IF_STA,&sta_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_ERROR_CHECK(esp_wifi_connect());
作为接入点AP
到目前为止,我们只将ESP32作为了接入接入点的WiFi站
但它也具有作为一个接入点使其他WiFi设备(站)连接的能力 。为了成为一个接入点,我们需要定义允许其他的SSID设备来区分我们的网络。 这个SSID可以被标记为为hidden, 如果我们不希望它在扫描中找到。 另外我们还要提供认证方式当台站希望与我们联系时,将使用该功能。 这是用来允许
的,实际的将ES32实例作为接入点AP请看下一篇文章
ESP32作为接入点AP
相关知识:wifi相关的API接口
关于esp32的省电模式的WiFi连接的更多相关文章
- STC12C5A60S2笔记5(省电模式)
1. 基本特性 STC12C5A60S2系列单片机可运行三种省电模式以降低功能,STC正常工作电流是2mA~7mA,而掉电模式下<0.1uA,空闲模式下<0.1mA. 1) 空闲模式:由电 ...
- 【转】iOS 9自带苹果式省电模式 依然软硬兼施
非本人总结,转自:http://news.91.com/apple/1506/21837672.html 说好的改善和优化,iOS 9真的带来了.且不说那些经过改善的功能,iOS 9 推出的低功耗模式 ...
- PhpStorm代码提示(省电模式)的设置与使用
PhpStorm中有个,Power Save Mode(省电模式),开启则代码不能自动提示,关闭则可以. 开启/关闭: 1.点击“File”菜单,最下面,Power Save Mode,勾选或取消: ...
- NB-IoT省电模式:PSM、DRX、eDRX【转】
转自:https://blog.csdn.net/zoomdy/article/details/80447372 NB-IoT支持三种省电模式:PSM (Power Saving Mode,省电模式) ...
- 802.11协议帧格式、Wi-Fi连接交互过程、无线破解入门研究
相关学习资料 Linux黑客大曝光: 第8章 无线网络 无线网络安全攻防实战进阶 无线网络安全 黑客大曝光 第2版 http://zh.wikipedia.org/wiki/IEEE_802.11 h ...
- ESP8266 HTTP 项目(2)HTTP网页修改WIFI连接,上电自动连接上次的WIFI。
网页 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf ...
- ubuntu wifi连接不上或经常断网,重启就好
问题1.知道wifi密码,驱动也有,可以点击连接,总是提示"连接断开,您现在处于离线状态". 1.打开终端"ctrl+alt+T" 2.输入: sudo vim ...
- Android开发拾遗(一)用Wi-Fi连接adb
可以用Wi-Fi通过标准的TCP/IP连接来连接Android设备. 这在开发监听USB相关事件的应用程序时会特别有用,原因是USB连接会起到干扰作用,比如USB的连接/断开事件. 首先要像通常一样用 ...
- Android配置----小米手机通过wifi连接ADB调试Android应用
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...
随机推荐
- CentOS内网机器利用iptables共享公网IP上网
公司有个业务是2B的以及日活不大,所以两台服务器搞定,一个6M EIP.两台机器都是CentOS7系统EIP为 xxx.xxx.xxx.xxx绑在 内网ip为 172.18.30.175的服务器上,内 ...
- ansible 问题
如下图,A服务器上用普通账号ansible有时就会报错,但有时却又正常,可以连接成功,用root账号执行ansible就完全没问题. 仅仅是这一台服务器有问题,其他都完全正常..ansible 文件删 ...
- join() ---- 使用四种不同的分隔符连接数组元素
var a = ['Wind', 'Rain', 'Fire']; var myVar1 = a.join(); // myVar1的值变为"Wind,Rain,Fire" var ...
- week0713.5 newspaper 安装问题
然后爆红说nltk==2.0.5 太老了 所以我们 把包下载下来将requirements文件中nltk==2.0.5改成3.3.0 然后 将包打包 然后安装这个包就OK 下载newpaper wge ...
- week07 13.3 NewsPipeline之 三News Deduper之 tf_idf 查重
我们运行看结果 安装包sklearn 安装numpy 安装scipy 终于可以啦 我们把安装的包都写在文件里面吧 4行4列 轴对称 只需要看一半就可以 横着看 竖着看都行 数值越接近1 表示越相似 我 ...
- 恢复mysql 中root 用户的所有权限
今天在研究数据库的时候不小心吧root用户的权限全给关了.这就尴尬了. 找了半天的解决方案. 如果你的用grant all 无法设定某个用户的权限可以试试这个方法. 1停止mysql服务器.使用ski ...
- jstat查看JVM GC情况
转自 https://www.cnblogs.com/yjd_hycf_space/p/7755633.html
- centos系统有多个内核,修改默认启动内核
打开系统文件 vim /boot/grub/grub.conf default=0,意思是GRUB在默认情况下,也就是用户没有选择的情况下,去启动显示在用户界面的第一个系统:GRUB启动系统时是从0 ...
- [Solution] 950. Reveal Cards In Increasing Order
Difficulty: Medium Problem In a deck of cards, every card has a unique integer. You can order the de ...
- socketserver 模块并发
socketserver是将socket封装的类. 实例: 服务端: import socketserver class Myserver(socketserver.BaseRequestHandle ...