[STM32]

基于STM32和ESP8266的低成本物联网控制盒子

[复制链接]
2472|7
手机看帖
扫描二维码
随时随地手机跟帖
384998430|  楼主 | 2016-12-5 11:29 | 显示全部楼层 |阅读模式
本帖最后由 384998430 于 2016-12-5 11:33 编辑

我之前发过一个帖子,这是关于搭建一个简单的智能家居系统。现在我把这个小智能家居系统给做了个小盒子出来了,目的是弄一个方便控制家庭常规电器的系统,可以实现手机联网状态下控制家里的电灯、电热水器、电风扇、大门、空调等等。
        整个系统的硬件构成是:主控STM32F103C8T6、wifi模块ESP8266、温湿度传感器SHT20、光强传感器、红外发射管、存储器AT24C02、蜂鸣器,以及一些洞洞板、杜邦线和一个塑料盒子。
        软件部分的话服务器使用的是CentOS,花钱买的服务器,一块钱一天,没办法,有钱就是任性!在服务器主机上用C语言写的一个简单的程序,设计支持100个账户同时登陆使用,没用数据库,用文件存储用户名和账号的,也没有其他数据,基本上这个服务器的作用就是进行数据透传任务。然后使用设计了安卓手机客户端软件,我不太会安卓程序设计,所以弄得比较粗超,界面也不绚丽,不过能凑合用,。        系统完成之后可以实现手机端对控制盒子进行控制,包括控制继电器以及读取终端传感器的数据。总体来说使用起来还是比较方便的,不过有的时候有一点延时存在,因为中间经过了一个远程的服务器,寄放在深圳好像是,网络可能会塞住。
        废话不多说了,看图吧还是。其实我给这个拍了一个视频,但是很气人的是我的手机上上个星期在公交车上被偷了,视频也没了,气死我了,我一直没买手机,就没有再拍视频了,所以。。。。。。



194329yejf0fvfviizij1j.png.thumb.png



1 设计构想




        我的设计构想是很好的,一个主控节点连接多个从节点,这种方案类似什么Zigbee,其实我也没弄过ZigBee,猜测是差不多原理的。所有从节点通过433MHz的无线模块发送数据给主节点,整个系统只有主节点能够连入互联网,这样就可以使用分布式节点的方式采集各个角落的信息,而且使用的SI4432无线模块的传输距离还是很不错的,卖家说能穿2000米,用的是棒状天线。





194332t5i8cxll5mc55mca.png.thumb.png          194915pwyqdwzwwaqdgwwy.png.thumb.png          194332eb1r9rzowa5t5o1o.png.thumb.png

图2 设计原型

一开始使用我的带屏幕的开发板实验开发的,接了几个传感器实验实验,等时机成熟之后再转到实物上去的,我不会工业设计只好买了个壳给装了起来,还挺可爱。壳上顶了一个继电器模块,控制家电用的,我把我的电风扇、台灯都接上去了,可以使用,的用热熔胶封好了,电到了就不好了。



194330lq5wh55hw27bhw3h.png.thumb.png


图3 实物正视图




194330mwtgtxgsylsouebu.png.thumb.png

图4 实物俯视图


194330lhzmkuwzek7nm1zb.png.thumb.png


图5 开肚图

        开肚之后大家会看见其实没什么玩意里面,就两块板子加点线什么的,做工很粗糙。手工DIY嘛,无所谓啦,能用就行了。有机会能做成工业产品那样的是最好了,呲呲undefined。



194330rcqzxowoouxp6iw7.png.thumb.png


图6 服务器运行截图


194331t9v15w10eu1nu9su.png.thumb.png 194331wt7nf7fxkth0ypyx.png.thumb.png


图7 手机软件启动解锁界面


194331xojytz11nnce1ehf.png.thumb.png


图8 手机登录界面

194331knrcen16c92a9r0w.png.thumb.png


图9 手机运行主界面




194332gzjru43uwikp34uz.png.thumb.png

图10 终端软件设计流程图

  终端盒子的程序设计是在RTOS基础上进行的,就4个线程吧,其实程序很简单,主要我觉得是与ESP8266模块的通信部分比较搞死人。








194332ocb5qq1ycc1kydzv.png.thumb.png

图11 服务器软件设计流程图




194333rysmo888l3py5no9.png.thumb.png


图12 安卓客户端软件设计流程图


        其他传感器的程序坛友们都会,我只想把我的ESP8266控制程序弄出来,因为我弄这个弄了不少时间,希望能够给想用ESP8266的朋友参考参考,写的不好见谅啊。
