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

汤权   2016-11-29 21:01 楼主
我之前发过一个帖子:https://bbs.eeworld.com.cn/thread-496527-1-1.html,这是关于搭建一个简单的智能家居系统。现在我把这个小智能家居系统给做了个小盒子出来了,目的是弄一个方便控制家庭常规电器的系统,可以实现手机联网状态下控制家里的电灯、电热水器、电风扇、大门、空调等等。 整个系统的硬件构成是:主控STM32F103C8T6、wifi模块ESP8266、温湿度传感器SHT20、光强传感器、红外发射管、存储器AT24C02、蜂鸣器,以及一些洞洞板、杜邦线和一个塑料盒子。 软件部分的话服务器使用的是CentOS,花钱买的服务器,一块钱一天,没办法,有钱就是任性!在服务器主机上用C语言写的一个简单的程序,设计支持100个账户同时登陆使用,没用数据库,用文件存储用户名和账号的,也没有其他数据,基本上这个服务器的作用就是进行数据透传任务。然后使用设计了安卓手机客户端软件,我不太会安卓程序设计,所以弄得比较粗超,界面也不绚丽,不过能凑合用,。 系统完成之后可以实现手机端对控制盒子进行控制,包括控制继电器以及读取终端传感器的数据。总体来说使用起来还是比较方便的,不过有的时候有一点延时存在,因为中间经过了一个远程的服务器,寄放在深圳好像是,网络可能会塞住。
废话不多说了,看图吧还是。其实我给这个拍了一个视频,但是很气人的是我的手机上上个星期在公交车上被偷了,视频也没了,气死我了,我一直没买手机,就没有再拍视频了,所以。。。。。。
图片1.png
1 设计构想
我的设计构想是很好的,一个主控节点连接多个从节点,这种方案类似什么Zigbee,其实我也没弄过ZigBee,猜测是差不多原理的。所有从节点通过433MHz的无线模块发送数据给主节点,整个系统只有主节点能够连入互联网,这样就可以使用分布式节点的方式采集各个角落的信息,而且使用的SI4432无线模块的传输距离还是很不错的,卖家说能穿2000米,用的是棒状天线。
图片10.png 图片11.png 图片15.png
图2 设计原型

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

