跳轉到內容

維基少年:樹莓派/樹莓派 Python 單獨可控 LED(ws2811)

來自華夏公益教科書

Andrew Oakley 和 Jonathan Teague 的教程 - 公共領域
2020-03-14 www.cotswoldjam.org

本教程將介紹如何使用基於 ws2811 控制器(也稱為“NeoPixels”)的單獨可控 LED 字串。

您的包中將包含以下元件

  • ×3 M-F 跳線(針腳到插座)
  • ×1 3 路 3A 聯結器條
  • ×1 3 個 5V ws2811 LED 的字串

步驟 1:將連線到 LED 的白色電線的跳線,將其插座(母端)插入 Pi 上的6 號引腳(GND)

步驟 2:將連線到 LED 的紅色電線的跳線,將其插座(母端)插入 Pi 上的2 號引腳(5V)

步驟 3:將連線到 LED 的綠色電線的跳線,將其插座(母端)插入 Pi 上的12 號引腳(GPIO 18)

啟動您的樹莓派。從桌面選單中,選擇程式設計 - Python 3 (IDLE)。然後使用檔案,新建檔案來建立一個新程式。

輸入以下程式,然後使用檔案,儲存將程式儲存為您的選擇名稱(不要忘記在結尾新增 .py)。

import board, neopixel, time
pixels = neopixel.NeoPixel(board.D18, 3, auto_write=False, pixel_order=neopixel.RGB)

pixels[0] = (255, 0, 0)
pixels[1] = (0, 255, 0)
pixels[2] = (0, 0, 255)
pixels.show()

time.sleep(2)

pixels.fill((0, 0, 0))
pixels.show()

您也可以在 Pi 主資料夾中找到此程式:python/addrleds/neopixels-start.py

執行您的程式。

要執行程式,請啟動一個終端 - 點選頂部的圖示,然後在終端視窗開啟後鍵入

sudo python3 thenameyouchose.py

如果操作成功,您應該會看到 3 個 LED 亮起紅色、綠色和藍色,持續兩秒鐘,然後熄滅。

程式的功能是什麼?

[編輯 | 編輯原始碼]

匯入載入 NeoPixels 庫(以及 time,以便我們可以插入延遲)。

pixels = neopixel.NeoPixel(board.D18, 3, auto_write=False, pixel_order=neopixel.RGB)

這告訴庫,我們已經將 LED 字串連線到 GPIO 18,有 3 個 LED,auto_write=False 意味著只有在我們呼叫 pixels.show() 時才更新 LED。最後,我們注意到顏色順序是紅色、綠色、藍色(RGB)。

pixels[0] = (255, 0, 0)

這將第一個 LED 設定為紅色,3 個值是 (R, G, B) - 因此每個 3 個 LED 都亮起不同的顏色。

pixels.fill((0, 0, 0))

這將所有畫素設定為 0,這意味著關閉,如果我們不這樣做,LED 將保持開啟狀態。

下一步做什麼?

[編輯 | 編輯原始碼]

現在開始做自己的事情!製作一個迪斯科序列!

交通訊號燈序列怎麼樣?請注意,黃燈是紅燈和綠燈的混合,例如:(255,255,0)

提示:將其放在 while True: 塊中,這樣它就會一直執行。不要忘記像這一行一樣縮排 while 塊中的程式碼!

按住CTRL鍵並按下C來停止 while True: 序列。

您可以在 Pi 主資料夾中找到示例程式:python/addrleds/neopixels-traffic.py

如何設計一個持續 20 秒的燈光序列,這正是您認真洗手所需的時間?

您可以在 Pi 主資料夾中找到示例程式:python/addrleds/neopixels-countdown.py

如果停止程式,並且燈仍然亮著,您可以使用 neopixels-off.py 程式將其關閉。

它是如何工作的?

[編輯 | 編輯原始碼]

每個 LED 都連線到一個 ws2811 積體電路 (IC) - 稱為 ws2811 的是 IC,LED 只是一個三色 LED。Pi 生成一個長長的 0 和 1 序列。每個 LED 24 位(每個顏色紅|綠|藍 3 組 8 位),因此對於我們的 3 個 LED 字串,Pi 將生成 3 × 24 位 = 72 位。

字串中的第一個裝置接收前 24 位,並使用它們設定其 LED 的紅|綠|藍。然後,它將剩餘的 48 位傳遞給第二個 LED。然後,第二個 LED 將從接收到的資料中獲取現在的前 24 位作為其 RGB,並將剩餘的 24 位傳遞給最後一個 LED。

