工程的建立
- 从ESP8266_RTOS_SDK中拷贝一个工程,用VSCODE打开(使用VSCODE建立ESP8266的工程)
- 将头文件添加到工程中。
API笔记:(官方API链接)
简介:WIFI API提供支持WIFI工作的模式,监视WIFI工作的状态,包含的配置如下:
- 工作站模式(STA模式或者WIFI客户端模式)ESP8266链接到一个工作点。
- AP模式(软AP模式,或者接入点模式)工作站连接到ESP8266。
- 混合模式AP-SAT(ESP8266同时链接到一个点和一个访问点的站点)
- 安全模式(WPA,WPA2,WEP)
- 扫描接入点
- Promiscuous mode monitoring of IEEE802.11 WiFi packets.
来自官方的重要说明:Since the ESP8266 RTOS SDK V3.0, we moved some functions from IRAM to flash, including malloc and free fucntions, to save more memory. In this case, please do not read/write/erase flash during sniffer or promiscuous mode. You need to disable the sniffer or promiscuous mode at first, then read/write/erase flash.(大致意思是说,从3.0开始,为了节省内存空间,他们把一些功能从IRAM移动了FLASH,包括malloc和free功能,让我们不要在 sniffer 和 promiscuous模式下察写FLASH,应先禁用这些模式,才能察写FLASH。)
esp_err_t esp_wifi_init(constwifi_init_config_t *config)
初始化WIFI,为WIFI分配资源。
重点
必须先调用此API才能调用其他的API
重点
始终用WIFI_INIT_CONFIG_DEFAULT 去初始化,配置成默认的值,这样可以guarantee (保证)所有的值都是正确的。如果你想设置自己的初始化的值请覆盖WIFI_INIT_CONFIG_DEFAULT,请注意wifi-init-config的“magic”字段应该始终是wifi-init-config-magic!
返回值为成功ESP_OK,没内存空间ESP_ERR_NO_MEM,其他参考code esp_err.h
esp_err_t esp_wifi_deinit(void)
复位WIFI设置:如果你想移除WIFI设备。
esp_err_t esp_wifi_set_mode(wifi_mode_tmode)
设置WiFi的模式
参数:
typedef enum {
WIFI_MODE_NULL = 0, /**< null mode */
WIFI_MODE_STA, /**< WiFi station mode */
WIFI_MODE_AP, /**< WiFi soft-AP mode */
WIFI_MODE_APSTA, /**< WiFi station + soft-AP mode */
WIFI_MODE_MAX
} wifi_mode_t;
返回值:
ESP_OK: succeed
ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init
ESP_ERR_INVALID_ARG: invalid argument
others: refer to error code in esp_err.h
esp_err_t esp_wifi_get_mode(wifi_mode_t *mode)
得到WIFI的模式。
esp_wifi_start(void)
根据当前WIFI模式配置WiFi,
用AP模式建立一个热点
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_log.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "esp_event_loop.h"
static const char *TAG = "wifi";
static EventGroupHandle_t wifi_event_group; //建立一个事件组
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
const int WIFI_CONNECTED_BIT = BIT0;
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
/* For accessing reason codes in case of disconnection */
system_event_info_t *info = &event->event_info;
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
ESP_LOGI(TAG, "got ip:%s",
ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT);
break;
case SYSTEM_EVENT_AP_STACONNECTED:
ESP_LOGI(TAG, "station:"MACSTR" join, AID=%d",
MAC2STR(event->event_info.sta_connected.mac),
event->event_info.sta_connected.aid);
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
ESP_LOGI(TAG, "station:"MACSTR"leave, AID=%d",
MAC2STR(event->event_info.sta_disconnected.mac),
event->event_info.sta_disconnected.aid);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGE(TAG, "Disconnect reason : %d", info->disconnected.reason);
if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) {
/*Switch to 802.11 bgn mode */
esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
}
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
void myinit_wifi()
{
wifi_event_group = xEventGroupCreate();//生产一组时间
tcpip_adapter_init();//初始化TCPIPzrre
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));//建立一个事件循环
wifi_init_config_t wifi_init_parameter = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_parameter));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
wifi_config_t wifi_config = {
.ap = {
.ssid = "ESP8266",
.ssid_len = strlen("ESP8266"),
.password = "asdASD123",
.max_connection = 4,
.authmode = WIFI_AUTH_WPA_WPA2_PSK},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_softap finished.SSID:ESP8266 password:asdASD123");
}
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);
myinit_wifi();
}
笔记
1.事件循环含义:ESP_IDF中的事件循环机制,可以实现不同组件之间的事件传递,比如,A,B,C 三个节点想实现相互之间的消息传递,一种简单的方法是,A,B,C 分别不停的去访问其他节点,询问是否有新事件发生。如果这时候引入D去统一管理,会把问题极大的简化。A,B,C分别到D处登记自己关心的事件,登记完成后由D去进行问询和分发,A,B,C可以专心做自己的事情,当需要发信号时,直接发送到D,当D发现有事件发生后,会根据登记的内容和先后顺序,通知对应的节点去处理。
ESP_IDF事件循环使用过程:
- 定义事件处理函数 esp_event_handler_t
- 创建一个事件循环esp_event_loop_create(),创建完成后会返回事件循环句柄(作用相当于D)
- 向事件循环注册事件esp_event_handler_register_with(),添加回调函数。(注册关注哪个事件,事件发生后执行哪个函数)
- 事件发生时,向事件循环发生通知esp_event_post_to()。
笔记参考链接:https://blog.csdn.net/qq_20515461/article/details/99640290
备注
typedef enum {
SYSTEM_EVENT_WIFI_READY = 0, /**< ESP8266 WiFi ready */
SYSTEM_EVENT_SCAN_DONE, /**< ESP8266 finish scanning AP */
SYSTEM_EVENT_STA_START, /**< ESP8266 station start */
SYSTEM_EVENT_STA_STOP, /**< ESP8266 station stop */
SYSTEM_EVENT_STA_CONNECTED, /**< ESP8266 station connected to AP */
SYSTEM_EVENT_STA_DISCONNECTED, /**< ESP8266 station disconnected from AP */
SYSTEM_EVENT_STA_AUTHMODE_CHANGE, /**< the auth mode of AP connected by ESP8266 station changed */
SYSTEM_EVENT_STA_GOT_IP, /**< ESP8266 station got IP from connected AP */
SYSTEM_EVENT_STA_LOST_IP, /**< ESP8266 station lost IP and the IP is reset to 0 */
SYSTEM_EVENT_STA_WPS_ER_SUCCESS, /**< ESP8266 station wps succeeds in enrollee mode */
SYSTEM_EVENT_STA_WPS_ER_FAILED, /**< ESP8266 station wps fails in enrollee mode */
SYSTEM_EVENT_STA_WPS_ER_TIMEOUT, /**< ESP8266 station wps timeout in enrollee mode */
SYSTEM_EVENT_STA_WPS_ER_PIN, /**< ESP8266 station wps pin code in enrollee mode */
SYSTEM_EVENT_AP_START, /**< ESP8266 soft-AP start */
SYSTEM_EVENT_AP_STOP, /**< ESP8266 soft-AP stop */
SYSTEM_EVENT_AP_STACONNECTED, /**< a station connected to ESP8266 soft-AP */
SYSTEM_EVENT_AP_STADISCONNECTED, /**< a station disconnected from ESP8266 soft-AP */
SYSTEM_EVENT_AP_STAIPASSIGNED, /**< ESP8266 soft-AP assign an IP to a connected station */
SYSTEM_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */
SYSTEM_EVENT_GOT_IP6, /**< ESP8266 station or ap or ethernet interface v6IP addr is preferred */
SYSTEM_EVENT_ETH_START, /**< ESP8266 ethernet start */
SYSTEM_EVENT_ETH_STOP, /**< ESP8266 ethernet stop */
SYSTEM_EVENT_ETH_CONNECTED, /**< ESP8266 ethernet phy link up */
SYSTEM_EVENT_ETH_DISCONNECTED, /**< ESP8266 ethernet phy link down */
SYSTEM_EVENT_ETH_GOT_IP, /**< ESP8266 ethernet got IP from connected AP */
SYSTEM_EVENT_MAX
} system_event_id_t;
调试心得
- 如果不去初始化,esp_evnet_loop,是错误的, esp_event_send 已经生产,所以必须处理。问题截图
解决
初始化,esp_event_loop_init;传参值为0,问题解决了,#目前尚不明白原因,还没有找到相关的手册
完成截图