跳轉到內容

維基少年:樹莓派/樹莓派星球大戰光劍

來自華夏公益教科書,為開放世界提供開放書籍

教程作者:安迪·貝克,說明作者:哈爾·莫特利

本教程屬於公有領域。在本教程中,您將連線一個多色 LED 到樹莓派,以建立一個類似於《星球大戰》中的光劍。

光劍的工作原理

[編輯 | 編輯原始碼]

在本教程中,變色 LED 代表一個凱伯水晶。在《星球大戰》宇宙中,光劍由凱伯水晶提供動力,絕地武士利用原力將之與自己的意志相協調。刀刃顏色種類繁多,包括

  • 盧克·天行者 - 綠色
  • 歐比旺·肯諾比 - 藍色
  • 梅斯·溫杜 - 紫色
  • 蕾伊·天行者 - 黃色
  • 阿索卡·塔諾 - 白色

達斯·維達、凱洛·倫和達斯·摩爾等西斯尊主的光劍是紅色的,因為他們利用原力控制凱伯水晶,使其流血。

您可以在此處檢視完整的雷射劍顏色列表:https://www.bossksbounty.com/films/every-lightsaber-color-in-star-wars

  • ×4 個公母 GPIO 跳線(也稱為 DuPont 線,最好是不同顏色)
  • ×1 個麵包板(一個小型 5×5 麵包板效果很好,但任何尺寸都可以)
  • ×1 個 68 歐姆(藍灰黑金)電阻
  • ×1 個 4 針變色 LED

使用麵包板

[編輯 | 編輯原始碼]

麵包板用於原型設計和測試電子元件,無需焊接。

每個孔都使用一種符號系統進行標識,該系統使用水平方向上的數字和垂直方向上的字母標識面包板上的孔位。

連線元件

[編輯 | 編輯原始碼]

要設定光劍,請執行以下操作

步驟 1:透過關閉樹莓派來斷開電源。

步驟 2:將變色 LED 連線到頂部的 4 個孔(A13A14A15A16)。確保最長的引腳(接地)與連線到 GPIO 39 (GND) 的跳線對齊,這樣 LED 就能夠正確接地。

步驟 3:將 68 歐姆電阻插入麵包板,將一根線插入 B15 孔,另一根線插入 B20 孔(第二行的最後一個孔),位於跳線之上。

步驟 4:將 4 根跳線從 GPIO 引腳 33 (GPIO 13)引腳 35 (SPI1 MISO)引腳 37 (GPIO 26)引腳 39 (GND)(最後 4 個右下角引腳,假設 USB 和乙太網埠在右邊)連線到麵包板的左下角 4 個孔。我建議儘量使用與電路圖完全匹配的相同顏色的跳線,不過可以使用任何顏色組合。

步驟 5:按照順序執行每個 Python 指令碼,即 lightsaber.pyls1.pyls2.pyls3.py。嘗試修改程式碼,看看你是否可以建立自己的顏色組合。

lightsaber.pdf

[編輯 | 編輯原始碼]

本教程的原始 PDF 檔案位於維基共享資源:Lightsaber.pdf

#!/usr/bin/env python

# Pull in the code libraries that the code will need to use.
from __future__ import division
import RPi.GPIO as GPIO
import time

# Set up the GPIO library to use the numbering of the pin on the board
# i.e. 1 - 40 of the main GPIO connector.
GPIO.setmode(GPIO.BOARD)

# Tell the code the red LED is plugged into pin 35, and that pin 35
# is an output, and set the output to low (i.e. red LED is off)
RED_LED = 35
GPIO.setup(RED_LED, GPIO.OUT)
GPIO.output(RED_LED, GPIO.LOW)

# A new pulse starts every second, and half of that time, the LED is on.
pulse_period = 1
on_fraction = 1/2

# This try and the except below allow the code to stop cleanly by
# capturing the exception from a keyboard ctrl-C. 
try:

  # Store off when the while loop starts.
  start_time = time.time()

  # Start looping around the code forever.  
  while True:

    # Work out what time it is since we started, and from that, the 
    # fraction of the pulse period.
    time.sleep(1/1000)
    clock_time = (time.time() - start_time) % pulse_period

    # For the LEDs, check how far through its fraction of the pulse it 
    # is and turn the LED on if it's less or off if it's more.

    #============================= RED =============================#

    if clock_time < on_fraction * pulse_period:
        GPIO.output(RED_LED, GPIO.HIGH)
    else:
        GPIO.output(RED_LED, GPIO.LOW) 

# The except here needs to do nothing but has to do something; the pass
# statement means do nothing.
except KeyboardInterrupt as e:
  pass

