6.wifi开发【智能家居:下】,正式开发:智能开关灯,智能采集温湿度,智能调彩灯

一。WEB Server开发

1.需求分析

用户通过页面操作插座+彩灯+温湿度

【开发前端1】:智能插座网页设计

智能插座网页设计需求

1.通过浏览器访问ESP8266 webserver

2.显示“自学项目-WiFi-智能家居”

3.显示“智能插座”

4.显示当前插座工作状态

5.按键触发插座动作

2.智能插座Web设计

智能插座网页设计

这里为自己设置的前端页面

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>智能插座</title>
<script defer="defer">
        function ledSwitch() {
            var xmlhttp;
            if (window.XMLHttpRequest) {
                xmlhttp = new XMLHttpRequest();
            } else {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.onreadystatechange = function () {
                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                        document.getElementById("txtState").innerHTML = xmlhttp.responseText;
                    }
                },
            xmlhttp.open("GET", "Switch", true);
            xmlhttp.send(); 
        }
    </script>
</head>

<body style="background-color: #2F4F4F">
<font size="12" color="yellow">
<b>
<div class="text" style=" text-align:center;"><big>创客学院-WiFi-智能家居</big></div>
</b>
</font>
<font size="12" color="yellow">
<b>
<div class="text" style=" text-align:center;"><big>智能插座</big></div>
</b>
</font>
<br> </br>     
<font size="20" color="white">
<div align="center" id="txtState">插座状态未知</div>
</font>
<br> </br>
<div style=" text-align:center;">
<input type="button" value="开关" style="width:80px;height:40px;" onclick="ledSwitch()">
</div>
</body>
</html>

3.智能插座嵌入式程序设计

1.继电器 驱动程序

        继电器就是一个上电的自动开关,所以只需要控制output为高电平或者低电平即可。

#include "esp_common.h"
#include "gpio.h"

/******************************************************************************
 * FunctionName : Relay_Control
 * Description  : Relay_Control 
 * Parameters   : uint32 mask
 * Returns      : none
*******************************************************************************/
void Relay_Control(uint32 mask)
{
    GPIO_OUTPUT(GPIO_Pin_5,mask);
}

2.HTTP协议 解析程序

        通过代码,可以看到html的页面是运行在esp8266中的,下方DefaultPage这个字符指针就存储了这个页面的数据,页面中使用javaScript来对用户按键进行相应,esp8266去GET到指令数据后,对数据进行处理,进而实现网页交互的功能。

#include "esp_common.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "httpserver.h"
#include "relay.c"

#define SERVERADDR "192.168.31.158"
#define SERVERPORT 80

const char *DefaultPage=
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
"<html xmlns=\"http://www.w3.org/1999/xhtml\">"
"<head>"
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"
"<title>智能插座</title>"
"<script defer=\"defer\">"
"        function ledSwitch() {"
"            var xmlhttp;"
"            if (window.XMLHttpRequest) {"
"                xmlhttp = new XMLHttpRequest();"
"            } else {"
"                xmlhttp = new ActiveXObject(\"Microsoft.XMLHTTP\");"
"            }"
"            xmlhttp.onreadystatechange = function () {"
"                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {"
"                        document.getElementById(\"txtState\").innerHTML = xmlhttp.responseText;"
"                    }"
"                },"
"            xmlhttp.open(\"GET\", \"Switch\", true);"
"            xmlhttp.send(); "
"        }"
"    </script>"
"</head>"
"<body style=\"background-color: #2F4F4F\">"
"<font size=\"12\" color=\"yellow\">"
"<b>"
"<div class=\"text\" style=\" text-align:center;\"><big>创客学院-WiFi-智能家居</big></div>"
"</b>"
"</font>"
"<font size=\"12\" color=\"yellow\">"
"<b>"
"<div class=\"text\" style=\" text-align:center;\"><big>智能插座</big></div>"
"</b>"
"</font>"
"<br> </br>     "
"<font size=\"20\" color=\"white\">"
"<div align=\"center\" id=\"txtState\">插座状态未知</div>"
"</font>"
"<br> </br>"
"<div style=\" text-align:center;\">"
"<input type=\"button\" value=\"开关\" style=\"width:80px;height:40px;\" onclick=\"ledSwitch()\">"
"</div>"
"</body>"
"</html>";