图片2.png
图3 实物正视图
图片3.png
图4 实物俯视图
图片4.png
图5 开肚图
开肚之后大家会看见其实没什么玩意里面,就两块板子加点线什么的,做工很粗糙。手工DIY嘛,无所谓啦,能用就行了。有机会能做成工业产品那样的是最好了,呲呲
图片5.png
图6 服务器运行截图
图片6.png 图片7.png
图7 手机软件启动解锁界面
图片8.png
图8 手机登录界面
图片9.png
图9 手机运行主界面
图片12.png
图10 终端软件设计流程图
终端盒子的程序设计是在RTOS基础上进行的,就4个线程吧,其实程序很简单,主要我觉得是与ESP8266模块的通信部分比较搞死人。
图片13.png
图11 服务器软件设计流程图
图片14.png
图12 安卓客户端软件设计流程图
其他传感器的程序坛友们都会,我只想把我的ESP8266控制程序弄出来,因为我弄这个弄了不少时间,希望能够给想用ESP8266的朋友参考参考,写的不好见谅啊。
  1. RESULT AT_WaitResponse(u16 timeout)
  2. {
  3. u8 c;
  4. u16 pt = 0;
  5. // ÏèμèêÕμ½μúò»¸ö×Ö½ú£¬μèμúò»¸ö×Ö½ú2»é趨3¬ê±ê±¼ä£¬
  6. // μ±êÕμ½μúò»¸ö×Ö½úÖ®oóoóÃæμÄ×Ö½úÔùé趨3¬ê±»úÖÆ
  7. //μè′yêÕμ½Ö¸áî»ØÏÔêy¾Y
  8. while(1)
  9. {
  10. c = UartGetByte(USART2);
  11. if(c == '\r' || c == '\n')
  12. {
  13. ResultStr[pt++] = '\r';
  14. ResultStr[pt++] = '\n';
  15. ResultStr[pt] = '\0';
  16. printf("%s",ResultStr); //′òó¡Ö¸áî»ØÏÔ
  17. break;
  18. }
  19. ResultStr[pt++] = c;
  20. }
  21. pt = 0; //
  22. // ResultStr[pt++] = UartGetByte(USART2); //μè′y»ñè¡μúò»¸ö»Øó|×Ö·û′®
  23. //»ñè¡esp8266μÄ»Øó|×Ö·û′®
  24. while(1)
  25. {
  26. if(UartGetByte2(USART2,(u32)timeout*1000,&c))
  27. {
  28. ResultStr[pt++] = c;
  29. // UartSendByte(USART1,c);
  30. }
  31. else
  32. break;
  33. }
  34. ResultStr[pt] = '\0'; //ìí¼óò»¸ö½áêø·û
  35. printf("%s",ResultStr); //′òó¡
  36. //2éÕò·μ»ØμÄ×Ö·û′®ÖDóDûóDERROR»òÕßOKμ¥′ê
  37. if(strstr((const char*)ResultStr,"OK"))
  38. {
  39. // printf("OK");
  40. return AT_OK;
  41. }
  42. else if(strstr((const char*)ResultStr,"ERROR"))
  43. {
  44. // printf("ERROR");
  45. return AT_ERROR;
  46. }
  47. return AT_ERROR;
  48. }
  49. //μè′yêÕμ½str×Ö·û′®Ôò·μ»Ø
  50. void AT_WaitResponse2(char *str)
  51. {
  52. u8 c,i = 0,len = strlen(str),data;
  53. QueueFlush(&Esp8266Queue); //ÏèÇå¿Õ¶óáD»o3åÇø
  54. //μè′yêÕμ½Ö¸áî»ØÏÔêy¾Y
  55. while(UartGetByte3(USART1,&c) == 0)
  56. {
  57. while(QueueGet(&Esp8266Queue,&data))
  58. {
  59. UartSendByte(USART1,data);
  60. if(data == str[i])
  61. {
  62. i++;
  63. if(i == len)
  64. {
  65. // printf("\r\nfind %s,breakout\r\n",str);
  66. printf("\r\n");
  67. return;
  68. }
  69. }
  70. else
  71. i = 0;
  72. }
  73. OS_Sleep(10);
  74. }
  75. }
  76. //str1±íê¾Õyè·,str2±íê¾′íÎó,oˉêyóμóD·μ»ØÖμ
  77. RESULT AT_WaitResponse3(char *str1,char *str2)
  78. {
  79. u8 c,cnt1 = 0,cnt2 = 0,len1 = strlen(str1),len2 = strlen(str2),data;
  80. //μè′yêÕμ½Ö¸áî»ØÏÔêy¾Y
  81. while(UartGetByte3(USART1,&c) == 0)
  82. {
  83. while(QueueGet(&Esp8266Queue,&data))
  84. {
  85. UartSendByte(USART1,data);
  86. if(data == str1[cnt1])
  87. {
  88. cnt1++;
  89. if(cnt1 == len1)
  90. {
  91. // printf("\r\nfind %s,breakout\r\n",str1);
  92. printf("\r\n");
  93. return AT_OK;
  94. }
  95. }
  96. else
  97. cnt1 = 0;
  98. if(data == str2[cnt2])
  99. {
  100. cnt2++;
  101. if(cnt2 == len2)
  102. {
  103. // printf("\r\nfind %s,breakout\r\n",str2);
  104. printf("\r\n");
  105. return AT_ERROR;
  106. }
  107. }
  108. else
  109. cnt2 = 0;
  110. }
  111. OS_Sleep(10);
  112. }
  113. return AT_ERROR;
  114. }
  115. RESULT AT_Reset(void)
  116. {
  117. printf("reset esp8266\r\n");
  118. //rstòy½ÅμÄéÏéyÑضÔesp8266½øDD¸′λ2ù×÷
  119. ESP8266_RST = 0;
  120. delay_ms(10);
  121. ESP8266_RST = 1;
  122. delay_ms(10);
  123. AT_WaitResponse2("ready");
  124. printf("reset done\r\n");
  125. return AT_OK;
  126. }
  127. RESULT AT_Test(void)
  128. {
  129. printf("test esp8266\r\n");
  130. sprintf((char*)Usart2Buf,"AT\r\n");
  131. UartSendStr(USART2,Usart2Buf);
  132. AT_WaitResponse2("OK");
  133. return AT_OK;
  134. }
  135. RESULT AT_Version(void)
  136. {
  137. printf("esp8266 version\r\n");
  138. sprintf((char*)Usart2Buf,"AT+GMR\r\n");
  139. UartSendStr(USART2,Usart2Buf);
  140. AT_WaitResponse2("OK");
  141. return AT_OK;
  142. }
  143. RESULT AT_STA_AP(CWMODE mode)
  144. {
  145. printf("esp8266 working mode\r\n");
  146. sprintf((char*)Usart2Buf,"AT+CWMODE=%d\r\n",mode);
  147. UartSendStr(USART2,Usart2Buf);
  148. AT_WaitResponse2("OK");
  149. return AT_OK;
  150. }
  151. RESULT AT_ListAP(void)
  152. {
  153. printf("list avalible AP\r\n");
  154. sprintf((char*)Usart2Buf,"AT+CWLAP\r\n");
  155. UartSendStr(USART2,Usart2Buf);
  156. AT_WaitResponse2("OK");
  157. return AT_OK;
  158. }
  159. RESULT AT_JoinAP(char *ssid,char *passwd)
  160. {
  161. printf("connect to ssid:%s with passwd:%s\r\n",ssid,passwd);
  162. sprintf((char*)Usart2Buf,"AT+CWJAP="%s","%s"\r\n",ssid,passwd);
  163. UartSendStr(USART2,Usart2Buf);
  164. // AT_WaitResponse3("OK","ERROR");
  165. return AT_WaitResponse3("OK","FAIL");
  166. }
  167. RESULT AT_QuitAP(void)
  168. {
  169. printf("disconnect from AP\r\n");
  170. sprintf((char*)Usart2Buf,"AT+CWQAP\r\n");
  171. UartSendStr(USART2,Usart2Buf);
  172. AT_WaitResponse2("OK");
  173. return AT_OK;
  174. }
  175. RESULT AT_IP(void)
  176. {
  177. printf("IP address\r\n");
  178. sprintf((char*)Usart2Buf,"AT+CIFSR\r\n");
  179. UartSendStr(USART2,Usart2Buf);
  180. AT_WaitResponse2("OK");
  181. return AT_OK;
  182. }
  183. //establish TCP connection
  184. RESULT AT_EstTCPCon(char *addr,u16 port)
  185. {
  186. printf("establish TCP connection\r\n");
  187. sprintf((char*)Usart2Buf,"AT+CIPSTART="TCP","%s",%d\r\n",addr,port);
  188. UartSendStr(USART2,Usart2Buf);
  189. //óDμÄÄ£¿éμÄ»Øó|êÇLinkedóDμÄêÇCONNECTED¼óOK£¬oüéËÄÔ¾-°¡
  190. // AT_WaitResponse2("OK");
  191. // AT_WaitResponse2("Linked");
  192. return AT_WaitResponse3("Linked","Unlink");;
  193. }
  194. //·Çí¸′«Ä£ê½Ï·¢Ëílen¸ö×Ö½úμÄêy¾Y
  195. RESULT AT_SendData(u8 *data,u8 len)
  196. {
  197. int i;
  198. printf("send data\r\n");
  199. sprintf((char*)Usart2Buf,"AT+CIPSEND=%d\r\n",len);
  200. UartSendStr(USART2,Usart2Buf);
  201. AT_WaitResponse2("OK");
  202. for(i=0;i<len;i++)
  203. UartSendByte(USART2,data[i]);
  204. AT_WaitResponse2("SEND OK");//μèμ½êÕμ½»Øó|
  205. return AT_OK;
  206. }
  207. //Transparent transmission
  208. RESULT AT_DirectTrans(u8 sw)
  209. {
  210. printf("transparent transmission\r\n");
  211. if(sw == On)
  212. {
  213. sprintf((char*)Usart2Buf,"AT+CIPMODE=1\r\n");
  214. UartSendStr(USART2,Usart2Buf);
  215. AT_WaitResponse2("OK");
  216. UartSendStr(USART2,"AT+CIPSEND\r\n");
  217. AT_WaitResponse2(">");
  218. return AT_OK;
  219. }
  220. else
  221. {
  222. UartSendStr(USART2,"+++");
  223. return AT_OK;
  224. }
  225. }
