零基础入门学用Arduino 第三部分(三)
重要的内容写在前面:
- 该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。
- 个人把这个教程学完之后,整体感觉是很好的,如果有条件的可以先学习一些相关课程,学起来会更加轻松,相关课程有数字电路(强烈推荐先学数电,不然可能会有一些地方理解起来很困难)、模拟电路等,然后就是C++(注意C++是必学的)。
- 文章中的代码都是跟着老师边学边敲的,不过比起老师的版本我还把注释写得详细了些,并且个人认为重要的地方都有详细的分析。
- 一些函数的介绍有参考太极创客官网给出的中文翻译,为了便于现查现用,把个人认为重要的部分粘贴了过来并做了一些修改。
- 如有错漏欢迎指正。
视频链接:3-0 本章介绍_哔哩哔哩_bilibili
太极创客官网:太极创客 – Arduino, ESP8266物联网的应用、开发和学习资料
三、LED灯带
1、FastLED库的安装
需要说明的是,在后面FastLED库的介绍中并不会详细介绍FastLED库的全部函数,仅展示部分函数的基本使用方法,另外不必深究一些弄不清的语法。
2、WS2812 LED灯带
(1)配合RGB-LED控制芯片,Arduino只需一个数字输入/输出引脚即可控制一个RGB-LED,如果将若干个RGB-LED控制芯片串联,那么Arduino只需一个数字输入/输出引脚即可控制若干个RGB-LED。
(2)将RGB-LED控制芯片与RGB-LED集成在一起,就是数字RGB-LED,虽然它与普通的RGB-LED一样有四个引脚,但二者的功能却不一样,数字RGB-LED的引脚功能取决于集成在它内部的芯片型号。下图所示的是WS2812(B) LED示意图,图中未说明的两个引脚,较短的一个接5V电源,较长的一个接GND,灯带中灯珠的供电电路连接方式为并联,控制信号电路的连接方式为串联,每一个WS2812 LED灯珠需60mA的电流才能达到最大亮度。
(3)下图所示的是WS2812(B) LED灯带实物。当不需要太长的灯带时,可以沿着灯带上的切割线(有一个剪刀图标)进行剪裁,然后自行在裁剪处焊接插针,不会影响灯带的正常使用。
3、使用Arduino控制LED灯带的电路
(1)开发时的Arduino控制LED电路如下图所示。
(2)使用时的Arduino控制LED电路(当USB未连接电脑时,Arduino可通过+5V引脚由电源模块进行供电)如下图所示。
4、FastLED库使用——基本点灯操作
(1)单个灯珠闪烁:
#include "FastLED.h" //此程序需要使用FastLED库#define NUM_LEDS 30 //LED灯珠数量
#define DATA_PIN 9 //Arduino输出控制信号引脚
#define LED_TYPE WS2812 //LED灯带型号
#define COLOR_ORDER GRB //RGB灯珠中红色、绿色、蓝色LED的排列顺序
uint8_t max_bright = 128; //LED亮度控制变量,可使用数值为0~255,数值越大,光带亮度越高CRGB leds[NUM_LEDS]; //为每个LED灯珠建立对象,将它们存放在数组leds中void setup()
{ Serial.begin(9600); //启动串行通讯delay(1000); //稳定性等待LEDS.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); //初始化灯带对象(不必纠结C++语法) FastLED.setBrightness(max_bright); //设置灯带亮度
}void loop()
{ leds[0] = CRGB::Red; //设置灯带中第一个灯珠颜色为红色,leds[0]为第一个灯珠,leds[1]为第二个灯珠FastLED.show(); //更新LED色彩delay(500); //等待500毫秒leds[0] = CRGB::Black; //设置灯带中第一个灯珠颜色为黑色,leds[0]为第一个灯珠,leds[1]为第二个灯珠FastLED.show(); //更新LED色彩delay(500); //等待500毫秒
}
①首先使用addLeds函数对灯带数组leds进行初始化,其中尖括号中的参数依次是灯带型号、输出灯带控制信号的Arduino引脚号、RGB灯珠中红绿蓝三种颜色的LED排列顺序,小括号中的参数依次是灯珠对象数组和灯珠数量;然后使用setBrightness函数设置灯带亮度,这个函数的作用不是点灯,而是设置当灯被点亮后的亮度参数。
②颜色参数的表示方式为“CRGB::<颜色名>”(Black表示熄灭灯珠),可以直接将颜色参数赋值给灯珠对象,然后使用show函数更新灯带的显示。
③对于灯珠对象数组,leds[0]控制灯带的第一个灯珠,leds[1]控制灯带的第二个灯珠,以此类推,通过反复让leds[0]在红色和黑色之间徘徊,可实现第一个灯珠闪烁的效果。
(2)一个光点顺着灯带“运动”:
#include "FastLED.h" //此程序需要使用FastLED库#define NUM_LEDS 30 //LED灯珠数量
#define DATA_PIN 9 //Arduino输出控制信号引脚
#define LED_TYPE WS2812 //LED灯带型号
#define COLOR_ORDER GRB //RGB灯珠中红色、绿色、蓝色LED的排列顺序
uint8_t max_bright = 128; //LED亮度控制变量,可使用数值为0~255, 数值越大则光带亮度越高CRGB leds[NUM_LEDS]; //为每个LED灯珠建立对象,将它们存放在数组leds中void setup()
{ Serial.begin(9600); //启动串行通讯delay(1000); //稳定性等待LEDS.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); //初始化灯带对象FastLED.setBrightness(max_bright); //设置灯带亮度
}void loop()
{ //依次点亮和熄灭灯带中灯珠,产生"光点移动"效果for (int i = 0; i <= NUM_LEDS; i++) {leds[i] = CRGB::Red;FastLED.show(); //第i个灯珠显示红色delay(50);leds[i] = CRGB::Black;FastLED.show(); //第i个灯珠熄灭delay(50); }delay(500);
}
①首先使用addLeds函数对灯带数组leds进行初始化,其中尖括号中的参数依次是灯带型号、输出灯带控制信号的Arduino引脚号、RGB灯珠中红绿蓝三种颜色的LED排列顺序,小括号中的参数依次是灯珠对象数组和灯珠数量;然后使用setBrightness函数设置灯带亮度,这个函数的作用不是点灯,而是设置当灯被点亮后的亮度参数。
②颜色参数的表示方式为“CRGB::<颜色名>”(Black表示熄灭灯珠),可以直接将颜色参数赋值给灯珠对象,然后使用show函数更新灯带的显示。
③对于灯珠对象数组,leds[0]控制灯带的第一个灯珠,leds[1]控制灯带的第二个灯珠,以此类推,使用for循环顺序遍历leds数组,每轮循环都仅控制一个灯珠的亮灭,由此可以实现依次点亮和熄灭灯带中灯珠,产生“光点移动”效果。
(3)一个变色的光点顺着灯带“运动”:
#include "FastLED.h" //此程序需要使用FastLED库#define NUM_LEDS 30 //LED灯珠数量
#define DATA_PIN 9 //Arduino输出控制信号引脚
#define LED_TYPE WS2812 //LED灯带型号
#define COLOR_ORDER GRB //RGB灯珠中红色、绿色、蓝色LED的排列顺序
uint8_t max_bright = 128; //LED亮度控制变量,可使用数值为0~255, 数值越大则光带亮度越高CRGB leds[NUM_LEDS]; //为每个LED灯珠建立对象,将它们存放在数组leds中void setup()
{ Serial.begin(9600); //启动串行通讯delay(1000); //稳定性等待LEDS.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); //初始化灯带对象FastLED.setBrightness(max_bright); //设置灯带亮度
}void loop()
{ //依次使用不同色彩点亮单个LED灯珠for (int i = 0; i <= NUM_LEDS; i++) {leds[i] = CRGB::Red;FastLED.show(); //第i个灯珠显示红色delay(20);leds[i] = CRGB::Green;FastLED.show(); //第i个灯珠显示绿色delay(20); leds[i] = CRGB::Blue;FastLED.show(); //第i个灯珠显示蓝色delay(20); leds[i] = CRGB::Black;FastLED.show(); //第i个灯珠熄灭delay(20); }delay(500);
}
①首先使用addLeds函数对灯带数组leds进行初始化,其中尖括号中的参数依次是灯带型号、输出灯带控制信号的Arduino引脚号、RGB灯珠中红绿蓝三种颜色的LED排列顺序,小括号中的参数依次是灯珠对象数组和灯珠数量;然后使用setBrightness函数设置灯带亮度,这个函数的作用不是点灯,而是设置当灯被点亮后的亮度参数。
②颜色参数的表示方式为“CRGB::<颜色名>”(Black表示熄灭灯珠),可以直接将颜色参数赋值给灯珠对象,然后使用show函数更新灯带的显示。
③对于灯珠对象数组,leds[0]控制灯带的第一个灯珠,leds[1]控制灯带的第二个灯珠,以此类推,使用for循环顺序遍历leds数组,每轮循环都仅控制一个灯珠多次变色,由此可以实现变色光点在灯带上“移动”的效果。
(4)三个连续的变色光点顺着灯带“运动”:
#include "FastLED.h" //此程序需要使用FastLED库#define NUM_LEDS 30 //LED灯珠数量
#define DATA_PIN 9 //Arduino输出控制信号引脚
#define LED_TYPE WS2812 //LED灯带型号
#define COLOR_ORDER GRB //RGB灯珠中红色、绿色、蓝色LED的排列顺序
uint8_t max_bright = 128; //LED亮度控制变量,可使用数值为0~255, 数值越大则光带亮度越高CRGB leds[NUM_LEDS]; //为每个LED灯珠建立对象,将它们存放在数组leds中void setup()
{ Serial.begin(9600); //启动串行通讯delay(1000); //稳定性等待LEDS.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); //初始化灯带对象FastLED.setBrightness(max_bright); //设置灯带亮度
}void loop()
{ //依次使用不同色彩点亮多个连续的LED灯珠for (int i = 0; i <= NUM_LEDS; i++) {leds[i-1] = CRGB::Red; //第i-1个灯珠显示红色leds[i] = CRGB::Red; //第i个灯珠显示红色leds[i+1] = CRGB::Red; //第i+1个灯珠显示红色FastLED.show();delay(50);leds[i-1] = CRGB::Green; //第i-1个灯珠显示绿色leds[i] = CRGB::Green; //第i个灯珠显示绿色leds[i+1] = CRGB::Green; //第i+1个灯珠显示绿色FastLED.show();delay(50); leds[i-1] = CRGB::Blue; //第i-1个灯珠显示蓝色leds[i] = CRGB::Blue; //第i个灯珠显示蓝色leds[i+1] = CRGB::Blue; //第i+1个灯珠显示蓝色FastLED.show();delay(50); leds[i-1] = CRGB::Black; //第i-1个灯珠熄灭leds[i] = CRGB::Black; //第i个灯珠熄灭leds[i+1] = CRGB::Black; //第i+1个灯珠熄灭FastLED.show();delay(50); }delay(500);
}
①首先使用addLeds函数对灯带数组leds进行初始化,其中尖括号中的参数依次是灯带型号、输出灯带控制信号的Arduino引脚号、RGB灯珠中红绿蓝三种颜色的LED排列顺序,小括号中的参数依次是灯珠对象数组和灯珠数量;然后使用setBrightness函数设置灯带亮度,这个函数的作用不是点灯,而是设置当灯被点亮后的亮度参数。
②颜色参数的表示方式为“CRGB::<颜色名>”(Black表示熄灭灯珠),可以直接将颜色参数赋值给灯珠对象,然后使用show函数更新灯带的显示。
③对于灯珠对象数组,leds[0]控制灯带的第一个灯珠,leds[1]控制灯带的第二个灯珠,以此类推,使用for循环顺序遍历leds数组,每轮循环都控制连续的三个灯珠多次变色,由此可以实现多个连续的变色光点在灯带上“移动”的效果。
(5)灯带的灯珠全部被点亮,然后全部被熄灭,以此往复:
#include "FastLED.h" //此程序需要使用FastLED库#define NUM_LEDS 30 //LED灯珠数量
#define DATA_PIN 9 //Arduino输出控制信号引脚
#define LED_TYPE WS2812 //LED灯带型号
#define COLOR_ORDER GRB //RGB灯珠中红色、绿色、蓝色LED的排列顺序
uint8_t max_bright = 128; //LED亮度控制变量,可使用数值为0~255, 数值越大则光带亮度越高CRGB leds[NUM_LEDS]; //为每个LED灯珠建立对象,将它们存放在数组leds中void setup()
{ Serial.begin(9600); //启动串行通讯delay(1000); //稳定性等待LEDS.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); //初始化灯带对象FastLED.setBrightness(max_bright); //设置灯带亮度
}void loop()
{ //点亮灯带所有灯珠for (int i = 0; i <= NUM_LEDS; i++) { leds[i] = CRGB::Red;FastLED.show();}delay(500);//熄灭灯带所有灯珠for (int i = 0; i <= NUM_LEDS; i++) {leds[i] = CRGB::Black;FastLED.show(); }delay(500);
}
①首先使用addLeds函数对灯带数组leds进行初始化,其中尖括号中的参数依次是灯带型号、灯带控制信号连接的Arduino引脚号、RGB灯珠中红绿蓝三种颜色的LED排列顺序,小括号中的参数依次是灯珠对象数组和灯珠数量。
②颜色参数的表示方式为“CRGB::<颜色名>”(Black表示熄灭灯珠),可以直接将颜色参数赋值给灯珠对象,然后使用show函数更新灯带的显示。
③对于灯珠对象数组,leds[0]控制灯带的第一个灯珠,leds[1]控制灯带的第二个灯珠,以此类推,使用for循环顺序遍历leds数组,第一次遍历将leds控制的灯珠全部点亮,第二次遍历将leds控制的灯珠全部熄灭,不过由于程序的执行本身要耗费一定时间,而show函数又被置于循环之中而不是循环之外,leds数组控制的灯珠经常还没全部被赋为红色或黑色就调用show函数,所以在视觉上灯带上的灯珠并不是同时被点亮,也不是同时被熄灭。
5、FastLED库使用——批量点灯操作
(1)灯带的灯珠全部同时被点亮,然后全部同时被熄灭,以此往复:
#include "FastLED.h" //此程序需要使用FastLED库#define NUM_LEDS 30 //LED灯珠数量
#define DATA_PIN 9 //Arduino输出控制信号引脚
#define LED_TYPE WS2812 //LED灯带型号
#define COLOR_ORDER GRB //RGB灯珠中红色、绿色、蓝色LED的排列顺序
uint8_t max_bright = 128; //LED亮度控制变量,可使用数值为0~255, 数值越大则光带亮度越高CRGB leds[NUM_LEDS]; //为每个LED灯珠建立对象,将它们存放在数组leds中void setup()
{ Serial.begin(9600); //启动串行通讯delay(1000); //稳定性等待LEDS.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); //初始化灯带对象FastLED.setBrightness(max_bright); //设置灯带亮度
}void loop ()
{ fill_solid(leds, 30, CRGB::Red); //点亮leds控制的30个灯珠FastLED.show(); delay(500);fill_solid(leds, 30, CRGB::Black); //熄灭leds控制的30个灯珠 FastLED.show(); delay(500);
}
①fill_solid函数的作用是批量更改leds数组控制的灯珠的颜色,第一个参数是leds数组名,第二个参数是需要更改颜色的灯珠数量,第三个参数是更改后的颜色参数。
②fill_solid函数中并没有调用show函数,它仅更改leds数组的存储内容,调用show函数时才会将leds中的颜色参数落实到实物LED灯带上。
(2)灯带头部前三个灯珠全部同时被点亮,然后全部同时被熄灭,以此往复:
#include "FastLED.h" //此程序需要使用FastLED库#define NUM_LEDS 30 //LED灯珠数量
#define DATA_PIN 9 //Arduino输出控制信号引脚
#define LED_TYPE WS2812 //LED灯带型号
#define COLOR_ORDER GRB //RGB灯珠中红色、绿色、蓝色LED的排列顺序
uint8_t max_bright = 128; //LED亮度控制变量,可使用数值为0~255, 数值越大则光带亮度越高CRGB leds[NUM_LEDS]; //为每个LED灯珠建立对象,将它们存放在数组leds中void setup()
{ Serial.begin(9600); //启动串行通讯delay(1000); //稳定性等待LEDS.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); //初始化灯带对象FastLED.setBrightness(max_bright); //设置灯带亮度
}void loop ()
{ //从灯带头开始,点亮熄灭3个LEDfill_solid(leds, 3, CRGB::Red);FastLED.show(); delay(500);fill_solid(leds, 3, CRGB::Black);FastLED.show(); delay(500);
}
①fill_solid函数的作用是批量更改leds数组控制的灯珠的颜色,第一个参数是leds数组名,第二个参数是需要更改颜色的灯珠数量,第三个参数是更改后的颜色参数。
②fill_solid函数中并没有调用show函数,它仅更改leds数组的存储内容,调用show函数时才会将leds中的颜色参数落实到实物LED灯带上。
③fill_solid函数的作用并不仅是同时控制灯带上的所有灯珠,可以仅控制部分,当第一个参数是leds数组名时,第二个参数是从灯带头部开始往后,需要控制的灯珠数量,将其取值为3,意味着仅控制灯带头部的前3个灯珠。
(3)灯带中部的连续三个灯珠全部同时被点亮,然后全部同时被熄灭,以此往复:
#include "FastLED.h" //此程序需要使用FastLED库#define NUM_LEDS 30 //LED灯珠数量
#define DATA_PIN 9 //Arduino输出控制信号引脚
#define LED_TYPE WS2812 //LED灯带型号
#define COLOR_ORDER GRB //RGB灯珠中红色、绿色、蓝色LED的排列顺序
uint8_t max_bright = 128; //LED亮度控制变量,可使用数值为0~255, 数值越大则光带亮度越高CRGB leds[NUM_LEDS]; //为每个LED灯珠建立对象,将它们存放在数组leds中void setup()
{ Serial.begin(9600); //启动串行通讯delay(1000); //稳定性等待LEDS.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); //初始化灯带对象FastLED.setBrightness(max_bright); //设置灯带亮度
}void loop ()
{ //从灯带头开始的第6个灯珠开始点亮熄灭3个LEDfill_solid(leds+5, 3, CRGB::Red);FastLED.show(); delay(500);fill_solid(leds+5, 3, CRGB::Black);FastLED.show();delay(500);
}
①fill_solid函数的作用是批量更改leds数组控制的灯珠的颜色,第一个参数是leds数组名,第二个参数是需要更改颜色的灯珠数量,第三个参数是更改后的颜色参数。
②fill_solid函数中并没有调用show函数,它仅更改leds数组的存储内容,调用show函数时才会将leds中的颜色参数落实到实物LED灯带上。
③fill_solid函数不只能从灯带头部第一个灯珠开始控制,它还可以从灯带中部的灯珠开始控制,当第一个参数是leds数组名与整型量的加法时,这里的“leds”是leds数组元素的首地址,而“leds+5”则是leds[5]的地址,那么fill_solid函数将从leds[5]开始更改leds数组的存储内容,也就是从灯带头部往后的第6个灯珠开始更改灯珠颜色参数,第二个参数为3,则fill_solid函数从第6个灯珠开始往后更改3个灯珠的颜色参数。
(4)三个光点组成的色条在灯带上反复摆动:
#include "FastLED.h" //此程序需要使用FastLED库#define NUM_LEDS 30 //LED灯珠数量
#define DATA_PIN 9 //Arduino输出控制信号引脚
#define LED_TYPE WS2812 //LED灯带型号
#define COLOR_ORDER GRB //RGB灯珠中红色、绿色、蓝色LED的排列顺序
uint8_t max_bright = 128; //LED亮度控制变量,可使用数值为0~255, 数值越大则光带亮度越高CRGB leds[NUM_LEDS]; //为每个LED灯珠建立对象,将它们存放在数组leds中void setup()
{ Serial.begin(9600); //启动串行通讯delay(1000); //稳定性等待LEDS.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); //初始化灯带对象FastLED.setBrightness(max_bright); //设置灯带亮度
}void loop ()
{ for (int i = 0; i < NUM_LEDS-3; i++) //色条正向运动{fill_solid(leds+i, 3, CRGB::Red);FastLED.show();delay(50);fill_solid(leds+i, 3, CRGB::Black); FastLED.show();delay(50);} for (int i = NUM_LEDS-3; i > 0; i--) //色条逆向运动{fill_solid(leds+i, 3, CRGB::Red);FastLED.show();delay(50);fill_solid(leds+i, 3, CRGB::Black); FastLED.show();delay(50);}
}
①fill_solid函数的作用是批量更改leds数组控制的灯珠的颜色,第一个参数是leds数组名,第二个参数是需要更改颜色的灯珠数量,第三个参数是更改后的颜色参数。
②fill_solid函数中并没有调用show函数,它仅更改leds数组的存储内容,调用show函数时才会将leds中的颜色参数落实到实物LED灯带上。
③当fill_solid函数的第一个参数是leds数组名与整型量的加法时,这里的“leds”是leds数组元素的首地址,而“leds+i”则是leds[i]的地址,那么fill_solid函数将从leds[i]开始更改leds数组的存储内容,也就是从灯带头部往后的第i个灯珠开始更改灯珠颜色参数,第二个参数为3,则fill_solid函数从第i个灯珠开始往后更改3个灯珠的颜色参数。不断改变i的值,被选中的灯珠也会随之改变。
6、FastLED库使用——自定义颜色
(1)除了FastLED库提供的颜色参数外,程序员还可以自定义颜色,FastLED提供了两种自定义颜色的方法,分别是CRGB方法与CHSV方法:
①CRGB方法就是将三原色(红色、绿色、蓝色)以不同比重(或者说数值)相加在一起得到其它颜色。
定义方式:CRGB <颜色变量名>(<rValue>,<gValue>,<bValue>);
#include "FastLED.h" #define NUM_LEDS 30
#define LED_DT 9
#define LED_TYPE WS2812
#define COLOR_ORDER GRB
uint8_t max_bright = 128;CRGB leds[NUM_LEDS];
//CRGB方法定义颜色
CRGB myRGBcolor(50,0,50); //myRGBcolor(rValue,gValue,bValue)——创建RGB颜色变量//rValue: 红色数值 0 - 255//gValue: 绿色数值 0 - 255//bValue: 蓝色数值 0 - 255
void setup()
{ LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);FastLED.setBrightness(max_bright);
}
void loop ()
{ myRGBcolor.r = 0; //更改红色数值,myRGBcolor(0, 0 ,50)myRGBcolor.b = 0; //更改蓝色数值,myRGBcolor(0, 0 ,0)fill_solid(leds, NUM_LEDS, myRGBcolor);FastLED.show();delay(500); myRGBcolor.r = 50; //更改红色数值,myRGBcolor(50, 0 ,0)myRGBcolor.b = 50; //更改蓝色数值,myRGBcolor(50, 0 ,50)fill_solid(leds, NUM_LEDS, myRGBcolor);FastLED.show();delay(500);
}
②CHSV方法同样有三个参数,它们分别为色调(H)、饱和度(S)和明亮度(V),色调的意义如下图的扇形图所示,饱和度的意义如下图右下角的渐变图所示(以色调H=0为例),明亮度的意义如下图右上角的渐变图所示(以色调H=0为例),通过不同数值的组合可以得到不同的颜色。
定义方式:CHSV <颜色变量名>(<hValue>,<sValue>,<vValue>);
#include "FastLED.h" #define NUM_LEDS 30
#define LED_DT 9
#define LED_TYPE WS2812
#define COLOR_ORDER GRB
uint8_t max_bright = 128;CRGB leds[NUM_LEDS];
//CHSV方法定义颜色
CHSV myHSVcolor(80,255,200); //myHSVcolor(色调,饱和度,明亮度)——创建HSV颜色变量void setup()
{ LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);FastLED.setBrightness(max_bright);
}
void loop ()
{ myHSVcolor.h++; //修改yHSVcolor.h,即myHSVcolor的色调数值 fill_solid(leds, NUM_LEDS, myHSVcolor);FastLED.show();delay(10);
}
(2)将下面的程序下载到开发板中,可以看见灯带全部被点亮,而且有一个“变色段”在灯带上运动,凡是“变色段”经过的地方,都会变成“变色段”所带有的颜色,而且“变色段”本身也在不断变色。
#include "FastLED.h" #define NUM_LEDS 30
#define LED_DT 9
#define LED_TYPE WS2812
#define COLOR_ORDER GRB
uint8_t max_bright = 128;CRGB leds[NUM_LEDS];
//CHSV方法定义颜色
CHSV myHSVcolor(80,255,200); //myHSVcolor(色调,饱和度,明亮度)——创建HSV颜色变量void setup()
{ LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);FastLED.setBrightness(max_bright);
}void loop ()
{ for (int i = 0; i < NUM_LEDS-3; i++) //变色段正向运动{myHSVcolor.h++; //修改色调fill_solid(leds+i, 3, myHSVcolor); //leds+i~leds+1+3是变色段FastLED.show();delay(50);} for (int i = NUM_LEDS-3; i >= 0; i--) //变色段逆向运动{myHSVcolor.h++; //修改色调fill_solid(leds+i, 3, myHSVcolor); //leds+i~leds+1+3是变色段FastLED.show();delay(50);}
}
(3)将下面的程序下载到开发板中,可以看见灯带有一个“变色段”在灯带上运动,“变色段”以外的灯珠全部熄灭。
#include "FastLED.h" #define NUM_LEDS 30
#define LED_DT 9
#define LED_TYPE WS2812
#define COLOR_ORDER GRB
uint8_t max_bright = 128;CRGB leds[NUM_LEDS];
//CHSV方法定义颜色
CHSV myHSVcolor(80,255,200); //myHSVcolor(色调,饱和度,明亮度)——创建HSV颜色变量void setup()
{ LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS);FastLED.setBrightness(max_bright);
}void loop ()
{for (int i = 0; i < NUM_LEDS-3; i++) //变色段正向运动{myHSVcolor.h++; //修改色调fill_solid(leds+i, 3, myHSVcolor);FastLED.show();delay(50);fill_solid(leds+i, 3, CRGB::Black); FastLED.show(); } for (int i = NUM_LEDS-3; i >= 0; i--) //变色段逆向运动{myHSVcolor.h++; //修改色调fill_solid(leds+i, 3, myHSVcolor);FastLED.show();delay(50);fill_solid(leds+i, 3, CRGB::Black); FastLED.show(); }
}
7、FastLED库使用——色调渐变灯带
(1)fill_rainbow函数有四个参数,其中最后一个参数可选,第一个参数是灯带对象的数组名,第二个参数是从第一个参数对应的灯珠开始往后需要控制的灯珠数量,第三个参数是起始色调值:
①若放弃可选参数,fill_rainbow函数会将选中的第一个灯珠颜色设置为起始色调,往后的灯珠色调呈递增趋势,递增值取决于需要控制的灯珠数量,最后所选的全部灯珠将呈现渐变的彩虹色。
②若采用可选参数,fill_rainbow函数会将选中的第一个灯珠颜色设置为起始色调,往后的灯珠色调呈递增趋势,递增值取决于可选参数值,如下图所示。
#include "FastLED.h" #define NUM_LEDS 30
#define LED_DT 9
#define LED_TYPE WS2812
#define COLOR_ORDER GRB uint8_t max_bright = 128; CRGB leds[NUM_LEDS]; uint8_t beginHue;void setup()
{ LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS); FastLED.setBrightness(max_bright);
}void loop ()
{ beginHue++; //初始色调改变fill_rainbow(leds, NUM_LEDS, beginHue, 9); //色调递增值取9FastLED.show();delay(25);
}
(2)fill_gradient_RGB函数有5个参数,第一个参数是灯带对象的数组名,第二个参数是第一个需要控制的灯珠在数组中的下标,第三个参数是起始RGB颜色(可用FastLED库提供的颜色参数,也可用CRGB方法自定义颜色变量),第四个参数是最后一个需要控制的灯珠在数组中的下标,第五个参数是结束RGB颜色(可用FastLED库提供的颜色参数,也可用CRGB方法自定义颜色变量),fill_gradient_RGB函数将会把选中的灯珠按起始和结束RGB颜色进行渐变设置,第一个灯珠设置为起始RGB颜色,最后一个灯珠设置为结束RGB颜色。
#include "FastLED.h" #define NUM_LEDS 30
#define LED_DT 9
#define LED_TYPE WS2812
#define COLOR_ORDER GRB uint8_t max_bright = 128; CRGB leds[NUM_LEDS]; void setup()
{ LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS); FastLED.setBrightness(max_bright);
}void loop ()
{ fill_gradient_RGB(leds, 0, CRGB::Red, 29, CRGB::Blue); FastLED.show();delay(50);
}
(3)fill_gradient函数有6个参数,第一个参数是灯带对象的数组名,第二个参数是第一个需要控制的灯珠在数组中的下标,第三个参数是起始颜色(可用FastLED库提供的颜色参数,也可用CRGB或者CHSV方法自定义颜色变量),第四个参数是最后一个需要控制的灯珠在数组中的下标,第五个参数是结束颜色(可用FastLED库提供的颜色参数,也可用CRGB或者CHSV方法自定义颜色变量),第六个参数是渐变方向,fill_gradient函数将会把选中的灯珠按起始和结束颜色进行渐变设置,第一个灯珠设置为起始颜色,最后一个灯珠设置为结束颜色,另外从一个颜色渐变到另外一个颜色有两个渐变方向,在灯珠数量相同的前提下,一个方向的色调变化值较大,对应参数“LONGEST_HUES”,另一个方向的色调变化值较小,对应参数“SHORTEST_HUES”。
#include "FastLED.h" #define NUM_LEDS 30
#define LED_DT 9
#define LED_TYPE WS2812
#define COLOR_ORDER GRB uint8_t max_bright = 128; CRGB leds[NUM_LEDS]; uint8_t beginHue;void setup()
{ LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS); FastLED.setBrightness(max_bright);
}void loop ()
{ fill_gradient(leds, 0, CHSV(50, 255,255) , 29, CHSV(150,255,255), LONGEST_HUES);FastLED.show();delay(50);
}
8、FastLED库使用——从调色板取色点灯
(1)下图所示的是FastLED库预设的其中两个调色板(截止3.7.0版本,预设的调色板共有8种),Arduino可以根据颜色序号从调色板上获取相应的颜色,当然,除了FastLED库预设的调色板,程序员也可自定义调色板然后使用之。
(2)fill_palette函数有7个参数,依次是灯带数组名、灯珠数量、起始颜色序号、相邻光珠的颜色序号差、调色板名(可以是库预设的,也可以是自定义的)、亮度值及线性渐变(LINEARBLEND)/非线性渐变(NOBLEND),其作用就是按照颜色序号将指定调色板上的颜色依次赋予灯带上的各个灯珠,若采用线性渐变,第一个灯珠的颜色对应起始颜色序号在调色板上的取色,再往后颜色序号将按照相邻光珠的颜色序号差进行递增,当颜色序号大于255时,大于255的部分从0开始继续递增。
(3)使用库预设的调色板CloudColors_p:在fill_palette函数中直接传入调色板名即可。
#include "FastLED.h" #define NUM_LEDS 30
#define LED_DT 9
#define LED_TYPE WS2812
#define COLOR_ORDER GRB uint8_t max_bright = 128; CRGB leds[NUM_LEDS]; uint8_t colorIndex;void setup()
{ LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS); FastLED.setBrightness(max_bright);
}void loop ()
{ colorIndex++; //每次给灯珠上色前,起始颜色序号都递增1fill_palette (leds, NUM_LEDS, colorIndex, 8, CloudColors_p, 255, LINEARBLEND);FastLED.show();delay(25);
}
(4)使用CRGBPalette16自定义调色板:这种方法需要16个RGB颜色参数,其中第一个参数对应调色板上颜色序号0-15的颜色,第二个参数对应调色板上颜色序号16-31的颜色,以此类推。
定义方式:CRGBPalette16 <调色板名> = CRGBPalette16(<16个逗号分隔的RGB颜色参数>);
#include "FastLED.h" #define NUM_LEDS 30
#define LED_DT 9
#define LED_TYPE WS2812
#define COLOR_ORDER GRB uint8_t max_bright = 128; CRGBPalette16 myColorPalette = CRGBPalette16(CRGB::Green, CRGB::Green, CRGB::Black, CRGB::Black, CRGB::Purple, CRGB::Purple, CRGB::Black, CRGB::Black,CRGB::Green, CRGB::Green, CRGB::Black, CRGB::Black,CRGB::Purple, CRGB::Purple, CRGB::Black, CRGB::Black);CRGB leds[NUM_LEDS]; uint8_t colorIndex;void setup()
{ LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS); FastLED.setBrightness(max_bright);
}void loop ()
{ colorIndex++; //每次给灯珠上色前,起始颜色序号都递增1fill_palette (leds, NUM_LEDS, colorIndex, 8, myColorPalette, 255, LINEARBLEND);FastLED.show();delay(25);
}
(5)使用CHSVPalette16自定义调色板:这种方法需要16个HSV颜色参数,其中第一个参数对应调色板上颜色序号0-15的颜色,第二个参数对应调色板上颜色序号16-31的颜色,以此类推。
定义方式:CHSVPalette16 <调色板名> = CHSVPalette16(<16个逗号分隔的HSV颜色参数>);
#include "FastLED.h" #define NUM_LEDS 30
#define LED_DT 9
#define LED_TYPE WS2812
#define COLOR_ORDER GRB uint8_t max_bright = 128; CHSVPalette16 myHSVColorPalette = CHSVPalette16(CHSV(0, 255, 200), CHSV(15, 255, 200), CHSV(31, 255, 200), CHSV(47, 255, 200),CHSV(0, 255, 0), CHSV(15, 255, 0), CHSV(31, 255, 0), CHSV(47, 255, 0),CHSV(0, 255, 200), CHSV(15, 255, 200), CHSV(31, 255, 200), CHSV(47, 255, 200),CHSV(0, 0, 200), CHSV(15, 0, 200), CHSV(31, 0, 200), CHSV(47, 0, 200));CRGB leds[NUM_LEDS]; uint8_t colorIndex;void setup()
{ LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS); FastLED.setBrightness(max_bright);
}void loop ()
{ colorIndex++; //每次给灯珠上色前,起始颜色序号都递增1fill_palette (leds, NUM_LEDS, colorIndex, 8, myHSVColorPalette, 255, LINEARBLEND);FastLED.show();delay(25);
}
(6)对于自定义调色板,它由16个颜色参数进行定义,而在程序运行过程中基本不会修改调色板,那么调色板完全可以作为只读的内容,如果将其存放在SARM中将会非常浪费SARM的空间,对此可以将其存放在FLASH中,从而很好地利用存储空间。存储在FALSH中的调色板,其定义方式见下例,同样需要16个颜色参数,其中第一个参数对应调色板上颜色序号0-15的颜色,第二个参数对应调色板上颜色序号16-31的颜色,以此类推。
#include "FastLED.h" #define NUM_LEDS 30
#define LED_DT 9
#define LED_TYPE WS2812
#define COLOR_ORDER GRB uint8_t max_bright = 128; const TProgmemPalette16 myProgmemPalette PROGMEM = {CRGB::Red, CRGB::Gray, CRGB::Blue, CRGB::Black,CRGB::Red, CRGB::Gray, CRGB::Blue, CRGB::Black,CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray,CRGB::Blue, CRGB::Blue, CRGB::Black, CRGB::Black}; CRGB leds[NUM_LEDS]; uint8_t colorIndex;void setup()
{ LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS); FastLED.setBrightness(max_bright);
}void loop ()
{ colorIndex++; //每次给灯珠上色前,起始颜色序号都递增1fill_palette (leds, NUM_LEDS, colorIndex, 8, myProgmemPalette, 255, LINEARBLEND);FastLED.show();delay(25);
}
相关文章:
零基础入门学用Arduino 第三部分(三)
重要的内容写在前面: 该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。个人把这个教程学完之后,整体感觉是很好的,如果有条件的可以先学习一些相关课程,学起来会更加轻松,相关课程有数字电路…...
Trusty qemu + android环境搭建详细步骤
下载源码 mkdir trusty cd trusty repo init -u https://android.googlesource.com/trusty/manifest -b master repo sync -j32 编译 ./trusty/vendor/google/aosp/scripts/build.py generic-arm64 查看编译结果 ls build-root/build-generic-arm64/lk.bin 安装运行依赖 …...
杀戮尖塔游戏
Java 你正在玩策略卡牌杀戮尖塔游戏,轮到你出牌,手里N张攻击卡,每张都需要花金币coust[i]和获得伤害dmager[i]。 最多花3金币能造成的最大伤害是多少? class Solution{public int calc(int[] cost, int[] dmager, N){int[][] db …...
Kubernetes (K8s) 和 Spring Cloud 的区别
Kubernetes (K8s) 和 Spring Cloud 是两种常用的云原生技术,它们在微服务架构和云计算领域中扮演着重要的角色。尽管两者都有助于开发和部署微服务,但它们的功能和目标存在显著差异。本文将详细讨论 Kubernetes 和 Spring Cloud 的区别,从它们…...
定个小目标之刷LeetCode热题(21)
这是道技巧题,利用了 (num - 1)% n 计算下标的形式来将数组元素与数组索引产生映射关系,代码如下,可以看下注释 class Solution {public List<Integer> findDisappearedNumbers(int[] nums) {int n nums.lengt…...
Oracle 打开钱包 ORA-28368: cannot auto-create wallet
ORA-28368: cannot auto-create wallet 开启钱包抱错,看下钱包信息 SQL> select * from v$encryption_wallet;WRL_TYPE -------------------- WRL_PARAMETER -------------------------------------------------------------------------------- STATUS ------…...
【麒麟虚拟机】NetworkManager没有运行
麒麟V10 建linux麒麟虚拟机,发现,网络没有配置 提示,NetworkManager没有运行。编辑联接也不能配置 解决方法,在终端输入命令: sudo systemctl start NetworkManager 启动以后,编辑连接选自动以太网&…...
vue之一键部署的shell脚本和它的点.bat文件、海螺AI、ChatGPT
MENU 前言vite.config.ts的配置deploy文件夹的其他内容remote.shpwd.txtdeploy.bat 前言 1、在src同级新建deploy.bat文件; 2、在src同级新建deploy文件夹,文件夹中新建pwd.txt和remote.sh文件; 3、配置好后,直接双击deploy.bat文…...
pg和oracle的区别
1、从功能上来说pg要比oracle数据库弱。 2、pg不支持索引组织表。 pg和oracle的相似之处: 1、使用共享内存的进程结构,客户端与数据库服务器建立一个连接后,数据库服务器就启动一个进程为这个连接服务。这与mysql的线程模型不一样。 2、p…...
Docker:在DockerHub上创建私有仓库
文章目录 Busybox创建仓库推送镜像到仓库 本篇开始要学习在DockerHub上搭建一个自己的私有仓库 Busybox Busybox是一个集成了三百多个最常用Linux命令和工具的软件,BusyBox包含了很多工具,这里拉取该镜像推送到仓库中: 安装 apt install …...
框架的使用
什么是框架? 盖房子,框架结构 框架结构就是房子主体,基本功能 把很多基础功能已经实现(封装了) 框架:在基础语言之上,对各种基础功能进行封装,方便开发者,提高开发效…...
Autosar-DEM诊断事件管理流程
文章目录 前言一、故障事件监控二、故障信息上报三、故障信息处理Event的使能条件四、故障信息存储五、故障系统降级关联文章:Autosar实践——DEM配置 前言 DEM全称“Diagnostic Event Management”,该模块是AUTOSAR架构中的BSW模块之一。谈到故障,我们首先会想到如何去监控…...
LabVIEW输送机动态特性参数监测系统
开发了一套基于LabVIEW软件和STM32F103ZET6单片机的带式输送机动态特性参数监测系统。该系统通过电阻应变式压力传感器和光电编码器实时采集输送带的张力和带速信息,通过5G模块将数据传输至上位机,实现数据的可视化处理与实时预警,有效提高输…...
绿色版DirectoryOpus功能强大且高度可定制的Windows文件管理器
Directory Opus(通常简称为DOpus)是一款功能强大且高度可定制的Windows文件管理器。它提供了许多超越Windows默认文件资源管理器(Explorer)的功能,使得文件和文件夹的管理变得更加高效和直观。以下是对Directory Opus的…...
Cocos Creator,Youtube 小游戏!
YouTube 官方前段时间发布了一则重磅通知,宣布平台旗下小游戏功能 Youtube Playables 正式登录全平台(安卓、iOS、网页),并内置了数十款精选小游戏。 Youtube Playables 入口: https://www.youtube.com/playables Coco…...
分层解耦
三层架构 controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据, service:业务逻辑层,处理具体的业务逻辑。 dao:数据访问层(Data Access Object)(持久层),负责数据访问操作,包括数…...
GenICam标准(六)
系列文章目录 GenICam标准(一) GenICam标准(二) GenICam标准(三) GenICam标准(四) GenICam标准(五) GenICam标准(六) 文章目录 系列文…...
JavaFX VBox
VBox布局将子节点堆叠在垂直列中。新添加的子节点被放置在上一个子节点的下面。默认情况下,VBox尊重子节点的首选宽度和高度。 当父节点不可调整大小时,例如Group节点,最大垂直列的宽度基于具有最大优选宽度的节点。 默认情况下,…...
xss+csrf项目实例
项目背景: 如下:我们是在一个类似文章管理系统的网站上面发现的该漏洞。我们将其运行在本地的phpstudy集成环境上面。 源码地址下载链接:https://pan.baidu.com/s/1MpnSAq7a_oOcGh4XgPE-2w 提取码:4444 考察内容: …...
速盾:cdn加速怎么计费?
CDN加速(Content Delivery Network)是一种将内容部署在全球多个节点上,通过就近访问提供服务的技术。它可以加快网站的速度和可靠性,同时减轻源服务器的负载。在使用CDN加速服务时,计费是一个重要的问题,下…...
Vue3 中 props 与 emit 用法
在 Vue3 中,props 和 emit 的用法有所改变,主要的变化在于它们现在都通过 setup 函数来访问和使用。 props: props 用于父组件向子组件传递数据。在 setup 函数中,props 是一个参数,我们可以通过它访问到父组件传入的所有 prop 值…...
【python】如何import 另一个路径下的py文件内容
目录结构: ├─common │ └─config.py └─own_module │ └─run.py问题描述: 如何在run.py 中调用 config.py 中的函数或类? 解决办法: import os import sys # 为了引用自定义模块,可临时将module的绝对路径…...
C/C++ Adaline自适应线性神经网络算法详解及源码
个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119qq.com] 📱…...
UniApp+Vue3使用Vant-微信小程序组件
第一步:打开创建好的UniappVue3的项目 第二步:下载Vant-Weapp npm i vant/weapp -S --production 第三步:修改目录名称 wxcomponents 必须是wxcomponents 第四步:将下载好的vant中的dist目录剪切到当前wxcomponents目录下 第五…...
python IP 端口 socket tcp 介绍
IP 端口 介绍 1、IP IP地址是分配给网络设备上网使用的数字标签,它能够标识网络中唯一的一台设备 windows环境可以使用 ipconfig 来查看自己的iplinux环境可以使用 ifconfig 来查看自己的ip 2、端口 端口是传输数据的通道,每个操作系统上都有 65535个…...
【动态规划】| 路径问题之最小路径和 力扣64
🎗️ 主页:小夜时雨 🎗️专栏:动态规划 🎗️如何活着,是我找寻的方向 目录 1. 题目解析2. 代码 1. 题目解析 题目链接: https://leetcode.cn/problems/minimum-path-sum/description/ 这道题目和之前一道…...
如何在vector中插入和删除元素?
在C的std::vector中插入和删除元素通常使用其成员函数来完成。以下是如何在std::vector中插入和删除元素的示例: 插入元素 在末尾插入元素:使用push_back函数。 cpp复制代码 #include <vector> int main() { std::vector<int> v; v.push_…...
独具韵味的移动端 UI 风格
独具韵味的移动端 UI 风格...
【SpringBoot】SpringBoot:构建实时聊天应用
文章目录 引言项目初始化添加依赖 配置WebSocket创建WebSocket配置类创建WebSocket处理器 创建前端页面创建聊天页面 测试与部署示例:编写单元测试 部署扩展功能用户身份验证消息持久化群组聊天 结论 引言 随着实时通信技术的快速发展,聊天应用在现代We…...
基于Matlab的车牌识别停车场出入库计时计费管理系统(含GUI界面)【W6】
简介: 在当今城市化进程加快的环境下,停车管理成为了一个日益重要和复杂的问题。城市中的停车资源有限,如何高效利用和管理这些资源,不仅关乎市民出行便利性,也涉及到城市交通拥堵、环境污染等诸多问题的解决。 传统的…...
做查询网站费用/行业关键词查询
ER图(实体关系图)是一种数据库建模方法,帮助表示实体和实体之间的关系。 MySQL本身不提供画ER图的功能,你可以使用第三方工具,如: LucidchartMicrosoft VisioGliffyDraw.io 这些工具都支持画ER图,且都有免费版本。可以…...
团购网站怎么做推广/百度收录官网
报错:叫我们删除log4j-over-slf4j.jar, 选中项目 然后搜索对应的包,然后排除即可,我这边已经排除了,就ok了 ctrlF搜索哦! 版本问题,使用插件解决吧: https://yidajava.blog.csdn.net/article/details/103668676...
宜昌云网站建设/长沙seo外包
前几天在家没事干,花了点心思折腾了两个小东西。第一个射击游戏是跟着pygame官网上下载的一个游戏边学习源码边抄的,抄了个开头就变成自己乱搞加参考了。。虽然有心想装下蒜,但不知道那些协议什么的怎么搞。只能在这提一下了。。 第二个是以前…...
哪些网站是用asp.net开发的/市场调研怎么写
场景 今天运用到了锁,记录一下lock和Synchronized的区别。 Synchronized synchronized 是 Java 中的关键字,是一种同步锁。它修饰的对象有以下几种: 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大…...
海沧网站建设/资源网
本文来源为node.js社区附上链接 http://cnodejs.org/topic/5231a630101e574521e45ef8 require 用来加载代码,而 exports 和 module.exports 则用来导出代码。但很多新手可能会迷惑于 exports 和 module.exports 的区别,为了更好的理解 exports 和 module…...
微信网站开发平台/一个产品营销策划方案
解决vscode出现两个光标的问题参考文章: (1)解决vscode出现两个光标的问题 (2)https://www.cnblogs.com/huahuayu/p/12235244.html 备忘一下。...