128
社区成员
发帖
与我相关
我的任务
分享
【试读开放时间】2022/1/24 - 2021/1/27
【试读文章内容】7日玩转ESP32——(第5日) 通过串口的WiFi 配网
【试读文章链接】https://blog.csdn.net/kangweijian/article/details/122499556
学习打卡 -- 7日玩转ESP32——(第5日) 通过串口的WiFi 配网
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "esp_system.h"
#include "driver/uart.h"
static const int RX_BUF_SIZE = 1024;
#define TXD_PIN (GPIO_NUM_4) //发送端口
#define RXD_PIN (GPIO_NUM_5) //接收端口
#define DEFAULT_SSID CONFIG_EXAMPLE_WIFI_SSID
#define DEFAULT_PWD CONFIG_EXAMPLE_WIFI_PASSWORD
#define DEFAULT_SCAN_LIST_SIZE 64
static const char *TAG = "scan";
wifi_ap_record_t ap_info[DEFAULT_SCAN_LIST_SIZE];
uint16_t ap_max_number = 0,ap_count=0;
//初始化GPIO
void init_gpio() {
const uart_config_t uart_config = { //串口参数结构体
.baud_rate = 115200, //波特率
.data_bits = UART_DATA_8_BITS, //数据位
.parity = UART_PARITY_DISABLE, //奇偶校验
.stop_bits = UART_STOP_BITS_1, //停止位
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE, //流控制
.source_clk = UART_SCLK_APB, //时钟源
};
// We won't use a buffer for sending data. 我们不会使用缓冲区来发送数据。
//向系统初始化uart,可以理解为:告诉系统使用的是哪个uart的资源,相应的接收和发送缓冲区大小是多少,是否有事件需要处理等等 启动串口功能,安装uart驱动
uart_driver_install(UART_NUM_1, RX_BUF_SIZE * 2, 0, 0, NULL, 0);
//设置串口 配置串口参数,主要是根据串口结构体配置串口的波特率,起始位,校验位,数据位以及是否需要流控等
uart_param_config(UART_NUM_1, &uart_config);
//配置串口的映射引脚。也就是说ESP32的串口是支持引脚映射的,比如我的开发板串口一默认的是GPIO9和GPIO10,现在将TX、RX映射到GPIO4和GPIO5上
uart_set_pin(UART_NUM_1, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
}
//初始化wifi
static void init_wifi_sta()
{
nvs_flash_init();
ESP_ERROR_CHECK(esp_netif_init()); //初始化底层TCP/IP堆栈。在应用程序启动时,应该调用此函数一次。
ESP_ERROR_CHECK(esp_event_loop_create_default()); // 创建系统事件任务并初始化应用程序事件的回调函数。
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); //使用WIFI_INIT_CONFIG_DEFAULT() 来获取一个默认的wifi配置参数结构体变量
ESP_ERROR_CHECK(esp_wifi_init(&cfg)); //根据cfg参数初始化wifi连接所需要的资源
// Initialize default station as network interface instance (esp-netif)
//将缺省站初始化为网络接口实例(esp-netif)
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); //设置WiFi的工作模式为 STA
ESP_ERROR_CHECK(esp_wifi_start()); // 启动WiFi连接
}
//扫描并记录AP信息
void wifi_scan()
{
memset(ap_info,0,sizeof(ap_info));
esp_wifi_scan_start(NULL, true); //扫描所有可用AP
esp_wifi_scan_get_ap_records(&ap_max_number,ap_info); //获取AP记录
esp_wifi_scan_get_ap_num(&ap_count); //获取上次扫描到的AP个数。
//搞不明白 ap_max_number 与 ap_count 的区别
for (int i = 0; (i < DEFAULT_SCAN_LIST_SIZE) && (i < ap_count); i++) {
ESP_LOGI(TAG, "SSID \t\t%s", ap_info[i].ssid);
ESP_LOGI(TAG, "RSSI \t\t%d", ap_info[i].rssi);
ESP_LOGI(TAG, "Channel \t%d\n", ap_info[i].primary);
}
}
void wifw_connect(char * pssid,char *ppassword){
// Initialize and start WiFi
//定义WiFi连接参数
wifi_config_t wifi_config = {
.sta = {
.ssid = "",
.password = "",
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
.pmf_cfg = {
.capable = true,
.required = false
},
},
};
strcpy((char*)wifi_config.sta.ssid,pssid);
strcpy((char*)wifi_config.sta.password,ppassword);
esp_wifi_set_config(WIFI_IF_STA,&wifi_config); //载入WiFi链接配置
uint32_t err = esp_wifi_connect();
if (ESP_OK == err)
{
ESP_LOGI(TAG, "链接WIFI SSID:%s 成功\n", pssid);
}else{
ESP_LOGI(TAG, "链接WIFI SSID:%s 失败,错误码为:%d\n", pssid,err);
}
}
static void read_data()
{
uint8_t* data = (uint8_t*) malloc(RX_BUF_SIZE+1);
while (1) {
const int rxBytes = uart_read_bytes(UART_NUM_1, data, RX_BUF_SIZE, 1000 / portTICK_RATE_MS); //接收数据
if (rxBytes > 0) {
if (NULL != strstr((char *)data, "A;"))
{
}else if (NULL != strstr((char *)data,"Q:"))
{
char w_ssid[32] ="";
memset(w_ssid,0,32);
sscanf((char *)data,"Q:%s",w_ssid);
for (int i = 0; (i < DEFAULT_SCAN_LIST_SIZE) && (i < ap_count); i++) {
if (NULL != strstr((char *)ap_info[i].ssid,w_ssid))
{
ESP_LOGI(TAG, "SSID \t\t%s", ap_info[i].ssid);
ESP_LOGI(TAG, "RSSI \t\t%d", ap_info[i].rssi);
ESP_LOGI(TAG, "Channel \t%d\n", ap_info[i].primary);
}
}
}
else if (NULL != strstr((char *)data,"C:"))
{
char w_ssid[32] ="",w_password[64] ="";
memset(w_ssid,0,32);
memset(w_password,0,62);
sscanf((char *)data,"C:%s,%s",w_ssid,w_password);
wifw_connect(w_ssid,w_password);
}
}
}
free(data);
}
void app_main(void)
{
init_gpio();
init_wifi_sta();
wifi_scan();
xTaskCreate(read_data, "uart_rx_task", 1024*2, NULL, configMAX_PRIORITIES, NULL); //创建新的任务实例
}