維基少年:樹莓派/樹莓派樂高®交通燈
教程作者:安德魯·奧克利
公有領域,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?