ESP32 C3实现Arduino控制24位WS2812彩色灯的渐变色与七彩流光效果
渐变色原理:
首先需要添加一个库文件
顺序为:项目->加载库->管理库
搜索:Adafruit_NeoPixel,并下载
源码:
// 调用Adafruit_NeoPixel模块
#include <Adafruit_NeoPixel.h>
// 设置灯珠数量
#define NUMPIXELS 24
// 设置SPI输出数据引脚
#define PIN_NEOPIXEL 6
// 初始化灯珠控制实例
Adafruit_NeoPixel pixels(NUMPIXELS, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);
// 当前灯珠指向
int16_t idx = 0;
// 启动设置
void setup() {
// 调试串口速率设置
Serial.begin(115200);
// 灯珠控制开始
pixels.begin();
// 设置亮度为255
pixels.setBrightness(255);
// 设置灯珠颜色,全部关闭
pixels.fill(0x000000);
delay(100);
// 设置灯珠颜色
pixels.fill(0xFF0000);
delay(100);
pixels.clear();
}
uint16_t c1 = 0;
uint16_t c2 = 0;
uint16_t c3 = 0;
uint16_t sign_bit =0;
uint16_t sign = 1;
// 循环主体程序
void loop() {
if(sign_bit == 0){//这个if语句在循环体内只运行一次,该if语句及下方if语句可以用switch代替
if(sign){
c1++;
if(c1>=255)
sign=0;
}else{
c2++;
if(c2>=255){
sign=1;
sign_bit = 1;
}
}
}
if(sign_bit == 1){
if(sign){
c1--;
if(c1<=0)
sign=0;
}else{
c3++;
if(c3>=255){
sign=1;
sign_bit = 2;
}
}
}
if(sign_bit == 2){
if(sign){
c2--;
if(c2<=0)
sign=0;
}else{
c1++;
if(c1>=255){
sign=1;
sign_bit = 3;
}
}
}
if(sign_bit == 3){
if(sign){
c3--;
if(c3<=0)
sign=0;
}else{
c2++;
if(c2>=255){
sign=1;
sign_bit = 1;
}
}
}
//在这里注释的是一个一个将灯珠点亮并实现渐变
idx++;
if(idx > 24){
idx = 0;
}
pixels.setPixelColor(idx, pixels.Color(c1,c2,c3));
/*=======================================
全部点亮用该函数
pixels.fill(pixels.Color(c1,c2,c3));
=======================================*/
delay(10);//延时,改变速度
// 显示
pixels.show();
}
}
视频效果:
VID_20220802_091105
上方则就是实现渐变色的算法
至于实现七彩流光效果,原理图如下
我们先将灯珠的颜色分为24个等级,再将灯点亮,先不要让灯珠颜色转动,代码原理如上图
成功点亮后,初始化时将灯珠保存于数组中,在循环体中依次将数组中的元素往后移动一个位置
相关的方法有很多,也有直接将分好等级的灯珠每一个直接开始渐变的,下面的方法我认为是最简单理解的了
代码:
// 调用Adafruit_NeoPixel模块
#include <Adafruit_NeoPixel.h>
// 设置灯珠数量
#define NUMPIXELS 24
// 设置SPI输出数据引脚
#define PIN_NEOPIXEL 6
// LED引脚设置
#define PIN_LED 18
// 初始化灯珠控制实例
Adafruit_NeoPixel pixels(NUMPIXELS, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);
// 当前灯珠指向
int16_t idx = 0;
//初始化将灯珠的等级保存于数组中
int16_t ArraySave[NUMPIXELS][3] = {0};
// 启动设置
void setup() {
// 调试串口速率设置
Serial.begin(115200);
pinMode(PIN_LED, OUTPUT);
// 灯珠控制开始
pixels.begin();
// 设置亮度为255
pixels.setBrightness(255);
// 设置灯珠颜色,全部关闭
pixels.fill(0x000000);
delay(100);
// 设置灯珠颜色
pixels.fill(0xFF0000);
delay(100);
pixels.clear();
int j = 0;
for(j=0;j<NUMPIXELS/3;j++){
pixels.setPixelColor(j,pixels.Color(248-255/(NUMPIXELS/3)*j,255/(NUMPIXELS/3)*j,0));
ArraySave[j][0]=248-255/(NUMPIXELS/3)*j;
ArraySave[j][1]=255/(NUMPIXELS/3)*j;
ArraySave[j][2]=0;
}
for(j=0;j<NUMPIXELS/3;j++){
pixels.setPixelColor(j+8,pixels.Color(0,248-255/(NUMPIXELS/3)*j,255/(NUMPIXELS/3)*j));
ArraySave[j+NUMPIXELS/3][0]=0;
ArraySave[j+NUMPIXELS/3][1]=248-255/(NUMPIXELS/3)*j;
ArraySave[j+NUMPIXELS/3][2]=255/(NUMPIXELS/3)*j;
}
for(j=0;j<NUMPIXELS/3;j++){
pixels.setPixelColor(j+16,pixels.Color(255/(NUMPIXELS/3)*j,0,248-255/(NUMPIXELS/3)*j));
ArraySave[j+NUMPIXELS/3*2][0]=255/(NUMPIXELS/3)*j;
ArraySave[j+NUMPIXELS/3*2][1]=0;
ArraySave[j+NUMPIXELS/3*2][2]=248-255/(NUMPIXELS/3)*j;
}
}
uint16_t c1 = 0;
uint16_t c2 = 0;
uint16_t c3 = 0;
uint16_t sign_bit =0;
uint16_t sign = 1;
// 循环主体程序
void loop(){
uint16_t i = 0,k = 0;
uint16_t t[3] = {0};
for(k=0;k<3;k++){
t[k]=ArraySave[0][k];
}
for(i=0;i<NUMPIXELS;i++){
for(k=0;k<3;k++){
ArraySave[i][k]=ArraySave[i+1][k];
}
pixels.setPixelColor(i,ArraySave[i][0],ArraySave[i][1],ArraySave[i][2]);
}
for(k=0;k<3;k++){
ArraySave[NUMPIXELS-1][k]=t[k];
}
pixels.setPixelColor(NUMPIXELS-1,ArraySave[NUMPIXELS-1][0],ArraySave[NUMPIXELS-1][1],ArraySave[NUMPIXELS-1][2]);
delay(50);
// 显示
pixels.show();
}
视频效果:
VID_20220802_091200
当然,点亮的方式有很多种,可以实现很多花样,具体算法自己琢磨吧