ESP8266局域网控制LED灯

一、网页控制原理 Esp8266相当于作为一个web服务器,当我连接wifi后通过外部设备输入相应的IP,esp8266进行解析,将存储在8266,falsh中的网页读取并显示出来,当我点击网页上的按钮后,8266进行解析,控制灯亮。网页与服务器之间使用Get/POST协议。

  1. 8266设置AP模式,建立wifi热点
  2. 创建TCP_server,建立帧听
  3. 等待clientl连接server,等待接收数据
  4. 根据接收的数据,读取flash中的网页,返回给浏览器。
  5. 当按下网页上按钮后,进行灯的亮灭控制。
二、ESP8266的FLASH 1. 内存分布情况
  • 程序区:代码编译生成的 bin 文件,烧录到 Flash 占用的区域
  • 系统参数区: esp_iot_sdk 中底层用于存放系统参数的区域
  • 用户参数区:上层应用程序存储用户参数的区域。
    ESP8266局域网控制LED灯
    文章图片

    ESP8266局域网控制LED灯
    文章图片

    2. 内存读写
    spi_flash_erase_sector()//擦除FLASH
    spi_flash_write()//写FLASH
    spi_flash_read()//读FLASH
三、 POSE和GET原理 一般在浏览器中输入网址访问资源都是通过GET方式;在FORM提交中,可以通过Method指定提交方式为GET或者POST,默认为GET提交Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET、POST、PUT、DELETE(查 、改 、增 、删)
GET方法实例
请求参数是作为一个key/value对的序列(查询字符串)附加到URL上的查询字符串的长度受到web浏览器和web服务器的限制(如IE最多支持2048个字符),不适合传输大型数据集同时,它很不安全。
GET /books/?sex=man&name=Professional HTTP/1.1 Host: www.wrox.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1 Connection: Keep-Alive

POST方法实例
请求参数是在http标题的一个不同部分(名为entity body)传输的,这一部分用来传输表单信息post设计用来支持web窗体上的用户字段,其参数也是作为key/value对传输。
Host: www.wrox.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050225 Firefox/1.0.1 Content-Type: application/x-www-form-urlencoded Content-Length: 40 Connection: Keep-Alive

【ESP8266局域网控制LED灯】HTTP响应实例
◆200 (OK): 找到了该资源,并且一切正常。
◆304 (NOT MODIFIED): 该资源在上次请求之后没有任何修改。这通常用于浏览器的缓存机制。
◆401 (UNAUTHORIZED): 客户端无权访问该资源。这通常会使得浏览器要求用户输入用户名和密码,以登录到服务器。
◆403 (FORBIDDEN): 客户端未能获得授权。这通常是在401之后输入了不正确的用户名或密码。
◆404 (NOT FOUND): 在指定的位置不存在所申请的资源。
HTTP/1.1 200 OK Date: Sat, 31 Dec 2005 23:59:59 GMT Content-Type: text/html; charset=ISO-8859-1 Content-Length: 122 <html> <head> <title>Wrox Homepage</title> </head> <body> <!-- body goes here --> </body> </html>

四、实现代码 web请求回调
void ICACHE_FLASH_ATTR webserver_recv(void *arg, char *pusrdata, unsigned short length) { URL_Frame *pURL_Frame = NULL; char *pParseBuffer = NULL; char *index = NULL; SpiFlashOpResult ret = 0; os_printf("-------------------------------\r\n"); os_printf("len:%u\r\n",length); os_printf("http request\r\n"); os_printf("-------------------------------\r\n"); os_printf("%s",pusrdata); os_printf("\r\n-------------------------------\r\n"); pURL_Frame = (URL_Frame *)os_zalloc(sizeof(URL_Frame)); parse_url(pusrdata, pURL_Frame); if(strstr(pusrdata,"ledToggle=1")){//处理消息体中按键触发后 post请求 GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1); }else if(strstr(pusrdata,"ledToggle=0")){ GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0); }switch (pURL_Frame->Type) { case GET: os_printf("-------------------------------\r\n"); os_printf("We have a GET request.\r\n"); os_printf("-------------------------------\r\n"); if(pURL_Frame->pFilename[0] == 0){ index = (char *)os_zalloc(index_size); if(index == NULL){ os_printf("os_zalloc error!\r\n"); goto _temp_exit; } // Flash read/write has to be aligned to the 4-bytes boundary ret = spi_flash_read(508*4096, (uint32 *)index, index_size); // start address:0x10000 + 0xC0000 if(ret != SPI_FLASH_RESULT_OK){ os_printf("spi_flash_read err:%d\r\n", ret); os_free(index); index = NULL; goto _temp_exit; } index[index_size] = 0; // put 0 to the end data_send(arg, true, index); os_free(index); index = NULL; } break; case POST: os_printf("-------------------------------\r\n"); os_printf("We have a POST request.\r\n"); os_printf("-------------------------------\r\n"); pParseBuffer = (char *)os_strstr(pusrdata, "\r\n\r\n"); if (pParseBuffer == NULL) { data_send(arg, false, NULL); break; } if(pParseBuffer != NULL){//返回一个网页 index = (char *)os_zalloc(index_size); if(index == NULL){ os_printf("os_zalloc error!\r\n"); goto _temp_exit; } ret = spi_flash_read(508*4096, (uint32 *)index, index_size); // start address:0x10000 + 0xC0000 if(ret != SPI_FLASH_RESULT_OK){ os_printf("spi_flash_read err:%d\r\n", ret); os_free(index); index = NULL; goto _temp_exit; } index[index_size] = 0; // put 0 to the end data_send(arg, true, index); os_free(index); index = NULL; } break; } _temp_exit: ; if(pURL_Frame != NULL){ os_free(pURL_Frame); pURL_Frame = NULL; } }

报文头发送
LOCAL void ICACHE_FLASH_ATTR data_send(void *arg, bool responseOK, char *psend) { uint16 length = 0; char *pbuf = NULL; char httphead[256]; struct espconn *ptrespconn = arg; os_memset(httphead, 0, 256); if (responseOK) { os_sprintf(httphead,"HTTP/1.0 200 OK\r\nContent-Length: %d\r\nServer: lwIP/1.4.0\r\n",psend ? os_strlen(psend) : 0); if (psend) { os_sprintf(httphead + os_strlen(httphead),"Content-Type: text/html; charset=utf-8\r\nPragma: no-cache\r\n\r\n"); length = os_strlen(httphead) + os_strlen(psend); pbuf = (char *)os_zalloc(length + 1); os_memcpy(pbuf, httphead, os_strlen(httphead)); os_memcpy(pbuf + os_strlen(httphead), psend, os_strlen(psend)); } else { os_sprintf(httphead + os_strlen(httphead), "\n"); length = os_strlen(httphead); } } else { os_sprintf(httphead, "HTTP/1.0 400 BadRequest\r\nContent-Length: 0\r\nServer: lwIP/1.4.0\r\n\n"); length = os_strlen(httphead); }if (psend) { espconn_sent(ptrespconn, pbuf, length); } else { espconn_sent(ptrespconn, httphead, length); }if (pbuf) { os_free(pbuf); pbuf = NULL; } }

    推荐阅读