# Finally turn off the LEDs and cleanup the GPIO.  
GPIO.output(RED_LED, GPIO.LOW)
GPIO.cleanup()
#!/usr/bin/env python

# Pull in the code libraries that the code will need to use.
from __future__ import division
import RPi.GPIO as GPIO
import time

# Set up the GPIO library to use the numbering of the pin on the board
# i.e. 1 - 40 of the main GPIO connector.
GPIO.setmode(GPIO.BOARD)

# Tell the code the red LED is plugged into pin 35, and that pin 35
# is an output, and set the output to low (i.e. red LED is off)
RED_LED = 35
GPIO.setup(RED_LED, GPIO.OUT)
GPIO.output(RED_LED, GPIO.LOW)

# Tell the code the green LED is plugged into pin 33, and that pin 33
# is an output, and set the output to low (i.e. green LED is off)
GREEN_LED = 33
GPIO.setup(GREEN_LED, GPIO.OUT)
GPIO.output(GREEN_LED, GPIO.LOW)

# Tell the code the blue LED is plugged into pin 37, and that pin 37
# is an output, and set the output to low (i.e. blue LED is off)
BLUE_LED = 37
GPIO.setup(BLUE_LED, GPIO.OUT)
GPIO.output(BLUE_LED, GPIO.LOW)

# A new pulse starts every second, and half of that time, the LED is on.
pulse_period = 1
on_fraction = 1/2

# This try and the except below allow the code to stop cleanly by
# capturing the exception from a keyboard ctrl-C. 
try:

  # Store off when the while loop starts.
  start_time = time.time()

  # Start looping around the code forever.  
  while True:

    # Work out what time it is since we started, and from that, the 
    # fraction of the pulse period.
    time.sleep(1/1000)
    clock_time = (time.time() - start_time) % pulse_period

    # For the LEDs, check how far through its fraction of the pulse it 
    # is and turn the LED on if it's less or off if it's more.

    #============================= RED =============================#

    if clock_time < on_fraction * pulse_period:
        GPIO.output(RED_LED, GPIO.HIGH)
    else:
        GPIO.output(RED_LED, GPIO.LOW) 

    #============================ GREEN =======-====================#

    if clock_time < on_fraction * pulse_period:
        GPIO.output(GREEN_LED, GPIO.HIGH)
    else:
        GPIO.output(GREEN_LED, GPIO.LOW)

    #============================= BLUE ============================#

    if clock_time < on_fraction * pulse_period:
        GPIO.output(BLUE_LED, GPIO.HIGH)
    else:
        GPIO.output(BLUE_LED, GPIO.LOW)

# The except here needs to do nothing but has to do something; the pass
# statement means do nothing.
except KeyboardInterrupt as e:
  pass

# Finally turn off the LEDs and cleanup the GPIO.  
GPIO.output(RED_LED, GPIO.LOW)
GPIO.output(GREEN_LED, GPIO.LOW)
GPIO.output(BLUE_LED, GPIO.LOW)
GPIO.cleanup()
#!/usr/bin/env python

# Pull in the code libraries that the code will need to use.
from __future__ import division
import RPi.GPIO as GPIO
import time

# Set up the GPIO library to use the numbering of the pin on the board
# i.e. 1 - 40 of the main GPIO connector.
GPIO.setmode(GPIO.BOARD)

# Tell the code the red LED is plugged into pin 35, and that pin 35
# is an output, and set the output to low (i.e. red LED is off)
RED_LED = 35
GPIO.setup(RED_LED, GPIO.OUT)
GPIO.output(RED_LED, GPIO.LOW)

# Tell the code the green LED is plugged into pin 33, and that pin 33
# is an output, and set the output to low (i.e. green LED is off)
GREEN_LED = 33
GPIO.setup(GREEN_LED, GPIO.OUT)
GPIO.output(GREEN_LED, GPIO.LOW)

# Tell the code the blue LED is plugged into pin 37, and that pin 37
# is an output, and set the output to low (i.e. blue LED is off)
BLUE_LED = 37
GPIO.setup(BLUE_LED, GPIO.OUT)
GPIO.output(BLUE_LED, GPIO.LOW)

# Each pulse period is 1 second, and each colour is on for a different
# number of thirds of this time.
pulse_period = 1
red_fraction = 1/3
green_fraction = 2/3
blue_fraction = 3/3

