esp-01 webconfig配网

前言:

玩esp-01有断时间了,自己使用homeassistant搭建后台控制中心,esp-01做终端控制灯、控制风扇、温度检测等等。但在控制之前esp-01需要配网,说到配网baidu搜索到最多应该就是smartconfig,以及微信的airkiss。但是不管是smartconfi或airkiss配置网,配置过程很不稳定,经常无法配置成功然后就只能断电重来;另一个原因是smartconfig需要app上配置很是麻烦。以上原因让我去寻找找到了另一种配网方式webconfig

webconfig基本思路

基本思路是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网页发送给网页,网页端就可以显示出网页。

实现过程

从flash中读取上次保留的wifi信息,若有wifi信息进入station模式反之进程softap模式等待配网

void ICACHE_FLASH_ATTR
init_done_cb_init(void)
{   
    struct station_config stconfig;
    struct softap_config  apconfig;

    print_chip_info();

    os_memset(&stconfig, 0, sizeof(struct station_config));
    wifi_station_get_config_default(&stconfig);
    if(os_strlen(stconfig.ssid) != 0){
        os_printf("ssid[%s]pass[%s]", stconfig.ssid, stconfig.password);
        wifi_set_opmode(STATION_MODE);
        wifi_station_set_reconnect_policy(TRUE);
        wifi_station_set_auto_connect(TRUE);
    }
    else{
        wifi_set_opmode(SOFTAP_MODE);
        wifi_softap_get_config(&apconfig);
        os_memset(apconfig.ssid, 0, 32);
        os_memset(apconfig.password, 0, 64);
        os_sprintf(apconfig.ssid,"ESP_%X",system_get_chip_id());
        apconfig.authmode = AUTH_OPEN;
        apconfig.ssid_len = 0;
        apconfig.max_connection = 5; 
        wifi_softap_set_config(&apconfig);
        wifi_station_set_reconnect_policy(FALSE);
        wifi_station_set_auto_connect(FALSE);
        wifi_station_disconnect();
    }
#if PLUG_DEVICE
    user_plug_init();
#elif FAN_DEVICE
    user_fan_init();
#elif DS18B20_DEVICE
    ds_init();
#endif
    user_webserver_init(SERVER_PORT);
}

在TCP Server接收函数中实现解析GET请求获取配网页面,POST请求配置

#define HTML    ""  \
                "

WiFi Settings

" \ "
"
\ "
"
\ "
"
LOCAL void ICACHE_FLASH_ATTR webconfig_set_wifi(char* urlparam){ char *p = NULL, *q = NULL; char ssid[10], pass[15]; os_memset(ssid, 0, sizeof(ssid)); os_memset(pass, 0, sizeof(pass)); p = (char *)os_strstr(urlparam, "ssid="); q = (char *)os_strstr(urlparam, "pass="); if ( p == NULL || q == NULL ){ return; } os_memcpy(ssid, p + 5, q - p - 6); os_memcpy(pass, q + 5, os_strlen(urlparam) - (q - urlparam) - 5); os_printf("ssid[%s]pass[%s]\r\n", ssid, pass); wifi_set_opmode(STATION_MODE); struct station_config stConf; stConf.bssid_set = 0; os_memset(&stConf.ssid, 0, sizeof(stConf.ssid)); os_memset(&stConf.password, 0, sizeof(stConf.password)); os_memcpy(&stConf.ssid, ssid, os_strlen(ssid)); os_memcpy(&stConf.password, pass, os_strlen(pass)); wifi_station_set_config(&stConf); //重启 system_restart(); return ; } LOCAL void ICACHE_FLASH_ATTR webserver_recv(void *arg, char *pusrdata, unsigned short length){ struct espconn *ptrespconn = arg; URL_Frame *pURL_Frame = NULL; char *pParseBuffer = NULL; char szOut[512]; int stat = -1; static char post_data[1024]; static bool last_post = false; os_printf("length[%d]\r\n", length); os_printf("recv[%s]\r\n", pusrdata); if(check_data(pusrdata, length) == false){ os_printf("check error\r\n"); data_send(ptrespconn, false, NULL); return ; } if(save_data(pusrdata, length) == false){ os_printf("save_data error\r\n"); data_send(ptrespconn, false, NULL); return ; } pURL_Frame = (URL_Frame *)os_zalloc(sizeof(URL_Frame)); parse_url(precvbuffer, pURL_Frame); os_printf("Type[%d]\r\n", pURL_Frame->Type); os_printf("pSelect[%s]\r\n", pURL_Frame->pSelect); os_printf("pCommand[%s]\r\n", pURL_Frame->pCommand); os_printf("pFilename[%s]\r\n", pURL_Frame->pFilename); switch (pURL_Frame->Type) { case GET: os_printf("We have a GET request.\n"); if((strlen(pURL_Frame->pSelect) == 1) && (os_strncmp(pURL_Frame->pSelect, "/", 1) == 0)){ //获取webconfig页面 html_send(ptrespconn, true, HTML); } if(os_strcmp(pURL_Frame->pSelect, "config") == 0 && os_strcmp(pURL_Frame->pCommand, "command") == 0) { os_memset(szOut, 0, sizeof(szOut)); #if PLUG_DEVICE stat = user_plug_getmethed(szOut); #elif FAN_DEVICE stat = user_fan_getmethed(szOut); #elif DS18B20_DEVICE stat = user_ds18b20_getmethed(szOut); #endif if(stat==0){ os_printf("get22szOut[%s]\r\n", szOut); data_send(ptrespconn, true, szOut); }else data_send(ptrespconn, false, NULL); }else data_send(ptrespconn, false, NULL); break ; case POST: os_printf("We have a POST request.\n"); pParseBuffer = (char *)os_strstr(precvbuffer, "\r\n\r\n"); if (pParseBuffer == NULL) { break; } pParseBuffer += 4; os_printf("pParseBuffer[%s]\r\n", pParseBuffer); if((strlen(pURL_Frame->pSelect) == 1) && (os_strncmp(pURL_Frame->pSelect, "/", 1) == 0)){ //webconfig配网 webconfig_set_wifi(pParseBuffer); data_send(ptrespconn, false, NULL); break ; }else if (os_strcmp(pURL_Frame->pSelect, "config") == 0 && os_strcmp(pURL_Frame->pCommand, "command") == 0) { os_memset(szOut, 0, sizeof(szOut)); #if PLUG_DEVICE stat = user_plug_postmethed(pParseBuffer, szOut); #elif FAN_DEVICE stat = user_fan_postmethed(pParseBuffer, szOut); #elif DS18B20_DEVICE stat = user_ds18b20_postmethed(pParseBuffer, szOut); #endif if(stat == 0){ os_printf("post22szOut[%s]\r\n", szOut); data_send(ptrespconn, true, szOut); }else data_send(ptrespconn, false, NULL); } else { os_printf("\r\nparse error!\r\n"); data_send(ptrespconn, false, NULL); } break ; } if (precvbuffer != NULL){ os_free(precvbuffer); precvbuffer = NULL; } os_free(pURL_Frame); pURL_Frame = NULL; }

OVER 很简单。本人参考使用Web页面配置ESP8266的参数思路开发修改。

git链接https://gitee.com/review/esp-01.git

这里写图片描述

你可能感兴趣的:(个人爱好,硬件开发)