一、安装下载GPIO
sudo apt-get install python3-rpi.gpio
一般都会提示已经为最新版本了
二、在树莓派上实现这段代码
这里条件比较简陋,没有外设显示,直接打印引脚状态进行查看。
注意:在使用某个GPIO时需要先GPIO.clearup()
一下,否则运行后可能会显示该引脚已被使用。
import RPi.GPIO as GPIO #引入函数库
import time
pin = 10 #选择10号引脚
GPIO.setmode(GPIO.BOARD) #设置引脚编号规则
GPIO.setup(pin,GPIO.OUT) #将10号引脚设置成输出模式
//开始控制该引脚
GPIO.output(pin, 1) #将引脚的状态设置为高电平
time.sleep(1) #程序休眠1秒钟
print(GPIO.input(pin)) #读取并打印该引脚电平状态
GPIO.output(pin, 0) #将引脚状态设置为低电平,此时LED灭了
time.sleep(1) #程序休眠1秒钟
print(GPIO.input(pin)) #读取并打印该引脚电平状态
GPIO.cleanup() #程序的最后别忘记清除所有资源
树莓派脚本程序运行结果如下:
三、树莓引脚图
图片来源于https://shumeipai.nxez.com/raspberry-pi-pins-version-40
四、树莓派GPIO基本应用
参考链接1:https://sourceforge.net/p/raspberry-gpio-python/wiki/BasicUsage/
参考链接2:https://shumeipai.nxez.com/2016/09/28/rpi-gpio-module-basics.html
参考链接3:https://www.jianshu.com/p/f31b90cc756f
1. 导入模块
import RPi.GPIO as GPIO
检查模块是否导入成功:
try:
import RPi.GPIO as GPIO
except RuntimeError:
print("Error importing RPi.GPIO! This is probably because you need superuser privileges. You can achieve this by using 'sudo' to run your script")
- 引脚编号
RPi.GPIO中的Raspberry Pi上的IO引脚编号有两种方法。
- 第一种是使用BOARD编号系统。这是指Raspberry Pi板的P1接头上的引脚号。使用此编号系统的优点是,无论RPi的主板版本如何,您的硬件将始终可以工作。您无需重新连接连接器或更改代码。(一般推荐)
- 第二个编号系统是BCM编号。这是一种较低级别的工作方式-指Broadcom SOC上的通道号。您必须始终使用哪个通道号转到RPi板上哪个引脚的图表。您的脚本可能会在Raspberry Pi板的修订版之间中断。
设置引脚编号规则:
GPIO.setmode(GPIO.BOARD)
# or
GPIO.setmode(GPIO.BCM)
【警告事项】
Raspberry Pi的GPIO上可能有多个脚本/电路。结果,如果RPi.GPIO检测到引脚已配置为默认值(输入)以外的其他值,则在尝试配置脚本时会收到警告。要禁用这些警告:
GPIO.setwarnings(False)
3. 引脚设置
- 设置一个引脚
对所需要使用的引脚设置为输入还是输出:
# hannel为引脚编号
GPIO.setup(channel, GPIO.IN) #设置引脚为输入
GPIO.setup(channel, GPIO.OUT) #设置引脚为输出
设置引脚的输入或者输出以及对引脚状态进行初始化:
#设置引脚为输出,且初始电平为高
GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH)
- 一次设置多个引脚
#也可以用元组形式:chan_list = (11,12)
chan_list = [11,12]
GPIO.setup(chan_list, GPIO.OUT) #同时设置引脚11、12为输出模式
4. 引脚状态的读取
GPIO.input(channel)
5. 设置引脚输出状态
- 设置一个引脚的输出状态
GPIO.output(channel, state)
state可以是0 / GPIO.LOW / False(设为低电平)或1 / GPIO.HIGH / True(设为高电平)
- 同时设置多个引脚输出状态
chan_list = [11,12] # 也可以用元组形式
GPIO.output(chan_list, GPIO.LOW) # 设置引脚11、12全为输出状态低电平
GPIO.output(chan_list, (GPIO.HIGH, GPIO.LOW)) # 引脚11输出为高电平、引脚12输出状态为低电平
6. 引脚释放
为避免破坏树莓派以及后续的方便使用,在脚本末尾需要对引脚设置进行清理:
GPIO.cleanup()
清理多个:
GPIO.cleanup(channel)
GPIO.cleanup( (channel1, channel2) )
GPIO.cleanup( [channel1, channel2] )
7. 引脚状态实时监控
有两种办法:
- 轮询:每隔一段时间检查输入的信号值,很可能会丢失输入信号。
- 中断(边缘检测):这里的边缘是指信号从高到低的变换(下降沿)或从低到高的变换(上升沿)
轮询方式
if GPIO.input(channel):
print('Input was HIGH')
else:
print('Input was LOW')
通过轮询方式等待一个按钮被按下:
while GPIO.input(channel) == GPIO.LOW:
time.sleep(0.01) # wait 10 ms to give CPU chance to do other things
中断方式
先介绍两个函数:
wait_for_edge()
wait_for_edge()被用于阻止程序的继续执行,直到检测到一个边沿。也就是说,上文中等待按钮按下的实例可以改写为:
# 等待最多5秒钟的上升沿(超时以毫秒为单位)
channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout=5000)
if channel is None:
print('Timeout occurred')
else:
print('Edge detected on channel', channel)
add_event_detect()
该函数对一个引脚进行监听,一旦引脚输入状态发生了改变,调用event_detected()函数会返回true,如下代码:
GPIO.add_event_detect(channel, GPIO.RISING) # 增加上升的信道的边缘检测
do_something()
# 下面的代码放在一个线程循环执行。
if GPIO.event_detected(channel):
print('Button pressed')
上面的代码需要自己新建一个线程去循环检测event_detected()的值,还算是比较麻烦的。
线程回调
RPi.GPIO运行第二个用于回调函数的线程。这意味着回调函数可以与主程序同时运行,以立即响应边缘。例如:
def my_callback(channel):
print('This is a edge event callback function!')
print('Edge detected on channel %s'%channel)
print('This is run in a different thread to your main program')
GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback) # 增加一个通道上上升沿检测
...the rest of your program...
需要多个回调函数:
def my_callback_one(channel):
print('Callback one')
def my_callback_two(channel):
print('Callback two')
GPIO.add_event_detect(channel, GPIO.RISING)
GPIO.add_event_callback(channel, my_callback_one)
GPIO.add_event_callback(channel, my_callback_two)
在这种情况下,回调函数是按顺序而不是并发运行的。这是因为只有一个线程用于回调,每个线程都按照其定义的顺序运行。
删除事件检测
如果由于某种原因,不再希望检测边缘事件,则可以将其停止:
GPIO.remove_event_detect(channel)
7. 在RPi.GPIO中使用PWM
参考链接:https://sourceforge.net/p/raspberry-gpio-python/wiki/PWM/