树莓派 GPIO按钮开关 原理与实现

本以为GPIO接一个开关是很简单的事情,但实际上需要学会很多前置的知识才能搞得下去,所以我把整个事情的原理和实现流程全部记录下来,希望帮助到像我一样的电路小白。

硬件

  • 树莓派 * 1(我的是1B型号)
  • 杜邦线(母对母) * 2
  • 按钮 * 1

给大家看一下我的按钮,是那种4个脚的:

开关有4个脚,红框内的2根脚是互相联通,电会从这俩脚里流过,我们任意选一组用就可以了!

大家买到的按钮的4个脚的联通关系可能与图中不同,自己研究一下或者问一下商家到底哪两个脚是联通的就行。

按钮的作用就是按下去电路就联通了,否则就断开了,没什么特别的。

电路

GPIO有个input模式,如果输入电流到GPIO口,那么编程读取GPIO返回HIGH,如果没有输入电流则返回LOW,从而我们可以检测到按钮的状态变化。

GPIO输入安全电压应该是3.3V,因此我们会使用树莓派的3.3V供电口而不是5v(大家有兴趣可以试试5.5v会发生什么)。

错误的电路

所以很直接的,我就想把电路连成这样:

从树莓派引出3.3V的电压,经过开关,接到某个出于输入状态的GPIO针脚。

开关闭合的时候,电流流入GPIO,可以读到HIGH。

开关断开的时候,电路不通,可以读到LOW。

然而问题就在红色字体的情况:开关断开时,GPIO引脚是悬空的,受周遭环境干扰可能产生微弱电流,导致GPIO输入时高时低。

用程序检测GPIO的输入变化,会发现按钮不停的在断开与闭合:

测试代码后面我们再看,这里主要是为了告诉大家这种悬空浮动问题是客观存在的,必须解决。

此时,实际接线如下:

左侧3.3V的电压 ,流经按钮 ,输入到GPIO 18口。

按钮没有按下的情况,出现floating问题,因此这个电路是错误的,我们接下来看一下如何修正。

下拉电阻

我们现在只要解决开关断开情况下的输入浮动问题即可,如何解决呢?

我们把电路改成这样:

电路的变更:在开关右侧,拉了一根线出来,接了一个电阻,然后接到GND地线。

在开关断开的情况下,GPIO和GND相连,可以把GND相当于一个0v的电源,整个电路没有电流输入,所以GPIO稳定为LOW。

在开关闭合的情况下,电流经过开关后出现分叉位置(相当于水流要分叉了),因为下拉电阻存在导致电流(理解成流动的电子)并没有全部涌入,所以剩余电流得以进入GPIO,所以是HIGH。

红圈内的电路其实树莓派都封装在GPIO针脚内部,我们可以视作黑盒使用,只需要编程时控制切换到下拉模式即可。

此时,我们要做的硬件工作如下:

  • 从3.3v连到开关
  • 从开关连到gpio引脚

程序需要开启GPIO口的下拉模式,开关断开时是LOW、闭合时是HIGH,所以我们监听输入的RISING(升高)即可获知按钮按下的事件:

上拉电阻

与下拉电阻类似,同样可以解决浮动问题。

电路图如下:

同样的,红圈都是GPIO内部的电路,可以通过编程控制切换到上拉模式。

我们要做的就是从树莓派的GND接到开关,开关接到GPIO针脚即可。

在开关断开情况下,电流经过上拉电阻,虽然电流小一点但也流向了GPIO,所以是HIGH。

在开关闭合情况下,电流经过上拉电阻后遇到分叉,接着电流(理解成流动的电子)会全部走向GND,可以理解成一个并联电路的短路分支。

代码需要设置GPIO为上拉模式:

我们刚才说了,断开时为HIGH,闭合时为LOW,所以要监听的是从HIGH变为LOW的事件,所以是检测FALLING变化。

我们一律加了bouncetime = 200,这是为了防抖用的,因为如果不加的话按下1次开关会发现事件触发了N次,可能是因为电路多次连续抖动的原因导致,所以忽略在200毫秒内的重复变化。

 

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~