ESP8266 RTOS AP模式创建热点

介绍

本次实验以ESP8266 为AP模式 创建一个热点 并将默认的ip地址从.4.1 改成了10.1
代码如下

/*ESP8266 WIFI Station 代码*/


#include <stdio.h>                      //..
#include <stdlib.h>                     //..
#include <string.h>                     //..

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "esp_wifi.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "esp_err.h"

#include "lwip/err.h"
#include "lwip/sys.h"
#include "driver/gpio.h"


#define CONFIG_ESP_WIFI_SSID   "ESP_AP"//热点WIFI的名称
#define CONFIG_ESP_WIFI_PASSWD "11223366" //热点的WiFi密码
#define CONFIG_ESP_MAX_STA_CONN 5         //热电动额最大连接数量


#define AP_CONNECTED_BIT BIT0

static const char *TAG = "wifi ap";
#define LED_PIN 2
EventGroupHandle_t wifi_event_group;
static struct netif *esp_netif[TCPIP_ADAPTER_IF_MAX];

void tcpip_adapter_set_ipaddr(tcpip_adapter_if_t tcpip_if);
esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname);

static esp_err_t oled_delay_ms(uint32_t time)
{
    vTaskDelay(time / portTICK_RATE_MS);
    return ESP_OK;
}

//GPIO 初始化代码
void gpio_config_init(void)
{
    gpio_config_t gpio_conf;

    gpio_conf.mode=GPIO_MODE_OUTPUT;
    gpio_conf.pin_bit_mask=(1ULL << LED_PIN);
    gpio_conf.pull_up_en=0;
    gpio_conf.pull_down_en=0;
    gpio_conf.intr_type=GPIO_INTR_DISABLE;
    gpio_config(&gpio_conf);

    // gpio_set_level(GPIO_Pin_2,1);

}
void HeartbeatLED(void)
{
    gpio_set_level(LED_PIN,0);
    oled_delay_ms(40);
    gpio_set_level(LED_PIN,1);
    oled_delay_ms(70);

    gpio_set_level(LED_PIN,0);
    oled_delay_ms(40);
    gpio_set_level(LED_PIN,1);


}

static void task1(void* arg)
{
    for(;;){
    printf("TASK1 IS RUNNING!\n");
    HeartbeatLED();
    vTaskDelay(1000 / portTICK_RATE_MS);
    }
    
}

//创建热点的处理函数
static void event_handler(void *ctx, system_event_t *event)
{
    system_event_info_t *info = &event->event_info;
    printf("event_id %d\n",event->event_id);
    
    switch(event->event_id)
    {
        case WIFI_EVENT_AP_START:
            xEventGroupSetBits(wifi_event_group,AP_CONNECTED_BIT);//设置事件组标志位
        break;
        case WIFI_EVENT_AP_STOP:
             xEventGroupClearBits(wifi_event_group,AP_CONNECTED_BIT);
        break;
        case WIFI_EVENT_AP_STACONNECTED: //14
        printf("station "MACSTR" join, AID=%d\n",
                 MAC2STR(event->event_info.sta_connected.mac), event->event_info.sta_connected.aid);
        break;
        case WIFI_EVENT_AP_STADISCONNECTED://15
        printf("station "MACSTR" leave,AID =%d\n",
                MAC2STR(event->event_info.sta_disconnected.mac),event->event_info.sta_disconnected.aid);
        break;   
        default:
        break;
    }
}


//创建热点的处理函数

void wifi_init_ap(void)
{
    tcpip_adapter_init();

    //设置默认IP地址
    tcpip_adapter_set_ipaddr(TCPIP_ADAPTER_IF_AP);
    //设置主机名
    // ESP_ERROR_CHECK(tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_AP,"ESP8266"));

    wifi_event_group = xEventGroupCreate();//创建事件组标志
    ESP_ERROR_CHECK(esp_event_loop_create_default());//创建本地事件组
    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));//初始化本地硬件
    //ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&event_handler,NULL));
   
    ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
    wifi_config_t wifi_ap_config = {
        .ap = {
            .ssid = CONFIG_ESP_WIFI_SSID,
            .password = CONFIG_ESP_WIFI_PASSWD,
            .ssid_len = strlen(CONFIG_ESP_WIFI_SSID),
            .max_connection = CONFIG_ESP_MAX_STA_CONN,
            .authmode = WIFI_AUTH_WPA2_PSK,
        },
    };
    //密码为空时设置为开放
    if (strlen(CONFIG_ESP_WIFI_PASSWD) == 0) {
        wifi_ap_config.ap.authmode = WIFI_AUTH_OPEN;
    }


    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP,&wifi_ap_config));

    ESP_ERROR_CHECK(esp_wifi_start());

    //等待AP启动
    xEventGroupWaitBits(wifi_event_group,AP_CONNECTED_BIT,false,true,portMAX_DELAY);
    ESP_LOGI(TAG,"wifi init ap finished,SSID:%s PASSWD:%s\n",CONFIG_ESP_WIFI_SSID,CONFIG_ESP_WIFI_PASSWD);


}