/*
"<html>"
"<head><title>Default</title></head>"
"<body>I am Http server!</body>"
"</html>"
;
*/

// 发送200 ok报头
int file_ok(int cfd, long flen)
{
    char *send_buf = zalloc(sizeof(char)*100);
    sprintf(send_buf, "HTTP/1.1 200 OK\r\n");
    send(cfd, send_buf, strlen(send_buf), 0);
    sprintf(send_buf, "Connection: keep-alive\r\n");
    send(cfd, send_buf, strlen(send_buf), 0);
    sprintf(send_buf, "Content-Length: %ld\r\n", flen);
    send(cfd, send_buf, strlen(send_buf), 0);
    sprintf(send_buf, "Content-Type: text/html\r\n");
    send(cfd, send_buf, strlen(send_buf), 0);
    sprintf(send_buf, "\r\n");
    send(cfd, send_buf, strlen(send_buf), 0);
    free(send_buf);
    return 0;
}

bool isLedTurnOpen = false; // 记录LED状态
/******************************************************************************
 * FunctionName : ATaskHttpServer
 * Description  : ATaskHttpServer 任务
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ATaskHttpServer( void *pvParameters )
{
    int iVariableExample = 0;
    int fd = -1;
    int cfd = -1;
    int NetTimeOnt = 2000;
    int ret;

    struct sockaddr_in ServerAddr;
    struct sockaddr ClientAddr;
    socklen_t ClientAddrlen = sizeof(struct sockaddr);
    char *Httpmsg;
    char *Sendmsg;

    STATION_STATUS StaStatus;
    do
    {
        StaStatus = wifi_station_get_connect_status();
        vTaskDelay(100);
    }while(StaStatus != STATION_GOT_IP);
    
    fd = socket(PF_INET,SOCK_STREAM,0);
    if(fd == -1)
    {
        printf("get socket fail!\n");
        vTaskDelete(NULL);
        return;
    }
    setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,&NetTimeOnt,sizeof(int));

    memset(&ServerAddr,0,sizeof(ServerAddr));
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_addr.s_addr = INADDR_ANY;
    ServerAddr.sin_port = htons(SERVERPORT);
    ServerAddr.sin_len = sizeof(ServerAddr);

    if(bind(fd,(struct sockaddr*)&ServerAddr,ServerAddr.sin_len) != 0)
    {        
        printf("bind socket fail!\n");
        vTaskDelete(NULL);
        return;
    }
    if(listen(fd,5) != 0)
    {
        printf("listen socket fail!\n");
        vTaskDelete(NULL);
        return;
    }
    Httpmsg = (char*)zalloc(sizeof(char)*1000);
    for(;;)
    {       
        cfd = accept(fd,&ClientAddr,&ClientAddrlen);
        if(cfd != -1)
        {           
            printf("HttpClient accept\n");
            ret = recv(cfd,Httpmsg,1000,0);
            if(ret > 0)
            {
                printf("HttpClient recv\n");
                printf("%s\n",Httpmsg);
                if(strstr(Httpmsg,"GET / HTTP/1.1") != NULL)
                {
                    file_ok(cfd,strlen(DefaultPage));
                    send(cfd,DefaultPage,strlen(DefaultPage),0);
                }
                else if(strstr(Httpmsg,"GET /Switch") != NULL)
                {                    
                    if(isLedTurnOpen)
                    {
                        Relay_Control(0);
                        send(cfd,"插座已经关闭",strlen("插座已经关闭"),0);
                        isLedTurnOpen = false;
                    }
                    else
                    {
                        Relay_Control(1);
                        send(cfd,"插座已经打开",strlen("插座已经关闭"),0);
                        isLedTurnOpen = true;
                    }
                }
            }
            else
            {
                printf("HttpClient data is no!\n");
            }
        }
        close(cfd);
    }
    free(Httpmsg);
    vTaskDelete( NULL );
}
/******************************************************************************
 * FunctionName : HttpServer_init
 * Description  : HttpServer_init 初始化
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void HttpServer_init(void)
{
    xTaskCreate(ATaskHttpServer, "HttpServer", 256, NULL, 4, NULL);
}

补充:user_main.c

1.user_main.c中提供的user_init函数就是SDK工程(提供的模版工程),这就是工程为我们提供的main入口,我们在这里创建Freertos操作系统的任务,这样就可以运行各类自写的线程函数。(以下几个实验,换汤不换药,原理只能说是一模一样)

运行结果:

 1.页面设计

2.打开之后,绿灯亮

【开发前端2】:智能环境采集页面设计

 1.需求分析

智能环境采集网页设计需求

1.通过浏览器访问ESP8266 webserver

2.显示“自学项目-WiFi-智能家居”

3.显示“智能环境采集”

4.显示当前温湿度数据

5.按键触发获取温湿度值

2.智能环境采集Web设计

这里是自己设置的环境采集页面

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>智能环境采集</title>
<script defer="defer">
        function ledSwitch() {
            var xmlhttp;
            if (window.XMLHttpRequest) {
                xmlhttp = new XMLHttpRequest();
            } else {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.onreadystatechange = function () {
                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                        document.getElementById("txtState").innerHTML = xmlhttp.responseText;
                    }
                },
            xmlhttp.open("GET", "Data", true);
            xmlhttp.send(); 
        }
    </script>
</head>

<body style="background-color: #2F4F4F">
<font size="12" color="yellow">
<b>
<div class="text" style=" text-align:center;"><big>创客学院-WiFi-智能家居</big></div>
</b>
</font>
<font size="12" color="yellow">
<b>
<div class="text" style=" text-align:center;"><big>智能环境采集</big></div>
</b>
</font>
<br> </br>     
<font size="20" color="white">
<div align="center" id="txtState">环境数据未知</div>
</font>
<br> </br>
<div style=" text-align:center;">
<input type="button" value="获取数据" style="width:80px;height:40px;" onclick="ledSwitch()">
</div>
</body>
</html>

3.智能环境采集嵌入式程序设计

1.DHT11 驱动程序

#include "esp_common.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "gpio.h"
#include "dht11.h"

#define DHT11_PIN_NUM 5
#define DHT11_PIN_BIT GPIO_Pin_5

#define DHT11_SET   1
#define DHT11_RESET 0

//温湿度定义

uint8 ucharT_data_H=0,ucharT_data_L=0,ucharRH_data_H=0,ucharRH_data_L=0,ucharcheckdata=0;

static void DHT11_TEST(void)   //温湿传感启动
{
  uint8 ucharT_data_H_temp,ucharT_data_L_temp,ucharRH_data_H_humidity,ucharRH_data_L_humidity,ucharcheckdata_temp;
  uint8 ucharFLAG = 0,uchartemp=0;
  uint8 ucharcomdata;
  uint8 i;  


  taskENTER_CRITICAL();

  {
  GPIO_OUTPUT_SET(DHT11_PIN_NUM,DHT11_RESET);
  os_delay_us(18*1000);
  GPIO_OUTPUT_SET(DHT11_PIN_NUM,DHT11_SET);
  GPIO_AS_INPUT(DHT11_PIN_BIT);
  os_delay_us(4*10);
  }
    
    if(!GPIO_INPUT_GET(DHT11_PIN_NUM)) 
         {
            ucharFLAG=2; 
            while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
            ucharFLAG=2;
            while(GPIO_INPUT_GET(DHT11_PIN_NUM)&&ucharFLAG++); 
            for(i=0;i<8;i++)    
              {
                 ucharFLAG=2; 
                 while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
                 os_delay_us(3*10);
                 uchartemp=0;
                 if(GPIO_INPUT_GET(DHT11_PIN_NUM))uchartemp=1;
                 ucharFLAG=2;
                 while(GPIO_INPUT_GET(DHT11_PIN_NUM)&&ucharFLAG++);   
                 if(ucharFLAG==1)break;    
                 ucharcomdata<<=1;
                 ucharcomdata|=uchartemp; 
               }
            ucharRH_data_H_humidity = ucharcomdata;
            for(i=0;i<8;i++)    
              {
                 ucharFLAG=2; 
                 while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
                 os_delay_us(3*10);
                 uchartemp=0;
                 if(GPIO_INPUT_GET(DHT11_PIN_NUM))uchartemp=1;
                 ucharFLAG=2;
                 while(GPIO_INPUT_GET(DHT11_PIN_NUM)&&ucharFLAG++);   
                 if(ucharFLAG==1)break;    
                 ucharcomdata<<=1;
                 ucharcomdata|=uchartemp; 
               }
            ucharRH_data_L_humidity = ucharcomdata;
            for(i=0;i<8;i++)    
              {
                 ucharFLAG=2; 
                 while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
                 os_delay_us(3*10);
                 uchartemp=0;
                 if(GPIO_INPUT_GET(DHT11_PIN_NUM))uchartemp=1;
                 ucharFLAG=2;
                 while((GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);   
                 if(ucharFLAG==1)break;    
                 ucharcomdata<<=1;
                 ucharcomdata|=uchartemp; 
               }
            ucharT_data_H_temp      = ucharcomdata;
            for(i=0;i<8;i++)    
              {
                 ucharFLAG=2; 
                 while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
                 os_delay_us(3*10);
                 uchartemp=0;
                 if(GPIO_INPUT_GET(DHT11_PIN_NUM))uchartemp=1;
                 ucharFLAG=2;
                 while((GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);   
                 if(ucharFLAG==1)break;    
                 ucharcomdata<<=1;
                 ucharcomdata|=uchartemp; 
               }
            ucharT_data_L_temp      = ucharcomdata;
            for(i=0;i<8;i++)    
              {
                 ucharFLAG=2; 
                 while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
                 os_delay_us(3*10);
                 uchartemp=0;
                 if(GPIO_INPUT_GET(DHT11_PIN_NUM))uchartemp=1;
                 ucharFLAG=2;
                 while((GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);   
                 if(ucharFLAG==1)break;    
                 ucharcomdata<<=1;
                 ucharcomdata|=uchartemp; 
               }
            ucharcheckdata_temp     = ucharcomdata;
//            humiture=1; 
            uchartemp=(ucharT_data_H_temp+ucharT_data_L_temp+ucharRH_data_H_humidity+ucharRH_data_L_humidity);
             
          if(uchartemp==ucharcheckdata_temp)
          {          
              ucharT_data_H  = ucharT_data_H_temp;
              ucharT_data_L  = ucharT_data_L_temp;
              ucharRH_data_H = ucharRH_data_H_humidity;
              ucharRH_data_L = ucharRH_data_L_humidity;
              ucharcheckdata = ucharcheckdata_temp;                    
          } 
       } 
    else //没用成功读取,返回0
       {
          ucharT_data_H  = 0;
          ucharT_data_L  = 0;
          ucharRH_data_H = 0;
          ucharRH_data_L = 0; 
       } 
    taskEXIT_CRITICAL();
}
/******************************************************************************
 * FunctionName : ATaskDht11
 * Description  : ATaskDht11 任务
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ATaskDht11( void *pvParameters )
{    
    for(;;)
    {
       vTaskDelay(500);
       DHT11_TEST();
       printf("ucharT_data_H = %d\n",ucharT_data_H);
       printf("ucharRH_data_H = %d\n",ucharRH_data_H);       
    }
    vTaskDelete( NULL );
}
/******************************************************************************
 * FunctionName : Dht11_init
 * Description  : Dht11_init 初始化
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void Dht11_init(void)
{   
    xTaskCreate(ATaskDht11, "ATaskDht11", 256, NULL, 4, NULL);
}

2.HTTP协议 解析程序

#include "esp_common.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "httpserver.h"
#include "dht11.h"

#define SERVERADDR "192.168.31.158"
#define SERVERPORT 80

const char *DefaultPage=
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
"<html xmlns=\"http://www.w3.org/1999/xhtml\">"
"<head>"
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"
"<title>智能环境采集</title>"
"<script defer=\"defer\">"
"        function ledSwitch() {"
"            var xmlhttp;"
"            if (window.XMLHttpRequest) {"
"                xmlhttp = new XMLHttpRequest();"
"            } else {"
"                xmlhttp = new ActiveXObject(\"Microsoft.XMLHTTP\");"
"            }"
"            xmlhttp.onreadystatechange = function () {"
"                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {"
"                        document.getElementById(\"txtState\").innerHTML = xmlhttp.responseText;"
"                    }"
"                },"
"            xmlhttp.open(\"GET\", \"Data\", true);"
"            xmlhttp.send(); "
"        }"
"    </script>"
"</head>"
"<body style=\"background-color: #2F4F4F\">"
"<font size=\"12\" color=\"yellow\">"
"<b>"
"<div class=\"text\" style=\" text-align:center;\"><big>创客学院-WiFi-智能家居</big></div>"
"</b>"
"</font>"
"<font size=\"12\" color=\"yellow\">"
"<b>"
"<div class=\"text\" style=\" text-align:center;\"><big>智能环境采集</big></div>"
"</b>"
"</font>"
"<br> </br>     "
"<font size=\"20\" color=\"white\">"
"<div align=\"center\" id=\"txtState\">环境数据未知</div>"
"</font>"
"<br> </br>"
"<div style=\" text-align:center;\">"
"<input type=\"button\" value=\"获取数据\" style=\"width:80px;height:40px;\" onclick=\"ledSwitch()\">"
"</div>"
"</body>"
"</html>";


/*
"<html>"
"<head><title>Default</title></head>"
"<body>I am Http server!</body>"
"</html>"
;
*/


