树莓派的GPIO可以控制发光二极管,这是GPIO的Output(输出)能力,它也具有input(读取)的能力,所以才能叫做I/O(输入/输出)端口。今天我们就来用GPIO的引脚来读取按钮的状态。
需要的材料
要完成本次实验,我们需要如下的元器件。
开关按钮
在我们日常生活中,开关按钮非常常见,每个电器的开关都是一个开关按钮。今天我们用的按钮如下图:
平时按钮的2个引脚是断开的,当按钮按下时,会连通2个引脚。四个引脚的按钮原理一样,只是两边的引脚是相通的,方便在电路中与其他元器件的连接。开关在电路图中的符合较多,常见的如下:
其他元器件上一节讲过,这里不再赘述。
所有器件的全家福如下:
让我们按下面的电路把元器件连接起来。
把开关的一端引脚连到GPIO的GND(接地点),另一端连接到GPIO 27引脚。最终连接好后电路实物如下
电路好了,接下来我们编写程序来读取按钮状态。
读取按钮状态的Python程序
我们先用gpiozero库来读取按钮状态,上一讲提到过这个类库对读取按钮状态做了封装,可以直接使用它的button类。在Thonny中新建一个python程序,代码如下:
from gpiozero import Button #引入Button类
button = Button(27) #按钮链接了GPIO27
button.wait_for_press() #等待按钮被按下
print("你按了按钮") #输出语句
运行这个程序,当按钮被按下时,可以看到在Thonny的输出窗口打印出来“你按了按钮”
这个程序在打印语句后就会退出,如果我们希望程序可以一直读取按钮状态,需要加入while循环。我们修改代码如下:
from gpiozero import Button #引入Button类
button = Button(27) #按钮链接了GPIO27
while True:
button.wait_for_press()
print("你按了按钮")
执行程序,然后按一下按钮,你发现了什么?是不是和我们预想的不同?是的,你的程序打印了很多的“你按了按钮”,而不是只有一个。
为什么会这样呢?
这是因为计算机的世界里事情发生的非常快,当我们按下按钮时,程序打印了“你按了按钮”后会马上回到while循环的第一句,也就是button.wait_for_press(),这仅需要几毫秒的时间,此时,我们的按钮还在被按下的状态,不需要等待被按下,所以就会马上执行下面的打印语句,然后继续下一个循环。虽然我们按了一下很快放开了按钮,但是按钮被按下的时间可能有几百毫秒,而每个循环只需要几毫秒,循环被执行了多次,我们就看到了很多的”“你按了按钮”。
那么如何实现我们按一次按钮,打印一句“你按了按钮”呢?我们可以加入一个等待语句,打印后稍等一下再进入下一个循环,此时按钮应该已经弹起了。新程序如下:
from gpiozero import Button
from time import sleep
button = Button(27)
while True:
button.wait_for_press()
print("你按了按钮")
sleep(0.3) #等待300毫秒,然后再进入下一次循环。
执行程序,我们可以看到每次按下,"你按了按钮"只会打印一次。
如果我们再按几次,每次都会打印一句"你按了按钮",而不是每次打印非常多句了。
使用RPi.GPIO库来读取按钮状态
刚才我们用gpiozero来读取按钮状态,语句容易理解,编写程序也容易,如果我们换成RPi.GPIO库应该怎么写程序呢?
这就比较复杂了,当把GPIO引脚设置为输入时,需要定义该引脚连接了上拉电阻还是下拉电阻,这2个概念对于孩子理解起来并不容易,可以简单理解为上拉电阻是引脚通过电阻连接高电位,下拉电阻是引脚通过电阻连接低电位。在我们的电路中没有接入电阻,但按原理应该算成是上拉电阻模式。最终的程序如下:
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BCM)
GPIO.setup(27,GPIO.IN,pull_up_down=GPIO.PUD_UP) #设置GPIO27为上拉电阻模式的输入
while True:
in_value = GPIO.input(27)
if in_value == False:
print("你按了按钮")
sleep(0.3)
执行这个程序,可以得到和前面用gpiozero库一样的效果,只是理解起来更难一些而已。
好了,现在我们已经知道如何通过GPIO来读取外部数据(按钮状态),也知道如何控制外部世界(发光二极管),接下来我们将用树莓派制作一个具有实用价值的东西:红绿灯。
全部0条评论
快来发表一下你的评论吧 !