//设置默认IP地址
void tcpip_adapter_set_ipaddr(tcpip_adapter_if_t tcpip_if)
{
        //改变默认ipd地址
    tcpip_adapter_ip_info_t  local_ip;
    tcpip_adapter_dhcps_stop(tcpip_if);
    IP4_ADDR(&local_ip.ip,192,168,10,254);
    IP4_ADDR(&local_ip.gw,192,168,10,254);
    IP4_ADDR(&local_ip.netmask,255,255,255,0);
    tcpip_adapter_set_ip_info(tcpip_if,&local_ip);
    tcpip_adapter_dhcps_start(tcpip_if);
}

#if 0
//设置主机名
esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname)
{
#if LWIP_NETIF_HOSTNAME
    struct netif *p_netif;
    static char hostinfo[TCPIP_ADAPTER_IF_MAX][TCPIP_HOSTNAME_MAX_SIZE + 1];

    if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || hostname == NULL) {
        return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
    }

    if (strlen(hostname) > TCPIP_HOSTNAME_MAX_SIZE) {
        return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
    }

    p_netif = esp_netif[tcpip_if];
    if (p_netif != NULL) {
        memset(hostinfo[tcpip_if], 0, sizeof(hostinfo[tcpip_if]));
        strlcpy(hostinfo[tcpip_if], hostname, sizeof(hostinfo[tcpip_if]));
        p_netif->hostname = hostinfo[tcpip_if];
        p_netif->
        return ESP_OK;
    } else {
        return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
    }
#else
    return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
#endif
}

#endif
void app_main()
{
    ESP_ERROR_CHECK(nvs_flash_init());
    printf("ESP8266 WIFI Station test!");
    vTaskDelay(1000/portTICK_PERIOD_MS);
    wifi_init_ap();
    gpio_config_init();
    xTaskCreate(task1, "task1_test", 512, NULL, 3, NULL);
    
}

分析

/*ESP8266 WIFI Station 代码*/


#include <stdio.h>                      //..
#include <stdlib.h>                     //..
#include <string.h>                     //..

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "esp_wifi.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "esp_err.h"

#include "lwip/err.h"
#include "lwip/sys.h"
#include "driver/gpio.h"

引入了一些要用到的头文件


#define CONFIG_ESP_WIFI_SSID   "ESP_AP"//热点WIFI的名称
#define CONFIG_ESP_WIFI_PASSWD "11223366" //热点的WiFi密码
#define CONFIG_ESP_MAX_STA_CONN 5         //热电动额最大连接数量


#define AP_CONNECTED_BIT BIT0

static const char *TAG = "wifi ap";
#define LED_PIN 2
EventGroupHandle_t wifi_event_group;
static struct netif *esp_netif[TCPIP_ADAPTER_IF_MAX];

void tcpip_adapter_set_ipaddr(tcpip_adapter_if_t tcpip_if);
esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname);

声明了一些用到的函数 热点的wifi名称 密码以及最大连接数量
创立了一个事件组 用来管理ap的过程 ,这个事件组有点类似于标志位 置位 清零 等待置位 或者清零
tcpip_adapter_set_ipaddr 设置IP地址的函数从.4 网段 改成了.10网段
tcpip_adapter_set_hostname 设置主机名 暂未实现

//创建热点的处理函数

void wifi_init_ap(void)
{
    tcpip_adapter_init();

    //设置默认IP地址
    tcpip_adapter_set_ipaddr(TCPIP_ADAPTER_IF_AP);
    //设置主机名
    // ESP_ERROR_CHECK(tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_AP,"ESP8266"));

    wifi_event_group = xEventGroupCreate();//创建事件组标志
    ESP_ERROR_CHECK(esp_event_loop_create_default());//创建本地事件组
    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));//初始化本地硬件
    //ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&event_handler,NULL));
   
    ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
    wifi_config_t wifi_ap_config = {
        .ap = {
            .ssid = CONFIG_ESP_WIFI_SSID,
            .password = CONFIG_ESP_WIFI_PASSWD,
            .ssid_len = strlen(CONFIG_ESP_WIFI_SSID),
            .max_connection = CONFIG_ESP_MAX_STA_CONN,
            .authmode = WIFI_AUTH_WPA2_PSK,
        },
    };
    //密码为空时设置为开放
    if (strlen(CONFIG_ESP_WIFI_PASSWD) == 0) {
        wifi_ap_config.ap.authmode = WIFI_AUTH_OPEN;
    }


    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP,&wifi_ap_config));

    ESP_ERROR_CHECK(esp_wifi_start());

    //等待AP启动
    xEventGroupWaitBits(wifi_event_group,AP_CONNECTED_BIT,false,true,portMAX_DELAY);
    ESP_LOGI(TAG,"wifi init ap finished,SSID:%s PASSWD:%s\n",CONFIG_ESP_WIFI_SSID,CONFIG_ESP_WIFI_PASSWD);


}

