ESP8266:API之WIFI篇(一):用AP模式建立一个热点

工程的建立

  1. 从ESP8266_RTOS_SDK中拷贝一个工程,用VSCODE打开(使用VSCODE建立ESP8266的工程
  2. 将头文件添加到工程中。

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事件循环使用过程:

  1. 定义事件处理函数 esp_event_handler_t
  2. 创建一个事件循环esp_event_loop_create(),创建完成后会返回事件循环句柄(作用相当于D)
  3. 向事件循环注册事件esp_event_handler_register_with(),添加回调函数。(注册关注哪个事件,事件发生后执行哪个函数)
  4. 事件发生时,向事件循环发生通知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;

调试心得

  1. 如果不去初始化,esp_evnet_loop,是错误的, esp_event_send 已经生产,所以必须处理。问题截图
    在这里插入图片描述
    解决
    初始化,esp_event_loop_init;传参值为0,问题解决了,#目前尚不明白原因,还没有找到相关的手册
    完成截图
    在这里插入图片描述
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值