维基少年:树莓派/树莓派乐高®交通灯
教程作者:安德鲁·奥克利
公有领域,2015年9月26日
www.cotswoldjam.org
LEGO®是乐高集团公司的商标,并不赞助、授权或认可本教程或Cotswold Raspberry Jam。
本教程将向你展示如何基于LED(灯)和树莓派计算机构建一套交通灯。这些灯可以放置在乐高®技术积木中,并与其他乐高®模型一起使用。
Things that appear on the screen or need to be typed in are written like this.
在每行代码的末尾,你通常需要按 ↵ Enter 键。
你的导师应该已经为你准备好了树莓派。如果没有,请参见文末的“准备工作”部分。
LED始终需要与电阻器连接。如果你不带电阻器连接它们,它们会烧毁,并且可能无法再次工作。 |
发光二极管(LED)有一个短腿和一个长腿。如果你摸摸边缘,你会发现一个平坦的边缘。短腿和平坦的边缘始终连接到负极(接地)。我们使用5mm LED,因为它们可以插入乐高®技术的孔中。
电阻器可以以任何方式连接。较低值(较低欧姆)的电阻器会允许更多的电流通过,使LED更亮;较高值的电阻器会允许更少的电流通过,使LED更暗。我们使用一个270欧姆的电阻器,但220-470欧姆之间的任何电阻器都可以正常工作。我们将使用一个连接到地线的电阻器来覆盖所有3个LED。
这三块乐高®积木可以组合成一个交通灯,5mm LED可以插入技术积木的孔中。
这些积木的零件编号 – 可以在eBay或Bricklink.com等网站上购买二手 – 为
将LED推入技术积木,使每个LED的短腿位于底部。
你需要将短腿连接到单个电阻器,然后连接到树莓派的地线引脚之一。你的导师可能已经做了一个特殊的“猪尾巴”电缆来做到这一点,或者你可以使用面包板。
猪尾巴电缆
你的导师可能已经使用DuPont压接器制作了这条电缆。
它在一侧有三个母头,插入LED的短腿,中间有一个电阻器,另一侧有一个母头,插入树莓派的9号引脚(接地)。一小段透明的胶带包裹在电阻器周围,以固定它。
面包板
如果你没有专门制作的猪尾巴电缆,你可以使用面包板来连接三个LED的短腿到一个电阻器和接地。你需要四根公对母跳线,加上电阻器。 不要担心跳线的颜色。它们不必与LED的颜色匹配。本文档的作者严重色盲,所以颜色无论如何都是随机的。 面包板顶部的三根跳线连接到LED的短腿。面包板底部的单根跳线连接到树莓派的接地(9号引脚)。 |
连接好电阻器和接地线到LED的短腿后,你可以使用一根母对母跳线将长腿连接到树莓派的1号引脚(3.3伏直流)(假设树莓派已通电)来测试任何LED。
但是,我们不希望灯一直亮着;我们需要通过程序控制它们。测试完灯后,断开1号引脚。
为了通过程序控制LED,使用母对母跳线将LED的长腿(正极)连接到树莓派的以下引脚:
- 11号引脚 - 红色
- 13号引脚 - 黄色
- 15号引脚 - 绿色
启动你的树莓派,登录并进入桌面。如果你需要登录,默认用户名是 `pi`,密码是 `raspberry`。如果桌面仍然没有出现,输入 `startx` 并按下 ↵ Enter 键。
从菜单中选择 Programming – Python 3。然后使用 File, New Window 创建一个新的程序。
输入以下程序,或者你也可以使用 File, Open 打开 python/traffic 文件夹中的 traffic1.py 程序。
import RPi.GPIO as GPIO, time
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
red=11
yellow=13
green=15
GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)
使用 File, Save 保存该程序为 `traffic1.py`。以下是该程序的功能
import RPi.GPIO as GPIO, time
此命令告诉树莓派关于其 GPIO 引脚的信息,因此它可以打开和关闭 LED,并且关于时间,因此我们可以告诉它在每种颜色之间等待几秒钟。
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
在这里,我们告诉计算机按板子上排列的顺序使用引脚编号来调用引脚(有一种称为 BCM 的替代编号方式)。接下来,我们告诉它不要在 GPIO 引脚已经被使用时发出警告。
red=11
yellow=13
green=15
现在,我们告诉树莓派哪些引脚用于哪种颜色的 LED。请注意,我们不必说明我们使用引脚 9 用于接地;这并不重要。
GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)
最后,我们告诉树莓派准备红色、黄色和绿色引脚用于输出。如果我们正在获取输入,例如读取开关,那么这段代码将看起来不同。
程序的这部分只是做好一切准备。它实际上并没有打开任何 LED。我们将在下一步中进行操作。
使用 File, Save As 保存程序为 `traffic1.py`。不用担心它告诉你该程序已经存在——无论如何保存它。
让我们从点亮黄色 LED 开始。在程序底部添加以下几行
GPIO.output(yellow, GPIO.HIGH)
time.sleep(2)
GPIO.output(yellow, GPIO.LOW)
HIGH 打开灯光。LOW 关闭灯光。
保存程序为 `traffic2.py`。
现在保持 Python 窗口打开,并通过转到主桌面菜单 - 附件 - 终端启动一个终端会话。你应该会看到一个黑色的窗口打开。
在终端中,输入
cd python/traffic
sudo python traffic2.py
你应该会看到黄色 LED 亮起两秒钟,然后 LED 会熄灭,程序将结束。你可以通过再次输入 `sudo python traffic2.py` 来重复程序。
尝试修改程序以点亮红色或绿色 LED。
现在让我们修改程序,使最后几行显示为
while (True):
GPIO.output(yellow, GPIO.HIGH)
time.sleep(2)
GPIO.output(yellow, GPIO.LOW)
time.sleep(2)
保存该程序为 `traffic3.py`。回到黑色终端窗口并使用以下命令运行它
sudo python traffic3.py
黄色 LED 应该每 2 秒闪烁一次。
按住 CTRL 键并轻触 C 键退出程序。这可能会使黄色灯光保持亮起!不用担心。
英国交通灯的完整序列是
- 红色(停止)——持续很长时间
- 红黄一起(准备行驶)——持续很短时间
- 绿色(行驶)——持续很长时间
- 单独的黄色(准备停止)——持续很短时间
让我们修改程序以执行完整的序列
while (True):
GPIO.output(red, GPIO.HIGH)
time.sleep(5)
GPIO.output(yellow, GPIO.HIGH)
time.sleep(2)
GPIO.output(red, GPIO.LOW)
GPIO.output(yellow, GPIO.LOW)
GPIO.output(green, GPIO.HIGH)
time.sleep(5)
GPIO.output(green, GPIO.LOW)
GPIO.output(yellow, GPIO.HIGH)
time.sleep(2)
GPIO.output(yellow, GPIO.LOW)
就是这样!保存该程序为 `traffic4.py`。回到终端窗口并使用以下命令运行它
sudo python traffic4.py
按住 CTRL 键并轻触 C 键退出程序。
你可以在停止程序后使用 alloff.py 程序来关闭所有灯光。此外,还有 `traffic5.py` 程序,它使用一些高级技术在程序停止时关闭灯光。
以下是一些你可以做的其他事情的想法
你可以使用引脚 12、16 和 18(加上引脚 14 用于接地)来控制另一组灯光。
在 Model B+ 或 Pi 2 上,你可以使用引脚 36、38 和 40(加上引脚 34 用于接地)来控制第三组灯光,或者你可以使用两台树莓派。
如果你有多台树莓派,如何同步灯光?两台树莓派如何相互通信?
如果是一辆塑料 LEGO® 汽车或一辆金属玩具汽车,你的策略是否有效,或者两者都行?汽车的重量是否重要?
如果是自行车或马怎么办?现实世界中的交通灯如何检测自行车和马——它们有其他策略吗,或者它们忽略了这个问题?
尝试搜索有关 `crontab @reboot` 命令的信息:https://www.adminschoice.com/crontab-quick-reference
本教程的文件可以在以下位置找到:http://www.cotswoldjam.org/downloads/2015-09/
请在 home/pi 目录下创建一个 `python` 文件夹,然后将文件解压缩到该 `python` 文件夹中。这可以在 LXTerminal 中完成
mkdir python
unzip traffic.zip
本教程的原始 PDF 文件位于 Wikimedia Commons:Cjam-traffic-light-tutorial.pdf
#!/usr/bin/env python
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
red=11
yellow=13
green=15
GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)
GPIO.output(red, GPIO.LOW)
GPIO.output(yellow, GPIO.LOW)
GPIO.output(green, GPIO.LOW)
import RPi.GPIO as GPIO, time
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
red=11
yellow=13
green=15
GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)
import RPi.GPIO as GPIO, time
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
red=11
yellow=13
green=15
GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)
GPIO.output(yellow, GPIO.HIGH)
time.sleep(2)
GPIO.output(yellow, GPIO.LOW)
import RPi.GPIO as GPIO, time
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
red=11
yellow=13
green=15
GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)
while (True):
GPIO.output(yellow, GPIO.HIGH)
time.sleep(2)
GPIO.output(yellow, GPIO.LOW)
time.sleep(2)
import RPi.GPIO as GPIO, time
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
red=11
yellow=13
green=15
GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)
while (True):
GPIO.output(red, GPIO.HIGH)
time.sleep(5)
GPIO.output(yellow, GPIO.HIGH)
time.sleep(2)
GPIO.output(red, GPIO.LOW)
GPIO.output(yellow, GPIO.LOW)
GPIO.output(green, GPIO.HIGH)
time.sleep(5)
GPIO.output(green, GPIO.LOW)
GPIO.output(yellow, GPIO.HIGH)
time.sleep(2)
GPIO.output(yellow, GPIO.LOW)
#!/usr/bin/env python
# GPIO traffic lights by Andrew Oakley for Cotswold Raspberry Jam
# http://www.cotswoldjam.org September 2015 Public Domain
# Start by reading the library about GPIO pins and timing
import RPi.GPIO as GPIO, time, signal, sys
# Set up the GPIO pins
# We're using board numbering as it works for all Pis
# including original Rev.1 boards
GPIO.setmode(GPIO.BOARD)
# Turn off warnings, notably if the pins are already set
GPIO.setwarnings(False)
# Turn off lights if process is killed
def signal_term_handler(signal, frame):
GPIO.output(red, GPIO.LOW)
GPIO.output(yellow, GPIO.LOW)
GPIO.output(green, GPIO.LOW)
print 'got SIGTERM'
sys.exit(0)
signal.signal(signal.SIGTERM, signal_term_handler)
# Which colours are on which pins?
# You can use pin 9 for ground
# Attach ground to the shortest leg of the LED
red=11
yellow=13
green=15
# Set up the pins for output
GPIO.setup(red, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(green, GPIO.OUT)
# We use TRY and EXCEPT to allow us to
# turn the lights off after stopping the
# program using CTRL-C, or during shutdown
try:
# Loop round forever, until stopped by CTRL-C
while (True):
# Start with Red
GPIO.output(red, GPIO.HIGH)
time.sleep(5)
# Leave red on, and turn yellow on too
# Red & yellow together is mostly a British thing
# Countries like France and the USA don't have it
# they go straight from red to green
GPIO.output(yellow, GPIO.HIGH)
time.sleep(2)
# Turn off red and yellow
GPIO.output(red, GPIO.LOW)
GPIO.output(yellow, GPIO.LOW)
# Turn on green
GPIO.output(green, GPIO.HIGH)
time.sleep(5)
# Turn off green
GPIO.output(green, GPIO.LOW)
# Turn on yellow
GPIO.output(yellow, GPIO.HIGH)
time.sleep(2)
GPIO.output(yellow, GPIO.LOW)
# If we have pressed CTRL-C, or if the computer
# is being shut down, then turn all lights off
except (KeyboardInterrupt, SystemExit):
GPIO.output(red, GPIO.LOW)
GPIO.output(yellow, GPIO.LOW)
GPIO.output(green, GPIO.LOW)
# Report the reason for stopping
raise
# Now have a think about how you might expand this program
# A T-junction needs 3 sets of lights
# A crossroads needs 4 sets
# Could you wire all sets of lights from one Raspberry Pi?
# What about a left turn filter?
# At night some part-time lights just flash yellow
# If you had two Raspberry Pis, how could they communicate
# so that they could synchronise their lights?