RESULT AT_WaitResponse(u16 timeout)
{
        u8 c;
        u16 pt = 0;
        
//         ÏèμèêÕμ½μúò»¸ö×Ö½ú£¬μèμúò»¸ö×Ö½ú2»é趨3¬ê±ê±¼ä£¬
//         μ±êÕμ½μúò»¸ö×Ö½úÖ®oóoóÃæμÄ×Ö½úÔùé趨3¬ê±»úÖÆ

        //μè′yêÕμ½Ö¸áî»ØÏÔêy¾Y
        while(1)
        {
                c = UartGetByte(USART2);
                if(c == '\r' || c == '\n')
                {
                        ResultStr[pt++] = '\r';
                        ResultStr[pt++] = '\n';
                        ResultStr[pt] = '\0';
                        printf("%s",ResultStr);        //′òó¡Ö¸áî»ØÏÔ
                        break;
                }
                ResultStr[pt++] = c;
        }
        pt = 0;        //
//         ResultStr[pt++] = UartGetByte(USART2);        //μè′y»ñè¡μúò»¸ö»Øó|×Ö·û′®
        //»ñè¡esp8266μÄ»Øó|×Ö·û′®
        while(1)
        {
                if(UartGetByte2(USART2,(u32)timeout*1000,&c))
                {
                        ResultStr[pt++] = c;
//                         UartSendByte(USART1,c);
                }
                else
                        break;
        }
        
        ResultStr[pt] = '\0';        //ìí¼óò»¸ö½áêø·û
        printf("%s",ResultStr);        //′òó¡
        
        //2éÕò·μ»ØμÄ×Ö·û′®ÖDóDûóDERROR»òÕßOKμ¥′ê
        if(strstr((const char*)ResultStr,"OK"))
        {
//                 printf("OK");
                return AT_OK;
        }
        else if(strstr((const char*)ResultStr,"ERROR"))
        {
//                 printf("ERROR");
                return AT_ERROR;
        }
        return AT_ERROR;
}

//μè′yêÕμ½str×Ö·û′®Ôò·μ»Ø
void AT_WaitResponse2(char *str)
{
        u8 c,i = 0,len = strlen(str),data;
        QueueFlush(&Esp8266Queue);        //ÏèÇå¿Õ¶óáD»o3åÇø
        //μè′yêÕμ½Ö¸áî»ØÏÔêy¾Y
        while(UartGetByte3(USART1,&c) == 0)
        {
                while(QueueGet(&Esp8266Queue,&data))
                {
                        UartSendByte(USART1,data);
                        if(data == str[i])
                        {
                                i++;
                                if(i == len)
                                {
//                                         printf("\r\nfind %s,breakout\r\n",str);
                                        printf("\r\n");
                                        return;
                                }
                        }
                        else
                                i = 0;
                }
                OS_Sleep(10);
        }
}

//str1±íê¾Õyè·,str2±íê¾′íÎó,oˉêyóμóD·μ»ØÖμ
RESULT AT_WaitResponse3(char *str1,char *str2)
{
        u8 c,cnt1 = 0,cnt2 = 0,len1 = strlen(str1),len2 = strlen(str2),data;
        //μè′yêÕμ½Ö¸áî»ØÏÔêy¾Y
        while(UartGetByte3(USART1,&c) == 0)
        {
                while(QueueGet(&Esp8266Queue,&data))
                {
                        UartSendByte(USART1,data);
                        if(data == str1[cnt1])
                        {
                                cnt1++;
                                if(cnt1 == len1)
                                {
//                                         printf("\r\nfind %s,breakout\r\n",str1);
                                        printf("\r\n");
                                        return AT_OK;
                                }
                        }
                        else
                                cnt1 = 0;
                        
                        if(data == str2[cnt2])
                        {
                                cnt2++;
                                if(cnt2 == len2)
                                {
//                                         printf("\r\nfind %s,breakout\r\n",str2);
                                        printf("\r\n");
                                        return AT_ERROR;
                                }
                        }
                        else
                                cnt2 = 0;
                }
                OS_Sleep(10);
        }
        return AT_ERROR;
}

RESULT AT_Reset(void)
{
        printf("reset esp8266\r\n");
        //rstòy½ÅμÄéÏéyÑضÔesp8266½øDD¸′λ2ù×÷
        ESP8266_RST = 0;
        delay_ms(10);
        ESP8266_RST = 1;
        delay_ms(10);
        
        AT_WaitResponse2("ready");
        printf("reset done\r\n");
        return AT_OK;
}

RESULT AT_Test(void)
{
        printf("test esp8266\r\n");
        sprintf((char*)Usart2Buf,"AT\r\n");
        UartSendStr(USART2,Usart2Buf);
        AT_WaitResponse2("OK");
        return AT_OK;
}

RESULT AT_Version(void)
{
        printf("esp8266 version\r\n");
        sprintf((char*)Usart2Buf,"AT+GMR\r\n");
        UartSendStr(USART2,Usart2Buf);
        AT_WaitResponse2("OK");
        return AT_OK;
}

