Esp8266學習之旅⑥ 瞭解SmartConfig與Airkiss一鍵配網,給8266一鍵配網上雲端。(帶Demo)
阿新 • • 發佈:2019-01-09
目錄:
一、前言
聽到 SmartConfig這個單詞,字義上就是智慧配置,但是我們電子發燒友都是稱之為一鍵配網,
聽到Airkiss這個單詞就有點意思了。飛吻,象徵著速度飛一般的快。
本博文的配網截圖:
8266串列埠列印資訊:
1.1、問題來了。
①、都不懂!SmartConfig和AirKiss是什麼東東!
- 答:大家買智慧裝置時候都會出現以下介面提示您要輸入wifi賬號和密碼!然後下一步操作搜尋,裝置成功連線網路成功就可以使用啦!這裡就引出了, SmartConfig 和 AirKiss 就是給裝置配網的方式,皆為無線操作給裝置發wifi名字和密碼的方式。
①、既然方式一樣,二者有啥不同嗎!
- 答:其實原理都是一樣,手機發出廣播,這廣播裡面有WIfi的名字 和密碼,也就是接下來裝置要接收的廣播,以及去連線這個Wifi! ,其然 ,Airkiss是微信專門為物聯網配網開發的,是對SmartConfig的進一步封裝。如果你沒有去整合微信開發環境去給裝置配網,大不可去了解airkiss,只需要懂得用SmartConfig配網就好了!
二、原理。
這裡我引用微信官網畫的一個通俗易懂一張圖片。圖下的智慧插座是要配網的裝置,而微信客戶端也就是我們的傳送端:APP軟體 ;
步驟
在APP軟體輸入將要連線的WIfi的名字和密碼。
之後App會空中髮網,帶有wifi的名字和密碼的資訊暴露。
智慧裝置收到資訊廣播之後,嘗試不斷去連線,一旦連線成功。就會返回資訊給APP通知配網成功!
三、走進8266一鍵配網的SmartConfig。
1. 翻開8266的程式設計SDK手冊,看看有哪些已經封裝好的介面,如圖 :
2. 主要的函式方法,如圖 :
3. 為了更好展示主要方法,我做個表格,大家可以方便查閱,如下 :
函式名字 | 函式引數 | 返回值 | 備註 |
---|---|---|---|
smartconfig_start() | sc_callback_t cb:SmartConfig 狀態發⽣生改變時,進⼊入回撥函式 | true:成功 ,false:失敗 | 開啟快連模式,快速連線 ESP8266 Station 到 AP |
smartconfig_stop () | SC_TYPE_ESPTOUCH,SC_TYPE_AIRKISS,SC_TYPE_ESPTOUCH_AIRKISS | true:成功 ,false:失敗 | 關閉快連模式,釋放 smartconfig_start 佔⽤用的記憶體。 |
三、電路圖與程式碼分析。
3、1 電路圖。
僅僅只是一個按鍵觸發配網模式,這個按鍵接GPIO14與GND端。
3、2 程式碼分析。
第一步:按鍵初始化,這裡我使用的是機智雲SOC方案提煉出來的按鍵中斷初始化 hal_key.h 和 hal_key.c 檔案封裝。
第二步:按鍵觸發回撥的函式 :如下,其中的smartconfig_done是方法回撥函式,見第三步驟。
//短按按鍵函式回撥
LOCAL void ICACHE_FLASH_ATTR keyShortPress(void) {
//配置一鍵配網型別
smartconfig_set_type(SC_TYPE_ESPTOUCH);
//開啟station模式
wifi_set_opmode(STATION_MODE);
//開始一鍵配網等待
smartconfig_start(smartconfig_done);
}
第三步: smartconfig_done函式 : 如下
void ICACHE_FLASH_ATTR smartconfig_done(sc_status status, void *pdata) {
switch (status) {
//連線未開始,請勿在此階段開始連線。
case SC_STATUS_WAIT:
os_printf("SC_STATUS_WAIT\n");
break;
//發現WIfi通道
case SC_STATUS_FIND_CHANNEL:
os_printf("SC_STATUS_FIND_CHANNEL\n");
break;
//得到wifi名字和密碼
case SC_STATUS_GETTING_SSID_PSWD:
os_printf("SC_STATUS_GETTING_SSID_PSWD\n");
sc_type *type = pdata;
if (*type == SC_TYPE_ESPTOUCH) {
os_printf("SC_TYPE:SC_TYPE_ESPTOUCH\n");
} else {
os_printf("SC_TYPE:SC_TYPE_AIRKISS\n");
}
break;
//已經獲取wifi名字與密碼在連線路由器
case SC_STATUS_LINK:
os_printf("SC_STATUS_LINK\n");
struct station_config *sta_conf = pdata;
wifi_station_set_config(sta_conf);
wifi_station_disconnect();
wifi_station_connect();
break;
//成功獲取到IP,連線路由完成。
case SC_STATUS_LINK_OVER:
if (pdata != NULL) {
uint8 phone_ip[4] = { 0 };
os_memcpy(phone_ip, (uint8*) pdata, 4);
//打印發廣播過來的裝置IP地址
os_printf("Phone ip: %d.%d.%d.%d\n", phone_ip[0], phone_ip[1], phone_ip[2], phone_ip[3]);
}
//停止配置
smartconfig_stop();
break;
}
}
四、完整程式碼。
#include "../include/debug.h"
#include "hal_key.h"
#include "../include/uart.h"
#include "ets_sys.h"
#include "osapi.h"
#include "ip_addr.h"
#include "espconn.h"
#include "mem.h"
#include "user_interface.h"
#include "smartconfig.h"
#include "airkiss.h"
//按鍵定義
#define GPIO_KEY_NUM 1
#define KEY_0_IO_MUX PERIPHS_IO_MUX_MTMS_U
#define KEY_0_IO_NUM 14
#define KEY_0_IO_FUNC FUNC_GPIO14
LOCAL key_typedef_t * singleKey[GPIO_KEY_NUM];
LOCAL keys_typedef_t keys;
LOCAL esp_udp ssdp_udp;
LOCAL struct espconn pssdpudpconn;
LOCAL os_timer_t ssdp_time_serv;
uint8_t lan_buf[200];
uint16_t lan_buf_len;
uint8 udp_sent_cnt = 0;
void ICACHE_FLASH_ATTR smartconfig_done(sc_status status, void *pdata) {
switch (status) {
//連線未開始,請勿在此階段開始連線
case SC_STATUS_WAIT:
os_printf("SC_STATUS_WAIT\n");
break;
//發現通道
case SC_STATUS_FIND_CHANNEL:
os_printf("SC_STATUS_FIND_CHANNEL\n");
break;
//得到wifi名字和密碼
case SC_STATUS_GETTING_SSID_PSWD:
os_printf("SC_STATUS_GETTING_SSID_PSWD\n");
sc_type *type = pdata;
if (*type == SC_TYPE_ESPTOUCH) {
os_printf("SC_TYPE:SC_TYPE_ESPTOUCH\n");
} else {
os_printf("SC_TYPE:SC_TYPE_AIRKISS\n");
}
break;
case SC_STATUS_LINK:
os_printf("SC_STATUS_LINK\n");
struct station_config *sta_conf = pdata;
wifi_station_set_config(sta_conf);
wifi_station_disconnect();
wifi_station_connect();
break;
//成功獲取到IP,連線路由完成。
case SC_STATUS_LINK_OVER:
os_printf("SC_STATUS_LINK_OVER \n\n");
if (pdata != NULL) {
uint8 phone_ip[4] = { 0 };
os_memcpy(phone_ip, (uint8*) pdata, 4);
os_printf("Phone ip: %d.%d.%d.%d\n", phone_ip[0], phone_ip[1], phone_ip[2], phone_ip[3]);
}
//停止配置
smartconfig_stop();
break;
}
}
//使用者自定義 RF_CAL 引數存放在 Flash 的扇區號
uint32 ICACHE_FLASH_ATTR user_rf_cal_sector_set(void) {
enum flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 5;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
break;
case FLASH_SIZE_16M_MAP_512_512:
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_32M_MAP_512_512:
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
break;
default:
rf_cal_sec = 0;
break;
}
return rf_cal_sec;
}
void ICACHE_FLASH_ATTR user_rf_pre_init(void) {
}
//長按五秒按鍵回撥
LOCAL void ICACHE_FLASH_ATTR keyLongPress(void) {
}
//短按按鍵回撥
LOCAL void ICACHE_FLASH_ATTR keyShortPress(void) {
os_printf("----------2 開始進去SmartConfig配網模式\n\n\n-----");
smartconfig_set_type(SC_TYPE_ESPTOUCH);
wifi_set_opmode(STATION_MODE);
smartconfig_start(smartconfig_done);
}
//按鍵初始化
LOCAL void ICACHE_FLASH_ATTR keyInit(void) {
singleKey[0] = keyInitOne(KEY_0_IO_NUM, KEY_0_IO_MUX, KEY_0_IO_FUNC,
keyLongPress, keyShortPress);
keys.singleKey = singleKey;
keyParaInit(&keys);
}
void ICACHE_FLASH_ATTR
user_init(void) {
uart_init(BIT_RATE_115200, BIT_RATE_115200);
os_printf("SDK version:%s\n", system_get_sdk_version());
os_printf("----------BIT_RATE_115200\n\n\n-----");
keyInit();
}
附加:相關除錯工具下載。