也不知道怎么回事代码格式怎么那么差劲,而且中文还是乱码,这个是MDK的问题。安卓的代码也发上来,有兴趣的朋友可以看看,写的很将就,不是很规范,见谅啊。
啊,附件大于15M上传不了,上传到资源中心了,正在审核中,没法发链接,
附件链接:https://download.eeworld.com.cn/detail/%E6%B1%A4%E6%9D%83/563026。不知道为什么要一个芯币,估计上传的时候没改,抱歉啦。
本帖最后由 汤权 于 2016-11-30 10:18 编辑
亚里士缺德

回复评论 (72)

学习一个
点赞  2016-11-29 21:18
汤大大威武
笑.gif
这个防水盒我也用过
虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2016-11-29 21:19
哈哈,手机界面做得好可爱,解锁界面很好看
点赞  2016-11-29 21:24
厉害了   格式乱码,在MDK的设置里面改下General Editor Settings 下的 Encoding 就不会中文注释乱码了
疏雨客晚归,荒烟乱,几许江南无晴!又落花,残香织梦,莫  莫  莫,白首衷肠……
点赞  2016-11-29 21:49
不错,我也弄过类似的东西,不过试用的移动的onenet平台。当时还加了PM2.5的数据,后来懒病犯了,就再没动过
点赞  2016-11-29 21:56
全部走的是TCP连接吗?然后控制指令和传感器数据通过服务器直接中转了?
点赞  2016-11-29 22:03
这篇文章不错,
点赞  2016-11-29 22:09
引用: wajuka 发表于 2016-11-29 21:49
厉害了   格式乱码,在MDK的设置里面改下General Editor Settings 下的 Encoding 就不会中文注释 ...

