ESP8266配網(wǎng)思路(不使用SmartConfig)
這是我之前學(xué)習(xí)ESP8266想的思路,后續(xù)用STM32來實(shí)現(xiàn)其中一個(gè)或兩個(gè)功能。
假設(shè)已經(jīng)開發(fā)了一個(gè)手機(jī)APP,這個(gè)APP完成的功能如下:
1、連接設(shè)備接的模塊ESP8266生成的熱點(diǎn)
2、給設(shè)備熱點(diǎn)發(fā)送要連接的路由器的名字和密碼
配網(wǎng)流程
1、設(shè)備讓ESP8266進(jìn)入AP模式設(shè)備MCU通過串口給ESP8266發(fā)送AT+CWMODE=2,讓ESP8266進(jìn)入AP模式。如果進(jìn)入AP模式成功,用手機(jī)可以搜索到ESP8266模塊的熱點(diǎn)信息。
2、用手機(jī)APP去連接這個(gè)熱點(diǎn)發(fā)送路由器ssid和password,假設(shè)格式為: ssid:“xxx”,password:“xxxx”
3、解析APP發(fā)過來的字符串格式ESP8266串口收到格式:
ssid:“xxx”,password:"xxxx"這個(gè)字符串設(shè)備MCU處理收到的這個(gè)字符串,將ssid和password提取出來。分別保存到緩存區(qū)SSID、PASSWORD。
4、設(shè)備讓ESP8266進(jìn)入STA模式設(shè)備MCU通過串口給ESP8266發(fā)送AT+CWMODE=1,讓ESP8266進(jìn)入STA模式。
5、設(shè)備連接路由器拿保存在緩存區(qū)的SSID和PASSWORD,設(shè)備通過串口給ESP8266發(fā)送連接指令A(yù)T+CWJAP=“SSID”,“PASSWORD”
6、連接公網(wǎng)服務(wù)器
===>120.78.136.134:8888AT+CIPSTART=“TCP”,“120.78.136.134”,9002
配網(wǎng)成功!如果以后不在初始化設(shè)置模式下,不會(huì)執(zhí)行該流程,默認(rèn)開機(jī)直接連接對(duì)應(yīng)的熱點(diǎn)和服務(wù)器。
假設(shè)已經(jīng)開發(fā)了一個(gè)上位機(jī),這個(gè)上位機(jī)完成的功能如下:
1、上位機(jī)通過串口連接設(shè)備
2、具有設(shè)置wifi帳號(hào)和密碼的功能(其實(shí)就是發(fā)送一條串口指令,帶有wifi帳號(hào)和密碼)
3、具有設(shè)置服務(wù)器ip和端口號(hào)的功能(其實(shí)就是發(fā)送一條串口指令,帶有服務(wù)器ip和端口號(hào))
配網(wǎng)流程
1、直接讓設(shè)備進(jìn)入STA模式 上位機(jī)通過串口給接有ESP8266的設(shè)備發(fā)送AT+CWMODE=1,讓ESP8266進(jìn)入STA模式。
2、設(shè)備接收到上位機(jī)發(fā)送過來的進(jìn)入STA模式的指令,透?jìng)鹘oESP8266, 這時(shí)ESP8266如果設(shè)置成功,則處于STA模式。
3、特定模式下(初始化設(shè)置),線程等待上位機(jī)下發(fā)的指令指令格式:(1)設(shè)置wifi連接路由器SSID:“xxxx”,“PASSWORD”:“xxxxx”(2)設(shè)置wifi連接服務(wù)器SERVER_IP:“xxx.xxx.xxx.xxx”,PORT:“xxxx”
4、設(shè)備接收到上位機(jī)下發(fā)的指令,進(jìn)行解析后分別保存在緩存區(qū)中。
5、設(shè)備連接路由器 拿保存在緩存區(qū)的SSID和PASSWORD,設(shè)備通過串口給ESP8266發(fā)送連接指令A(yù)T+CWJAP=“SSID”,“PASSWORD”
6、連接公網(wǎng)服務(wù)器
===>xxx.xx.xxx.xxx:xxxx例如:AT+CIPSTART=“TCP”,“120.78.136.134”,9002
配網(wǎng)成功!如果以后不在初始化設(shè)置模式下,不會(huì)執(zhí)行該流程,默認(rèn)開機(jī)直接連接對(duì)應(yīng)的熱點(diǎn)和服務(wù)器。
假設(shè)以及開發(fā)了一個(gè)上位機(jī),這個(gè)上位機(jī)完成的功能如下:
1、上位機(jī)可以用TCP/IP連接wifi熱點(diǎn)(ESP8266)===>需要知道esp8266的ip和端口號(hào),通過window網(wǎng)絡(luò)狀態(tài)可以查到。
2、具有設(shè)置wifi帳號(hào)和密碼的功能(其實(shí)就是發(fā)送一條串口指令,帶有wifi帳號(hào)和密碼)
3、具有設(shè)置服務(wù)器ip和端口號(hào)的功能(其實(shí)就是發(fā)送一條串口指令,帶有服務(wù)器ip和端口號(hào))
配網(wǎng)流程
設(shè)備端
1、直接讓設(shè)備進(jìn)入AP模式上位機(jī)通過串口給接有ESP8266的設(shè)備發(fā)送AT+CWMODE=2,讓ESP8266進(jìn)入AP模式。
指令:
AT+CWMODE=2
2、重啟設(shè)備,確保AP模式設(shè)置成功指令:
AT+RST
3、開啟多路連接指令:
AT+CIPMUX=1
4、為設(shè)備端創(chuàng)建熱點(diǎn)指令:
AT+CWSAP=“WIFI名稱”,“WIFI密碼”,1,4
5、設(shè)備端啟動(dòng)服務(wù)器指令:
AT+CIPSERVER=1,8080
PC端
1、事先需要讓PC去連接wifi熱點(diǎn)===>WIFI名稱、WIFI密碼
2、通過網(wǎng)絡(luò)連接詳情查看當(dāng)前熱點(diǎn)的IPv4服務(wù)器地址
3、PC端開發(fā)的上位機(jī)連接IPv4服務(wù)器地址,端口號(hào)就是設(shè)備端指定的端口號(hào):8080
4、PC端開發(fā)的上位機(jī)下發(fā)指令給設(shè)備端指令格式:
(1)設(shè)置wifi連接路由器SSID:“xxxx”,“PASSWORD”:“xxxxx”
(2)設(shè)置wifi連接服務(wù)器
SERVER_IP:“xxx.xxx.xxx.xxx”,PORT:“xxxx”
設(shè)備端
1、解析字符串,如果含有
SSID:“xxxx”,“PASSWORD”:“xxxxx”,取得ssid和password,保存到設(shè)備端的FLASH中,如果為其它,則設(shè)定接收出錯(cuò)的條件。
2、解析字符串,如果含有如下字符串:
SERVER_IP:“xxx.xxx.xxx.xxx”,PORT:“xxxx”
這時(shí)候程序解析取得server_ip和port,保存到設(shè)備端的FLASH中,如果為其它,則設(shè)定接收出錯(cuò)的條件。
3、如果已經(jīng)解析完兩個(gè)字符串,自動(dòng)重啟,切換到STA模式,取出ssid和password,連接ap,連接成功后,接下來取出flash中的server_ip和port,連接服務(wù)器,如果成功,則可進(jìn)入數(shù)據(jù)上傳,如果不成功,則返回ap連接,依次進(jìn)行,直到成功后,此時(shí)程序中連接成功的標(biāo)志會(huì)置一。
4、定時(shí)查詢與服務(wù)器端確認(rèn)是否連接成功,如果不成功,需要重新連接服務(wù)器。
5、可上傳數(shù)據(jù)
ESP8266端,其實(shí)我已經(jīng)寫好了一個(gè)程序,只是還不是那么的完善,但現(xiàn)在已經(jīng)可以用了,分享出來,大家可以去完善它。
大致程序框架設(shè)計(jì)如下,分別是配置WIFI的過程以及正常連接WIFI的過程:
//配置wifi網(wǎng)絡(luò)
int Cofig_Wifi_NetWork(void)
{
int ret = -1 ;
char *buf = NULL;
while(1)
{
switch(ESP8266_INFO.config_network_status)
{
case CHECK_WIFI_EXIST:
ret = Wifi_Test_Exist();
if(0 != ret)
{
printf("wifi初始化失敗,請(qǐng)檢查硬件是否連接!\r\n");
ESP8266_INFO.config_network_status = CHECK_WIFI_EXIST ;
LED1(ON);
return -1 ;
}
else
{
ESP8266_INFO.config_network_status = WIFI_SET_MODE ;
LED1(OFF);
}
break ;
case WIFI_SET_MODE:
ret = Wifi_Set_Mode(3);
if(0 != ret)
{
printf("wifi設(shè)置模式失敗\r\n");
ESP8266_INFO.config_network_status = CHECK_WIFI_EXIST ;
LED1(ON);
}
else
{
ESP8266_INFO.config_network_status = WIFI_BUILD_AP ;
LED1(OFF);
}
break ;
case WIFI_BUILD_AP:
printf("準(zhǔn)備ap....\n");
ret = ESP8266_BuildAP("ESP8266", "123456", WPA2_PSK);
if(1 != ret)
{
printf("wifi創(chuàng)建AP失敗...\r\n");
ESP8266_INFO.config_network_status = CHECK_WIFI_EXIST ;
LED1(ON);
}
else
{
ESP8266_INFO.config_network_status = WIFI_CONFIG_MULTI ;
LED1(OFF);
printf("創(chuàng)建ap成功\n");
}
break ;
case WIFI_CONFIG_MULTI:
printf("配置多連接模式!\r\n");
ret = ESP8266_Enable_MultipleId(ENABLE);
if(1 != ret)
{
printf("配置多連接失敗\n");
ESP8266_INFO.config_network_status = WIFI_BUILD_AP ;
LED1(ON);
}
else
{
ESP8266_INFO.config_network_status = WIFI_START_SERVER ;
LED1(OFF);
}
break ;
case WIFI_START_SERVER:
ret = ESP8266_StartOrShutServer(ENABLE, "8080", "10") ;
if(1 != ret)
{
printf("創(chuàng)建端口號(hào):%d失敗\r\n", 8080);
ESP8266_INFO.config_network_status = WIFI_CONFIG_MULTI ;
LED1(ON);
}
else
{
printf("創(chuàng)建端口號(hào):%d成功\r\n", 8080);
ESP8266_INFO.config_network_status = WIFI_GET_AP_IP ;
LED1(OFF);
}
break ;
case WIFI_GET_AP_IP:
buf = malloc(20);
if(buf == NULL)
return -1;
if(1 != ESP8266_Inquire_ApIp(buf, 20))
{
if(1 == ESP8266_StartOrShutServer(DISABLE, "8080", "5000"))
{
printf("關(guān)閉服務(wù)器成功!\r\n");
ESP8266_INFO.config_network_status = WIFI_START_SERVER ; //回到開啟服務(wù)器的流程
LED1(OFF);
}
free(buf);
}
printf("獲取ap ip:%s成功\r\n", buf);
free(buf);
ESP8266_INFO.config_network_status = WAIT_CLIENT_CONNECT;
break ;
case WAIT_CLIENT_CONNECT:
while(1)
{
//接收上位機(jī)連接
ret = ESP8266_Get_IdLinkStatus();
if(0 != ret)
{
printf("設(shè)備已和上位機(jī)建立連接....\r\n");
ESP8266_INFO.config_network_status = BACK_TO_CONFIG_PROCESS ;
LED1(ON);
break ;
}
LED2(ON);
Delay_ms (10);
LED2(OFF);
Delay_ms(10);
}
break ;
default:
break ;
}
if(ESP8266_INFO.config_network_status == BACK_TO_CONFIG_PROCESS)
{
LED1(OFF);
LED2(OFF);
LED3(OFF);
break ;
}
}
return 0 ;
}
//wifi正常連接流程
void Wifi_NetWork_Process(void)
{
int ret = -1 ;
while(1)
{
switch(ESP8266_INFO.wifi_status)
{
case WIFI_EXIST_CHECK:
ret = Wifi_Test_Exist();
if(0 != ret)
{
printf("wifi硬件故障!\n");
return ;
}
ESP8266_INFO.wifi_status = WIFI_SET_MODE ;
break ;
case WIFI_SET_MODE:
ret = Wifi_Set_Mode(STA);
if(0 != ret)
{
printf("wifi設(shè)置模式失敗\r\n");
ESP8266_INFO.wifi_status = WIFI_EXIST_CHECK ;
}
else
ESP8266_INFO.wifi_status = WIFI_CONNECT_ROUTER;
break ;
case WIFI_CONNECT_ROUTER:
ret = Wifi_Connect_Router((const char *)ESP8266_INFO.wifi_ssid, (const char *)ESP8266_INFO.wifi_password);
if(ret != 0)
{
printf("連接wifi熱點(diǎn)失敗\n");
ESP8266_INFO.wifi_status = WIFI_SET_MODE ;
return ;
}
else
{
printf("連接wifi熱點(diǎn):%s成功\n", ESP8266_INFO.wifi_ssid);
ESP8266_INFO.wifi_status = WIFI_CLOSE_MULTI ;
}
case WIFI_CLOSE_MULTI:
//關(guān)閉多連接
if(1 != ESP8266_Enable_MultipleId(DISABLE))
{
printf("關(guān)閉多連接失敗!\n");
ESP8266_INFO.wifi_status = WIFI_CONNECT_ROUTER ;
}
else
{
printf("關(guān)閉多連接成功!\n");
ESP8266_INFO.wifi_status = WIFI_CONNECT_SERVER ;
}
break ;
case WIFI_CONNECT_SERVER:
ret = Wifi_Connect_Server("TCP", (const char *)ESP8266_INFO.server_ip, atoi((char *)ESP8266_INFO.server_port));
if(ret != 0)
{
printf("連接服務(wù)器失敗\n");
ESP8266_INFO.wifi_status = WIFI_CONNECT_ROUTER ;
}
else
{
printf("連接服務(wù)器:%s成功\n", ESP8266_INFO.server_ip);
ESP8266_INFO.wifi_status = WIFI_CONFIG_OK ;
}
break ;
default:
break ;
}
//wifi連接成功
if(WIFI_CONFIG_OK == ESP8266_INFO.wifi_status)
{
LED3(ON);
break ;
}
}
return ;
}
//返回當(dāng)前子串在原字符串中的索引
int Sub_String_Index(char *str, char *sub_str)
{
char *p1 = NULL ;
char *__str = str ;
char *__sub_str = sub_str ;
p1 = strstr(__str, __sub_str);
return p1 - __str ;
}
/////////////////////////////////////ESP8266解析參數(shù)
int Esp8266_Process_Para(void)
{
char *str = NULL ;
char *p1 = NULL ;
char *p2 = NULL ;
int index1 = 0, index2 = 0 ;
//開始wifi配置
while(1)
{
//如果該標(biāo)志為0,則代表上位機(jī)已經(jīng)連上設(shè)備了
if(BACK_TO_CONFIG_PROCESS == ESP8266_INFO.config_network_status)
{
if(0 == ESP8266_Get_IdLinkStatus())
{
printf("客戶端已掉線,需重新連接....\n");
LED2(ON);
Delay_ms(300);
LED2(OFF);
Delay_ms(300);
}
//此時(shí)客戶端沒有掉線
else
{
printf("客戶端已連接,可下發(fā)數(shù)據(jù)....\n");
//準(zhǔn)備配置wifi_ssid
str = ESP8266_ReceiveString(DISABLE);
p1 = str + 12 ;
if(NULL != strstr(p1, "SSID"))
{
//拷貝wifi ssid
index1 = Sub_String_Index(p1, "=");
index2 = Sub_String_Index(p1, ";");
memcpy(ESP8266_INFO.wifi_ssid, p1 + index1 + 1, index2 - index1 - 1);
//拷貝wifi密碼
p2 = p1 + index2 + 1 ;
index1 = Sub_String_Index(p2, "=") ;
index2 = Sub_String_Index(p2, ";") ;
memcpy(ESP8266_INFO.wifi_password, p2 + index1 + 1, index2 - index1 - 1);
printf("wifi_ssid:%s wifi_password:%s\r\n", ESP8266_INFO.wifi_ssid, ESP8266_INFO.wifi_password);
macESP8266_Usart ("setting ssid_password success");
ESP8266_INFO.wifi_config_ap_flag = 1 ;
}
else if(NULL != strstr(p1, "SERVER_IP"))
{
//拷貝服務(wù)器相關(guān)參數(shù)===>server_ip
index1 = Sub_String_Index(p1, "=");
index2 = Sub_String_Index(p1, ";");
memcpy(ESP8266_INFO.server_ip, p1 + index1 + 1, index2 - index1 - 1);
//拷貝服務(wù)器相關(guān)參數(shù)===>server_port
p2 = p1 + index2 + 1 ;
index1 = Sub_String_Index(p2, "=") ;
index2 = Sub_String_Index(p2, ";") ;
memcpy(ESP8266_INFO.server_port, p2 + index1 + 1, index2 - index1 - 1);
printf("server_ip:%s server_port:%s\r\n", ESP8266_INFO.server_ip, ESP8266_INFO.server_port);
macESP8266_Usart ("setting server_ip port success");
ESP8266_INFO.wifi_cofnig_server_flag = 1 ;
}
//如果都配置了,則進(jìn)入正常啟動(dòng)流程
if((1 == ESP8266_INFO.wifi_config_ap_flag) && (1 == ESP8266_INFO.wifi_cofnig_server_flag))
{
ESP8266_INFO.config_network_status = 1 ;
return ESP8266_INFO.config_network_status ;
}
}
}
else if(1 == ESP8266_INFO.config_network_status)
{
return ESP8266_INFO.config_network_status ;
}
}
}
手機(jī)APP設(shè)計(jì)得比較簡(jiǎn)陋
以下使用QT設(shè)計(jì)的一個(gè)簡(jiǎn)單的配置工具界面
深圳市云之手科技有限公司
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!