Drive.google.com/drive/folders/1ahbeoEHkjxoo4NV1wReOmpoRWbl448z-javascript
1.Tornado簡介css
Tornado一款使用 Python 編寫的,相對簡單的 非阻塞式 Web 服務器,它是非阻塞式服務器,並且速度至關快。得利於其 非阻塞的方式和對 epoll 的運用,Tornado 每秒能夠處理數以千計的鏈接,所以 Tornado 是實時 Web 服務的一個 理想框架。html
官方網站:http://www.tornadoweb.cn前端
官方文檔:http://www.tornadoweb.cn/documentationjava
整個文檔就一個網頁,把http服務器經常使用的功能都講述了一遍,若是有編程基礎,應該很快就能上手。python
2.Tornado安裝jquery
方式1:pip 安裝:
sudo pip install tornadoweb
方式2:源代碼安裝:
wget https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz
tar xvzf tornado-4.3.tar.gz
cd tornado-4.3
python setup.py build
sudo python setup.py installajax
2、基本原理shell
借用Tornado官方的Hello World例子:
import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") application = tornado.web.Application([ (r"/", MainHandler), ]) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
大體的思路是:經過Tornado開啓http端口偵聽,預設好路由規則,當有請求符合路由規則時,調用對應的Handler進行處理,這也是大部分Web服務器的處理方式。支持get和post請求。
擴展一下,利用Tornado搭建一個http服務器,上面放一個網頁,網頁端傳入須要控制的GPIO針腳編號和狀態,服務器端接收到傳入的參數,作相應的處理,便可實現控制GPIO針腳電平的輸出了。
3、實現步驟
1.前端html頁面
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>樹莓派Web控制中心</title> <script src="static/js/jquery-3.2.1.min.js" type="text/javascript"></script> <script src="static/js/bootstrap.min.js" type="text/javascript"></script> <link href="static/css/bootstrap.css" rel="stylesheet" type="text/css" /> <link href="static/css/font-awesome-4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" /> <style type="text/css"> .page-header { margin: 20px 0; border-bottom: 1px solid #eee; padding-bottom: 0; text-align: center; } .btn-item { text-align: center; } i { margin-right: 3px; display: inline-block; } h1 { text-align: center; } .tip { font-weight: bold; color: black; } .lead { font-size: small; } .gpio-item { text-align: center; } .btn-gnd, .btn-gpio { padding: 10px 5px; margin-bottom: 5px; width: 100%; font-size: small; } .gpio .row { margin-top: 5px; } </style> </head> <body> <div class="container"> <div class="page-header"> <h3> 樹莓派Web控制中心</h3> <p class="lead"> 用於控制鏈接到樹莓派的各類傳感器 </p> </div> <div class="panel panel-default"> <div class="panel-heading"> 設備</div> <div class="panel-body"> <div class="row"> <div class="col-xs-3 btn-item"> </div> <div class="col-xs-3 btn-item"> <a class="btn btn-danger btn-trigger"><i class="fa fa-power-off"></i>關機</a> </div> <div class="col-xs-3 btn-item"> <a class="btn btn-primary btn-trigger"><i class="fa fa-refresh"></i>重啓</a> </div> <div class="col-xs-3 btn-item"> </div> <script type="text/javascript"> var url = "/"; $(function () { $(".btn-trigger").click(function () { var text = $(this).text().replace(/ /g, "").replace(/\n/g, "").replace(/\r/g, "").replace(/\t/g, ""); var cmd = ""; switch (text) { case "關機": cmd = "sudo shutdown -h now"; break; case "重啓": cmd = "sudo reboot"; break; } if (confirm("肯定要執行該命令嗎?")) { $.ajax({ type: "POST", url: url, data: { action: "run-shell-cmd", cmd: cmd }, success: function (result) { //$(".tip").html(result); } }); } }); }); </script> </div> </div> </div> <div class="panel panel-default"> <div class="panel-heading"> GPIO (藍色->低電平,紅色->高電平)</div> <div class="panel-body gpio"> <div class="row"> <div class="col-xs-6 gpio-item"> 左側 </div> <div class="col-xs-6 gpio-item"> 右側 </div> </div> <div class="row"> <div class="col-xs-6 gpio-item"> <button disabled="disabled" class="btn btn-info btn-gnd"> GND (9) 左05</button> </div> <div class="col-xs-6 gpio-item"> <button disabled="disabled" class="btn btn-info btn-gnd"> GND (6) 右03</button> </div> </div> <div class="row"> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="17">17 (11) 左06</a> </div> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="18">18 (12) 右06</a> </div> </div> <div class="row"> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="27">27 (13) 左07</a> </div> <div class="col-xs-6 gpio-item"> <button disabled="disabled" class="btn btn-info btn-gnd"> GND (14) 右07</button> </div> </div> <div class="row"> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="22">22 (15) 左08</a> </div> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="23">23 (16) 右08</a> </div> </div> <div class="row"> <div class="col-xs-6 gpio-item"> <button disabled="disabled" class="btn btn-info btn-gnd"> GND (25) 左13</button> </div> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="24">24 (18) 右09</a> </div> </div> <div class="row"> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="5">05 (29) 左15</a> </div> <div class="col-xs-6 gpio-item"> <button disabled="disabled" class="btn btn-info btn-gnd"> GND (20) 右10</button> </div> </div> <div class="row"> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="6">06 (31) 左16</a> </div> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="25">25 (22) 右11</a> </div> </div> <div class="row"> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="13">13 (33) 左17</a> </div> <div class="col-xs-6 gpio-item"> <button disabled="disabled" class="btn btn-info btn-gnd"> GND (30) 右15</button> </div> </div> <div class="row"> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="19">19 (35) 左18</a> </div> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="12">12 (32) 右16</a> </div> </div> <div class="row"> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="26">26 (37) 左19</a> </div> <div class="col-xs-6 gpio-item"> <button disabled="disabled" class="btn btn-info btn-gnd"> GND (34) 右17</button> </div> </div> <div class="row"> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="20">20 (37) 右19</a> </div> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="16">16 (36) 右18</a> </div> </div> <div class="row"> <div class="col-xs-6 gpio-item"> <button disabled="disabled" class="btn btn-info btn-gnd"> GND (39) 右20</button> </div> <div class="col-xs-6 gpio-item"> <a class="btn btn-primary btn-gpio" pin="21">21 (40) 右20</a> </div> </div> <script type="text/javascript"> $(function () { $(".btn-gpio").click(function () { var gpio = $(this).attr("pin"); if ($(this).hasClass("btn-danger")) { $(this).removeClass("btn-danger").addClass("btn-primary"); } else { $(this).removeClass("btn-primary").addClass("btn-danger"); } var status = $(this).hasClass("btn-danger") ? 1 : 0; $.ajax({ type: "POST", url: url, data: { action: "set-gpio-pin", pin: gpio, status: status }, success: function (result) { //$(".tip").html(result); } }); }); }) </script> </div> </div> </div> </body> </html>
2.Python腳本
#coding: utf8 import sys import RPi.GPIO as GPIO import time import os import tornado.ioloop import tornado.web import tornado.httpserver import tornado.options from tornado.options import define,options #初始化 def init(): GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) #設置GPIO針腳電平輸出 def SetPinStatus(pin,status): GPIO.cleanup(int(pin)) GPIO.setup(int(pin),GPIO.OUT) if(int(status)==0): GPIO.output(int(pin),GPIO.LOW) else: GPIO.output(int(pin),GPIO.HIGH) #路由處理 class IndexHandler(tornado.web.RequestHandler): def get(self): self.render("index.html") def post(self): init() action=self.get_argument('action') #設置GPIO針腳電平輸出 if(action=="set-gpio-pin"): pin = self.get_argument('pin') status = self.get_argument('status') SetPinStatus(pin,status) self.write("true") #執行shell腳本,如:關機,重啓 elif(action=="run-shell-cmd"): cmd = self.get_argument('cmd') os.system(cmd) if __name__ == '__main__': #控制檯輸出響應結果,正式環境能夠不開啓 #tornado.options.parse_command_line() settings={ "static_path":os.path.join(os.path.dirname(__file__),"static") } app = tornado.web.Application( handlers=[ (r"/",IndexHandler), (r"(apple-touch-icon\.png)",tornado.web.StaticFileHandler,dict(path=settings['static_path'])) ],**settings) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(8020) tornado.ioloop.IOLoop.instance().start() GPIO.cleanup()
3.目錄結構
4.部署調試
在終端輸入:python /var/www/html/pi/gpio/gpio.py (路徑爲我樹莓派中文件路徑,實際路徑以你本身的環境爲準。)
若是終端沒報錯,此時打開瀏覽器,輸入地址:http://localhost:8020 便可訪問到頁面,8020是python腳本中偵聽的端口,你能夠自行設置。
5.運行結果
6.源碼下載
http://download.csdn.net/download/a497785609/9990088