Neopixel 是很多 maker 愛用的 RGB 七彩燈條,不管在 arduino、microbit 或數莓派的平台上,都有廣泛的應用,甚至可以輕易找到對應的函示庫應用,這篇來聊聊 NeoPixel RGB 燈條原理與在 ESP32 平台上怎麼使用。
1. NeoPixel RGB 燈條原理
一般在市面上 neopixel 的 RGB 燈條通常會製作成長條或環狀,以配合不同的產品應用。如果我們仔細觀察燈條上的元件,其實就是一顆 WS2812 系列的 RGB LED 晶片串聯組成,最常見的型號是 WS2812B,2812 整合數位通訊協定與 LED 的封裝,所以只要將電源與 GND 連接後,就可以透過單條的訊號線完成數據的傳送,下面為 WS2812B 的接腳定義:(圖片截取自 ws2812b datasheet)
由上圖來看,除了剛剛提到的 VDD VSS DIN 三隻腳外,還有一支 DOUT 腳位,各位朋友可能會好奇這是做什麼的?JIMI 哥先來講一下傳統 LED 在多顆應用上的缺點,以前 LED 如果一次要使用多顆且需單獨獨立控制時,在每顆 LED 就會有一支控制腳位來進行控制,這樣的結果就會導致在電路上的佈局繁瑣,10 顆LED就需要 10 條控制線路,100 顆豈不是要 100 條?所以 DOUT 這個腳位就是被設計用來『串接』多顆 LED 用途。下面就是多顆 2812 LED 串接的典型連接圖:
注意到了嗎? 從最上方的第1顆 LED (U1)開始,DIN 接收我們控制器傳給 2812 的數據命令, DOUT 就連接到第 2 顆 LED(U2)的 DIN 腳位,以此類推,第 2 顆的 DOUT 就連接到第 3 顆的 DIN,串接越多顆,也僅是 DOUT->DIN 連接越多次,如此一來,明顯地減少佈線的複雜度。至於 DOUT 腳位是什麼功能呢?為什麼只要將 DOUT 連到下一顆 LED DIN,就可以不用為每個 LED 連接控制線?JIMI哥 用白話一點的方式解釋:當DIN 收到指令後,內部的邏輯處理會將屬於自己的指令留下,DOUT 就會『PASS』 剩下指令出去,這就是為什麼只要把 DOUT 接到下一個 DIN,就可以進行資料傳輸的原因 。
這樣的連接架構解決了多顆 LED 佈線的問題,有沒有缺點? 當然有~當你用一顆傳一顆的傳送架構的來傳遞數據時,最大的問題就是 Delay,少顆的 LED 延遲效應不明顯,當到了 100 顆呢?或許就會有一點點的時間差,這對於在一些特別講究時間差的應用上(如視覺暫留 POV),就可能需要計算調整相關的參數。
另一個需要知道的細節就是電源的供應電流,JIMI哥查了一下 2812 的官網資料(www.worldsemi.com),此顆LED 在運作時的功率可以達到 0.24W,單顆 LED 消耗電流可以到 48mA(0.24w/5v),假設簡化成 50mA,當使用 LED 燈條時,各位朋友可以試著去計算燈條上的 LED 數量,也就是要使用功率多大的 5V 電源,燈條上有10顆,就記得選用0.05A*10=0.5A,同時加上一顆 100uF-470uF 大電容到 5V,讓 LED 控制時可以電源波動可以更小,盡量不要無腦直接去使用 ESP32S 5v 電源,因為電腦的 USB port 標準通常是只有 0.5A 電流供應,注意這些細節就可以避免系統異常狀況發生。
2. neopixel 類別
micropython 已經內建 neopixel 的模組可以直接使用,所以直接 import 匯入使用,下面為操作範例:
import machine, neopixel np = neopixel.NeoPixel(machine.Pin(14), 2) #指定GPIO14為數據輸出腳位,neopixel有兩顆LED np[0]=(255,255,100) #第1顆LED燈的顏色 np[1]=(100,100,100) #第2顆LED燈的顏色 np.write() #啟動傳輸並點亮LED
因為 neopixel 是利用實體的 GPIO 腳位來進行資料傳輸,所以這邊要匯入 machine 和 neopixel 兩個模組。再來就是建立起 neopixel 的物件, neopixel.NeoPixel(machine.Pin(14), 2) 這個方法的第一個參數為指定的 GPIO 物件,範例是使用 GPIO14,第2個參數是指這個 neopixel 燈條有幾顆 RGB LED,也就上面放了幾顆的 WS2812B。第3-4行就是指定 RGB LED 的顏色,np[0] 是指定第 1 顆 LED,np[1] 也就是第 2 顆,顏色的表示法是 RGB 色碼,刮號內的數值分別代表R、G、B 數值。 第 5 行為將這些參數寫入 neopixel 的模組內,同時啟動點亮。
3. NeoPixel 跑馬燈
– 電路連接
由於 NeoPixel 燈條通常已經把內部需要的線路都設計完成,各位朋友只要確認燈條的功率與電壓後,將 DIN、5V、 GND 連接至 ESP32 對應的腳位連接即可。(此處的 DIN 連接到 ESP32 GPIO14)
(不知道要選那支腳位做為資料傳輸的話,可以參考這篇 :EPS32 IO 基本知識 )
– 完整程式碼
JIMI哥 這邊用 micropython 官方說明文件的跑馬燈程式加個 RGB 變化做簡單示範。
import machine,neopixel,utime np = neopixel.NeoPixel(machine.Pin(14), 8) try: while 1: for i in range(16*3): if (i//16)==0: l=64;m=0;n=0 elif (i//16)==1: l=0;m=64;n=0 elif (i/16)==2 : l=0;m=0;n=64 for j in range(8): np[j] = (l,m,n) if (i // 8) % 2 == 0: np[i % 8] = (0, 0, 0) else: np[8 - 1 - (i % 8)] = (0, 0, 0) np.write() utime.sleep_ms(100) except: for i in range(8): np[i] = (0, 0, 0) np.write()
– 程式說明
import machine,neopixel,utime np = neopixel.NeoPixel(machine.Pin(14), 8)
這邊建立起 neopixel 的物件,並指定 ESP32 的 GPIO14 作為資料傳輸,設定 neopixel 的 LED 顆數有 8 顆。
try: while 1: for i in range(16*3): if (i//16)==0: l=64;m=0;n=0 #set led to red elif (i//16)==1: l=0;m=64;n=0 #set led to green elif (i/16)==2 : l=0;m=0;n=64 #set led to blue for j in range(8): np[j] = (l,m,n)
先說明一下這個程式的主要動作:每當跑馬燈來回一次時,需變換一次顏色。所以先將跑馬燈的來回一次的程序進行編號,來回一次的狀態編號為 0-15(共 16 個狀態),因為共 3 次變化(R-G-B),所以共 16*3 個狀態,當程序處於 0-15編號時,LED顯示紅色 np[]=(64,0,0)
,當程序處於16-31編號時,LED則為綠色 np=(0,64,0)
,以此類推。
if (i // 8) % 2 == 0: np[i % 8] = (0, 0, 0) else: np[8 - 1 - (i % 8)] = (0, 0, 0) np.write() utime.sleep_ms(100)
這段程式碼決定在每次迴圈時,LED 燈滅的位置,各位朋友可以簡單帶入迴圈的數字,即可以得知每次燈滅的位置在哪。utime.sleep_ms() 為每次迴圈 delay 的時間,數字大小也決定跑馬燈的來回速度。
except: for i in range(8): np[i] = (0, 0, 0) np.write()
最後利用 except 語法,當系統中斷時,關閉所有 neopixel 的 LED 燈。
4. 總結
neopixel 是相當常見的 RGB LED 燈條,配合 micropython 內建的函示庫,可以很快在 ESP32 實現想要的燈光效果,如呼吸燈、色域變化等,且 python 語法另一個好處就是網路上都可以找到好用的 Library 可以參考,所以像是 HSV 轉 RGB 或呼吸函數等等,就可以不用自己改寫,縮短開發時間,各位如果有時間的話,可以自己在動手試試看~
今天的內容就到這邊,如果有遇到什麼問題,歡迎在下面留言或寫信與我討論!~
↓↓↓↓↓↓賣場連結↓↓↓↓↓↓
歡迎大家有需要的話,可以多多支持一下我們的蝦皮賣場喔! 😀
吉米家官方店-創客機器人材料專賣 https://shopee.tw/jimirobot.tw
Follow JIMI哥 Twitter : https://twitter.com/jimirobot <–得到最新文章通知