本文源自:
Using the Raspberry Pi GPIO with Python
译文如下:
所以你拿到了一个装了系统的树莓派,它用起来就像你的电脑一样。很好!那么现在呢?你没有买一个仅仅是为了替代你电脑的树莓派,是吗?好吧,树莓派可以做更多的事…比你的电脑做的事情还多!
树莓派A/B型的GPIO
你有没有发现在你的树莓派的一个角上有很多小引脚?这叫“通用输入输出”引脚(或者是GPIO引脚),这些引脚可以让你的树莓派连接到外界。树莓派A型和B型有26个引脚(其中17个是GPIO引脚),而B+型和B2型有40个引脚(26个GPIO引脚),B+型和B2型兼容A型和B型。
控制这些引脚最简单的方法就是调用RPi.GPIO Python库,这个库预装了最新版的Raspbian系统。以防这个库丢失,在任何情况下,我们都要学如何安装这个库。通过本教程,你可以学会使用树莓派GPIO引脚执行简单的输入输出操作。
Contents
- 树莓派引脚配置
- [RPi.GPIO Python库](#RPi.GPIO Python库)
- 安装
- Hello World: 树莓派LED灯闪烁
- 小背景
- 电路
- 使用树莓派GPIO库
- 考虑计时
- 一起编码吧
- 视频
- 进阶:读取输入
- 算法
- 一起编码吧
- 测试:设计一个计时器
- 现在呢?
- 总结
树莓派引脚配置
正如之前提到的,树莓派A/B型和B+型引脚兼容,下面这张图(来自raspberrypi-spy.co.uk)展示了A/B型(rev 2)和B+型引脚的排布:
树莓派B型Rev 2和B+型的排布(来自raspberrypi-spy.co.uk)
B模型有两个版本,其中的引脚配置改变了一点。树莓派B型包括引脚1到引脚26,其中只有17个引脚被用作GPIO,剩余的引脚包括供电(5v和3.3v),地线和串行引脚。树莓派B型包括上述所有的引脚,其中26个引脚可被用作GPIO。
引脚左右边提到的标签对应的是BCM2835 CPU引脚的编号,例如:BCM2835 CPU的引脚GPIO 16对应树莓派B+的第36号引脚。是什么意思呢?它对你有什么区别呢?我们一会儿再做了解!:)
RPi.GPIO Python库
现在我们了解了解这个库。为了控制树莓派的GPIO引脚,我们要用RPi.GPIO的Python库。以0.5.6版本为例,这个库也支持树莓派B+型。虽然这个库是连接和控制GPIO引脚的做好的途径,但是他还是缺少对SPI,12C,硬件PWM和串口功能的支持(这是关于0.5.6版本的,后续版本有望被改善)。
这是一个允许你通过任何的方式(如:轮询、触发器、事件等)从任何GPIO引脚读取或写入的非常简单的库。在这篇文章中,我们将讨论轮询的方法(不用担心这个名字,我们后期会处理它的,“轮询”这个概念非常的简单),在我的接下来的文章中我将会谈谈其他的方法。
安装
方法 1 - 从库中安装
RPi.GPIO库预装了最新版的Raspbian系统,以防这个库不可用,你需要通过在命令行运行下面的指令从库中安装最新版:
sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install python-rpi.gpio python3-rpi.gpio
你要做的就是这些!简单吗?:)
方法 2 - 从源码编译
如果你想从源码编译,首先要从这里下载库。下载好后,你要解压它。打开命令行,浏览你下载的库的文件夹,敲下面的命令来解压它(用你下载的文件的名字替换那个文件的名字):
tar zxvf RPi.GPIO-0.5.6.tar.gz
然后进入解压后的文件夹:
cd RPi.GPIO-0.5.6
在你安装前,确保你的系统安装了Python(这是因为它预装在所有操作系统的镜像)。以防Python没有安装,敲下面的命令来安装:
sudo apt-get install python-dev python3-dev
然后敲下面的命令来安装这个包:
sudo python setup.py install
# 或
sudo python3 setup.py install
应该就是这样了!接下来你要让一些LED灯山说起来!:)
Hello World: 树莓派LED灯闪烁
一个“Hello world”程序是最简单的可以写出来说明任何设备最基本功能的程序之一。在我们这个树莓派的例子中,像所有其他嵌入式系统一样,它的“Hello world”是让LED灯闪烁起来!不仅仅是让初学者知道事情是如何运转的,也是为了验证所有工具和设备是否正确地安装工作了。
在本文中,我们将用Python编程。当然我们也可以用很多其他的语言来编程,但是我们现在选择用Python,是因为它很简单。我会在其他文章中用C语言实现同样的效果,或许再来一篇文章我会教大家如何写自己的Linux内核模型来控制GPIO。:)
小背景
对于那些对电路不太懂的同学们,这个任务看起来有点难,所以这里有一个关于闪烁LED灯概念的小知识需要了解一下。如果你不是很熟,那么来看看:LED是一个在引脚上一接上正电压(正向偏置)就会发出某一颜色(红色、蓝色、绿色、黄色、白色等)的光的小设备。如果你把正负极换一换,LED等就不会亮了。根据下面LED的图,你要保证穿过LED的电压(从+到-)是正向的,才能把它点亮。
LED示意图详解
如果你直接连接了5v的电压,LED会闪一下(爆掉),因为电压超过了LED的极限。为了防止这种情况的发生,我们通常会让LED串联一个电阻来分担电压,这样LED就安全了并且可以持续的发亮,通常任何在100Ω到1000Ω之间的电阻都可以用。这样不会让太多的电压分担到LED上让它爆掉。
好了,现在我们来看看电路示意图。
电路
免责声明:我们绝不对任何你闯的祸负责。下面展示的电路经测试,工作良好。然而如果你连接错误并且/或或让电路板短路损坏了你的树莓派,你需要自己负全责。总而言之,自己承担后果。当然小心漏电。树莓派的GPIO引脚直接和BCM8235 CPU的引脚相连,没有保护,所以小心行事。如果你没有把握,试试用一些像Gertboard的东西作为中间接口。
我们将用不需要无焊线路板来做这个电路。如果你不知道怎么在线路板上做电路,可以先试着看看这个视频。我们需要的所有东西是:
- 树莓派及其配件
- F/M跨接导线(F/F和M/M组合也可以用)
- 一个LED(3mm或5mm)
- 两个330Ω的电阻
- 一个按钮
检查一下下面的电路,我们现在要实现红色框框标记的区域,这是LED闪烁。注意树莓派的第7号引脚连接到电路的正极(+),第6号引脚(地线)连接到电路的负极(-)。
这意味着当7号引脚被驱动高时(原文是:when pin 7 is driven high),高电压(通常是5v)从7号引脚产生,点亮LED;并且当7号引脚被驱动低时,低电压(通常为0v)从7号引脚产生,关掉LED。
Cool!一旦你完成红色区域的电路的制作,就可以进入下一步了,我们将学习怎么用RPi.GPIO库来编写树莓派。
树莓派GPIO电路例子,红色区域是LED闪烁电路
这里有一些线路板上电路的图片:
LED闪烁线路板电路
树莓派LED闪烁
使用树莓派GPIO库
导入模块
RPi.GPIO包允许我们用类的方式控制GPIO引脚,我们以导入模块作为开始:
import RPi.GPIO as GPIO
这可以让我们通过简单地使用GPIO来代替它的全名RPi.GPIO。
指定操作模式
下一步是指定我们使用模块的模式。还记得我们提过的树莓派(BOARD)和那个CPU(BCM)引脚数量不同吗?这是关键之处。你需要在这两个系统之间选择,通过敲:
GPIO.setmode(GPIO.BOARD) # 树莓派
# 或
GPIO.setmode(GPIO.BCM) # CPU
建立通道
下一步我们需要建立想要的通道作为输入或输出,我们可以这样做:
GPIO.setmode(channel, GPIO.IN) # 输入通道
# 或
GPIO.setmode(channel, GPIO.OUT) # 输出通道
例如,对于LED闪烁,我们将线路板上的7号引脚连接到LED。这意味着我们必须把那个引脚配置为输出通道。同样,重述一遍,线路板的7号引脚是映射到CPu的GPIO 4引脚上,所以你要做:
GPIO.setup(7, GPIO.OUT) # 如果使用BOARD编号系统
# 或
GPIO.setup(4, GPIO.OUT) # 如果使用BCM编号系统
建议使用BOARD编号系统,因为它用起来更简单。其实你用那一个无关紧要,只要你选择好一个,用它就好。
驱动通道(原文:Drive a channel)
下一步是驱动通道为高或低(原文是:Next step is to drive the channel high or low.),可以这样写:
GPIO.output(channel, state)
例如:要驱动第7引脚为高(原文是:to drive pin 7 high),我们敲下面的代码:
GPIO.output(7, True)
# 或
GPIO.output(7, GPIO.HIGH)
# 或
GPIO.output(7, 1)
同样,驱动7号引脚为低(原文:to drive the same 7 low),我们敲:
GPIO.output(7, False)
# 或
GPIO.output(7, GPIO.LOW)
# 或
GPIO.output(7, 0)
读通道(原文:Read channel)
为了读取任何一个GPIO引脚的值,简单地写:
GPIO.input(channel)
我们将在这次教程的后面学到如何使用它。因为我们所有的引脚都是输出引脚,所以我们在LED闪烁中不需要。
清除(原文:clearup)
一旦我们完成GPIO的操作,我们需要清除并释放掉任何我们已经使用过的资源。这个不是必须要求,但是它是一个良好的编程习惯,你要做的就是:
GPIO.clearnup()
考虑计时
你需要知道的另一件事是延时的概念,它指的是当LED闪烁的时候,你确实是想看到它闪烁,而不应该是它闪烁得太快,以至于你看到它一直是亮的,或者是它闪烁得太慢,以至于你看到它的状态一直是亮的或暗的。同样,你也需要控制LED闪烁速度(比方说你想要LED没1/4秒闪烁一次)。所以我们要做:
- 打开LED
- 等待一会儿
- 关闭LED
- 等待一会儿
- 重复1-4步
为了实现上面提到的步骤2和步骤4,Python有一个可以调用做同样的事的sleep()函数的time库(原文是:Python has a time library which has a function called sleep() which does exactly the same thing!)。下面是我们使用的方法:
import time # 导入'time'库
time.sleep(n) # 睡眠n秒
我觉得我们要开始变成了,我假定你已经熟悉了一些基本的Python程序,如果你不熟悉Python,你可以先学一下,然后回来!
一起编码吧
好了,伙计们!是时候伸出你们的咸猪手开始编程了!我们将用Python 2.7.3写代码,为了可以写代码,打开你最喜欢的文本编辑器(如gedit, Geany等)。通常对于Python来说,我们更喜欢用IDLE,所以我们去命令行,敲:
sudo idle
我们需要用超级用户(管理员)权限运行IDLE,因为RPi.GPIO库需要控制硬件引脚的权限。不要打开IDLE 3,我们不用Python 3。
接下来,敲写如下代码:
import RPi.GPIO as GPIO ## 导入GPIO库
import time ## 导入time库
pin = 7 ## 使用7号引脚
GPIO.setmode(GPIO.BOARD) ## 使用BOARD引脚编号
GPIO.setup(pin, GPIO.OUT) ## 设置7号引脚为输出通道
for i in range(0,20): ## 重复20次
GPIO.output(pin, GPIO.HIGH) ## 打开GPIO引脚(HIGH)
time.sleep(1) ## 等待1秒钟
GPIO.output(pin, PGIO.LOW) ## 关闭GPIO引脚(LOW)
time.sleep(1) ## 等待1秒钟
GPIO.cleanup() ## 清除,释放资源
完成后,保存文件并以你希望的名字命名(像:blinky.py)。然后,点击F5运行它,如果你敲错了代码,你会看到错误框弹出。如果它说某种语法错误,请检查确保你正在运行IDLE而不是IDLE3。如果它提示权限不足,确保你用过超级用户(管理员)身份运行IDLE(通过使用sudo)。
你也可以通过通过命令行在工作目录敲如下代码来运行这个Python文件:
sudo python blinky.py
你看到了什么?你的LED闪烁了吗?如果一切进展顺利,你的LED就会闪烁,但是只有一次。那是因为我们还没有实现循环!让我们修改代码:
import RPi.GPIO as GPIO ## 导入GPIO库
import time ## 导入time库
pin = 7 ## 使用7号引脚
GPIO.setmode(GPIO.BOARD) ## 使用BOARD引脚编号
GPIO.setup(pin, GPIO.OUT) ## 设置7号引脚输出
for i in range(0, 20): ## 重复20次
GPIO.output(pin, GPIO.HIGH) ## 打开GPIO引脚(HIGH)
time.sleep(1) ## 等1秒
GPIO.output(pin, GPIO.LOW) ## 关闭GPIO引脚(LOW)
time.sleep(1) ## 等1秒
PIO.cleanup() ## 清除
确保你正确使用制表符缩进代码而不是空格。
Python严格依赖合适的代码缩进,保存并运行它。你看到了什么?LED闪烁了20次了吗?哇哦?!好棒!干得漂亮!:)
现在试着玩玩!改变循环重复的次数,改变延迟的时间等。
但是为什么只闪烁20次呢?如果你想永远闪烁怎么办呢?!为了实现这个效果,你需要用下面的代码替换for循环:
while True:
# 循环代码从这里开始
# 这个循环无限制地迭代下去
# 因为循环的条件永远是True
好,继续!这些你都做好了!(原文:And there you go! You’re all set!)我准备了我的LED闪烁的视频,下面有。我用了以下的代码,这份代码获取用户的输入然后实现了闪烁的功能。
# 树莓派LED闪烁代码
笔者正在翻译中…