溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

.NET與樹(shù)莓派控制彩色燈帶WS28XX怎么實(shí)現(xiàn)

發(fā)布時(shí)間:2022-04-06 10:17:41 來(lái)源:億速云 閱讀:195 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容介紹了“.NET與樹(shù)莓派控制彩色燈帶WS28XX怎么實(shí)現(xiàn)”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

彩色燈帶,相信不用老周多說(shuō),大家都知道,沒(méi)準(zhǔn)你家里的燈墻里面就有。老周的茅屋是早期建造的,所以沒(méi)有預(yù)留的燈槽,明燈的話是不好看的,因此老周家里沒(méi)使用燈帶。不過(guò),像柜子后面,顯示器后面,書(shū)桌邊沿這些地方,可以貼彩色燈帶。書(shū)架上也貼了一些,因?yàn)槟莻€(gè)書(shū)架是圣誕樹(shù)形狀的,沒(méi)辦法一條燈帶貼完,只能把它剪開(kāi) N 段,測(cè)算好每一段的距離,再用烙鐵加線重新焊接起來(lái)(嫌麻煩的話可以直接買連接頭,不用焊接)。

買燈帶時(shí)老周沒(méi)有買驅(qū)動(dòng)器,畢竟一開(kāi)始老周就計(jì)劃自己寫(xiě)個(gè)程序來(lái)控制燈帶的色彩。裝飾用的燈帶,5V 電壓足矣。如果燈較多可以考慮獨(dú)立供電,5V電源比較方便好弄,手機(jī)充電頭、鋰電池+5V穩(wěn)壓板即可輕松解決。其實(shí),兩米長(zhǎng)度內(nèi)直接用開(kāi)發(fā)板供電都沒(méi)啥問(wèn)題。要是五米一卷的,用樹(shù)莓派的5V引腳供電沒(méi)有問(wèn)題,但用 ESP32 的話,電壓好像有點(diǎn)不夠,亮度降低。

老周的臥室里面目前使用的裝飾燈是用 ESP 32 做的,兩顆18650電池供電(需要穩(wěn)壓模塊調(diào)到5V電壓)。主要是看中 ESP32有 WiFi 功能,上面寫(xiě)個(gè) UDP 服務(wù)器,通過(guò)接收到的命令來(lái)切換燈帶顏色。

控制命令比較簡(jiǎn)單,全用文本格式,客戶端只要發(fā)送滿足格式要求的命令到 ESP32 即可。比如,發(fā)送

SET+255 125 127

首先識(shí)別出“SET+”,后面三個(gè)數(shù)值用空格分隔,依次表示 RGB 三個(gè)值。例如,讓燈變成藍(lán)色

SET+0 0 255

彩色燈帶使用 WS28XX 作為IC,常見(jiàn)的像 WS2812B。每個(gè)燈珠都可以單獨(dú)控制,燈帶剪開(kāi)后只需要串聯(lián)好就行,燈帶末端不需要連接回路,WS28XX 自帶回路。

WS28XX 的時(shí)序其實(shí)很簡(jiǎn)單,+5V 和 GND 是供電接口,剩下一根數(shù)據(jù)線來(lái)傳輸信號(hào),所以這貨是單數(shù)據(jù)線控制的。當(dāng)N個(gè)燈珠串聯(lián)起來(lái)后,第一個(gè)燈珠的 Din 輸入信號(hào),Dout 輸出信號(hào);第一個(gè)燈珠 Dout 聯(lián)第二個(gè)燈珠的 Din;第二個(gè)燈珠的 Dout 聯(lián)第三個(gè)燈珠的 Din ……

.NET與樹(shù)莓派控制彩色燈帶WS28XX怎么實(shí)現(xiàn)

我們都知道,RGB三個(gè)值,各為一個(gè)字節(jié),8位,三個(gè)值合起來(lái) 24 位,所以每個(gè)燈珠的數(shù)據(jù)為24位,3個(gè) byte。對(duì)于每個(gè)二進(jìn)制位,WS28XX 是通過(guò)單周期內(nèi)高電平的持續(xù)時(shí)間來(lái)判斷 0 或 1。

請(qǐng)看下面的高清無(wú)碼美圖。

.NET與樹(shù)莓派控制彩色燈帶WS28XX怎么實(shí)現(xiàn)

上面這個(gè)就是 WS28XX 的時(shí)序圖。在一個(gè)脈沖周期內(nèi),如果:

高電平持續(xù)時(shí)間為 0.4 微秒,低電平持續(xù)時(shí)間為 0.85 微秒,那么就是0;

高電平持續(xù)時(shí)間為 0.85 微秒,低電平持續(xù)時(shí)間為 0.4 微秒,那么就是1。

故一個(gè)周期的總時(shí)長(zhǎng)為 1.25 微秒,即頻率為 1000000 / 1.25 = 800 KHz,即 0.8 MHz。

