这篇日志的内容应该算是《RPi.GPIO 模块使用基础》Input 部分的扩展讲解,详细讲解了 Input 部分的一些高级应用技巧。

目前有几种途径可以在您的程序中获得 GPIO 的输入信息。第一种也是最简易的一种为在某个时间点检查输入值。这即是所谓的“轮询(polling)”,而且如果您的程序在错误的时间里进行了读取,可能会错过某个输入值。在循环中运用轮询,有可能使处理器资源紧张。另一种对 GPIO 输入进行响应的方式可以使用“中断(interruots)”(边缘检测(edge detection))。边缘可以是从 HIGH 到 LOW 的过度(下降临界值(falling edge))或从 LOW 到 HIGH 的过度(上升临界值(rising edge))。

上拉/下拉电阻

如果您在输入针脚上没有连接任何元件,那么它将是“浮动(float)”的。换句话说,因为您没有连接任何元件,在按下按钮或开关之前,读取的值是没有意义的。由于电源的波动,获取到的值可能会有很大的变化。

为了解决这个问题,我们需要使用上拉/下拉电阻。这样,我们就可设定输入的默认值了。在这里,可以使用硬件或软件对电阻进行上拉/下拉。使用硬件方式,将一个 10K 的电阻连接在输入通道与 3.3V(上拉)或 0V(下拉)之间是常用的做法。而 RPi.GPIO 也允许您通过软件的方式对配置 Broadcom SOC 来达到目的:

GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)

或者

GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

(通道编号是基于您所使用的编号系统所指定的(BOARD 或 BCM)。)

输入测试(轮询(polling))

您可以在某个时间点获得一次输入的快照:

if GPIO.input(channel):

print('Input was HIGH')

else:

print('Input was LOW')

在循环中等待按钮被按下后进行轮询:

while GPIO.input(channel) == GPIO.LOW:

time.sleep(0.01) # 为 CPU 留出 10 毫秒,供其处理其它事物

(这里假设为当按下按钮时,输入状态从 LOW 到 HIGH)

中断和边检检测

边缘的定义为电信号从 LOW 到 HIGH(上升临界值)或从 HIGH 到 LOW(下降临界值)状态的改变。正常情况下,对于输入的值来说,我们更关心的是输入的状态是否发生了改变。这种状态上的改变是很重要的。

为了避免您的程序在忙于处理其它的事物时而错过了您按下按钮的操作,这里有两种方法可以解决:

wait_for_edge() 函数

event_detected() 函数

在检测到边缘时执行线程回调函数

wait_for_edge() 函数

wait_for_edge() 函数被设计用于在检测到边缘之前阻止程序的运行。换句话说,上面的示例中,等待按钮被按下的语句可以改写为:

GPIO.wait_for_edge(channel, GPIO.RISING)

注意,您可以输入 GPIO.RISING、GPIO.FALLING、GPIO.BOTH 对边缘进行检测。这种方式的优点是占用 CPU 资源很少,因此系统可以有充裕的资源处理其它事物。

event_detected() 函数 event_detected() 函数被设计用于循环中有其它东西时使用,但不同于轮询的是,它不会错过当 CPU 忙于处理其它事物时输入状态的改变。这在类似使用 Pygame 或 PyQt 时主循环实时监听和响应 GUI 的事件是很有用的。

GPIO.add_event_detect(channel, GPIO.RISING) # 在通道上添加上升临界值检测

do_something()

if GPIO.event_detected(channel):

print('Button pressed')

注意,您可以输入 GPIO.RISING、GPIO.FALLING、GPIO.BOTH 对边缘进行检测。

线程回调

RPi.GPIO 在第二条线程中执行回调函数。这意味着回调函数可以同您的主程序同时运行,并且可以立即对边缘进行响应。例如:

def my_callback(channel):

print('这是一个边缘事件回调函数!')

print('在通道 %s 上进行边缘检测'%channel)

print('该程序与您的主程序运行在不同的进程中')

GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback) # 在通道上添加上升临界值检测

... 其它程序代码 ...

如果您需要多个回调函数:

def my_callback_one(channel):

print('回调 1')

def my_callback_two(channel):

print('回调 2')

GPIO.add_event_detect(channel, GPIO.RISING)

GPIO.add_event_callback(channel, my_callback_one)

GPIO.add_event_callback(channel, my_callback_two)

注意,在该示例中,回调函数为顺序运行而不是同时运行。这是因为当前只有一个进程供回调使用,而回调的运行顺序是依据它们被定义的顺序。

开关防抖

您可能会注意到,每次按钮按下时,回调操作被调用不止一次。这种现象被称作“开关抖动(switch bounce)”。这里有两种方法解决开关抖动问题:

将一个 0.1uF 的电容连接到开关上。

软件防止抖动

两种方式一起用

使用软件方式抖动,可以在您指定的回调函数中添加 bouncetime= 参数。

抖动时间需要使用毫秒为单位进行书写。例如:

# 在通道上添加上升临界值检测,忽略由于开关抖动引起的小于 200ms 的边缘操作

GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback, bouncetime=200)

或者

GPIO.add_event_callback(channel, my_callback, bouncetime=200)

remove_event_detect()

