第3章 树莓派的GPIO 通俗地说,GPIO(GeneralPurposeI/OPorts,通用输入输出端口)就是一些引脚,可以 通过它们输出高低电平或者读入引脚的状态(高电平或低电平)。树莓派的GPIO 如图3. 1 所示。 图3. 1 GPIO 的引脚 GPIO 是一个比较重要的概念。用户可以通过GPIO 与硬件进行数据交互(如 UART )、控制硬件工作(如LED 、蜂鸣器等)、读取硬件的工作状态信号(如中断信号)等。 利用它们可以与外界交互,对树莓派进行各种各样的扩展,作为可编程开关控制其他事务, 以及接收外界的信息。 GPIO 的使用非常广泛。掌握了GPIO,就具备了操作硬件的能力。数字艺术家可以 使用它们创建交互式显示,机器人建造者可使用它们提升自己的作品。 在开始构建电路之前,首先需要知道如何连接树莓派的GPIO 。 树莓派智能项目设计:RaspberyPi4ModelB上的Python实现 66 .................................................. .............. 1.内转外接头 使用内接转外接头是最简单的选择。作为转接头,内接头可以连接GPIO引脚,外接 头可以插入面包板,这是访问GPIO的最简便方法。 2.GPIO 扩展板(T型扩展板) 2所示。 可以使用40P排线将树莓派的GPIO引脚通过GPIO扩展板连接起来,如图3. 注意,连接的时候,必须将40P排线上有“小三角”符号的一端(1号脚)对准树莓派的1号 脚(图3.则会导致树莓派被烧坏。 2中被排线遮住的下方引脚)。如果插反, 图3. 2 GPIO 扩展板与树莓派通过40P排线连接 一旦在GPIO上连接了其他硬件,就有可能直接给CPU供电,也就有可能将其损坏。 绝对不能将3.是需要特别注意。 3V电压连接到GPIO上。这一点非常重要, 与使用内转外接头相比,GPIO虽然没有提供任何新特性,但是看起来更整洁,也不容 易混淆引脚。 3.无焊面包板 无论选择上述哪种方式,都需要使用面包板。通过它可以快速地将各个组件的电路连 接在一起,完成之后可以轻松拆除。 面包板有不同的尺寸,但基本排列十分类似。在典型面包板的长边上,有两条平行接口,用 来连接电源的正负极。它们中间是两排插孔,插孔中间留有间隙。与长边垂直的每5个孔板常 用一条金属条连接。面包板中央的一条凹槽,是为需要集成电路、芯片的试验而设计的。 可以将元器件直接插入孔中,使用公对公连接线或者小段单芯线缆将各个元件连接起来。 通过树莓派的I/O口可以外接很多外设,如伺服电动机、红外发送接收模块、继电器、 步进电动机、各类兼容传感器、屏幕等,通过这些外设可以进行很多有趣的设计。 4.RP.I iGPO 对于Pyn用户,可以使用RPiGPIO提供的API对GPIO进行编程,GPIO是 一个控制树莓派GPIO通道的模块,它提供了一个类来控制树莓派上的GPIO 。通常在文 件开头使用iGPIOasGPIO导入。 tho.RPi. mportRPi. 大多数树莓派的镜像默认安装了RPi.可以直接使用它。如果没有,则可以通过 GPIO, 第3章 树莓派的GPIO 67 ............ .............. 执行命令sudoapt-getinstalpython-dev进行安装。 3. 1 LED 树莓派GPIO控制输出的入门案例都是从控制LED(LightEmitingDiode,发光二极 管)开始。 3.1.1 七彩LED 图3.3所示的七彩LED上电后,会自动闪烁内置的颜色,常用于制作迷人的灯光效 果,原理如图3. 4所示。 图3.七彩LED 图3.七彩LED的原理 34 树莓派的功能名、BCM编码、1所示,T 物理引脚与七彩LED引脚之间的关系如表3. 型转接板与RGBLED之间的连线如图3.6所示, 连接VCC,中间引脚连接GND 。 5所示。实物如图3.七彩LED的S引脚 表3.树莓派与七彩LED 引脚之间的关系 1 功能名BCM编码(T型转接板) 物理引脚(BOARD编码) 七彩LED模块的引脚 5V 5V 2、4 VCC GND GND GND GND 图3.七彩LED 的连线图3.七彩LED 的实物 56 树莓派智能项目设计:RaspberyPi4ModelB上的Python实现 68 .................................................. .............. 3.1.2 双色LED 双色LED能够发出两种不同的颜色,经常用作电视机、数字照相机和遥控器的指示灯, 实验用的双色LED如图3.7所示(“-”引脚对应GND,中间引脚对应R,S引脚对应G)。 本实验将引脚R和G连接到树莓派的GPIO,对树莓派进行编程,将LED的颜色从红 色变为绿色,然后使用PWM(PulseWidthModulation,脉宽调制)混合成其他颜色。原理 如图3. 8所示。 图3.双色LED 图3.双色LED 的原理 78 1.电路连接 树莓派的功能名、BCM编码、 9所示, 10所示。注意,2所示,T 物理引脚与双色LED引脚之间的关系如表3. 型转接板与双色LED之间的连线如图3.实物如图3.不同的实物引 脚顺序有所不同,图3.其“ 引脚对应GND,中间引脚对应R,S引脚对 应G。 7所示的实物, -” 表3.树莓派与双色LED 引脚之间的关系 2 功能名BCM编码(T型转接板) 物理引脚(BOARD编码) 双色LED模块的引脚 GPIO.0 17 11 R GPIO.1 18 12 G GND GND GND GND 图3.双色LED 的连线图3.双色LED 的实物 9 10 第3 章 树莓派的GPIO ............ ..6 9............ 2.软件编写 在pi目录下新建文件夹book,在book目录下新建文件ch3.1.2.py,代码如下: #!/usr/bin/env python import RPi.GPIO as GPIO import time colors = [0xFF0000, 0x00FF00, 0x0FF000, 0xF00F00] pins = {'pin_R':11, 'pin_G':12} GPIO.setmode(GPIO.BOARD) for i in pins: GPIO.setup(pins[i], GPIO.OUT) GPIO.output(pins[i], GPIO.HIGH) p_R = GPIO.PWM(pins['pin_R'], 2000) p_G = GPIO.PWM(pins['pin_G'], 2000) p_R.start(0) p_G.start(0) def map(x, in_min, in_max, out_min, out_max): return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min def setColor(col): R_val = (col & 0xFF0000) >> 16 G_val = (col & 0x00FF00) >> 8 R_val = map(R_val, 0, 255, 0, 100) G_val = map(G_val, 0, 255, 0, 100) p_R.ChangeDutyCycle(R_val) p_G.ChangeDutyCycle(G_val) def loop(): while True: for col in colors: setColor(col) time.sleep(0.5) def destroy(): p_R.stop() p_G.stop() .......... ..70.. 树..莓..派..智..能..项..目..设..计..:R..as..pb..err..yP..i4..M..od..el..B..上..的..Pyt..ho..n实..现.. for i in pins: GPIO.output(pins[i], GPIO.HIGH) GPIO.cleanup() if __name__ == "__main__": try: loop() except KeyboardInterrupt: destroy() (1)语句if__name__ =="__main__":的含义。对于很多编程语言来说,程序都必 须要有一个入口,比如C、C++,以及完全面向对象的编程语言Java、C# 等。 C和C++都需要有一个main()函数来作为程序的入口,也就是程序的运行会从main() 函数开始。同样,Java和C#必须要有一个包含main()方法的主类作为程序入口。而 Python则不同,它属于脚本语言,不像编译型语言那样,先将程序编译成二进制再运行,而 是动态的逐行解释运行。也就是从脚本第一行开始运行,没有统一的入口。 图3.11 const.py程序及运行结果 一个Python源码文件除了可以被直接运行外,还 可以作为模块(也就是库)被导入。不管是导入还是直 接运行,最顶层的代码都会被运行(Python用缩进来区 分代码层次)。而实际上在导入的时候,有一部分代码 我们是不希望被运行的。 假设有一个const.py 文件,代码及运行结果如图 3.11所示。 在这个文件里定义了PI为3.14,然后又写了一个 main()函数来输出定义的PI,最后运行main()函数就 相当于对定义做一遍人工检查,看看值设置得对不对。 假设又有一个area.py 文件,用于计算圆的面积, 该文件里边需要用到const.py 文件中的PI,那么从 const.py中把PI导入到area.py中,代码及运行结果如图3.12所示。 可以看到,const中的main()函数也被运行了,实际上是不希望它被运行,提供main() 也只是为了对常量定义进行测试。这时,if__name__ == '__main__' 就派上了用场。修 改const.py代码,再运行area.py,修改的代码以及输出结果如图3.13所示,这才是想要的 效果。 if__name__ == '__main__'就相当于是Python模拟的程序入口。Python本身并没 有规定这么写,这只是一种编码习惯。由于模块之间相互引用,不同模块可能都有这样的 定义,而入口程序只能有一个。到底哪个入口程序被选中,这取决于__name__ 的值。 结论:if__name__ == '__main__' 的意思就是,当模块被直接运行时,以下代码块将 被运行,当模块是被导入时,代码块不被运行。 第3 章 树莓派的GPIO ............ ..7 1............ 图3.12 area.py程序及运行结果 图3.13 if__name__ == '__main__'的作用 (2)异常处理。异常即是一个事件,该事件会在程序执行过程中发生,影响程序的正 常执行。一般情况下,在Python无法正常处理程序时就会发生一个异常。当Python发生 .......... ..72.. 树..莓..派..智..能..项..目..设..计..:R..as..pb..err..yP..i4..M..od..el..B..上..的..Pyt..ho..n实..现.. 异常时需要捕获处理它,否则程序将会终止执行。 捕捉异常可以使用try…except语句,try…except语句用来检测try语句块中的错误, 从而让except语句捕获异常信息并处理。 以下为简单的try…except…else的语法。 try: <语句> #运行别的代码 except <名字>: <语句> #如果在try 部分引发了'name'异常 except <名字>,<数据>: <语句> #如果引发了'name'异常,获得附加的数据 else: <语句> #如果没有异常发生 在如图3.14所示的程序中,发生异常时执行函数destroy(),关闭所有的LED。其中, KeyboardInterrupt表示用户中断执行(通常是按Ctrl+C键)。 图3.14 异常处理 GPIO.cleanup()的作用是释放脚本中使用的GPIO 引脚。一般来说,程序到达最后都 需要释放资源,这个好习惯可以避免损坏树莓派。 正常情况下执行loop()函数,循环执行setColor(col)函数和time.sleep(0.5)方法(休 息0.5s)。 (3)#! /usr/bin/envpython的作用。这条语句的作用是为了防止操作系统用户没 有将Python安装在默认的/usr/bin路径里。当系统看到这一行的时候,首先会到env设 置里查找Python的安装路径,再调用对应路径下的解释器程序完成操作。 (4)设置模式GPIO.setmode。GPIO.setmode(mode)的mode参数有两个值,GPIO. BOARD和GPIO.BCM(注意,全是大写)。前者告诉程序按物理位置找GPIO(或者称 第3 章 树莓派的GPIO ............ ..7 3............ channel),后者按GPIO 端口编号。两种模式各有各的好处,前者方便查找,后者方便程序 在不同的树莓派版本上运行。 对照图3.1和表3.2,树莓派GPIO 的0端口(GPIO.0),对应BCM 编码为17,对应物 理引脚(BOARD编码)为11;树莓派GPIO 的1端口(GPIO.1),对应BCM 编码为18,对应 物理引脚(BOARD编码)为12。 由于程序中使用了GPIO.BOARD,所以GPIO.setmode(GPIO.BOARD)上面一行的 代码,pins= {'pin_R':11,'pin_G':12},代表的是物理引脚11 和12,即GPIO.0 和 GPIO.1。 (5)设置GPIO 的输入和输出GPIO.setup。GPIO.setup(channel,mode)的参数 channel就是要用的GPIO,参数mode分为输入GPIO.IN 和输出GPIO.OUT。 GPIO.output(channel,GPIO.HIGH)表示输出高电平,就是输出信号1;GPIO.output (channel,GPIO.LOW)表示输出低电平,就是输出信号0。 (6)设置调制脉宽,输出模拟信号GPIO.PWM。树莓派本身既不能接收模拟信号,也 不能输出模拟信号,要么输出1,要么输出0。不过可以通过改变数字信号的输出占空比 (DutyCycle,就是一个周期内GPIO 的打开时间占总时间的比例),使输出效果近似模拟 信号。占 空比是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,如 图3.15所示。 图3.15 占空比示意图 对于LED的光度调节,有一个传统办法,就是串联一个可调电阻,改变电阻,灯的亮度 就会改变。 .......... ..74.. 树..莓..派..智..能..项..目..设..计..:R..as..pb..err..yP..i4..M..od..el..B..上..的..Pyt..ho..n实..现.. 还有一个办法,就是脉宽调制。该方法不用串联电阻,而是串联一个开关。假设在1s 内,有0.5s的时间开关是打开的,0.5s关闭,那么灯就亮0.5s,灭0.5s。这样持续下去,灯就 会闪烁。如果把频率调高一点,例如1ms(即0.5ms开,0.5ms灭),那么灯的闪烁频率就很 高。当闪烁频率超过一定值时,人眼就会感觉不到,所以这时看不到灯的闪烁,只看到灯的 亮度只有原来的一半。同理,如果1ms内(即0.1ms开,0.9ms灭),那么灯的亮度就只有原 来的1/10。这就是PWM 的基本原理。 在GPIO.PWM(channel,frequency)中,参数channel是GPIO,参数frequency是频 率。代码GPIO.PWM(pins['pin_R'],2000)和GPIO.PWM(pins['pin_G'],2000),就是给 GPIO.0和GPIO.1(物理引脚11和12)设置2kHz的频率。 在函数setColor(col)中,ChangeDutyCycle(dc)的作用就是改变占空比(0.0< = dc< =100.0),确定“开启”时间与常规时间的比例。 (7)setColor(col)函数。在loop()中,执行循环forcolincolors。对于程序开始时的 代码colors= [0xFF0000,0x00FF00,0x0FF000,0xF00F00]中的每个颜色,在setColor (col)函数中执行(col&0xFF0000)> >16和(col&0x00FF00)> >8。 RGB颜色是由红(Red)、绿(Green)、蓝(Blue)三原色组成的,所以可以使用这3个颜 色的组合来代表一种具体的颜色,其中R、G、B的每个数值都为0~255的整数。 在表达颜色的时候,既可以使用3个十进制数字来表达,也可以使用0X00RRGGBB 格式的十六进制来表达。下面是常见颜色的表达形式:红色(255,0,0)或0x00FF0000、绿 色(0,255,0)或0x0000FF00、蓝色(255,255,255)或0x00FFFFFF。 语句(col&0x00ff0000)> >16的含义是,首先将颜色值与十六进制表示的00ff0000 进行“与”运算,运算结果除了表示红色的数字值之外,GGBB部分颜色都为0。再将结果向 右移位16位,得到的就是红色的值。所以这句代码主要用来从一个颜色中抽取其组成色 (红色)的值。 同样也可以通过代码(color & 0x0000ff00)> >8 得到绿色的值,代码(col & 0x000000ff)> >0得到蓝色的值。 由于双色LED只有两种颜色(红和绿),所以程序在得到R_val和G_val的值后,通过 map()函数得到0~100的占空比。最后执行ChangeDutyCycle,实现LED 从红色到绿 色,再到混合色的效果。 图3.16 RGBLED 3.1.3 RGB LED RGBLED可以发出各种颜色的光,红色、绿色和蓝色的3 个LED被封装在透明或半透明的塑料外壳中,并带有4个引 脚,如图3.16所示。 红色、绿色和蓝色三原色可以按照亮度混合并组合各种 颜色,可以通过控制电路使RGBLED 发出彩色光。原理如 图3.17所示。 第3 章 树莓派的GPIO ............ ..7 5............ 图3.17 RGBLED 的原理 1.电路连接 树莓派的功能名、BCM 编码、物理引脚与RGBLED引脚之间的关系如表3.3所示,T 型转接板与RGBLED模块之间的连线如图3.18所示,实物如图3.19所示。 表3.3 树莓派与RGBLED 引脚之间的关系 功 能 名BCM 编码(T型转接板) 物理引脚(BOARD编码) RGBLED模块的引脚 GPIO.0 17 11 R GPIO.1 18 12 G GPIO.2 27 13 B GND GND GND GND 图3.18 RGBLED 的连线 图3.19 RGBLED 的实物 2.软件编写 在book目录下新建文件ch3.1.3.py,代码如下: #!/usr/bin/env python import RPi.GPIO as GPIO import time .......... ..76.. 树..莓..派..智..能..项..目..设..计..:R..as..pb..err..yP..i4..M..od..el..B..上..的..Pyt..ho..n实..现.. colors = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF] R = 11 G = 12 B = 13 def setup(Rpin, Gpin, Bpin): global pins global p_R, p_G, p_B pins = {'pin_R': Rpin, 'pin_G': Gpin, 'pin_B': Bpin} GPIO.setmode(GPIO.BOARD) for i in pins: GPIO.setup(pins[i], GPIO.OUT) GPIO.output(pins[i], GPIO.HIGH) p_R = GPIO.PWM(pins['pin_R'], 2000) p_G = GPIO.PWM(pins['pin_G'], 1999) p_B = GPIO.PWM(pins['pin_B'], 5000) p_R.start(100) p_G.start(100) p_B.start(100) def map(x, in_min, in_max, out_min, out_max): return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min def off(): for i in pins: GPIO.output(pins[i], GPIO.HIGH) def setColor(col): R_val = (col & 0xff0000) >> 16 G_val = (col & 0x00ff00) >> 8 B_val = (col & 0x0000ff) >> 0 R_val = map(R_val, 0, 255, 0, 100) G_val = map(G_val, 0, 255, 0, 100) B_val = map(B_val, 0, 255, 0, 100) p_R.ChangeDutyCycle(100-R_val) p_G.ChangeDutyCycle(100-G_val) p_B.ChangeDutyCycle(100-B_val) def loop(): while True: 第3 章 树莓派的GPIO ............ ..7 7............ for col in colors: setColor(col) time.sleep(1) def destroy(): p_R.stop() p_G.stop() p_B.stop() off() GPIO.cleanup() if __name__ == "__main__": try: setup(R, G, B) loop() except KeyboardInterrupt: destroy() 代码与上一节大同小异。运行程序,可以看到RGBLED 灯亮起,依次显示不同的 颜色。 3.2 继 电 器 如图3.20所示,继电器是一种电控制器件,用于在输入量的变化达到规定要求时,使 电气输出电路的被控量发生预定的阶跃变化。它通常应用于自动化控制电路中控制器与 受控设备之间的隔离。 图3.20 继电器 继电器的基本原理是利用了电磁效应控制机械触点达到通或断的目的。当继电器通 电时,电流开始流经控制线圈,电磁铁开始通电,衔铁被吸到线圈上,将触动点拉动,从而与 常开触点连接,使带负载的电路通电;当继电器断电时,在弹簧的作用下,动触头被拉到常 闭触点,使带负载的电路断电。这样,继电器的接通和断开就可以控制负载电路的状态。 当需要用小信号控制大电流或电压时,继电器非常有用,在电路中起着自动调节、安全保 护、转换电路的作用。 继电器的原理如图3.21所示。 树莓派智能项目设计:RaspberyPi4ModelB上的Python实现 78 .................................................. .............. 图3.继电器的原理 21 1.电路连接 树莓派的功能名、BCM编码、4所示, 物理引脚与继电器引脚之间的关系如表3.继电 器模块与双色LED引脚之间的关系如表3. 5所示。 表3.树莓派与继电器引脚之间的关系 4 功能名BCM编码(T型转接板) 物理引脚(BOARD编码) 继电器模块的引脚 GPIO.0 17 11 SIG 5V 5V 2 VCC 5V 5V 4 COM GND GND GND GND 表3.继电器与双色LED 引脚之间的关系 5 继电器模块的触点BCM编码(T型转接板) 双色LED模块的引脚 常开R GND GND 常闭G T型板、继电器、22所示, 23所示。 双色LED的连线如图3.实物如图3. 第3 章 树莓派的GPIO ............ ..7 9............ 图3.22 T型板、继电器、双色 LED 的连线 图3.23 T型板、继电器、双色 LED 的实物 2.软件编写 在book目录下新建文件ch3.2.py,代码如下: #!/usr/bin/env python import RPi.GPIO as GPIO import time RelayPin = 11 def setup(): GPIO.setmode(GPIO.BOARD) GPIO.setup(RelayPin, GPIO.OUT) GPIO.output(RelayPin, GPIO.HIGH) def loop(): while True: print ('...relayd on') GPIO.output(RelayPin, GPIO.LOW) time.sleep(0.5) print ('relay off...') GPIO.output(RelayPin, GPIO.HIGH) time.sleep(0.5) def destroy(): GPIO.output(RelayPin, GPIO.HIGH) GPIO.cleanup() .......... ..80.. 树..莓..派..智..能..项..目..设..计..:R..as..pb..err..yP..i4..M..od..el..B..上..的..Pyt..ho..n实..现.. if __name__ == '__main__': setup() try: loop() except KeyboardInterrupt: destroy() 运行程序,可以听到常闭触点打开、常开触点闭合时发出的嘀嗒声,同时看到LED 双 色灯的变化,以及如图3.24所示的Shell输出内容(直到按Ctrl+C键结束运行)。 图3.24 Shell显示效果 3.3 激光发射模块 激光是20世纪60年代的新光源,具有方向性好、亮度高、单色性好和高能量密度等特 点。以激光器为基础的激光工业在全球发展迅猛,现在已广泛应用于工业生产、通信、信息 处理、医疗卫生、军事、文化教育以及科研等方面。 激光发射模块如图3.25所示。它是一种可以发射激光的模块,原理如图3.26所示。 图3.25 激光发射模块 图3.26 激光发射模块的原理 1.电路连接 树莓派的功能名、BCM 编码、物理引脚与激光发射引脚之间的关系如表3.6所示。 第3 章 树莓派的GPIO ............ ..8 1............ 表3.6 树莓派与激光发射模块引脚之间的关系 功 能 名BCM 编码(T型转接板) 物理引脚(BOARD编码) 激光发射模块的引脚 GPIO.0 17 11 SIG 5V 5V VCC 激光发射模块的连线如图3.27所示,实物如图3.28所示,中间引脚不用连接。 图3.27 激光发射模块的连线图3.28 激光发射模块的实物 2.软件编写 在book目录下新建文件ch3.3.py,代码如下: #!/usr/bin/env python import RPi.GPIO as GPIO import time LedPin = 11 def setup(): GPIO.setmode(GPIO.BOARD) GPIO.setup(LedPin, GPIO.OUT) GPIO.output(LedPin, GPIO.HIGH) def loop(): while True: print ('...Laser on') .......... ..82.. 树..莓..派..智..能..项..目..设..计..:R..as..pb..err..yP..i4..M..od..el..B..上..的..Pyt..ho..n实..现.. GPIO.output(LedPin, GPIO.LOW) time.sleep(0.5) print ('Laser off...') GPIO.output(LedPin, GPIO.HIGH) time.sleep(0.5) def destroy(): GPIO.output(LedPin, GPIO.HIGH) GPIO.cleanup() if __name__ == '__main__': setup() try: loop() except KeyboardInterrupt: destroy() 运行程序,可以看到激光的发射,直到按Ctrl+C键结束运行。 注意,千万不要将激光对着眼睛照射! 3.4 开 关 本节介绍轻触开关、倾斜开关、震动开关、干簧管和触摸开关的使用。 3.4.1 轻触开关 按钮模块是使用最为频繁的电子部件,内部由一对轻触拨盘组成,按下时闭合导通,松 开时自动弹开断开,如图3.29所示。 使用常开按钮作为树莓派的输入设备,按下按钮时,GPIO 将变为低电平(0V)。通过 编程检测GPIO 的状态,如果GPIO 变为低电平,则表示按按钮。原理如图3.30所示。 图3.29 轻触开关 图3.30 轻触开关的原理 1.电路连接 树莓派的功能名、BCM 编码、物理引脚与轻触开关引脚之间的关系如表3.7所示,与 双色LED引脚之间的关系如表3.8所示。 第3 章 树莓派的GPIO ............ ..8 3............ 表3.7 树莓派与轻触开关引脚之间的关系 功 能 名BCM 编码(T型转接板) 物理引脚(BOARD编码) 轻触开关模块的引脚 GPIO.0 17 11 SIG 5V 5V 5V VCC GND GND GND GND 表3.8 树莓派与双色LED 引脚之间的关系 功 能 名BCM 编码(T型转接板) 物理引脚(BOARD编码) 双色LED模块的引脚 GPIO.1 18 12 R GPIO.2 27 13 G GND GND GND GND 轻触开关的连线如图3.31所示,实物如图3.32所示。 图3.31 轻触开关的连线图3.32 轻触开关的实物 2.软件编写 在book目录下新建文件ch3.4.1.py,代码如下: #!/usr/bin/env python import RPi.GPIO as GPIO BtnPin = 11 Gpin = 12 Rpin = 13 .......... ..84.. 树..莓..派..智..能..项..目..设..计..:R..as..pb..err..yP..i4..M..od..el..B..上..的..Pyt..ho..n实..现.. def setup(): GPIO.setmode(GPIO.BOARD) GPIO.setup(Gpin, GPIO.OUT) GPIO.setup(Rpin, GPIO.OUT) GPIO.setup(BtnPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.add_event_detect(BtnPin, GPIO.BOTH, callback=detect, bouncetime=200) def Led(x): if x == 0: GPIO.output(Rpin, 1) GPIO.output(Gpin, 0) if x == 1: GPIO.output(Rpin, 0) GPIO.output(Gpin, 1) def Print(x): if x == 0: print (' ***********************') print (' * Button Pressed! *') print (' ***********************') def detect(chn): Led(GPIO.input(BtnPin)) Print(GPIO.input(BtnPin)) def loop(): while True: pass def destroy(): GPIO.output(Gpin, GPIO.HIGH) GPIO.output(Rpin, GPIO.HIGH) GPIO.cleanup() if __name__ == '__main__': setup() try: loop() except KeyboardInterrupt: destroy()