請(qǐng)記住這個(gè)頻率,后面有用。

WS28XX的信號(hào)是連續(xù)發(fā)的,中間不需要停頓;如果出現(xiàn)超過(guò) 50 微秒的低電平,那么WS28XX會(huì)認(rèn)為你的信號(hào)發(fā)送完畢。如果數(shù)據(jù)線上有數(shù)據(jù)來(lái)就會(huì)從第一個(gè)燈珠開(kāi)始進(jìn)行處理(等于更新整個(gè)燈帶的數(shù)據(jù))。

例如,有四個(gè)燈珠串聯(lián),每個(gè)燈的RGB有24位,那么,你需要向WS28XX連續(xù)發(fā)送 24 * 4 = 96 位數(shù)據(jù),數(shù)據(jù)發(fā)送中不要停頓,所有數(shù)據(jù)都是連著發(fā)的—— 96位連續(xù)發(fā),中間不用停頓;全部發(fā)完后再輸出50微秒左右的低電平表示結(jié)束發(fā)送。

比如,紅色,RGB 是 255,0,0,那么這24位就是:

1111 1111 0000 0000 0000 0000

如果有三個(gè)燈珠,第一個(gè)燈珠設(shè)置為綠色,第二個(gè)燈珠為白色,第三個(gè)燈珠為藍(lán)色,那么三組RGB為:

【0,255,0】【255,255,255】【0,0,255】

于是,72位二進(jìn)制為:

0000 0000 1111 1111 0000 0000 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000 1111 1111

在發(fā)送的時(shí)候,這72位是連續(xù)發(fā)送的,中間不需要延時(shí),發(fā)完后把電平拉低,50 us后WS28XX就會(huì)認(rèn)為你已經(jīng)發(fā)完數(shù)據(jù)。

 正如你所看到的,WS28XX 的通信協(xié)議比較簡(jiǎn)單。但是,問(wèn)題出在它的時(shí)間很短。你如果純手動(dòng)寫(xiě)代碼來(lái)改變電平的高低,要求程序有很高的性能。低配的單片機(jī)可能不夠快,像樹(shù)莓派這樣的開(kāi)發(fā)板,雖然處理器肯定比單片機(jī)快,但是代碼傳遞到系統(tǒng)驅(qū)動(dòng),再由驅(qū)動(dòng)傳到底層硬件。而且每次切換電平需要來(lái)回兩次通信,花的時(shí)間太長(zhǎng),都有可能超出 1.25 us 的周期。

所以,一般不采取直接寫(xiě)GPIO電平的方式通信,而是借助硬件上所支持的協(xié)議。能夠做這事的硬件協(xié)議有倆:

1、PWM。這個(gè)估計(jì)大家能理解,前面老周說(shuō)要記住那個(gè)通信頻率,現(xiàn)在用上了。把PWM頻率設(shè)為 800 KHz,然后一個(gè)周期的時(shí)長(zhǎng)就是 1.25 us。最后你一定猜到了,發(fā)送1時(shí),高電平持續(xù)0.85 us,占空比 68%;發(fā)送0時(shí),高電平持續(xù)0.4 us,占空比 32%。于是呢,不斷地改變占空比,就能給WS28XX發(fā)信號(hào)。許多方案是和DMA一起使用的,就是為了提高速度。.NET Iot 封裝的 PWM 不支持 DMA 方式,因此這個(gè)方案跳過(guò)。

2、SPI,這個(gè)方案是目前最優(yōu)秀方案。.NET Iot 封裝的庫(kù)也是采用 SPI 協(xié)議。這是個(gè)巧妙利用,將SPI的 MOSI 口與燈帶的 Din 連接,讓 SPI 時(shí)序來(lái)控制燈珠。

為啥不用 IIC (I2C)呢?因?yàn)?IIC 要從機(jī)地址啊,我們又不是真的使用 IIC 設(shè)備,所以這里不適合。根據(jù)官方的示例,使用SPI時(shí)要設(shè)置以下幾個(gè)參數(shù):

a、速率 2400 KHz,正好是 800 K 的三倍。于是乎,SPI 中 3 個(gè)二進(jìn)制位對(duì)應(yīng)WS28XX中 1 個(gè)二進(jìn)制位。要發(fā)送 1 ,SPI 寫(xiě)入二進(jìn)制 110;要發(fā)送 0 ,SPI 寫(xiě)入二進(jìn)制 100。一個(gè)燈珠的數(shù)據(jù)是3字節(jié)24位,那么 SPI 就得寫(xiě)入72位(9個(gè)字節(jié))。

 b、SPI 模式選擇 Mode0。

c、數(shù)據(jù)長(zhǎng)度為8位。

因?yàn)闃?shù)莓派是支持硬件 SPI 的,所以 SPI 方案是沒(méi)有問(wèn)題的。若開(kāi)發(fā)板沒(méi)有硬件 SPI(靠軟件模擬),就不能使用SPI方案了,速度跟不上。

