使用Arduino简化编程并不是什么新鲜事。几乎所有内容都有Arduino库,并且即使您是一个很笨的初学者,也可以使用其中的一个或多个库来制作很棒的小项目。对LED进行编程也不例外,FastLED库当然简化了这一过程。
在本文中,我们将大致讨论数字LED,并提供一些有关如何使用FastLED库的示例。
目录
什么是数字RGB LED?
对此的一个答案是,您可以使用少量电线(与LED数量无关)单独控制LED。这些LED通常以LED灯带或LED矩阵的形式出现,但也可以是单独的LED,它们之间通过电线连续连接在一起。在文章中,我们将重点介绍LED灯条。
LED条只是一排LED,通常在一侧像胶带一样带有粘合剂。沿着带状结构,可以有三根或四根电导体,具体取决于类型。这些导体中的三个是电源电压,接地和数据信号。在某些类型的LED灯条上,您还有一个时钟信号作为第四根导线。这些带有专用时钟信号的同步LED灯带被认为比只有三根导线的异步LED灯带更坚固。
LED灯带的类型很多。WS2811 / WS2812及其相关版本是一些常见的版本。这些是异步LED,有些地方更名为NeoPixel。其他常见的是WS2801和APA102,它们都是同步的。后者是某些地方更名为SuperLED的地方。
这些类型的LED灯带的一个非常方便的特性是,您可以将其切割成任意长度。只需订购一个大卷的LED灯条,并切断小工具所需的电量即可。
所有LED均可单独控制,并且条带可以切割成所需的长度
RGB与HSV
RGB是Red Green Blue的首字母缩写。使用这三个通道,您可以重新创建任何颜色。这些通道通常由8位(值0-255)表示,但不一定。
HSV是表示相同颜色的另一种方法,但另一方面,它是Hue Saturation Value的首字母缩写。这可能是首选方法,因为它有时会使颜色更清晰地参数化:Hue决定颜色是红色,蓝色等,Saturation控制与纯白光相比存在多少颜色,而Value控制光强度。如果Value通道为零,则无论其他两个通道是什么,LED都将关闭。HSV在每个通道的分辨率方面类似于RGB。
LED功耗和USB电流限制
当将Arduino连接到USB端口以供电时,绝对不要超过500mA。
您应该始终检查LED灯带,看看它可能消耗多少功率,通常将其指定为每米瓦特数或整个灯带长度仅瓦特数。此数字表示全强度的白色。您还应该知道带材每米有多少个LED。这里常见的数字是每米30、60和144个LED。
让我们用两个不同的例子来计算每个LED消耗多少mA:
例子1
APA102
- 5伏
- 60 LED /米
- 18瓦/米
我们将功率(18)除以LED密度(60),得到0.3 W / LED。我们将其除以电压(5),得到60 mA / LED。
例子2
WS2812b
- 5伏
- 30个LED /米
- 45 W /条
- 条带长度5 m
我们将功率(45)除以长度5得到9 W / m。然后,将这个数字除以LED密度(30),得到0.3 W / LED。这与示例1中的相同,并且由于电压也相同,因此得到60 mA / LED。
这些数字告诉我们什么?
要保持低于500mA(这在使用USB作为电源时非常重要),您不应该在这些LED灯带上打开超过500/60≈8个全白强度的LED。
如果仅使用RGB通道之一,则LED只会消耗大约先前计算值(20 mA)的三分之一。在这种情况下,我们可以将500/20 = 25个LED设置为全红,绿或蓝强度,而不会超过最大USB电流限制。在这种情况下,更容易设置RGB值而不是HSV值。
伽玛校正
您应该记住,人类不会线性感知LED的强度。我们发现1-10之间的差异比246-255之间的差异大得多。本文解释了这种现象。
FastLED库
这是一个Arduino库,可为您完成所有低级操作,因此您只需设置需要将哪些LED更新为哪种颜色值即可。
芯片组和平台支持
该库的主要优点在于,它可以与一长串LED类型(也称为芯片组)一起使用:
- LPD8806
- WS2801
- SM16716
- P9813 –又名。全面控制照明
- APA102 –又名。超级LED
- WS2811 / WS2812 / WS2812b –又名。NeoPixel
- TM1809 / TM1804
- TM1803
- UCS1903 / UCS1903B / UCS1904 / UCS2903
- GW6205
- LPD1886
除了Arduino外,该库还可以在同一类别的其他多个平台上使用。
例子
在以下示例中,我们使用带有22个LED的WS2812b LED灯条。
例子1
#include "FastLED.h"
// How many leds in your strip?
#define NUM_LEDS 22
#define DATA_PIN 5
//#define CLOCK_PIN 13
CRGB leds[NUM_LEDS];
void setup() {
// Uncomment/edit one of the following lines for your leds arrangement.
// FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
// FastLED.addLeds<APA104, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<SM16716, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<LPD8806, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<P9813, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<APA102, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<DOTSTAR, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
// FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
}
void loop() {
for(int i=0; i<NUM_LEDS; i++){
leds[i] = CHSV(160, 255, 128);
FastLED.show();
delay(50);
leds[i] = CHSV(0,0,0);
FastLED.show();
}
}
这些行中的大多数都被注释掉,只是为了显示您需要包括的内容,具体取决于您的LED类型。如您所见,由于我们正在使用WS2812b,因此我们未对其进行注释。我们还注释掉了CLOCK_PIN定义,因为我们不在此LED灯条上使用时钟引脚。
此代码将LED设置为强度为50%的蓝色,并在关闭之前将其保持打开状态50毫秒,然后继续执行测试条上的下一个LED,直到所有LED都轮到为止,然后重新开始。
注意该FastLED.show()功能。这有点像刷新功能,它将所需的状态发送到每个LED。自上次调用该功能以来未更改其状态的LED将保持其最后状态。您不必为要更改的每个LED都调用此功能,只需在要刷新所有LED时调用它即可。
例子2
#include "FastLED.h"
#define NUM_LEDS 22
#define DATA_PIN 5
#define TWO_HUNDRED_PI 628
CRGB leds[NUM_LEDS];
int element = 0;
int last_element = 0;
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
}
void loop() {
for(int i=0; i<TWO_HUNDRED_PI; i++){
element = round((NUM_LEDS-1)/2*(sin(i/100.0)+1));
leds[element].g = 64;
FastLED.show();
delay(1);
if(element < last_element){
leds[element].g = 0;
FastLED.show();
}
last_element = element;
}
}
此代码以25%的绿色强度逐一点亮所有LED,然后以正弦波模式逐一关闭所有LED。
例子3
在最后一个示例中,我们将进行一些LED衰减。
#include "FastLED.h"
#define NUM_LEDS 22
#define DATA_PIN 5
#define TWO_HUNDRED_PI 628
#define TWO_THIRDS_PI 2.094
CRGB leds[NUM_LEDS];
int val1 = 0;
int val2 = 0;
int val3 = 0;
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
}
void loop() {
for(int i=0; i<TWO_HUNDRED_PI; i++){
val1 = round(255/2.0*(sin(i/100.0)+1));
val2 = round(255/2.0*(sin(i/100.0+TWO_THIRDS_PI)+1));
val3 = round(255/2.0*(sin(i/100.0-TWO_THIRDS_PI)+1));
leds[7] = CHSV(0, 255, val1);
leds[8] = CHSV(96, 255, val2);
leds[9] = CHSV(160, 255, val3);
FastLED.show();
delay(1);
}
}
在这里,我们以正弦波模式上下衰减具有三种不同颜色的三个独立的LED。每个LED之间的淡入周期相移60度。
总结
LED是嵌入式系统中最酷的东西,使用Arduino和FastLED库使LED的工作变得非常容易。该库具有比我们在这些示例中使用的功能更多的功能。
请问三个灯珠一个IC的怎么控制? ✗咧嘴笑✗
调用库就行,库里面有设置灯的函数。#define里有设置连接的RGB灯的引脚,这是只有一个数据引脚的,通过库很方便控制
你好,请问单独控制多条灯带的亮度应该如何完成?