由于某种原因,您不希望您的程序检测边缘事件,您可以将它停止:

GPIO.remove_event_detect(channel)

相关网站

树莓派模拟量输入范围_使用 RPi.GPIO 模块的输入(Input)功能相关推荐

  1. 树莓派Raspberry Pi上安装和使用RPi.GPIO模块以及引脚对照表

    记录自己学习树莓派的过程. 如果要使用Python来使用GPIO信号,需要使用RPi.GPIO模块. 如果你使用的是Python2版本,树莓派默认安装了RPi.GPIO模块(python-rpi.gp ...

  2. 树莓派笔记(三) 使用 RPi.GPIO 模块

    目录 树莓派笔记(三) 使用 RPi.GPIO 模块 RPi.GPIO 引脚简介 引脚编号 引脚图 引脚设置 指定引脚编号系统 配置通道 释放引脚 输出 pwm 输入 上拉/下拉电阻 轮询输入 中断和 ...

  3. 使用 RPI.GPIO 模块的脉宽调制(PWM)功能

    脉宽调制(PWM)是指用微处理器的数字输出来对模拟电路进行控制,是一种对模拟信号电平进行数字编码的方法.在树莓派上,可以通过对GPIO的编程来实现PWM. 创建一个 PWM 实例: p = GPIO. ...

  4. 树莓派模拟量输入范围_模拟量输入值超过了em235的量程范围,可以吗?-工业支持中心-西门子中国...

    最好不要超过15V,不过15V应该还不至于烧毁模块!如果你的量程是0-10V的话,超过10V就一直显示32000了 回答者: 迷失中原 - 助理工程师&nbsp&nbsp第8级 201 ...

  5. 树莓派pythongpio编程_树莓派gpio接口及编程方法

    树莓派现在越来越火,网上树莓派的资料也越来越多.树莓派源自英国,国外嵌入式开源领域具有良好的分享精神,树莓派各种集成库也层出不穷,下面详细介绍一下树莓派gpio接口及编程方法. GPIO基本介绍 GP ...

  6. RPi.GPIO 官方使用文档翻译

    简介 源代码及其来源 RPi.GPIO是python的一个module( 模块 ), 树莓派官方系统默认已经安装, 仍在不断更新中, 截至20160314, 最新版0.6.2, 适配了树莓派3, 访 ...

  7. Raspuberry PI3 RPi.GPIO 官方文档翻译

    最近毕业设计用到了Raspberry pi 做毕业设计,在学校学得编程语言是C,但是raspberry pi的官方推荐编程语言是Python,当然raspberry也有基于C的IO包,但是我的毕业设计 ...

  8. RASPBERRY PI3 - RPi.GPIO 官方使用文档翻译

    简介 源代码及其来源 RPi.GPIO是Python的一个module( 模块 ), 树莓派官方系统默认已经安装, 仍在不断更新中, 截至20160314, 最新版0.6.2, 适配了树莓派3, 访 ...

  9. GPIO模块常用的一些方法

    官方文档:https://sourceforge.net/p/raspberry-gpio-python/wiki/BasicUsage/ https://blog.csdn.net/fhqlongt ...

最新文章

  1. LeetCode Binary Tree Right Side View(搜索)
  2. SQLite在C#的使用
  3. mac pdf去水印_今天才知道,Word、PDF文档去水印这么简单!一键水印说拜拜
  4. javafx 使用_使用JavaFX AnimationTimer
  5. Eclipse程序员要掌握的常用快捷键
  6. 一个优雅的报警处理系统范例
  7. 零窗口探测怎么抓包_天问·探路火星|五大亮点!最快“胖五”把探测器送入苍穹...
  8. linux系统mysql创建表,Linux系统下手动新建数据库
  9. 3.啊哈!算法 --- 一大波数正在靠近——枚举!很暴力
  10. java txt 修改_java创建TXT文件并进行读、写、修改操作
  11. windows10桌面_三大虚拟桌面软件对比,总有一款适合你!
  12. JVM 宋红康版 : JVM与Java体系结构
  13. C语言,利用条件语句进行身高预测
  14. android手机如何截屏,安卓手机怎么截图? (全文)
  15. 面向对象的三大特征:封装、继承和多态的简单概述
  16. 华夏第一都城《禹州市》
  17. 使用梯子导致的浏览器不能正常使用
  18. iPhone5预测:在微创新中逐渐沦陷[转]
  19. [CodeForces877 E. Danil and a Part-time Job]dfs序+线段树
  20. 计算机入门模拟卷A(有详细答案),《计算机入门》模拟卷C答案-华东师范大学

热门文章

  1. CSS清除浮动_清除float浮动
  2. 点在多边形内的判断(射线法)
  3. JSP/SERVLET(6)——Jquery EasyUI 选项卡Tabs的使用方法
  4. 无法打开 configsource 文件
  5. WP7应用开发笔记(12) 添加页面动画
  6. [原创]java读写word文档,完美解决方案
  7. 由一个异常开始思考springmvc参数解析
  8. java异常——捕获异常+再次抛出异常与异常链
  9. 解决问题 inner element must either be a resource reference or empty.
  10. 用jQuery作为JS对象从选项中添加选项的最佳方法是什么?