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灯_第1张图片
    ESP8266局域网控制LED灯_第2张图片
    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

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;
    }
}

你可能感兴趣的:(ESP8266局域网控制LED灯)