一、首先需要安装一个库FastLED.h
二、灯带的基本操作:
#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]; // 建立光带leds
void setup() {
LEDS.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); // 初始化光带
FastLED.setBrightness(max_bright); // 设置光带亮度
}
void loop() {
leds[0] = CRGB::Red; // 设置光带中第一个灯珠颜色为红色,leds[0]为第一个灯珠,leds[1]为第二个灯珠
FastLED.show(); // 更新LED色彩
delay(50); // 等待500毫秒
}
三、按键的基本操作:
这里使用了四个触摸按键,分别执行了单击、双击、滑动操作(实现原理请看注释)
void button_State()
{
//A
if(digitalRead(button1)){ //检测按键是否按下
delay(20); //延时去抖动
if(digitalRead(button1)){//判断长短键
while((digitalRead(button1))&&c<KEYA_SPEED1){ //循环判断长按,到1s跳出or按键松开跳转else
c++;delay(10); //长按判断的计时
}
if(c>=KEYA_SPEED1){ //长键处理 循环100次为长按1s
//长按后执行的程序放到此处
openState = 2;
Serial.println("A键长按 \r\n");
while(digitalRead(button1));//等待按键松开
}
else{ //单击处理 按键A松开后
if(digitalRead(button2)){//判断按键B是否按下,按下为滑动操作
k+=light; //用于显示的计数值
/*这里放入滑动的操作*/
Serial.print("A:");
Serial.println(k);
a=1;s=1; //a是单双击判断标志,s是刚刚结束滑动标志
}
if(a==0){
for(b=0;b<KEYA_SPEED2;b++){//检测双击 循环10次200ms
delay(20);
if(digitalRead(button1)){//判断200ms内是否再次按下
a=1;
//双击后执行的程序放到此处
openState = 1;
Serial.println("A键双击 \r\n");
while(digitalRead(button1));//等待按键松开
}
}
if(a==0){ //判断单击
if(s==1){ //判断是不是刚执行完滑动操作
s=0; //如果是则本次不执行单击处理(因为是滑动的放开操作)
}
else{ //如果不是,则正常执行单击处理
//单击后执行的程序放到此处
openState = 0;
Serial.println("A键单击 \r\n");
}
}
}
}
a=0;c=0; //参数清0
}
} //按键判断在此结束
//B
if(digitalRead(button2)){ //检测按键是否按下
delay(20); //延时去抖动
if(digitalRead(button2)){//判断长短键
while((digitalRead(button2))&&c<KEYA_SPEED1){ //循环判断长按,到时跳转
c++;delay(10); //长按判断的计时
}
if(c>=KEYA_SPEED1){ //长键处理
//长按后执行的程序放到此处
openState = 6;
Serial.println("B键长按 \r\n");
while(digitalRead(button2));
}
else{ //单击处理
if(digitalRead(button3)){//判断按键C是否按下,按下为滑动操作
k+=light;
Serial.print("B:");
Serial.println(k);
a=1;s=1; //a是单双击判断标志,s是刚刚结束滑动标志
}
if(digitalRead(button1)){//判断按键A是否按下,按下为滑动操作
k-=light;
Serial.print("B:");
Serial.println(k);
a=1;s=1; //a是单双击判断标志,s是刚刚结束滑动标志
}
if(a==0){
for(b=0;b<KEYA_SPEED2;b++){//检测双击
delay(20);
if(digitalRead(button2)){
a=1;
//双击后执行的程序放到此处
openState = 1;
Serial.println("B键双击 \r\n");
while(digitalRead(button2));
}
}
if(a==0){ //判断单击
if(s==1){ //判断是不是刚执行完滑动操作
s=0; //如果是则本次不执行单击处理(因为是滑动的放开操作)
}else{ //如果不是,则正常执行单击处理
//单击后执行的程序放到此处
openState = 3;
Serial.println("B键单击 \r\n");
}
}
}
}
a=0;c=0; //参数清0
}
} //按键判断在此结束
//C
if(digitalRead(button3)){ //检测按键是否按下
delay(20); //延时去抖动
if(digitalRead(button3)){//判断长短键
while((digitalRead(button3))&&c<KEYA_SPEED1){ //循环判断长按,到时跳转
c++;delay(10); //长按判断的计时
}
if(c>=KEYA_SPEED1){ //长键处理
//长按后执行的程序放到此处
openState = 7;
Serial.println("C键长按 \r\n");
while(digitalRead(button3));
}
else{ //单击处理
if(digitalRead(button4)){
k+=light;
Serial.print("C:");
Serial.println(k);
a=1;s=1; //a是单双击判断标志,s是刚刚结束滑动标志
}
if(digitalRead(button2)){
k-=light;
Serial.print("C:");
Serial.println(k);
a=1;s=1; //a是单双击判断标志,s是刚刚结束滑动标志
}
if(a==0){
for(b=0;b<KEYA_SPEED2;b++){//检测双击
delay(20);
if(digitalRead(button3)){
a=1;
//双击后执行的程序放到此处
openState = 1;
Serial.println("C键双击 \r\n");
while(digitalRead(button3));
}
}
if(a==0){ //判断单击
if(s==1){ //判断是不是刚执行完滑动操作
s=0; //如果是则本次不执行单击处理(因为是滑动的放开操作)
}else{ //如果不是,则正常执行单击处理
//单击后执行的程序放到此处
openState = 4;
Serial.println("C键单击 \r\n");
}
}
}
}
a=0;c=0; //参数清0
}
} //按键判断在此结束
//D
if(digitalRead(button4)){ //检测按键是否按下
delay(20); //延时去抖动
if(digitalRead(button4)){//判断长短键
while((digitalRead(button4))&&c<KEYA_SPEED1){ //循环判断长按,到时跳转
c++;delay(10); //长按判断的计时
}
if(c>=KEYA_SPEED1){ //长键处理
//长按后执行的程序放到此处
openState = 8;
Serial.println("D键长按 \r\n");
while(digitalRead(button4));
}
else{ //单击处理
if(digitalRead(button3)){
k-=light;
Serial.print("D:");
Serial.println(k);
a=1;s=1; //a是单双击判断标志,s是刚刚结束滑动标志
}
if(a==0){
for(b=0;b<KEYA_SPEED2;b++){//检测双击
delay(20);
if(digitalRead(button4)){
a=1;
//双击后执行的程序放到此处
openState = 1;
Serial.println("D键双击 \r\n");
while(digitalRead(button4));
}
}
if(a==0){ //判断单击
if(s==1){ //判断是不是刚执行完滑动操作
s=0; //如果是则本次不执行单击处理(因为是滑动的放开操作)
}else{ //如果不是,则正常执行单击处理
//单击后执行的程序放到此处
openState = 5;
Serial.println("D键单击 \r\n");
}
}
}
}
a=0;c=0; //参数清0
}
} //按键判断在此结束
}
四、不同按键对应不同的模式,使用switch语句
switch (openState)
{
case 0:
// openState = 0;
mode_1(); //A开灯
break;
case 1:
mode_0(); //关灯
break;
case 2:
mode_2(); //A键长按
break;
case 3:
mode_3(); //B单击
break;
case 4:
mode_4(); //C单击
break;
case 5:
mode_5(); //D单击
break;
case 6:
mode_6(); //B键长按
break;
case 7:
mode_7(); //C键长按
break;
case 8:
mode_8(); //D键长按
break;
default:
break;
}
最后:附上完整代码:
#include "FastLED.h" //程序需要使用FastLED库
#define NUM_LEDS 8 // LED灯珠数量
#define LED_DT 2 // Arduino输出控制信号引脚
#define LED_TYPE WS2812 // LED灯带型号
#define COLOR_ORDER GRB // RGB灯珠中红色、绿色、蓝色LED的排列顺序
#define button1 3 //触摸按键接口定义
#define button2 4
#define button3 5
#define button4 6
#define light 20 //亮度步长
#define KEYA_SPEED1 50 //长按的时间长度(单位10mS) 总共1s 100
#define KEYA_SPEED2 10 //双击的时间长度(单位20mS) 200ms双击间隔
uint8_t colorR, colorG, colorB, colorW; //RGB,亮度
uint8_t openState = 1;/灯效模式,默认关灯
//uint8_t max_bright = 128; // LED亮度控制变量,可使用数值为 0 ~ 255, 数值越大则光带亮度越高
uint8_t k=125; //用于滑动加减计数,控制亮度
uint8_t b; //长按判断标志位
bool a=0,c=0,s=0; //刚刚结束滑动标志
//bool m1, m2, m3, m4;
CRGB leds[NUM_LEDS]; // 建立光带leds
//RGB方法定义颜色
CRGB myRGBcolor(255,255,255); // myRGBcolor(rValue,gValue,bValue)
// rValue: 红色数值 0 - 255
// gValue: 绿色数值 0 - 255
// bValue: 蓝色数值 0 - 255
//HSV方法定义颜色
CHSV myHSVcolor(80,255,200); //HSV方法定义颜色 myHSVcolor(色调,饱和度,明亮度)
//自定义色盘
CRGBPalette16 myColorPalette = CRGBPalette16(
CRGB::Green, CRGB::Green, CRGB::Black, CRGB::Black,
// 0-15 GREEN, 16-31 GREEN, 32-47 Black, 48-63 Black,
CRGB::Purple, CRGB::Purple, CRGB::Black, CRGB::Black,
// 64-79 Purple, 80-95 Purple, 96-111 Black, 112-127 Black,
CRGB::Green, CRGB::Green, CRGB::Black, CRGB::Black,
// 128-143 Green,144-159 Green, 160-175 Black,176-191 Black,
CRGB::Purple, CRGB::Purple, CRGB::Black, CRGB::Black );
// 192-207 Purple,208-223 Purple,224-239 Black,240-255 Black
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));
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 };
void setup() {
Serial.begin(115200);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
pinMode(button3, INPUT);
pinMode(button4, INPUT);
LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS); // 初始化光带
FastLED.setBrightness(k); // 设置光带亮度
}
void button_State()
{
//A
if(digitalRead(button1)){ //检测按键是否按下
delay(20); //延时去抖动
if(digitalRead(button1)){//判断长短键
while((digitalRead(button1))&&c<KEYA_SPEED1){ //循环判断长按,到1s跳出or按键松开跳转else
c++;delay(10); //长按判断的计时
}
if(c>=KEYA_SPEED1){ //长键处理 循环100次为长按1s
//长按后执行的程序放到此处
openState = 2;
Serial.println("A键长按 \r\n");
while(digitalRead(button1));//等待按键松开
}
else{ //单击处理 按键A松开后
if(digitalRead(button2)){//判断按键B是否按下,按下为滑动操作
k+=light; //用于显示的计数值
/*这里放入滑动的操作*/
Serial.print("A:");
Serial.println(k);
a=1;s=1; //a是单双击判断标志,s是刚刚结束滑动标志
}
if(a==0){
for(b=0;b<KEYA_SPEED2;b++){//检测双击 循环10次200ms
delay(20);
if(digitalRead(button1)){//判断200ms内是否再次按下
a=1;
//双击后执行的程序放到此处
openState = 1;
Serial.println("A键双击 \r\n");
while(digitalRead(button1));//等待按键松开
}
}
if(a==0){ //判断单击
if(s==1){ //判断是不是刚执行完滑动操作
s=0; //如果是则本次不执行单击处理(因为是滑动的放开操作)
}
else{ //如果不是,则正常执行单击处理
//单击后执行的程序放到此处
openState = 0;
Serial.println("A键单击 \r\n");
}
}
}
}
a=0;c=0; //参数清0
}
} //按键判断在此结束
//B
if(digitalRead(button2)){ //检测按键是否按下
delay(20); //延时去抖动
if(digitalRead(button2)){//判断长短键
while((digitalRead(button2))&&c<KEYA_SPEED1){ //循环判断长按,到时跳转
c++;delay(10); //长按判断的计时
}
if(c>=KEYA_SPEED1){ //长键处理
//长按后执行的程序放到此处
openState = 6;
Serial.println("B键长按 \r\n");
while(digitalRead(button2));
}
else{ //单击处理
if(digitalRead(button3)){//判断按键C是否按下,按下为滑动操作
k+=light;
Serial.print("B:");
Serial.println(k);
a=1;s=1; //a是单双击判断标志,s是刚刚结束滑动标志
}
if(digitalRead(button1)){//判断按键A是否按下,按下为滑动操作
k-=light;
Serial.print("B:");
Serial.println(k);
a=1;s=1; //a是单双击判断标志,s是刚刚结束滑动标志
}
if(a==0){
for(b=0;b<KEYA_SPEED2;b++){//检测双击
delay(20);
if(digitalRead(button2)){
a=1;
//双击后执行的程序放到此处
openState = 1;
Serial.println("B键双击 \r\n");
while(digitalRead(button2));
}
}
if(a==0){ //判断单击
if(s==1){ //判断是不是刚执行完滑动操作
s=0; //如果是则本次不执行单击处理(因为是滑动的放开操作)
}else{ //如果不是,则正常执行单击处理
//单击后执行的程序放到此处
openState = 3;
Serial.println("B键单击 \r\n");
}
}
}
}
a=0;c=0; //参数清0
}
} //按键判断在此结束
//C
if(digitalRead(button3)){ //检测按键是否按下
delay(20); //延时去抖动
if(digitalRead(button3)){//判断长短键
while((digitalRead(button3))&&c<KEYA_SPEED1){ //循环判断长按,到时跳转
c++;delay(10); //长按判断的计时
}
if(c>=KEYA_SPEED1){ //长键处理
//长按后执行的程序放到此处
openState = 7;
Serial.println("C键长按 \r\n");
while(digitalRead(button3));
}
else{ //单击处理
if(digitalRead(button4)){
k+=light;
Serial.print("C:");
Serial.println(k);
a=1;s=1; //a是单双击判断标志,s是刚刚结束滑动标志
}
if(digitalRead(button2)){
k-=light;
Serial.print("C:");
Serial.println(k);
a=1;s=1; //a是单双击判断标志,s是刚刚结束滑动标志
}
if(a==0){
for(b=0;b<KEYA_SPEED2;b++){//检测双击
delay(20);
if(digitalRead(button3)){
a=1;
//双击后执行的程序放到此处
openState = 1;
Serial.println("C键双击 \r\n");
while(digitalRead(button3));
}
}
if(a==0){ //判断单击
if(s==1){ //判断是不是刚执行完滑动操作
s=0; //如果是则本次不执行单击处理(因为是滑动的放开操作)
}else{ //如果不是,则正常执行单击处理
//单击后执行的程序放到此处
openState = 4;
Serial.println("C键单击 \r\n");
}
}
}
}
a=0;c=0; //参数清0
}
} //按键判断在此结束
//D
if(digitalRead(button4)){ //检测按键是否按下
delay(20); //延时去抖动
if(digitalRead(button4)){//判断长短键
while((digitalRead(button4))&&c<KEYA_SPEED1){ //循环判断长按,到时跳转
c++;delay(10); //长按判断的计时
}
if(c>=KEYA_SPEED1){ //长键处理
//长按后执行的程序放到此处
openState = 8;
Serial.println("D键长按 \r\n");
while(digitalRead(button4));
}
else{ //单击处理
if(digitalRead(button3)){
k-=light;
Serial.print("D:");
Serial.println(k);
a=1;s=1; //a是单双击判断标志,s是刚刚结束滑动标志
}
if(a==0){
for(b=0;b<KEYA_SPEED2;b++){//检测双击
delay(20);
if(digitalRead(button4)){
a=1;
//双击后执行的程序放到此处
openState = 1;
Serial.println("D键双击 \r\n");
while(digitalRead(button4));
}
}
if(a==0){ //判断单击
if(s==1){ //判断是不是刚执行完滑动操作
s=0; //如果是则本次不执行单击处理(因为是滑动的放开操作)
}else{ //如果不是,则正常执行单击处理
//单击后执行的程序放到此处
openState = 5;
Serial.println("D键单击 \r\n");
}
}
}
}
a=0;c=0; //参数清0
}
} //按键判断在此结束
}
void mode_0()熄灯
{
for (int i = 0; i <= NUM_LEDS; i++) {
leds[i] = CRGB::Black;
FastLED.show();
}
}
void mode_1()
{
FastLED.setBrightness(k);
for (int i = 0; i <= NUM_LEDS; i++) {
leds[i] = CRGB::Red;
FastLED.show();
}
}
void mode_2()
{
// myRGBcolor.r = 0;
// myRGBcolor.g = 0;
// myRGBcolor.b = 0;
FastLED.setBrightness(k);
fill_solid(leds, NUM_LEDS, myRGBcolor);
FastLED.show();
}
void mode_3()
{
FastLED.setBrightness(k);
for (int i = 0; i <= NUM_LEDS; i++) {
leds[i] = CRGB::Cyan;
FastLED.show();
}
}
void mode_4()
{
FastLED.setBrightness(k);
for (int i = 0; i <= NUM_LEDS; i++) {
leds[i] = CRGB::GreenYellow;
FastLED.show();
}
}
void mode_5()
{
FastLED.setBrightness(k);
for (int i = 0; i <= NUM_LEDS; i++) {
leds[i] = CRGB::Green;
FastLED.show();
}
}
void mode_6()
{
FastLED.setBrightness(k);
myHSVcolor.h++; // 修改HSV定义颜色的单一数值
// myHSVcolor.h为myHSVcolor的色调数值
fill_solid(leds, NUM_LEDS, myHSVcolor);
FastLED.show();
delay(30);
}
uint8_t beginHue; // 起始灯珠号
void mode_7()
{
FastLED.setBrightness(k);
beginHue++;
fill_rainbow(leds, NUM_LEDS, beginHue, 20); //相邻LED灯珠色调差为20
FastLED.show();
delay(25);
}
//uint8_t colorIndex;
void mode_8()
{
// FastLED.setBrightness(k);
// colorIndex++;
beginHue++;
// fill_palette (leds, NUM_LEDS, beginHue, 8, myColorPalette, k, LINEARBLEND );
//fill_palette (led名称, 光珠数字, 起始颜色序号, 光珠间颜色差, palette色盘名, 亮度, TBlendType blendType)
//fill_palette (leds, NUM_LEDS, beginHue, 8, myHSVColorPalette, k, LINEARBLEND );
fill_palette (leds, NUM_LEDS, beginHue, 1, myProgmemPalette, k, LINEARBLEND );
FastLED.show();
delay(25);
}
void loop () {
button_State();
switch (openState)
{
case 0:
// openState = 0;
mode_1(); //A开灯
break;
case 1:
mode_0(); //关灯
break;
case 2:
mode_2(); //A键长按
break;
case 3:
mode_3(); //B单击
break;
case 4:
mode_4(); //C单击
break;
case 5:
mode_5(); //D单击
break;
case 6:
mode_6(); //B键长按
break;
case 7:
mode_7(); //C键长按
break;
case 8:
mode_8(); //D键长按
break;
default:
break;
}
}