有關完整詳細資訊,請檢視以下資料表:http://www.world-semi.com/DownLoadFile/129

在家中操作

[編輯 | 編輯原始碼]

如果您沒有使用我們預製的 SD 卡,則需要從 Raspbian Buster 中進行一些設定。

  1. 樹莓派選單 - 首選項 - 樹莓派配置 - 介面 - SPI 啟用 - I2C 啟用 - 確定
  2. 樹莓派選單 - 關機 - 重啟

然後安裝庫

sudo pip3 install rpi_ws281x adafruit-circuitpython-neopixel

您可以從以下網址下載我們的示例程式碼:www.cotswoldjam.org/downloads/2020-03

在現實世界中使用 ws2811 的注意事項

[編輯 | 編輯原始碼]

我們只給了你一小串 LED,因為那是 Pi 可以可靠供電的全部。如果你使用的是長條的 ws2811 或 ws2812,你需要考慮兩件事。

  1. ws2811 燈條可以是 5V 或 12V,ws2812 是 5V。Pi 只能提供 5V 低電流,足以驅動幾個 LED。要驅動 5V 的長條或任何 12V 的燈條,你需要提供額外的電源,可能在燈條上的多個位置。如果你打算在你的臥室天花板周圍安裝燈條 😊,那麼 Pi 只能提供 LED 的控制邏輯,而不是電源。
  2. ws2811 和 ws2812 的控制邏輯在 5V 時被指定,Pi GPIO 引腳為 3.3V。在本教程中,我們可以使用 GPIO,但為了確保它可以正常工作,你可能需要使用邏輯電平轉換器將 Pi 的 3.3V 轉換為 5V。

neopixels-countdown.py

[編輯 | 編輯原始碼]
#!/usr/bin/python3
import board, neopixel, time
pixels = neopixel.NeoPixel(board.D18, 3, auto_write=False, pixel_order=neopixel.RGB)

# Count 20 seconds for washing our hands!

# Start with pixels off
pixels.fill((0, 0, 0))
pixels.show()

# First 5 seconds are red - count three forward
# Notice how we start counting from zero
# and stop before we reach 3
for x in range(0,3):
  pixels.fill((0, 0, 0))
  pixels[x] = (255, 0, 0)
  pixels.show()
  time.sleep(1)

# Now count two back
# We start at 1
# and stop before we reach -1
# and count -1 each time
for x in range(1,-1,-1):
  pixels.fill((0, 0, 0))
  pixels[x] = (255, 0, 0)
  pixels.show()
  time.sleep(1)

# Next 5 seconds are yellow
for x in range(0,3):
  pixels.fill((0, 0, 0))
  pixels[x] = (255, 255, 0)
  pixels.show()
  time.sleep(1)
for x in range(1,-1,-1):
  pixels.fill((0, 0, 0))
  pixels[x] = (255, 255, 0)
  pixels.show()
  time.sleep(1)

# Next 5 seconds are green
for x in range(0,3):
  pixels.fill((0, 0, 0))
  pixels[x] = (0, 255, 0)
  pixels.show()
  time.sleep(1)
for x in range(1,-1,-1):
  pixels.fill((0, 0, 0))
  pixels[x] = (0, 255, 0)
  pixels.show()
  time.sleep(1)

# Final 5 seconds are blue
for x in range(0,3):
  pixels.fill((0, 0, 0))
  pixels[x] = (0, 0, 255)
  pixels.show()
  time.sleep(1)
for x in range(1,-1,-1):
  pixels.fill((0, 0, 0))
  pixels[x] = (0, 0, 255)
  pixels.show()
  time.sleep(1)

# Finish with pixels off
pixels.fill((0, 0, 0))
pixels.show()

neopixels-demo.py

[編輯 | 編輯原始碼]
#!/usr/bin/python3
import board
import neopixel
from random import randrange
import time


# NeoPixels must be connected to D10, D12, D18 or D21 to work.
pixel_pin = board.D18

# The number of NeoPixels
num_pixels = 3

# The order of the pixel colors - RGB or GRB. Some NeoPixels have red and green reversed!
ORDER = neopixel.GRB

pixels = neopixel.NeoPixel(pixel_pin, num_pixels, auto_write=False,
                           pixel_order=ORDER)


def wheel(pos):
    # Input a value 0 to 255 to get a color value.
    # The colours are a transition r -> g -> b -> back to r.
    if pos < 0 or pos > 255:
        r = g = b = 0
    elif pos < 85:
        r = int(pos * 3)
        g = int(255 - pos*3)
        b = 0
    elif pos < 170:
        pos -= 85
        r = int(255 - pos*3)
        g = 0
        b = int(pos*3)
    else:
        pos -= 170
        r = 0
        g = int(pos*3)
        b = int(255 - pos*3)
    return (r, g, b)


