任务1:WS2812B彩灯控制和按键控制(arduino程序)

一、首先需要安装一个库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;
  } 
  
}

 

  • 15
    点赞
  • 116
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值