首先是初始化适配器,在初始化适配器之后修改了IP地址
创立了事件组
初始化硬件信息
设置ap参数
设置wifi模式
启动wifi
等待置位标志 也就是等待AP启动 如果AP停止 又会被清零

//创建热点的处理函数
static void event_handler(void *ctx, system_event_t *event)
{
    system_event_info_t *info = &event->event_info;
    printf("event_id %d\n",event->event_id);
    
    switch(event->event_id)
    {
        case WIFI_EVENT_AP_START:
            xEventGroupSetBits(wifi_event_group,AP_CONNECTED_BIT);//设置事件组标志位
        break;
        case WIFI_EVENT_AP_STOP:
             xEventGroupClearBits(wifi_event_group,AP_CONNECTED_BIT);
        break;
        case WIFI_EVENT_AP_STACONNECTED: //14
        printf("station "MACSTR" join, AID=%d\n",
                 MAC2STR(event->event_info.sta_connected.mac), event->event_info.sta_connected.aid);
        break;
        case WIFI_EVENT_AP_STADISCONNECTED://15
        printf("station "MACSTR" leave,AID =%d\n",
                MAC2STR(event->event_info.sta_disconnected.mac),event->event_info.sta_disconnected.aid);
        break;   
        default:
        break;
    }
}

在AP连接上 会置位 断开后会复位 AP连接上时会打印STA的IP地址 MAC地址等信息
AP断开时会打印断开STA的信息

//设置默认IP地址
void tcpip_adapter_set_ipaddr(tcpip_adapter_if_t tcpip_if)
{
        //改变默认ipd地址
    tcpip_adapter_ip_info_t  local_ip;
    tcpip_adapter_dhcps_stop(tcpip_if);
    IP4_ADDR(&local_ip.ip,192,168,10,254);
    IP4_ADDR(&local_ip.gw,192,168,10,254);
    IP4_ADDR(&local_ip.netmask,255,255,255,0);
    tcpip_adapter_set_ip_info(tcpip_if,&local_ip);
    tcpip_adapter_dhcps_start(tcpip_if);
}

设置ip地址将默认的.4.1的网段改成了.10.1 的网段 并且将自己的网址设置成了192.168.10.254
该函数必须在初始化tcpip适配器后执行,如果在tcpip中修改 那么就是全局的修改,所以在适配器后执行就是只限于本程序的修改 在修改前先停止dhcp服务 修改后再启动

static esp_err_t delay_ms(uint32_t time)
{
    vTaskDelay(time / portTICK_RATE_MS);
    return ESP_OK;
}

//GPIO 初始化代码
void gpio_config_init(void)
{
    gpio_config_t gpio_conf;

    gpio_conf.mode=GPIO_MODE_OUTPUT;
    gpio_conf.pin_bit_mask=(1ULL << LED_PIN);
    gpio_conf.pull_up_en=0;
    gpio_conf.pull_down_en=0;
    gpio_conf.intr_type=GPIO_INTR_DISABLE;
    gpio_config(&gpio_conf);

    // gpio_set_level(GPIO_Pin_2,1);

}
void HeartbeatLED(void)
{
    gpio_set_level(LED_PIN,0);
    delay_ms(40);
    gpio_set_level(LED_PIN,1);
    delay_ms(70);

    gpio_set_level(LED_PIN,0);
    delay_ms(40);
    gpio_set_level(LED_PIN,1);


}

static void task1(void* arg)
{
    for(;;){
    printf("TASK1 IS RUNNING!\n");
    HeartbeatLED();
    vTaskDelay(1000 / portTICK_RATE_MS);
    }
    
}

最后写了一个任务1 就行心跳灯的程序 测试多任务性能

void app_main()
{
    ESP_ERROR_CHECK(nvs_flash_init());
    printf("ESP8266 WIFI Station test!");
    vTaskDelay(1000/portTICK_PERIOD_MS);
    wifi_init_ap();
    gpio_config_init();
    xTaskCreate(task1, "task1_test", 512, NULL, 3, NULL);
    
}

效果展示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值