极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14412|回复: 2

利用单片机快速实现家庭智能控制平台

[复制链接]
发表于 2017-6-29 11:15:13 | 显示全部楼层 |阅读模式
  0x00前言

  一提到智能家庭,大家可能首先想到的是各种大佬级公司搞的牛逼产品,或者说是创新产品。想想就觉得很复杂,有的用工控机,有的用树莓派,还有的用arduino,不管用什么,都绕不过服务器进行控制,比如yeelink平台,腾讯的智能硬件平台等等。其实,真实实现起来,并没有想想中这么复杂,我们甚至只用一个小的单片机就能实现。

  0x01单片机实现web服务器

  探讨用单片机来实现web服务器的文章通过baidu也能找到几篇,但比较详实的实现方法并没有找到,这里考虑有两种思路可以完成,一种是有线的lan模块,如w5500,这种模块本身就带有web服务的部分功能,使用起来比较简单,但是只能基于lan进行访问。另一种是通过stm32等单片机,配合网络模块来完成。当前我能想到的最简单的方法就是用stm32+esp8266来实现。

  基于第一种方法,我觉得受模块性能影响比较大,受限于模块,没有开发感。于是考虑用第二种方法。这个方法里,有人用arduino来完成,这要基于c进行编程。另外,就是考虑用micropython,这样直接可以用python来实现。这里依然使用tpyboardV202。

  0x02模拟实现家庭智能家居控制平台

  因为没有想好要做一个多么复杂的实验,只是想能模拟一下效果,所有在整个的模块过程中,我选用了tpyboardv202开发板做主控制板,用一个发光二极管来模拟一个台灯(现实中,这里其实可以用一个继电器来控制其它设备的通断电),用一个直流小电机加迷你风扇叶表示模拟电风扇。整个实现还用到了一个三极管(S9014,NPN)来控制直流电机。

  0x03硬件的搭建与连接

  1、发光二极管的使用

  发光二极管使用比较简单,直接看它的两条“腿”,长的那个是正极,反之是负极。



  2、直流小电机的使用方法



  上图直流小电机中,红色框内的两个接线端A和B,无论那个接正极或负极都可以,只不过转动的方向不一样而已。本次我是用B端接入正极,正好是顺时针转动。

  3、三极管S9014(NPN)的使用方法

         


  本次我们使用S9014的放大和开关功能,集电极接入v202的3.3V引脚,发射极接入电机某一端,通过给基极高低电平来控制发射极和集电极之间是否导通,从而控制直流电机转动或停止。

  下面来介绍一下接线方法

三极管(S9014)        TPYBoard v202        直流小电机
集电极                               3.3V                           --
基极                                        G5                           --
发射极                               --                         B 端
--                                     GND                         A端