def rainbow_cycle(wait):
    for j in range(255):
        for i in range(num_pixels):
            pixel_index = (i * 256 // num_pixels) + j
            pixels[i] = wheel(pixel_index & 255)
        pixels.show()
        time.sleep(wait)


def fade_in_out(wait):
    for j in range(255):
        pixels[0] = (j,0,0)
        pixels[1] = (0,j,0)
        pixels[2] = (0,0,j)
        pixels.show()
        time.sleep(wait)
    for j in range(254,0,-1):
        pixels[0] = (j,0,0)
        pixels[1] = (0,j,0)
        pixels[2] = (0,0,j)
        pixels.show()
        time.sleep(wait)


def random_leds(times, wait):
    for i in range(times):
        for j in range(num_pixels):
            pixels[j] = (randrange(256),randrange(256),randrange(256))
        pixels.show()
        time.sleep(wait)


while True:
    pixels.fill((255, 0, 0))   # Red = 255, Green = 0, Blue = 0
    pixels.show()
    time.sleep(1)

    pixels.fill((0, 255, 0))
    pixels.show()
    time.sleep(1)

    pixels.fill((0, 0, 255))
    pixels.show()
    time.sleep(1)

    pixels.fill((255, 255, 255))
    pixels.show()
    time.sleep(1)

    rainbow_cycle(0.02)

    fade_in_out(0.02)

    for i in range(num_pixels):
        pixels.fill((0,0,0))
        pixels[i] = (255, 0, 0)
        pixels.show()
        time.sleep(1)

    random_leds(100, 0.1)

neopixels-explained.py

[編輯 | 編輯原始碼]
#!/usr/bin/python3
# To set everything up in Raspbian Buster:
#   Raspberry menu - Preferences - Raspberry pi configuration - SPI enable - I2C enable
#   Raspberry menu - Shutdown - Reboot
# Then install the libraries:
#   sudo pip3 install rpi_ws281x adafruit-circuitpython-neopixel
# Note that you may need to use sudo to run programs using the neopixel library
# You can manage without sudo by just using rpi_ws281x, but it's not as easy as neopixel

import board, neopixel, time

# Our strip is on pin 18
# There are 3 LED in our strip
# Don't automatically update the pixels without the show() command
# Colours are in Red Green Blue order (some strips use GRB)
pixels = neopixel.NeoPixel(board.D18, 3, auto_write=False, pixel_order=neopixel.RGB)

pixels[0] = (255, 0, 0)
pixels[1] = (0, 255, 0)
pixels[2] = (0, 0, 255)
pixels.show()

time.sleep(2)

pixels.fill((0, 0, 0))
pixels.show()

neopixels-off.py

[編輯 | 編輯原始碼]
#!/usr/bin/python3
import board, neopixel, time
pixels = neopixel.NeoPixel(board.D18, 3, auto_write=False, pixel_order=neopixel.RGB)
pixels.fill((0, 0, 0))
pixels.show()

neopixels-start.py

[編輯 | 編輯原始碼]
import board, neopixel, time
pixels = neopixel.NeoPixel(board.D18, 3, auto_write=False, pixel_order=neopixel.RGB)

pixels[0] = (255, 0, 0)
pixels[1] = (0, 255, 0)
pixels[2] = (0, 0, 255)
pixels.show()

time.sleep(2)

pixels.fill((0, 0, 0))
pixels.show()

neopixels-traffic.py

[編輯 | 編輯原始碼]
import board, neopixel, time
pixels = neopixel.NeoPixel(board.D18, 3, auto_write=False, pixel_order=neopixel.RGB)

while True:
  pixels[0] = (255, 0, 0)
  pixels[1] = (0, 0, 0)
  pixels[2] = (0, 0, 0)
  pixels.show()
  time.sleep(10)

  pixels[0] = (255, 0, 0)
  pixels[1] = (255, 255, 0)
  pixels[2] = (0, 0, 0)
  pixels.show()
  time.sleep(2)

  pixels[0] = (0, 0, 0)
  pixels[1] = (0, 0, 0)
  pixels[2] = (0, 255, 0)
  pixels.show()
  time.sleep(14)

  pixels[0] = (0, 0, 0)
  pixels[1] = (255, 255, 0)
  pixels[2] = (0, 0, 0)
  pixels.show()
  time.sleep(3)
華夏公益教科書