跳转到内容

维基少年:树莓派/树莓派星球大战光剑

来自维基教科书,为开放世界提供开放书籍

教程作者:安迪·贝克,说明作者:哈尔·莫特利

本教程属于公有领域。在本教程中,您将连接一个多色 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()
华夏公益教科书