树莓派 GPIO 控制 / WEB控制 - 备忘

转载于:
https://www.cnblogs.com/zhenqichai/p/raspberry-pi-control-GPIO-with-python.html

Python 控制树莓派 GPIO 输出:控制 LED 灯

树莓派 GPIO 控制输出的入门应该都是从控制 LED 灯开始的吧。

树莓派版本:Model 3B+

树莓派系统:Raspbian Stretch with desktop and recommended software,April 2019

连接装置

准备一个 LED 灯,两个两头都为母的杜邦线。对照下图连接树莓派和 LED 灯,要求一个是地线(GND)连接灯的负极,一个有 GPIO + BCM 编号连接正极。我选择了 pin 号为 6 和 12 的两个引脚。你也可以选择别的,记得将之后的代码中 BCM 编号修改正确

在断电状态下连接。连接好的如下图,我的 LED 灯有正负极的提示,图中所示红色箭头指向的是正极,蓝色箭头是负极。如果你的 LED 灯是最简单的那种,长引脚就是正极,短的负极。

树莓派开机。

安装 RPI.GPIO

我装的树莓派系统已经满足所需要的环境,不需要额外下载。

你可以测试是否已经有该模块,在终端打开 Python3,然后尝试导入库: import RPi.GPIO as GPIO 。如果没有出现error,就表示已经有了,可以直接跳到下一步。

如果出现错误,则执行以下命令:

sudo apt-get update
sudo apt-get install python3-rpi.gpio

测试 GPIO

按下图所示依次输入命令,观察。

GPIO.setmode() 有两种参数可以选择:可以使用 GPIO.BOARD 选项告诉库根据 GPIO 接口的引脚号引用信号,或者使用 Broadcom 芯片的信号编号( GPIO.setmode(GPIO.BCM) )。

在选择了模式之后,需要确定在程序中使用哪一个 GPIO 信号以及将家门用来作为输入还是输出:GPIO.setup(channel, direction)。我给的例子里是 GPIO.setup(18, GPIO.OUT) 。

后面两个命令控制灯的开关: GPIO.output(18, GPIO.HIGH) 和 GPIO.output(18, GPIO.LOW) 。

GPIO.cleanup() 用于重置 GPIO 接口,它把所有的 GPIO 引脚设置为低电平状态,所以没有多余的信号出现在界面上。在不使用改函数的情况下,如果试图配置一个已分配信号值的 GPIO 信号引脚,那么 RPi.GPIO 模块会产生一条警告信息。

闪烁 LED

然后我在树莓派上编写了下面这个代码让 LED 灯闪烁五次,保存在 Desktop,命名为 led.py。

复制代码
#!/usr/bin/python3

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
GPIO.output(18, GPIO.LOW)
blinks = 0
print('开始闪烁')
while (blinks < 5):
    GPIO.output(18, GPIO.HIGH)
    time.sleep(1.0)
    GPIO.output(18, GPIO.LOW)
    time.sleep(1.0)
    blinks = blinks + 1
GPIO.output(18, GPIO.LOW)
GPIO.cleanup()
print('结束闪烁')
复制代码

 

演示结果:

也可以以通过 PWM 信号来达到让灯闪烁的效果。

#!/usr/bin/python3

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
blink = GPIO.PWM(18, 1)
try:
    blink.start(50)
    while True:
        pass
except KeyboardInterrupt:
    blink.stop()
GPIO.cleanup()

 

start() 方法指定了占空比(从 1 到 100)。在开始 PWM 信号后,程序就可以解放出来做其他事情了。GPIO 18 会持续发送 PWM 信号,直到停止它。 blink = GPIO.PWM(18, 1) 指定了 PWM 信号以 1HZ 的频率发送,灯 1 秒闪烁一次。按 Control + C 中止闪烁。

参考资料

《树莓派Python编程 入门与实战(第2版)》,人民邮电出版社

上述内容转载至:
作者:Zhenqi Chai
出处:https://www.cnblogs.com/zhenqichai/
版权声明:本文为作者原创文章,欢迎转载,但必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

-------------------------------------------------------------------------
树莓派-通过Web控制GPIO针脚输出高低电平(改进版)

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

 

3.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>

 

4.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()


5.示例

上述内容转载于:
https://blog.csdn.net/a497785609/article/details/78060029
6.案例脚本
#coding: utf8

import sys
import RPi.GPIO as GPIO
import time
import os


# RuntimeError: Please set pin numbering mode using GPIO.setmode(GPIO.BOARD) or GPIO.setmode(GPIO.BCM)
GPIO.setmode(GPIO.BCM)
GPIO.setup(19,GPIO.OUT)
GPIO.output(19,GPIO.HIGH)
# GPIO.output(19,GPIO.LOW)

GPIO.setup(26,GPIO.OUT)
GPIO.output(26,GPIO.HIGH)
# GPIO.output(26,GPIO.LOW)
# GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)

 

...