# This try and the except below allow the code to stop cleanly by
# capturing the exception from a keyboard ctrl-C. 
try:

  # Store off when the while loop starts.
  start_time = time.time()

  # Start looping around the code forever.  
  while True:

    # Work out what time it is since we started, and from that, the 
    # fraction of the pulse period.
    time.sleep(1/10)
    clock_time = (time.time() - start_time) % pulse_period

    # For the LEDs, check how far through its fraction of the pulse it 
    # is and turn the LED on if it's less or off if it's more.

    #============================= RED =============================#

    if clock_time < red_fraction * pulse_period:
        GPIO.output(RED_LED, GPIO.HIGH)
    else:
        GPIO.output(RED_LED, GPIO.LOW) 

    #============================ GREEN =======-====================#

    if clock_time < green_fraction * pulse_period:
        GPIO.output(GREEN_LED, GPIO.HIGH)
    else:
        GPIO.output(GREEN_LED, GPIO.LOW)

    #============================= BLUE ============================#

    if clock_time < blue_fraction * pulse_period:
        GPIO.output(BLUE_LED, GPIO.HIGH)
    else:
        GPIO.output(BLUE_LED, GPIO.LOW)

# The except here needs to do nothing but has to do something; the pass
# statement means do nothing.
except KeyboardInterrupt as e:
  pass

# Finally turn off the LEDs and cleanup the GPIO.  
GPIO.output(RED_LED, GPIO.LOW)
GPIO.output(GREEN_LED, GPIO.LOW)
GPIO.output(BLUE_LED, GPIO.LOW)
GPIO.cleanup()

lightsaber.py

[編輯 | 編輯原始碼]
#!/usr/bin/env python

# Pull in the code libraries that the code will need to use.
from __future__ import division
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BOARD)

# Tell the code the red LED is plugged into pin 35, and that pin 35
# is an output, and set the output to low (i.e. red LED is off)
RED_LED = 35
GPIO.setup(RED_LED, GPIO.OUT)
GPIO.output(RED_LED, GPIO.LOW)

# Tell the code the green LED is plugged into pin 33, and that pin 33
# is an output, and set the output to low (i.e. green LED is off)
GREEN_LED = 33
GPIO.setup(GREEN_LED, GPIO.OUT)
GPIO.output(GREEN_LED, GPIO.LOW)

# Tell the code the blue LED is plugged into pin 37, and that pin 37
# is an output, and set the output to low (i.e. blue LED is off)
BLUE_LED = 37
GPIO.setup(BLUE_LED, GPIO.OUT)
GPIO.output(BLUE_LED, GPIO.LOW)

# Each pulse period is 1/100 second, and each colour is on for a different
# number amount of time each time round the loop.
pulse_period = 1/100

red_fraction = 1/500
red_on = 0

blue_fraction = 1/300
blue_on = 0

green_fraction = 1/200
green_on = 0

# This try and the except below allow the code to stop cleanly by
# capturing the exception from a keyboard ctrl-C. 
try:

  # Store off when the while loop starts.
  start_time = time.time()

  # Start looping around the code forever.  
  while True:

    # Work out what time it is since we started, and from that, the 
    # fraction of the pulse period.
    time.sleep(1/1000)
    clock_time = (time.time() - start_time) % pulse_period

    # For the LEDs, check how far through its fraction of the pulse it 
    # is and turn the LED on if it's less or off if it's more.
    # In this case, the fraction changes each time round the loop, so
    # the LEDs change their brightness.

    #============================= RED =============================#

    if clock_time < red_on * pulse_period:
        GPIO.output(RED_LED, GPIO.HIGH)
    else:
        GPIO.output(RED_LED, GPIO.LOW) 

    red_on += red_fraction 
    if red_on > 1 or red_on < 0:
        red_fraction = -red_fraction
        red_on += red_fraction

    #============================ GREEN =======-====================#

    if clock_time < green_on * pulse_period:
        GPIO.output(GREEN_LED, GPIO.HIGH)
    else:
        GPIO.output(GREEN_LED, GPIO.LOW)

    green_on += green_fraction
    if green_on > 1 or green_on < 0:
        green_fraction = -green_fraction
        green_on += green_fraction


    #============================= BLUE ============================#

    if clock_time < blue_on * pulse_period:
        GPIO.output(BLUE_LED, GPIO.HIGH)
    else:
        GPIO.output(BLUE_LED, GPIO.LOW)

    blue_on += blue_fraction
    if blue_on > 1 or blue_on < 0:
        blue_fraction = -blue_fraction
        blue_on += blue_fraction

# The except here needs to do nothing but has to do something; the pass
# statement means do nothing.
except KeyboardInterrupt as e:
  pass

# Finally turn off the LEDs and cleanup the GPIO.  
GPIO.output(RED_LED, GPIO.LOW)
GPIO.output(GREEN_LED, GPIO.LOW)
GPIO.output(BLUE_LED, GPIO.LOW)
GPIO.cleanup()
華夏公益教科書