RESULT AT_STA_AP(CWMODE mode)
{
        printf("esp8266 working mode\r\n");
        sprintf((char*)Usart2Buf,"AT+CWMODE=%d\r\n",mode);
        UartSendStr(USART2,Usart2Buf);
        AT_WaitResponse2("OK");
        return AT_OK;
}

RESULT AT_ListAP(void)
{
        printf("list avalible AP\r\n");
        sprintf((char*)Usart2Buf,"AT+CWLAP\r\n");
        UartSendStr(USART2,Usart2Buf);
        AT_WaitResponse2("OK");
        return AT_OK;
}

RESULT AT_JoinAP(char *ssid,char *passwd)
{
        printf("connect to ssid:%s with passwd:%s\r\n",ssid,passwd);
        sprintf((char*)Usart2Buf,"AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,passwd);
        UartSendStr(USART2,Usart2Buf);
//         AT_WaitResponse3("OK","ERROR");
        return AT_WaitResponse3("OK","FAIL");
}

RESULT AT_QuitAP(void)
{
        printf("disconnect from AP\r\n");
        sprintf((char*)Usart2Buf,"AT+CWQAP\r\n");
        UartSendStr(USART2,Usart2Buf);
        AT_WaitResponse2("OK");
        return AT_OK;
}

RESULT AT_IP(void)
{
        printf("IP address\r\n");
        sprintf((char*)Usart2Buf,"AT+CIFSR\r\n");
        UartSendStr(USART2,Usart2Buf);
        AT_WaitResponse2("OK");
        return AT_OK;
}

//establish TCP connection
RESULT AT_EstTCPCon(char *addr,u16 port)
{
        printf("establish TCP connection\r\n");
        sprintf((char*)Usart2Buf,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",addr,port);
        UartSendStr(USART2,Usart2Buf);
        //óDμÄÄ£¿éμÄ»Øó|êÇLinkedóDμÄêÇCONNECTED¼óOK£¬oüéËÄÔ¾-°¡
//         AT_WaitResponse2("OK");
//         AT_WaitResponse2("Linked");
        return AT_WaitResponse3("Linked","Unlink");;
}

//·Çí¸′«Ä£ê½Ï·¢Ëílen¸ö×Ö½úμÄêy¾Y
RESULT AT_SendData(u8 *data,u8 len)
{
        int i;
        printf("send data\r\n");
        sprintf((char*)Usart2Buf,"AT+CIPSEND=%d\r\n",len);
        UartSendStr(USART2,Usart2Buf);
        AT_WaitResponse2("OK");
        for(i=0;i<len;i++)
                UartSendByte(USART2,data[i]);
        AT_WaitResponse2("SEND OK");//μèμ½êÕμ½»Øó|
        return AT_OK;
}

//Transparent transmission
RESULT AT_DirectTrans(u8 sw)
{
        printf("transparent transmission\r\n");
        if(sw == On)
        {
                sprintf((char*)Usart2Buf,"AT+CIPMODE=1\r\n");
                 UartSendStr(USART2,Usart2Buf);
                AT_WaitResponse2("OK");

                UartSendStr(USART2,"AT+CIPSEND\r\n");
                AT_WaitResponse2(">");
                return AT_OK;
        }
        else
        {
                 UartSendStr(USART2,"+++");
                return AT_OK;
        }
}

194331knrcen16c92a9r0w.png.thumb.png

相关帖子

windows100| | 2017-1-3 22:51 | 显示全部楼层
也在写8266,不懂得太多了。

使用特权

评论回复
pass1876| | 2017-1-5 17:05 | 显示全部楼层
我也在使用8266,刚用,有点问题咨询下。链路:手机通过---路由器---发命令给8266;可是8266只能把路由器的SSID和PWD保存到FLASH,而AT+CIPSERVER=1,8080 和AT+CIPMUX=1,这个两个命令不能保存到FLASh,导致每次掉电后都的重新设置。   怎么可以把这两个命令也弄到FLASH中去?或者有什么办法呢? 求指教

使用特权

评论回复
knice08126| | 2017-1-5 22:51 | 显示全部楼层
牛人!

使用特权

评论回复
yingcloud| | 2017-1-7 08:45 | 显示全部楼层
厉害,慢慢学习

使用特权

评论回复
渔夫的烟斗| | 2017-1-12 13:46 | 显示全部楼层

使用特权

评论回复
白骨之舞| | 2017-1-14 15:04 | 显示全部楼层
楼主的想法挺好的,很有帮助。顺便谴责那些偷手机的人!

使用特权

评论回复
oayzw| | 2017-1-15 17:58 | 显示全部楼层
最近也买了块8266,刷成nodemcu了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

6

帖子

0

粉丝