TPYBoard  v202        发光二极管
            G4                     正极
           GND                     负极


  我的实物连接图



  0x04利用micropython实现web服务器

  首先,编辑一个main.py文件。v202开机自启动main.py文件

  1. try:
  2.     import usocket as socket
  3. except:
  4.     import socket
  5. import network
  6. from machine import UART
  7. from machine import Pin

  8. led_flag=Pin(2, Pin.OUT)#esp8266模块上的小灯 高电平:灭 低电平:亮
  9. led = Pin(4, Pin.OUT)#发光二极管的控制引脚
  10. motor = Pin(5, Pin.OUT)#直流电机的控制引脚
  11. #初始化
  12. led.low()
  13. motor.low()
  14. led_flag.high()
  15. def do_connect(ssid,pwd):
  16.     sta_if = network.WLAN(network.STA_IF)#STA 模式
  17.     sta_if.active(False)
  18.     if not sta_if.isconnected():#判断是否连接
  19.         sta_if.active(True)
  20.         sta_if.connect(ssid,pwd)#ssid:WIFI名称 pwd:WIFI 密码
  21.         while not sta_if.isconnected():
  22.             pass
  23.     if sta_if.isconnected():
  24.         return sta_if.ifconfig()[0]
  25. def main(ip_,dev_data,login_data,name,pwd):

  26.     s = socket.socket()
  27.     ai = socket.getaddrinfo(ip_, 80)
  28.     addr = ai[0][-1]
  29.     s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  30.     s.bind(addr)
  31.     s.listen(5)
  32.     led_flag.low()
  33.     #s_data=login_data
  34.     while True:
  35.         res = s.accept()
  36.         client_s = res[0]
  37.         client_addr = res[1]
  38.         led_flag.high()
  39.         req =client_s.readline()
  40.         while True:
  41.             h = client_s.readline()
  42.             if h == b"" or h == b"\r\n":
  43.                 break
  44.             #print(h)
  45.             req+=(h.decode('utf-8').lower())
  46.         print("Request:")
  47.         req=req.decode('utf-8').lower().split('\r\n')
  48.         #http header 解析
  49.         req_data=req[0].lstrip().rstrip().replace(' ','')
  50.         print(req_data)
  51.         if req_data.find('favicon.ico')>-1:
  52.             client_s.close()
  53.             continue
  54.         else:
  55.             if len(req_data)<=12:
  56.                 #说明是第一次访问,输入login.html
  57.                 s_data=login_data
  58.             else:
  59.                 req_data=req_data.replace('get/?','').replace('http/1.1','')
  60.                 _name=req_data.find('name')
  61.                 _pwd=req_data.find('pwd')
  62.                 if _name>-1 and _pwd>-1:
  63.                     #判断是否是用户登录
  64.                     if req_data.find(name)>-1 and req_data.find(pwd)>-1:
  65.                         s_data=dev_data
  66.                         print('Login Success!')
  67.                     else:
  68.                         f=open('fail.html','r')
  69.                         s_data=f.read()
  70.                         f.close()
  71.                         print('Login Fail!')
  72.                 else:
  73.                     #判断是否是控制LED
  74.                     _index=req_data.find('led=')
  75.                     if _index>-1:
  76.                         s_data=dev_data
  77.                         led_val=req_data[_index+4:_index+6].lstrip().rstrip()
  78.                         print('led:',led_val)
  79.                         if led_val=='on':
  80.                             led.value(1)
  81.                         else:
  82.                             led.value(0)
  83.                     #判断是否是控制电机
  84.                     _index=req_data.find('motor=')
  85.                     if _index>-1:
  86.                         s_data=dev_data
  87.                         motor_val=req_data[_index+6:_index+8].lstrip().rstrip()
  88.                         print('motor_val:',motor_val)
  89.                         if motor_val=='on':
  90.                             motor.value(1)
  91.                         else:
  92.                             motor.value(0)
  93.             print('-----------')
  94.             client_s.send(s_data)
  95.             client_s.close()
  96.         led_flag.low()
  97.         
  98. f=open('device.html','r')
  99. dev_html=f.read()
  100. f.close()
  101. f=open('login.html','r')
  102. login_html=f.read()
  103. f.close()
  104. f=open('info.txt','r')
  105. info=f.read()
  106. f.close()
  107. name=info.split(',')[0].lstrip().rstrip()
  108. pwd=info.split(',')[1].lstrip().rstrip()
  109. print('name:',name)
  110. print('pwd:',pwd)
  111. myip_=do_connect('essid','pwd')#家中网络的WIFI名称和密码
  112. print(myip_)
  113. main(myip_,dev_html,login_html,name,pwd)
复制代码


  login.html登录页面

  1. <html>
  2.     <head>
  3.         <title>智能家庭网络</title>
  4.         <meta name="viewport" content="width=device-width, initial-scale=1" />
  5.         <style type="text/css">
  6.             h2
  7.             {
  8.                 margin-top:4%;
  9.                 margin-bottom:40px;
  10.             }
  11.         </style>
  12.     </head>
  13.     <body>
  14.         <center>
  15.         <h2>欢迎登录智能家庭网络平台</h2>
  16.             <form action="/" method="get" accept-charset="utf-8">
  17.                 <p>用户名:&nbsp;<input type="text" name="name"  /></p>  
  18.                 <p>密&nbsp;码:&nbsp;&nbsp;<input type="password" name="pwd"  /></p>
  19.                 <input type="Submit" value="登录"  />         
  20.                
  21.             </form>
  22.         </center>
  23.     </body>
  24. </html>
复制代码


  device.html控制页面

  1. <html>
  2.     <head>
  3.         <title>智能家庭网络平台</title>
  4.         <meta name="viewport" content="width=device-width, initial-scale=1" />
  5.         <style type="text/css">
  6.             h2
  7.             {
  8.                 margin-top:4%;
  9.                 margin-bottom:40px;
  10.             }
  11.         </style>
  12.     </head>
  13.     <body>
  14.         <center>
  15.         <h2>欢迎使用智能家庭网络-控制平台</h2>
  16.             <form action="/" method="get" accept-charset="utf-8">
  17.                 <p>灯光:&nbsp;<input type="Submit" value="ON" name="led" />&nbsp;<input type="Submit" value="OFF" name="led" /></p>  
  18.                 <p>风扇:&nbsp;<input type="Submit" value="ON" name="motor" />&nbsp;<input type="Submit" value="OFF" name="motor" /></p>         
  19.                
  20.             </form>
  21.         </center>
  22.     </body>
  23. </html>
复制代码


  fail.html登录错误页面(就是把login.html稍做了一下改动)

  1. <html>
  2.     <head>
  3.         <title>智能家庭网络</title>
  4.         <meta name="viewport" content="width=device-width, initial-scale=1" />
  5.         <style type="text/css">
  6.             h2
  7.             {
  8.                 margin-top:4%;
  9.                 margin-bottom:40px;
  10.             }
  11.         </style>
  12.     </head>
  13.     <body>
  14.         <center>
  15.         <h2>欢迎登录智能家庭网络平台</h2>
  16.             <form action="/" method="get" accept-charset="utf-8">
  17.                 <p style="color:red">用户名或密码错误!</p>
  18.                 <p>用户名:&nbsp;<input type="text" name="name"  /></p>  
  19.                 <p>密&nbsp;码:&nbsp;&nbsp;<input type="password" name="pwd"  /></p>
  20.                 <input type="Submit" value="登录"  />         
  21.                
  22.             </form>
  23.         </center>
  24.     </body>
  25. </html>
复制代码


  info.txt这里是用文件存放的用户名和密码(英文逗号分隔),前面是用户名,后面是密码。这里的用户名和密码是用来登录我们智能家居控制平台的。

  1. admin,123456
复制代码


  0x05程序下载测试

  使用MicroPythonFileUploader工具,将源代码下载到v202中。

  工具下载地址:http://tpyboard.com/download/tool/170.html

  1、        使用usb数据线将v202接入到电脑,打开设备管理器,查看加载的端口。我的是COM44

  ※如果驱动安装失败,可以下载CH340的驱动,手动安装。

  CH340驱动下载地址:http://tpyboard.com/download/drive/163.html



  2、        打开MicroPythonFileUploader选择端口,点击[Open]。



  3、        取消[Autorun]的打钩,点击红框的文件夹图标,选择源码,点击[Send]等待发送成功。



  4、        将上面的源码文件都下载到v202中,下载完毕后,点击[Run/Reset]就会开始执行代码。



  5、        开始运行后,红色框内打印的是我们存放在info.txt里的用户名和密码,这个可以自定义。

  6、        下面桃红色框内打印的是我们v202从路由器那里获取到的IP地址,只要打印了IP地址,说明就成功接入网络了。我的v202获取的IP地址是192.168.1.192。

  7、        到此,我们的web服务器就搭建完成了。

  0x06智能家庭网络平台的使用

  1、在家庭局域网内,我们可以选用pc或者手机,通过浏览器,打开192.168.1.192就可以看到登录界面。



  2、默认用户名admin密码123456,大家可以通过修改info.txt文件来进行修改。

  (1)输入错误的用户名和密码会进入错误界面。



  (2)输入正确的,进入控制平台。



  3、接下来,我们就可以通过网页开控制灯光和小风扇了,看我的实验效果图。




  这里,我只是做了一个实例,受时间限制,没有再做更深入的开发。大家可以自己结合自己的创意再深入去做。如果能够通过路由器给tpyboardv202设一个外网Ip,这样就可以从外网进行访问,从而完成外网对家内设备的控制

  

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2017-7-1 11:36:38 | 显示全部楼层
直接用esp8266自带的nodemcu 来就省去了单片机 ,连接贝壳网就搞不用外网IP了.
回复 支持 反对

使用道具 举报

发表于 2017-10-11 00:03:59 | 显示全部楼层
  谢谢分享。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-26 06:20 , Processed in 0.039097 second(s), 20 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表