是么是么?天哪  我都不知道,非常感谢非常感谢,这个乱码问题烦我很久了。
亚里士缺德
点赞  2016-11-30 08:58
引用: littleshrimp 发表于 2016-11-29 21:19
汤大大威武

这个防水盒我也用过

哈哈,我还不是大大啊,虾哥才是大大啊。这个防水壳才两三块钱,质量真心不错,我用电烙铁在上面打眼的,因为没电转,呲呲
亚里士缺德
点赞  2016-11-30 09:01
引用: yayasoso 发表于 2016-11-29 21:56
不错,我也弄过类似的东西,不过试用的移动的onenet平台。当时还加了PM2.5的数据,后来 ...

咦,其实我也有弄OneNet的,申请了OneNet的开发板还,平台很不错的。
亚里士缺德
点赞  2016-11-30 09:01
引用: johnrey 发表于 2016-11-29 22:03
全部走的是TCP连接吗?然后控制指令和传感器数据通过服务器直接中转了?

嗯,是的,还没来得及加心跳包,不过试了下ESP8266也不会从服务器断开,就懒了没加了。
亚里士缺德
点赞  2016-11-30 09:04
引用: dontium 发表于 2016-11-29 22:09
这篇文章不错,

谢版主夸奖
亚里士缺德
点赞  2016-11-30 09:05
已经上传的资源我已经都审核完了哦
玩板看这里: https://bbs.eeworld.com.cn/elecplay.html EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!
点赞  2016-11-30 10:10
楼主快更新下附件链接把
玩板看这里: https://bbs.eeworld.com.cn/elecplay.html EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!
点赞  2016-11-30 10:10
引用: okhxyyo 发表于 2016-11-30 10:10
楼主快更新下附件链接把

好的,thankyou
亚里士缺德
点赞  2016-11-30 10:16
上传时默认的是1积分哦。扣的是积分不是芯币哦。你可以自己调整售价。如果你想要更改售价可以联系我进行更改。
玩板看这里: https://bbs.eeworld.com.cn/elecplay.html EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!
点赞  2016-11-30 11:34
引用: okhxyyo 发表于 2016-11-30 11:34
上传时默认的是1积分哦。扣的是积分不是芯币哦。你可以自己调整售价。如果你想要更改售价可以联系我进行更 ...

喔喔,帮我把这个改成0积分下载吧,不想弄什么下载屏障。thankyou
亚里士缺德
点赞  2016-11-30 11:40
引用: 汤权 发表于 2016-11-30 11:40
喔喔,帮我把这个改成0积分下载吧,不想弄什么下载屏障。thankyou

已经调整好了
玩板看这里: https://bbs.eeworld.com.cn/elecplay.html EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!
点赞  2016-11-30 15:00
先赞一个吧,暂时没有看懂
点赞  2016-11-30 15:33
1234下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复