// 发送200 ok报头
int file_ok(int cfd, long flen)
{
    char *send_buf = zalloc(sizeof(char)*100);
    sprintf(send_buf, "HTTP/1.1 200 OK\r\n");
    send(cfd, send_buf, strlen(send_buf), 0);
    sprintf(send_buf, "Connection: keep-alive\r\n");
    send(cfd, send_buf, strlen(send_buf), 0);
    sprintf(send_buf, "Content-Length: %ld\r\n", flen);
    send(cfd, send_buf, strlen(send_buf), 0);
    sprintf(send_buf, "Content-Type: text/html\r\n");
    send(cfd, send_buf, strlen(send_buf), 0);
    sprintf(send_buf, "\r\n");
    send(cfd, send_buf, strlen(send_buf), 0);
    free(send_buf);
    return 0;
}

bool isLedTurnOpen = false; // 记录LED状态
/******************************************************************************
 * FunctionName : ATaskHttpServer
 * Description  : ATaskHttpServer 任务
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ATaskHttpServer( void *pvParameters )
{
    int iVariableExample = 0;
    int fd = -1;
    int cfd = -1;
    int NetTimeOnt = 2000;
    int ret;

    struct sockaddr_in ServerAddr;
    struct sockaddr ClientAddr;
    socklen_t ClientAddrlen = sizeof(struct sockaddr);
    char *Httpmsg;
    char *Sendmsg;
	char data[30];

    STATION_STATUS StaStatus;
    do
    {
        StaStatus = wifi_station_get_connect_status();
        vTaskDelay(100);
    }while(StaStatus != STATION_GOT_IP);
    
    fd = socket(PF_INET,SOCK_STREAM,0);
    if(fd == -1)
    {
        printf("get socket fail!\n");
        vTaskDelete(NULL);
        return;
    }
    setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,&NetTimeOnt,sizeof(int));

    memset(&ServerAddr,0,sizeof(ServerAddr));
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_addr.s_addr = INADDR_ANY;
    ServerAddr.sin_port = htons(SERVERPORT);
    ServerAddr.sin_len = sizeof(ServerAddr);

    if(bind(fd,(struct sockaddr*)&ServerAddr,ServerAddr.sin_len) != 0)
    {
        printf("bind socket fail!\n");
        vTaskDelete(NULL);
        return;
    }

    if(listen(fd,5) != 0)
    {
        printf("listen socket fail!\n");
        vTaskDelete(NULL);
        return;
    }
    Httpmsg = (char*)zalloc(sizeof(char)*1000);
    for(;;)
    {        
        cfd = accept(fd,&ClientAddr,&ClientAddrlen);
        if(cfd != -1)
        {        
            printf("HttpClient accept\n");
            ret = recv(cfd,Httpmsg,1000,0);
            if(ret > 0)
            {
                printf("HttpClient recv\n");
                printf("%s\n",Httpmsg);
                if(strstr(Httpmsg,"GET / HTTP/1.1") != NULL)
                {
                    file_ok(cfd,strlen(DefaultPage));
                    send(cfd,DefaultPage,strlen(DefaultPage),0);
                }
                else if(strstr(Httpmsg,"GET /Data") != NULL)
                {
                    
					sprintf(data,"温度=%d\n湿度=%d",ucharT_data_H,ucharRH_data_H);
                    send(cfd,data,strlen(data),0);

                }
            }
            else
            {
                printf("HttpClient data is no!\n");
            }
        }
        close(cfd);
    }
    free(Httpmsg);
    vTaskDelete( NULL );
}
/******************************************************************************
 * FunctionName : HttpServer_init
 * Description  : HttpServer_init 初始化
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void HttpServer_init(void)
{
    xTaskCreate(ATaskHttpServer, "HttpServer", 256, NULL, 4, NULL);
}

运行结果:

【开发前端3】:智能灯泡页面设计

1.需求分析

智能灯泡网页设计需求

通过浏览器访问ESP8266 webserver

显示“WiFi-智能家居”

显示“智能灯泡”

显示当前灯泡工作状态(内容字体颜色与灯泡状态一直)

按键触发不同色彩控制(红、橙、黄、绿、青、蓝、紫)

2.智能灯泡Web设计

这里为自己的智能灯泡页面

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>智能灯泡</title>
<script defer="defer">
        function ledSwitch(string) {
            var xmlhttp;
            if (window.XMLHttpRequest) {
                xmlhttp = new XMLHttpRequest();
            } else {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.onreadystatechange = function () {
                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                        document.getElementById("txtState").innerHTML = xmlhttp.responseText;
						document.getElementById("txtState").style.color = string;   
                    }
                },
            xmlhttp.open("GET", string, true);
            xmlhttp.send(); 
        }
    </script>
</head>

<body style="background-color: #2F4F4F">
<font size="12" color="yellow">
<b>
<div class="text" style=" text-align:center;"><big>创客学院-WiFi-智能家居</big></div>
</b>
</font>
<font size="12" color="yellow">
<b>
<div class="text" style=" text-align:center;"><big>智能灯泡</big></div>
</b>
</font>
<br> </br>     
<font size="20" color="white">
<div align="center" id="txtState">灯泡状态未知</div>
</font>
<br> </br>
<div style=" text-align:center;">
<input type="button" value="红色" style="width:80px;height:40px;background:red;" onclick="ledSwitch('red')" />
<input type="button" value="橙色" style="width:80px;height:40px;background:orange;" onclick="ledSwitch('orange')">
<input type="button" value="黄色" style="width:80px;height:40px;background:yellow;" onclick="ledSwitch('yellow')">
<input type="button" value="绿色" style="width:80px;height:40px;background:green;" onclick="ledSwitch('green')">
<input type="button" value="青色" style="width:80px;height:40px;background:cyan;" onclick="ledSwitch('cyan')">
<input type="button" value="蓝色" style="width:80px;height:40px;background:blue;" onclick="ledSwitch('blue')">
<input type="button" value="紫色" style="width:80px;height:40px;background:purple;" onclick="ledSwitch('purple')">
</div>
</body>
</html>

3.智能灯泡嵌入式程序设计

1.WS2812 驱动程序

#include "esp_common.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "gpio.h"
#include "ws2812.h"

uint32 ColourArray[COLOUR_NUM] = {
    0x00FF00,
    0xA5FF00,
    0xFFFF00,
    0x800000,
    0xFF00FF,
    0x0000FF,
    0x008080
};
static volatile uint8_t time;

void delay100Ns(void)
{
    time ++;
}
/******************************************************************************
 * FunctionName : SEND_WS_0
 * Description  : 写0码
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
static void  SEND_WS_0(void)
{
    GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, GPIO_Pin_5);
    GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 0);
    
    GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 0);
    GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, GPIO_Pin_5);

    delay100Ns();
    delay100Ns();
    delay100Ns();
}
/******************************************************************************
 * FunctionName : SEND_WS_1
 * Description  : 写1码
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
static void  SEND_WS_1(void)
{
    GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, GPIO_Pin_5);
    GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 0);
    delay100Ns();
    delay100Ns();
    GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 0);
    GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, GPIO_Pin_5);
    delay100Ns();
}
/******************************************************************************
 * FunctionName : Ws2812REST
 * Description  : 帧切换
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
static void  Ws2812REST(void)
{
    GPIO_OUTPUT(GPIO_Pin_5,0);
    os_delay_us(250);
	//GPIO_OUTPUT(GPIO_Pin_5,0);
}
/******************************************************************************
 * FunctionName : Ws2812Write
 * Description  : 写入色彩数据
 * Parameters   : 色彩编码
 * Returns      : none
*******************************************************************************/
void Ws2812Write(colours colour)
{
    uint32 mask;
    uint8 i;
    taskENTER_CRITICAL();
    Ws2812REST();
    for(i = 0;i < 7;i++)
    {
        mask = 0x800000;
        while(mask)
        {
            if(ColourArray[colour]&mask)
            SEND_WS_1();
            else
            SEND_WS_0();
            mask >>= 1;
        }
    }
    taskEXIT_CRITICAL();
}
/******************************************************************************
 * FunctionName : Ws2812_init
 * Description  : Ws2812_init 初始化
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void Ws2812_init(void)
{
    GPIO_AS_OUTPUT(GPIO_Pin_5);
}

2.HTTP协议 解析程序

#include "esp_common.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "httpserver.h"
#include "WS2812.h"

#define SERVERADDR "192.168.31.158"
#define SERVERPORT 80

const char *DefaultPage=
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
"<html xmlns=\"http://www.w3.org/1999/xhtml\">"
"<head>"
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"
"<title>智能灯泡</title>"
"<script defer=\"defer\">"
"        function ledSwitch(string) {"
"            var xmlhttp;"
"            if (window.XMLHttpRequest) {"
"                xmlhttp = new XMLHttpRequest();"
"            } else {"
"                xmlhttp = new ActiveXObject(\"Microsoft.XMLHTTP\");"
"            }"
"            xmlhttp.onreadystatechange = function () {"
"                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {"
"                        document.getElementById(\"txtState\").innerHTML = xmlhttp.responseText;"
"                         document.getElementById(\"txtState\").style.color = string;"
"                    }"
"                },"
"            xmlhttp.open(\"GET\", string, true);"
"            xmlhttp.send(); "
"        }"
"    </script>"
"</head>"
"<body style=\"background-color: #2F4F4F\">"
"<font size=\"12\" color=\"yellow\">"
"<b>"
"<div class=\"text\" style=\" text-align:center;\"><big>创客学院-WiFi-智能家居</big></div>"
"</b>"
"</font>"
"<font size=\"12\" color=\"yellow\">"
"<b>"
"<div class=\"text\" style=\" text-align:center;\"><big>智能灯泡</big></div>"
"</b>"
"</font>"
"<br> </br>     "
"<font size=\"20\" color=\"white\">"
"<div align=\"center\" id=\"txtState\">灯泡状态未知</div>"
"</font>"
"<br> </br>"
"<div style=\" text-align:center;\">"
"<input type=\"button\" value=\"红色\" style=\"width:80px;height:40px;background:red;\" onclick=\"ledSwitch(\'red\')\" />"
"<input type=\"button\" value=\"橙色\" style=\"width:80px;height:40px;background:orange;\" onclick=\"ledSwitch(\'orange\')\">"
"<input type=\"button\" value=\"黄色\" style=\"width:80px;height:40px;background:yellow;\" onclick=\"ledSwitch(\'yellow\')\">"
"<input type=\"button\" value=\"绿色\" style=\"width:80px;height:40px;background:green;\" onclick=\"ledSwitch(\'green\')\">"
"<input type=\"button\" value=\"青色\" style=\"width:80px;height:40px;background:cyan;\" onclick=\"ledSwitch(\'cyan\')\">"
"<input type=\"button\" value=\"蓝色\" style=\"width:80px;height:40px;background:blue;\" onclick=\"ledSwitch(\'blue\')\">"
"<input type=\"button\" value=\"紫色\" style=\"width:80px;height:40px;background:purple;\" onclick=\"ledSwitch(\'purple\')\">"
"</div>"
"</body>"
"</html>";

/*
"<html>"
"<head><title>Default</title></head>"
"<body>I am Http server!</body>"
"</html>"
;
*/
// 发送200 ok报头
int file_ok(int cfd, long flen)
{
    char *send_buf = zalloc(sizeof(char)*100);
    sprintf(send_buf, "HTTP/1.1 200 OK\r\n");
    send(cfd, send_buf, strlen(send_buf), 0);
    sprintf(send_buf, "Connection: keep-alive\r\n");
    send(cfd, send_buf, strlen(send_buf), 0);
    sprintf(send_buf, "Content-Length: %ld\r\n", flen);
    send(cfd, send_buf, strlen(send_buf), 0);
    sprintf(send_buf, "Content-Type: text/html\r\n");
    send(cfd, send_buf, strlen(send_buf), 0);
    sprintf(send_buf, "\r\n");
    send(cfd, send_buf, strlen(send_buf), 0);
    free(send_buf);
    return 0;
}