知道原理后,咱們可以動(dòng)手做了。

第1步,引用 Iot.Device.Bindings 包(Nuget),依賴包 System.Device.Gpio 會(huì)自動(dòng)引入,所以不用管它。

第2步,using 以下命名空間:

using System.Device.Spi;
using System.Drawing;
using Iot.Device.Graphics;
using Iot.Device.Ws28xx;

第3步,初始化 SpiDevice 對(duì)象。

SpiConnectionSettings setting = new(0)
{
    Mode = SpiMode.Mode0,
    ClockFrequency = 2400_000,  //注意速率
    DataBitLength = 8
};
using SpiDevice spidev = SpiDevice.Create(setting);

把 ClockFrequency 設(shè)置為 2400,000 hz,原因前面解釋過(guò)。

第4步,老周買的燈帶是 WS2812B 芯片的,所以,實(shí)例化 WS28XX 時(shí)用 Ws2812b 類,大部分燈帶都是這個(gè)。

// 30表示使用30個(gè)燈珠,這個(gè)按實(shí)際來(lái)傳值,要用到50個(gè)燈珠,就傳50
const int LED_NUM = 30;
Ws28xx leds = new Ws2812b(spidev, LED_NUM);

老周現(xiàn)用來(lái)測(cè)試的燈帶是五米長(zhǎng)的,150 個(gè)燈,但為了省電,只選擇了 30 個(gè)燈做實(shí)驗(yàn),你可以根據(jù)實(shí)際情況改代碼。咱們這里用的燈帶,所以只考慮寬度,高度忽略;如果用的是點(diǎn)陣屏,則要考慮高度,即幾行幾列。

第5步,準(zhǔn)備七種常用顏色,待會(huì)咱們做色彩輪換效果。

Color[] colors =
{
    Color.Blue,         // 藍(lán)色
    Color.Yellow,       // 黃色
    Color.White,        // 白色
    Color.Red,          // 紅色
    Color.Green,        // 綠色
    Color.Pink,         // 粉色
    Color.Orange        // 橙色
};

第6步,色彩輪換,七種顏色輪著顯示。

// Color數(shù)組中正在使用的索引
int theIndex = 0;
// 進(jìn)入循環(huán),開(kāi)始溜燈
while (true)
{
    // 當(dāng)表示索引的值超出數(shù)組范圍后,重回0
    if (theIndex > colors.Length - 1)
    {
        theIndex = 0;
    }
    // 獲取位圖對(duì)象
    BitmapImage image = leds.Image;
    // 循環(huán)修改每個(gè)燈珠的顏色
    for (int x = 0; x < LED_NUM; x++)
    {
        // 更新像素點(diǎn)(對(duì)應(yīng)一個(gè)燈珠)
        image.SetPixel(x, 0, colors[theIndex]);
        // 調(diào)用更新,才會(huì)刷新燈帶顯示
        leds.Update();
        Thread.Sleep(10);
    }
    theIndex++;
    Thread.Sleep(1000);
}

可以把一個(gè)燈珠視為一個(gè)像素,先從 Image 屬性中獲得對(duì) BitmapImage 對(duì)象的引用,然后用 SetPixel 方法來(lái)設(shè)置每個(gè)燈的顏色。這里因?yàn)橛玫氖菬魩В?y 坐標(biāo)都是 0,僅改變 x 坐標(biāo)上的值。

修改完顏色后,如果想燈珠馬上更新,請(qǐng)調(diào)用 Update 方法。

最后,強(qiáng)調(diào)一下:接線時(shí),樹(shù)莓派的 MOSI 接燈帶的數(shù)據(jù)接口(Din 或 Di)。

.NET與樹(shù)莓派控制彩色燈帶WS28XX怎么實(shí)現(xiàn)

 如果SPI不能用,請(qǐng)執(zhí)行 sudo raspi-config,然后進(jìn)入“Interface Options”,確認(rèn) SPI 總線啟用。

.NET與樹(shù)莓派控制彩色燈帶WS28XX怎么實(shí)現(xiàn)

 看看最終效果。

.NET與樹(shù)莓派控制彩色燈帶WS28XX怎么實(shí)現(xiàn)

【補(bǔ)充】如果出現(xiàn)程序運(yùn)行幾秒鐘就“卡死”的情況,那是SPI被系統(tǒng)降頻了所致。若遇到此問(wèn)題,可以在 config.txt 文件中修改 GPU 超頻參數(shù)。

sudo nano /boot/config.txt

加上這兩行:

core_freq=250
core_freq_min=250

或者

core_freq=500
core_freq_min=250

這樣配置后,至少保證了 GPU 內(nèi)核在空閑時(shí)的頻率不低于 250 MHz。

“.NET與樹(shù)莓派控制彩色燈帶WS28XX怎么實(shí)現(xiàn)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI