|
0x00前言
一提到智能家庭,大家可能首先想到的是各種大佬級公司搞的牛逼產(chǎn)品,或者說是創(chuàng)新產(chǎn)品。想想就覺得很復(fù)雜,有的用工控機(jī),有的用樹莓派,還有的用arduino,不管用什么,都繞不過服務(wù)器進(jìn)行控制,比如yeelink平臺,騰訊的智能硬件平臺等等。其實(shí),真實(shí)實(shí)現(xiàn)起來,并沒有想想中這么復(fù)雜,我們甚至只用一個(gè)小的單片機(jī)就能實(shí)現(xiàn)。
0x01單片機(jī)實(shí)現(xiàn)web服務(wù)器
探討用單片機(jī)來實(shí)現(xiàn)web服務(wù)器的文章通過baidu也能找到幾篇,但比較詳實(shí)的實(shí)現(xiàn)方法并沒有找到,這里考慮有兩種思路可以完成,一種是有線的lan模塊,如w5500,這種模塊本身就帶有web服務(wù)的部分功能,使用起來比較簡單,但是只能基于lan進(jìn)行訪問。另一種是通過stm32等單片機(jī),配合網(wǎng)絡(luò)模塊來完成。當(dāng)前我能想到的最簡單的方法就是用stm32+esp8266來實(shí)現(xiàn)。
基于第一種方法,我覺得受模塊性能影響比較大,受限于模塊,沒有開發(fā)感。于是考慮用第二種方法。這個(gè)方法里,有人用arduino來完成,這要基于c進(jìn)行編程。另外,就是考慮用micropython,這樣直接可以用python來實(shí)現(xiàn)。這里依然使用tpyboardV202。
0x02模擬實(shí)現(xiàn)家庭智能家居控制平臺
因?yàn)闆]有想好要做一個(gè)多么復(fù)雜的實(shí)驗(yàn),只是想能模擬一下效果,所有在整個(gè)的模塊過程中,我選用了tpyboardv202開發(fā)板做主控制板,用一個(gè)發(fā)光二極管來模擬一個(gè)臺燈(現(xiàn)實(shí)中,這里其實(shí)可以用一個(gè)繼電器來控制其它設(shè)備的通斷電),用一個(gè)直流小電機(jī)加迷你風(fēng)扇葉表示模擬電風(fēng)扇。整個(gè)實(shí)現(xiàn)還用到了一個(gè)三極管(S9014,NPN)來控制直流電機(jī)。
0x03硬件的搭建與連接
1、發(fā)光二極管的使用
發(fā)光二極管使用比較簡單,直接看它的兩條“腿”,長的那個(gè)是正極,反之是負(fù)極。
01.jpg (12.55 KB, 下載次數(shù): 87)
下載附件
2017-6-29 10:36 上傳
2、直流小電機(jī)的使用方法
02.jpg (17.23 KB, 下載次數(shù): 73)
下載附件
2017-6-29 10:36 上傳
上圖直流小電機(jī)中,紅色框內(nèi)的兩個(gè)接線端A和B,無論那個(gè)接正極或負(fù)極都可以,只不過轉(zhuǎn)動(dòng)的方向不一樣而已。本次我是用B端接入正極,正好是順時(shí)針轉(zhuǎn)動(dòng)。
3、三極管S9014(NPN)的使用方法
03.png (61.43 KB, 下載次數(shù): 80)
下載附件
2017-6-29 10:36 上傳
本次我們使用S9014的放大和開關(guān)功能,集電極接入v202的3.3V引腳,發(fā)射極接入電機(jī)某一端,通過給基極高低電平來控制發(fā)射極和集電極之間是否導(dǎo)通,從而控制直流電機(jī)轉(zhuǎn)動(dòng)或停止。
下面來介紹一下接線方法
我的實(shí)物連接圖
03-02.jpg (149.7 KB, 下載次數(shù): 85)
下載附件
2017-6-29 10:37 上傳
0x04利用micropython實(shí)現(xiàn)web服務(wù)器
首先,編輯一個(gè)main.py文件。v202開機(jī)自啟動(dòng)main.py文件
- try:
- import usocket as socket
- except:
- import socket
- import network
- from machine import UART
- from machine import Pin
- led_flag=Pin(2, Pin.OUT)#esp8266模塊上的小燈 高電平:滅 低電平:亮
- led = Pin(4, Pin.OUT)#發(fā)光二極管的控制引腳
- motor = Pin(5, Pin.OUT)#直流電機(jī)的控制引腳
- #初始化
- led.low()
- motor.low()
- led_flag.high()
- def do_connect(ssid,pwd):
- sta_if = network.WLAN(network.STA_IF)#STA 模式
- sta_if.active(False)
- if not sta_if.isconnected():#判斷是否連接
- sta_if.active(True)
- sta_if.connect(ssid,pwd)#ssid:WIFI名稱 pwd:WIFI 密碼
- while not sta_if.isconnected():
- pass
- if sta_if.isconnected():
- return sta_if.ifconfig()[0]
- def main(ip_,dev_data,login_data,name,pwd):
- s = socket.socket()
- ai = socket.getaddrinfo(ip_, 80)
- addr = ai[0][-1]
- s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- s.bind(addr)
- s.listen(5)
- led_flag.low()
- #s_data=login_data
- while True:
- res = s.accept()
- client_s = res[0]
- client_addr = res[1]
- led_flag.high()
- req =client_s.readline()
- while True:
- h = client_s.readline()
- if h == b"" or h == b"\r\n":
- break
- #print(h)
- req+=(h.decode('utf-8').lower())
- print("Request:")
- req=req.decode('utf-8').lower().split('\r\n')
- #http header 解析
- req_data=req[0].lstrip().rstrip().replace(' ','')
- print(req_data)
- if req_data.find('favicon.ico')>-1:
- client_s.close()
- continue
- else:
- if len(req_data)<=12:
- #說明是第一次訪問,輸入login.html
- s_data=login_data
- else:
- req_data=req_data.replace('get/?','').replace('http/1.1','')
- _name=req_data.find('name')
- _pwd=req_data.find('pwd')
- if _name>-1 and _pwd>-1:
- #判斷是否是用戶登錄
- if req_data.find(name)>-1 and req_data.find(pwd)>-1:
- s_data=dev_data
- print('Login Success!')
- else:
- f=open('fail.html','r')
- s_data=f.read()
- f.close()
- print('Login Fail!')
- else:
- #判斷是否是控制LED
- _index=req_data.find('led=')
- if _index>-1:
- s_data=dev_data
- led_val=req_data[_index+4:_index+6].lstrip().rstrip()
- print('led:',led_val)
- if led_val=='on':
- led.value(1)
- else:
- led.value(0)
- #判斷是否是控制電機(jī)
- _index=req_data.find('motor=')
- if _index>-1:
- s_data=dev_data
- motor_val=req_data[_index+6:_index+8].lstrip().rstrip()
- print('motor_val:',motor_val)
- if motor_val=='on':
- motor.value(1)
- else:
- motor.value(0)
- print('-----------')
- client_s.send(s_data)
- client_s.close()
- led_flag.low()
-
- f=open('device.html','r')
- dev_html=f.read()
- f.close()
- f=open('login.html','r')
- login_html=f.read()
- f.close()
- f=open('info.txt','r')
- info=f.read()
- f.close()
- name=info.split(',')[0].lstrip().rstrip()
- pwd=info.split(',')[1].lstrip().rstrip()
- print('name:',name)
- print('pwd:',pwd)
- myip_=do_connect('essid','pwd')#家中網(wǎng)絡(luò)的WIFI名稱和密碼
- print(myip_)
- main(myip_,dev_html,login_html,name,pwd)
復(fù)制代碼
login.html登錄頁面
- <html>
- <head>
- <title>智能家庭網(wǎng)絡(luò)</title>
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <style type="text/css">
- h2
- {
- margin-top:4%;
- margin-bottom:40px;
- }
- </style>
- </head>
- <body>
- <center>
- <h2>歡迎登錄智能家庭網(wǎng)絡(luò)平臺</h2>
- <form action="/" method="get" accept-charset="utf-8">
- <p>用戶名: <input type="text" name="name" /></p>
- <p>密 碼: <input type="password" name="pwd" /></p>
- <input type="Submit" value="登錄" />
-
- </form>
- </center>
- </body>
- </html>
復(fù)制代碼
device.html控制頁面
- <html>
- <head>
- <title>智能家庭網(wǎng)絡(luò)平臺</title>
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <style type="text/css">
- h2
- {
- margin-top:4%;
- margin-bottom:40px;
- }
- </style>
- </head>
- <body>
- <center>
- <h2>歡迎使用智能家庭網(wǎng)絡(luò)-控制平臺</h2>
- <form action="/" method="get" accept-charset="utf-8">
- <p>燈光: <input type="Submit" value="ON" name="led" /> <input type="Submit" value="OFF" name="led" /></p>
- <p>風(fēng)扇: <input type="Submit" value="ON" name="motor" /> <input type="Submit" value="OFF" name="motor" /></p>
-
- </form>
- </center>
- </body>
- </html>
復(fù)制代碼
fail.html登錄錯(cuò)誤頁面(就是把login.html稍做了一下改動(dòng))
- <html>
- <head>
- <title>智能家庭網(wǎng)絡(luò)</title>
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <style type="text/css">
- h2
- {
- margin-top:4%;
- margin-bottom:40px;
- }
- </style>
- </head>
- <body>
- <center>
- <h2>歡迎登錄智能家庭網(wǎng)絡(luò)平臺</h2>
- <form action="/" method="get" accept-charset="utf-8">
- <p style="color:red">用戶名或密碼錯(cuò)誤!</p>
- <p>用戶名: <input type="text" name="name" /></p>
- <p>密 碼: <input type="password" name="pwd" /></p>
- <input type="Submit" value="登錄" />
-
- </form>
- </center>
- </body>
- </html>
復(fù)制代碼
info.txt這里是用文件存放的用戶名和密碼(英文逗號分隔),前面是用戶名,后面是密碼。這里的用戶名和密碼是用來登錄我們智能家居控制平臺的。
0x05程序下載測試
使用MicroPythonFileUploader工具,將源代碼下載到v202中。
工具下載地址:tpyboard點(diǎn)com/download/tool/170.html
1、 使用usb數(shù)據(jù)線將v202接入到電腦,打開設(shè)備管理器,查看加載的端口。我的是COM44
※如果驅(qū)動(dòng)安裝失敗,可以下載CH340的驅(qū)動(dòng),手動(dòng)安裝。
04.png (26.74 KB, 下載次數(shù): 96)
下載附件
2017-6-29 10:38 上傳
2、 打開MicroPythonFileUploader選擇端口,點(diǎn)擊[Open]。
05.png (61.22 KB, 下載次數(shù): 70)
下載附件
2017-6-29 10:39 上傳
3、 取消[Autorun]的打鉤,點(diǎn)擊紅框的文件夾圖標(biāo),選擇源碼,點(diǎn)擊[Send]等待發(fā)送成功。
06.png (41.28 KB, 下載次數(shù): 82)
下載附件
2017-6-29 10:39 上傳
4、 將上面的源碼文件都下載到v202中,下載完畢后,點(diǎn)擊[Run/Reset]就會開始執(zhí)行代碼。
07.png (37.14 KB, 下載次數(shù): 92)
下載附件
2017-6-29 10:39 上傳
5、 開始運(yùn)行后,紅色框內(nèi)打印的是我們存放在info.txt里的用戶名和密碼,這個(gè)可以自定義。
6、 下面桃紅色框內(nèi)打印的是我們v202從路由器那里獲取到的IP地址,只要打印了IP地址,說明就成功接入網(wǎng)絡(luò)了。我的v202獲取的IP地址是192.168.1.192。
7、 到此,我們的web服務(wù)器就搭建完成了。
0x06智能家庭網(wǎng)絡(luò)平臺的使用
1、在家庭局域網(wǎng)內(nèi),我們可以選用pc或者手機(jī),通過瀏覽器,打開192.168.1.192就可以看到登錄界面。
08.png (10.18 KB, 下載次數(shù): 79)
下載附件
2017-6-29 10:39 上傳
2、默認(rèn)用戶名admin密碼123456,大家可以通過修改info.txt文件來進(jìn)行修改。
(1)輸入錯(cuò)誤的用戶名和密碼會進(jìn)入錯(cuò)誤界面。
09.png (12.97 KB, 下載次數(shù): 86)
下載附件
2017-6-29 10:39 上傳
。2)輸入正確的,進(jìn)入控制平臺。
10.png (12.54 KB, 下載次數(shù): 99)
下載附件
2017-6-29 10:39 上傳
3、接下來,我們就可以通過網(wǎng)頁開控制燈光和小風(fēng)扇了,看我的實(shí)驗(yàn)效果圖。
11.jpg (68.92 KB, 下載次數(shù): 111)
下載附件
2017-6-29 10:39 上傳
12.jpg (80.61 KB, 下載次數(shù): 91)
下載附件
2017-6-29 10:40 上傳
這里,我只是做了一個(gè)實(shí)例,受時(shí)間限制,沒有再做更深入的開發(fā)。大家可以自己結(jié)合自己的創(chuàng)意再深入去做。如果能夠通過路由器給tpyboardv202設(shè)一個(gè)外網(wǎng)Ip,這樣就可以從外網(wǎng)進(jìn)行訪問,從而完成外網(wǎng)對家內(nèi)設(shè)備的控制
|
|