1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 树莓派笔记(三) 使用 RPi.GPIO 模块

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

时间:2019-12-13 10:19:48

相关推荐

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

目录

树莓派笔记(三) 使用 RPi.GPIO 模块RPi.GPIO引脚简介引脚编号引脚图 引脚设置指定引脚编号系统配置通道释放引脚 输出pwm输入上拉/下拉电阻轮询输入中断和边检检测线程回调开关防抖

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

RPi.GPIO

RPI.GPIO是python的一个模块,树莓派官方系统默认已经安装

使用python控制GPIO需要导入RPI.GPIO模块

导入模块

#导入模块并检查它是否成功:import RPi.GPIO as GPIO try:import RPi.GPIO as GPIO except RuntimeError :print("导入RPi.GPIO时出错,可能是权限问题")

引脚简介

引脚编号

RPi.GPIO中使用的IO引脚编号有两种方法。

BOARD编号系统。如下图中物理接口。使用此编号系统的优点是,无论树莓派的版本如何,您的硬件将始终可以工作。您无需重新连接连接器或更改代码。BCM编号系统。不同版本的树莓派不一样可能要重新修改代码,这是一种较低级别的工作方式-指Broadcom SOC上的通道号。您必须始终使用哪个通道号到达树莓派板上哪个引脚的图表。您的脚本可能会在树莓派板的修订版之间中断。

引脚功能

如下图,功能名一栏写名了树莓派引脚的功能

主要有如下分类

电源引脚 5v、3.3v :为输出5v、3.3v电源0v /GND :即负极,或接地级 GPIO引脚 通用输入输出引脚,可编程控制高低电平 其他功能引脚 i2c --> SDA,SCLSPI —> MOSI,MISO,SCLK 等等

查询引脚编号

若忘了引脚编号,又找不到图,你可以在树莓派linux终端中输入命令查询引脚编号,如下

gpio readall

引脚图

引脚设置

指定引脚编号系统

上面提到,树莓派有多个编号系统,在编程之前需要指定一个编号系统。指定后,即使用该编号进行编程,若使用其他编号会导致错误

GPIO.setmode(GPIO.BOARD) #指定为BOARD编号# orGPIO.setmode(GPIO.BCM)#指定为BCM编号

若要检测已经使用了什么编号可使用

mode = GPIO.getmode()

mode为GPIO.BOARD,GPIO.BCM、None,其意义显而易见

配置通道

GPIO引脚是通用输入输出引脚,其是可以作为输入或输出所用

因此使用之前,你需要告诉系统,该引脚你需要作为输入还是输出

设置为输入模式

GPIO.setup(引脚,GPIO.IN)还可以设置上拉电阻(具体用处后面会介绍)GPIO.setup(引脚,GPIO.IN,pull_up_down=GPIO.PUD_UP)下拉电阻GPIO.setup(引脚,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)

设置为输出模式

GPIO.setup(引脚,GPIO.OUT)设置为输出并初始为为HIGH或LOWGPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)可以同时 设置多个引脚chan_list = [ 11 ,12 ]#你可以用元组代替,即:#chan_list =(11,12)GPIO.setup(chan_list, GPIO.OUT)

注意引脚的编号为你上面指定的编号系统 ❗️❗️❗️

释放引脚

程序结束不释放引脚是一个很危险的行为❗️❗️❗️❗️❗️❗️

假如执行程序时 你设置引脚输出为高电平,而程序结束时你未释放引脚它将保持这一状态,一旦意外接触到该引脚与GND将会短路,烧毁你的树莓派

释放引脚:

GPIO.cleanup()

注意,同时GPIO.cleanup()也会清除正在使用的引脚编号系统。

输出

根据上文,进行输出操作前,应有

import RPi.GPIO as GPIO try:import RPi.GPIO as GPIO except RuntimeError :print("导入RPi.GPIO时出错,可能是权限问题")GPIO.setmode(GPIO.BCM)#指定为BCM编号GPIO.setup(17,GPIO.OUT)

设置 GPIO 针脚的输出状态:

GPIO.output(channel, state) state可以是0 / GPIO.LOW / False --- 低电平或者 1 / GPIO.HIGH / True --- 高电平

输出切换,高变低,低变高

GPIO.output(channel, not GPIO.input(channel))

pwm

脉宽调制(PWM)是指用微处理器的数字输出来对模拟电路进行控制,是一种对模拟信号电平进行数字编码的方法

创建一个 PWM 实例:p = GPIO.PWM(channel, frequency)启用 PWM:p.start(dc) # dc 代表占空比(范围:0.0 <= dc >= 100.0)更改频率:p.ChangeFrequency(freq) # freq 为设置的新频率,单位为 Hz更改占空比:p.ChangeDutyCycle(dc) # 范围:0.0 <= dc >= 100.0停止 PWM:p.stop()

示例

import timeimport RPi.GPIO as GPIOGPIO.setmode(GPIO.BOARD)GPIO.setup(12, GPIO.OUT)p = GPIO.PWM(12, 50) # 通道为 12 频率为 50Hzp.start(0)try:while 1:for dc in range(0, 101, 5):p.ChangeDutyCycle(dc)time.sleep(0.1)for dc in range(100, -1, -5):p.ChangeDutyCycle(dc)time.sleep(0.1)except KeyboardInterrupt:passp.stop()GPIO.cleanup()

输入

输入要比输出复杂一些

上拉/下拉电阻

如果输入引脚没有接其他器件(或者开关关闭),那么这个引脚将处于浮动的状态,即可能高电平可能低电平,或者在两者之间切换。这时候读取引脚的值没有意义。所以我们需要上拉/下拉电阻,使引脚状态确定

物理方法

将一个 10K 的电阻连接在输入通道与 3.3V(上拉)

或 输入通道与0V之间(下拉)程序方法

上拉电阻 GPIO.setup(引脚,GPIO.IN,pull_up_down=GPIO.PUD_UP)下拉电阻GPIO.setup(引脚,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)

轮询输入

这是最简易的一种方式,在某个时间点检查输入值。这即是所谓的“轮询 ”,而且如果您的程序在错误的时间里进行了读取,可能会错过某个输入值。在循环中运用轮询,有可能使处理器资源紧张。

示例

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 毫秒,供其处理其它事物

中断和边检检测

用这种方法输入不会因为cpu在忙其他事而错过输入,且占用 CPU 资源很少

边缘就是是从 HIGH 到 LOW 的过度(下降临界值falling edge)或从 LOW 到 HIGH 的过度(上升临界值rising edge)

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

wait_for_edge(channel, state) 函数

用于在检测到边缘之前阻止程序的运行。

上面的示例中,等待按钮被按下的语句可以改写为:

GPIO.wait_for_edge(channel, GPIO.RISING)

如果您只想等待一段时间,则可以使用timeout参数:

#上升沿等待最多5秒(超时以毫秒为单位)pin= GPIO.wait_for_edge(channel, GPIO_RISING, timeout=5000)if pin is None:print('Timeout occurred')else:print('Edge detected on pin', pin)

event_detected(channel, state) 函数

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

GPIO.add_event_detect(channel, GPIO.RISING) # 在通道上添加上升临界值检测do_something()if GPIO.event_detected(channel):print('Button pressed')

state可以为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)

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

开关防抖

每次按钮按下时,回调操作被调用不止一次。这种现象被称作“开关抖动 ”。这里有两种方法解决开关抖动问题:

物理方法 将一个 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)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。