bool isLedTurnOpen = false; // 记录LED状态
/******************************************************************************
 * FunctionName : ATaskHttpServer
 * Description  : ATaskHttpServer 任务
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ATaskHttpServer( void *pvParameters )
{
    int iVariableExample = 0;
    int fd = -1;
    int cfd = -1;
    int NetTimeOnt = 2000;
    int ret;

    struct sockaddr_in ServerAddr;
    struct sockaddr ClientAddr;
    socklen_t ClientAddrlen = sizeof(struct sockaddr);
    char *Httpmsg;
    char *Sendmsg;

    STATION_STATUS StaStatus;
    do
    {
        StaStatus = wifi_station_get_connect_status();
        vTaskDelay(100);
    }while(StaStatus != STATION_GOT_IP);
    
    fd = socket(PF_INET,SOCK_STREAM,0);
    if(fd == -1)
    {
        printf("get socket fail!\n");
        vTaskDelete(NULL);
        return;

    }
    setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,&NetTimeOnt,sizeof(int));

    memset(&ServerAddr,0,sizeof(ServerAddr));
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_addr.s_addr = INADDR_ANY;
    ServerAddr.sin_port = htons(SERVERPORT);
    ServerAddr.sin_len = sizeof(ServerAddr);

    if(bind(fd,(struct sockaddr*)&ServerAddr,ServerAddr.sin_len) != 0)
    {        
        printf("bind socket fail!\n");
        vTaskDelete(NULL);
        return;
    }

    if(listen(fd,5) != 0)
    {

        printf("listen socket fail!\n");
        vTaskDelete(NULL);
        return;
    }
    Httpmsg = (char*)zalloc(sizeof(char)*1000);
    for(;;)
    {

        
        cfd = accept(fd,&ClientAddr,&ClientAddrlen);
        if(cfd != -1)
        {
            
            printf("HttpClient accept\n");
            ret = recv(cfd,Httpmsg,1000,0);
            if(ret > 0)
            {
                printf("HttpClient recv\n");
                printf("%s\n",Httpmsg);
                if(strstr(Httpmsg,"GET / HTTP/1.1") != NULL)
                {
                    file_ok(cfd,strlen(DefaultPage));
                    send(cfd,DefaultPage,strlen(DefaultPage),0);
                }
                else if(strstr(Httpmsg,"red") != NULL)
                {
                    Ws2812Write(red);
					send(cfd,"灯泡状态为红色",strlen("灯泡状态为红色"),0);
                }
                else if(strstr(Httpmsg,"orange") != NULL)
                {
                    Ws2812Write(orange);
					send(cfd,"灯泡状态为橙色",strlen("灯泡状态为橙色"),0);
                }				
                else if(strstr(Httpmsg,"yellow") != NULL)
                {
                    Ws2812Write(yellow);
					send(cfd,"灯泡状态为黄色",strlen("灯泡状态为黄色"),0);
                }
                else if(strstr(Httpmsg,"green") != NULL)
                {
                    Ws2812Write(green);
					send(cfd,"灯泡状态为绿色",strlen("灯泡状态为绿色"),0);
                }
                else if(strstr(Httpmsg,"cyan") != NULL)
                {
                    Ws2812Write(cyan);
					send(cfd,"灯泡状态为青色",strlen("灯泡状态为青色"),0);
                }
                else if(strstr(Httpmsg,"blue") != NULL)
                {
                    Ws2812Write(blue);
					send(cfd,"灯泡状态为蓝色",strlen("灯泡状态为蓝色"),0);
                }	
                else if(strstr(Httpmsg,"purple") != NULL)
                {
                    Ws2812Write(purple);
					send(cfd,"灯泡状态为紫色",strlen("灯泡状态为紫色"),0);
                }				
            }
            else
            {
                printf("HttpClient data is no!\n");
            }
        }
        close(cfd);
    }
    free(Httpmsg);
    vTaskDelete( NULL );
}
/******************************************************************************
 * FunctionName : HttpServer_init
 * Description  : HttpServer_init 初始化
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void HttpServer_init(void)
{
    xTaskCreate(ATaskHttpServer, "HttpServer", 256, NULL, 4, NULL);
}

运行结果:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值