之前写过一篇《树莓派-通过Web控制GPIO针脚输出高低电平》采用的是Apache+php+python方式,通过网页端修改配置文件,再由python定时轮询,执行命令的方式实现的。

    python轮询配置文件的变更,显得很鸡肋,影响性能。后面发现用python的Tornado Web服务器可以进行改进,下面进行讲述。

    一、Tornado是什么

    1.Tornado简介

    Tornado一款使用 Python 编写的,相对简单的 非阻塞式 Web 服务器,它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,因此 Tornado 是实时 Web 服务的一个 理想框架。

    官方网站:http://www.tornadoweb.cn

    官方文档:http://www.tornadoweb.cn/documentation

    整个文档就一个网页,把http服务器常用的功能都讲述了一遍,如果有编程基础,应该很快就能上手。

    2.Tornado安装

    方式1:pip 安装:
    sudo pip install tornado

    方式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 install

    二、基本原理

    借用Tornado官方的Hello World例子:

    1. class MainHandler(tornado.web.RequestHandler): self.write("Hello, world")application = tornado.web.Application([if __name__ == "__main__": tornado.ioloop.IOLoop.instance().start()

    大致的思路是:通过Tornado开启http端口侦听,预设好路由规则,当有请求符合路由规则时,调用对应的Handler进行处理,这也是大部分Web服务器的处理方式。支持get和post请求。

    扩展一下,利用Tornado搭建一个http服务器,上面放一个网页,网页端传入需要控制的GPIO针脚编号和状态,服务器端接收到传入的参数,做相应的处理,即可实现控制GPIO针脚电平的输出了。

    三、实现步骤

    1.前端html页面

    1. <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".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; }<div class="page-header"><div class="panel panel-default"><div class="panel-heading"><div class="col-xs-3 btn-item"><div class="col-xs-3 btn-item"><a class="btn btn-danger btn-trigger"><i class="fa fa-power-off"></i>关机</a><div class="col-xs-3 btn-item"><a class="btn btn-primary btn-trigger"><i class="fa fa-refresh"></i>重启</a><div class="col-xs-3 btn-item"><script type="text/javascript"> $(".btn-trigger").click(function () {var text = $(this).text().replace(/ /g, "").replace(/\n/g, "").replace(/\r/g, "").replace(/\t/g, ""); cmd = "sudo shutdown -h now";if (confirm("确定要执行该命令吗?")) {success: function (result) {<div class="panel panel-default"><div class="panel-heading"> GPIO (蓝色->低电平,红色->高电平)</div><div class="panel-body gpio"><div class="col-xs-6 gpio-item"><div class="col-xs-6 gpio-item"><div class="col-xs-6 gpio-item"><button disabled="disabled" class="btn btn-info btn-gnd"><div class="col-xs-6 gpio-item"><button disabled="disabled" class="btn btn-info btn-gnd"><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="17">17 (11) 左06</a><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="18">18 (12) 右06</a><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="27">27 (13) 左07</a><div class="col-xs-6 gpio-item"><button disabled="disabled" class="btn btn-info btn-gnd"><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="22">22 (15) 左08</a><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="23">23 (16) 右08</a><div class="col-xs-6 gpio-item"><button disabled="disabled" class="btn btn-info btn-gnd"><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="24">24 (18) 右09</a><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="5">05 (29) 左15</a><div class="col-xs-6 gpio-item"><button disabled="disabled" class="btn btn-info btn-gnd"><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="6">06 (31) 左16</a><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="25">25 (22) 右11</a><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="13">13 (33) 左17</a><div class="col-xs-6 gpio-item"><button disabled="disabled" class="btn btn-info btn-gnd"><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="19">19 (35) 左18</a><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="12">12 (32) 右16</a><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="26">26 (37) 左19</a><div class="col-xs-6 gpio-item"><button disabled="disabled" class="btn btn-info btn-gnd"><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="20">20 (37) 右19</a><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="16">16 (36) 右18</a><div class="col-xs-6 gpio-item"><button disabled="disabled" class="btn btn-info btn-gnd"><div class="col-xs-6 gpio-item"><a class="btn btn-primary btn-gpio" pin="21">21 (40) 右20</a><script type="text/javascript"> $(".btn-gpio").click(function () {var gpio = $(this).attr("pin");if ($(this).hasClass("btn-danger")) { $(this).removeClass("btn-danger").addClass("btn-primary"); $(this).removeClass("btn-primary").addClass("btn-danger");var status = $(this).hasClass("btn-danger") ? 1 : 0;success: function (result) {

    2.Python脚本

    1. import tornado.httpserverfrom tornado.options import define,optionsdef SetPinStatus(pin,status): GPIO.setup(int(pin),GPIO.OUT) GPIO.output(int(pin),GPIO.LOW) GPIO.output(int(pin),GPIO.HIGH)class IndexHandler(tornado.web.RequestHandler): self.render("index.html") action=self.get_argument('action')if(action=="set-gpio-pin"): pin = self.get_argument('pin') status = self.get_argument('status')elif(action=="run-shell-cmd"): cmd = self.get_argument('cmd')if __name__ == '__main__':"static_path":os.path.join(os.path.dirname(__file__),"static") app = tornado.web.Application( (r"(apple-touch-icon\.png)",tornado.web.StaticFileHandler,dict(path=settings['static_path'])) http_server = tornado.httpserver.HTTPServer(app) tornado.ioloop.IOLoop.instance().start()

    3.目录结构

    树莓派-通过Web控制GPIO针脚输出高低电平(改进版)_JavaScript_清山博客-CSDN博客 - 图1

    4.部署调试

    在终端输入:python /var/www/html/pi/gpio/gpio.py (路径为我树莓派中文件路径,实际路径以你自己的环境为准。)

    如果终端没报错,此时打开浏览器,输入地址:http://localhost:8020 即可访问到页面,8020是python脚本中侦听的端口,你可以自行设置。

    5.运行结果

    树莓派-通过Web控制GPIO针脚输出高低电平(改进版)_JavaScript_清山博客-CSDN博客 - 图2

    6.源码下载

    http://download.csdn.net/download/a497785609/9990088