前言 使用Web頁面配置ESP8266的參數相對於使用串口AT指令配置更加直觀和簡單。與配置路由器方式類似。 基本思路 基本思路是ESP8266工作AP模式下,作為TCP Server監聽TCP Client的連接。因為網頁HTTP預設的埠是80,所以ESP8266作為TCP Server的埠需 ...
前言
使用Web頁面配置ESP8266的參數相對於使用串口AT指令配置更加直觀和簡單。與配置路由器方式類似。
基本思路
基本思路是ESP8266工作AP模式下,作為TCP Server監聽TCP Client的連接。因為網頁HTTP預設的埠是80,所以ESP8266作為TCP Server的埠需要設置為80。電腦連接上ESP8266的AP後,網頁訪問預設IP地址192.168.4.1,此時ESP8266就會收到來自網頁的HTTP的Get請求,此請求數據為HTML格式。ESP8266收到請求後,讀出保存在Flash中的HTML格式網頁,並將帶有HTML應答頭的HTML網頁發送給網頁,網頁端就可以顯示出網頁。下麵是具體實現步驟:
開發環境
- ESP8266 SDK版本:ESP8266_NONOS_SDK_2.0.0
- IDE:ESP8266 IDE v2.0
- 操作系統:64位 Win7
步驟
1. 設置ESP8266工作模式
設置為AP模式,並設置AP模式下的參數,作為TCP Server,註冊連接回調函數,監聽TCP Client的連接。具體不詳述。
1 void ICACHE_FLASH_ATTR 2 user_init(void) 3 { 4 os_printf("SDK version:%s\r\n", system_get_sdk_version()); 5 os_printf("Compile time:%s %s\r\n", __DATE__, __TIME__); 6 7 wifi_set_opmode(STATIONAP_MODE); 8 // ESP8266 softAP set config. 9 user_set_softap_config(); 10 11 user_webserver_init(SERVER_PORT); 12 }
1 void ICACHE_FLASH_ATTR 2 user_webserver_init(uint32 port) 3 { 4 LOCAL struct espconn esp_conn; 5 LOCAL esp_tcp esptcp; 6 7 esp_conn.type = ESPCONN_TCP; 8 esp_conn.state = ESPCONN_NONE; 9 esp_conn.proto.tcp = &esptcp; 10 esp_conn.proto.tcp->local_port = port; 11 espconn_regist_connectcb(&esp_conn, webserver_listen); 12 13 espconn_accept(&esp_conn); 14 }
2. 在連接回調函數中註冊接收回調函數,在接收回調函數中處理Client發送的數據
1 LOCAL void ICACHE_FLASH_ATTR 2 webserver_listen(void *arg) 3 { 4 struct espconn *pesp_conn = arg; 5 6 espconn_regist_recvcb(pesp_conn, webserver_recv); 7 espconn_regist_reconcb(pesp_conn, webserver_recon); 8 espconn_regist_disconcb(pesp_conn, webserver_discon); 9 espconn_regist_sentcb(pesp_conn, webserver_sent); 10 }
3. 帶無線網卡的電腦連接ESP8266的AP,併在路由器中輸入192.168.4.1
此時瀏覽器會將HTML格式的GET請求發送給TCP Server。這時網頁是顯示錯誤的,因為TCP Server並沒有上傳網頁到Web端。可以使用HttpWatch這個IE瀏覽器插件抓取網頁發送的GET請求數據。
4. 在TCP Server接收函數中實現解析GET請求並上傳保存在Flash中的HTML網頁
這裡主要是解析HTML格式字元串,請求網頁的那個GET請求時不帶Filename的,需要區別不同的GET請求,具體看網頁實現。如果是GET請求網頁,就從Flash中讀取保存的網頁,並通過HTML格式發送給網頁端,然後就可以顯示出網頁了。
1 void ICACHE_FLASH_ATTR 2 webserver_recv(void *arg, char *pusrdata, unsigned short length) 3 { 4 URL_Frame *pURL_Frame = NULL; 5 char *pParseBuffer = NULL; 6 char *index = NULL; 7 SpiFlashOpResult ret = 0; 8 9 USER_DBG("len:%u\r\n",length); 10 USER_DBG("Webserver recv:-------------------------------\r\n%s\r\n", pusrdata); 11 12 pURL_Frame = (URL_Frame *)os_zalloc(sizeof(URL_Frame)); 13 parse_url(pusrdata, pURL_Frame); 14 15 switch (pURL_Frame->Type) { 16 case GET: 17 USER_DBG("We have a GET request.\r\n"); 18 19 if(pURL_Frame->pFilename[0] == 0){ 20 index = (char *)os_zalloc(FLASH_READ_SIZE+1); 21 if(index == NULL){ 22 ERR_LOG("os_zalloc error!\r\n"); 23 goto _temp_exit; 24 } 25 26 // Flash read/write has to be aligned to the 4-bytes boundary 27 ret = spi_flash_read(0xD0*SPI_FLASH_SEC_SIZE, (uint32 *)index, FLASH_READ_SIZE); // start address:0x10000 + 0xC0000 28 if(ret != SPI_FLASH_RESULT_OK){ 29 ERR_LOG("spi_flash_read err:%d\r\n", ret); 30 os_free(index); 31 index = NULL; 32 goto _temp_exit; 33 } 34 35 index[HTML_FILE_SIZE] = 0; // put 0 to the end 36 data_send(arg, true, index); 37 38 os_free(index); 39 index = NULL; 40 } 41 break; 42 43 case POST: 44 USER_DBG("We have a POST request.\r\n"); 45 46 pParseBuffer = (char *)os_strstr(pusrdata, "\r\n\r\n"); 47 if (pParseBuffer == NULL) { 48 data_send(arg, false, NULL); 49 break; 50 } 51 // Prase the POST data ... 52 break; 53 } 54 55 _temp_exit: 56 ; 57 if(pURL_Frame != NULL){ 58 os_free(pURL_Frame); 59 pURL_Frame = NULL; 60 } 61 }
5. 網頁配置就是POST請求,網頁發送HTML格式的POST請求,ESP8266解析數據並作出設置。
POST請求數據中的Content內容可以是自定也格式,一般使用json格式比較好。這裡就詳細列出如何處理了。ESP8266 SDK的IOT demo中有HTML格式的解析以及回應HTML格式數據的常式,可以參考。
註意點
網頁是通過燒錄固件的工具燒錄到Flash的。當時如何把網頁的數據保存到Flash中這個問題困擾我很久,網上找很久都沒有具體說明,是直接將xx.html文件燒錄到Flash中的,此Flash空間是用戶可用區間,具體見官方文檔。不同Flash都是不同的,這個地址也是需要記下的,SPI讀取時需要用到,文件大小也是需要記下。下麵是32Mbit 的Flash的燒錄截圖。