xiao_y 发表于 2020-11-28 20:03:02

Arduino控制WS2812灯带问题,大神请来解惑?

各位大神请帮忙看看,谢谢!!!

手机蓝牙控制Arduino-Uno主板实现对3条WS2812灯带控制。

目标:led1和led2不同颜色不同频率流水,led3常亮。

问题:手机发送A,led1开始流水动画,进入for循环。手机发送B,C,led2和led3没有反应。
          由于手机蓝牙一次只能接受一次数据,但是流水for循环不一定跳出循环。

如何解决这个问题,?程序需要修改还是构架思路需要换一个?



程序如下:

#include "FastLED.h"            // 此示例程序需要使用FastLED库

#define NUM_LEDS_A 5             // LED灯珠数量
#define NUM_LEDS_B 5
#define NUM_LEDS_C 5

#define DATA_PIN_A 9             // Arduino输出控制信号引脚
#define DATA_PIN_B 10
#define DATA_PIN_C 11

#define LED_TYPE WS2812         // LED灯带型号
#define COLOR_ORDER GRB         // RGB灯珠中红色、绿色、蓝色LED的排列顺序

uint8_t max_bright = 255;       // LED亮度控制变量,可使用数值为 0 ~ 255, 数值越大则光带亮度越高
uint8_t min_bright = 128;

CRGB leds_A;            // 建立光带leds
CRGB leds_B;
CRGB leds_C;

char getstr;
char serialData;
int i;

void setup()
{
   Serial.begin(9600);
   delay(3000);                  // 稳定性等待

LEDS.addLeds<LED_TYPE, DATA_PIN_A, COLOR_ORDER>(leds_A, NUM_LEDS_A);// 初始化光带
FastLED.setBrightness(max_bright);                            // 设置光带亮度

LEDS.addLeds<LED_TYPE, DATA_PIN_B, COLOR_ORDER>(leds_B, NUM_LEDS_B);// 初始化光带
FastLED.setBrightness(min_bright);                            // 设置光带亮度

LEDS.addLeds<LED_TYPE, DATA_PIN_C, COLOR_ORDER>(leds_C, NUM_LEDS_C);// 初始化光带
FastLED.setBrightness(min_bright);                            // 设置光带亮度

}



void led1on()
{

for (int i=0;i<=20;i++)             //循环20次    如何可以一直循环?
{leds_A = CRGB::Yellow;    // 设置光带中第一个灯珠颜色为黄色,leds为第一个灯珠,leds为第二个灯珠

FastLED.show();                // 更新LED色彩
delay(100);   // 等待100毫秒

leds_A = CRGB::Yellow;

FastLED.show();                // 更新LED色彩
delay(100);   // 等待100毫秒

leds_A = CRGB::Yellow;

FastLED.show();                // 更新LED色彩
delay(100);   // 等待100毫秒

leds_A = CRGB::Yellow;   

FastLED.show();                // 更新LED色彩
delay(100);   // 等待100毫秒

leds_A = CRGB::Yellow;

FastLED.show();                // 更新LED色彩
delay(100);   // 等待100毫秒


   leds_A = CRGB::Black;    // 设置光带中第一个灯珠颜色为黑色,leds为第一个灯珠,leds为第二个灯珠

FastLED.show();                // 更新LED色彩
delay(100);   // 等待100毫秒

leds_A = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(100);   // 等100毫秒

leds_A = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(100);   // 等100毫秒

leds_A = CRGB::Black;   

FastLED.show();                // 更新LED色彩
delay(100);   // 等100毫秒

leds_A = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(100);   // 等100毫秒



/*    getstr=Serial.read();    //    尝试打断循环,失败

   if(getstr=='B')

   break;
*/

}
   }


   void led1off()
{

    leds_A = CRGB::Black;    // 设置光带中第一个灯珠颜色为黑色,leds为第一个灯珠,leds为第二个灯珠

FastLED.show();                // 更新LED色彩
delay(100);   // 等待100毫秒

leds_A = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(100);   // 等100毫秒

leds_A = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(100);   // 等100毫秒

leds_A = CRGB::Black;   

FastLED.show();                // 更新LED色彩
delay(100);   // 等100毫秒

leds_A = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(100);   // 等100毫秒

}


void led2on()
{
LEDS.addLeds<LED_TYPE, DATA_PIN_B, COLOR_ORDER>(leds_B, NUM_LEDS_B);// 初始化光带
FastLED.setBrightness(min_bright);                            // 设置光带亮度

for (int i=0;i<=30;i++)             //循环30次    如何可以一直循环?
{leds_B = CRGB::Red;    // 设置光带中第一个灯珠颜色为红色,leds为第一个灯珠,leds为第二个灯珠

FastLED.show();                // 更新LED色彩
delay(200);   // 等待200毫秒

leds_B = CRGB::Red;

FastLED.show();                // 更新LED色彩
delay(200);   // 等待200毫秒

leds_B = CRGB::Red;

FastLED.show();                // 更新LED色彩
delay(200);   // 等待200毫秒

leds_B = CRGB::Red;   

FastLED.show();                // 更新LED色彩
delay(200);   // 等待200毫秒

leds_B = CRGB::Red;

FastLED.show();                // 更新LED色彩
delay(200);   // 等待200毫秒


   leds_B = CRGB::Black;    // 设置光带中第一个灯珠颜色为黑色,leds为第一个灯珠,leds为第二个灯珠

FastLED.show();                // 更新LED色彩
delay(200);   // 等待200毫秒

leds_B = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(200);   // 等200毫秒

leds_B = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(200);   // 等200毫秒

leds_B = CRGB::Black;   

FastLED.show();                // 更新LED色彩
delay(200);   // 等200毫秒

leds_B = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(200);   // 等200毫秒



/*    getstr=Serial.read();    //    尝试打断循环,失败

   if(getstr=='D')

   break;
*/

}
   }


   void led2off()
{

    leds_B = CRGB::Black;    // 设置光带中第一个灯珠颜色为黑色,leds为第一个灯珠,leds为第二个灯珠

FastLED.show();                // 更新LED色彩
delay(200);   // 等待200毫秒

leds_B = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(200);   // 等200毫秒

leds_B = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(200);   // 等200毫秒

leds_B = CRGB::Black;   

FastLED.show();                // 更新LED色彩
delay(200);   // 等200毫秒

leds_B = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(100);   // 等100毫秒

}





   void led3on()
{

LEDS.addLeds<LED_TYPE, DATA_PIN_C, COLOR_ORDER>(leds_C, NUM_LEDS_C);// 初始化光带
FastLED.setBrightness(min_bright);                            // 设置光带亮度

leds_C = CRGB::Red;    // 设置光带中第一个灯珠颜色为红色,leds为第一个灯珠,leds为第二个灯珠

FastLED.show();                // 更新LED色彩
delay(5);   // 等待100毫秒

leds_C = CRGB::Red;

FastLED.show();                // 更新LED色彩
delay(5);   // 等待100毫秒
    leds_C = CRGB::Red;    // 设置光带中第一个灯珠颜色为红色,leds为第一个灯珠,leds为第二个灯珠

FastLED.show();                // 更新LED色彩
delay(5);   // 等待100毫秒

leds_C = CRGB::Red;

FastLED.show();                // 更新LED色彩
delay(5);   // 等待100毫秒
leds_C = CRGB::Red;    // 设置光带中第一个灯珠颜色为红色,leds为第一个灯珠,leds为第二个灯珠

FastLED.show();                // 更新LED色彩
delay(5);   // 等待100毫秒



}

   void led3off()
{
leds_C = CRGB::Black;    // 设置光带中第一个灯珠颜色为红色,leds为第一个灯珠,leds为第二个灯珠

FastLED.show();                // 更新LED色彩
delay(5);   // 等待100毫秒

leds_C = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(5);   // 等待100毫秒
    leds_C = CRGB::Black;    // 设置光带中第一个灯珠颜色为红色,leds为第一个灯珠,leds为第二个灯珠

FastLED.show();                // 更新LED色彩
delay(5);   // 等待100毫秒

leds_C = CRGB::Black;

FastLED.show();                // 更新LED色彩
delay(5);   // 等待100毫秒
    leds_C = CRGB::Black;    // 设置光带中第一个灯珠颜色为红色,leds为第一个灯珠,leds为第二个灯珠

FastLED.show();                // 更新LED色彩
delay(5);   // 等待100毫秒

   }




void loop()
{
getstr=Serial.read(); //   查询并读取手机蓝牙发送指令

if(getstr=='A')
            {   
                      Serial.println("led1 on");
                     led1on();
               }

else if(getstr=='B')
               {
                     Serial.println("led1 off");
                     led1off();
                }
    else if(getstr=='C')
                {
                      Serial.println("led2 on");
                     led2on();
               }
    else if(getstr=='D')
                {
                     Serial.println("led2 off");
                        led2off();
                }   
else if(getstr=='E')
               {
                     Serial.println("led3 on");
                        led3on();
               }   
else if(getstr=='F')
               {
                        Serial.println("led3 off");
                        led3off();
               }   
}

kpj001 发表于 2020-12-18 23:15:58

滥用 delay 的后果。 WS2812 有现成的库,不好用吗?

xiao_y 发表于 2020-12-21 10:56:02

kpj001 发表于 2020-12-18 23:15
滥用 delay 的后果。 WS2812 有现成的库,不好用吗?

做流水就是要用delay来实现呀、、
大神 有推荐的库吗?
可否分享,谢谢

kevin_huihui 发表于 2021-1-25 15:31:41

xiao_y 发表于 2020-12-21 10:56
做流水就是要用delay来实现呀、、
大神 有推荐的库吗?
可否分享,谢谢

真的是滥用delay,而且循环并非一定要使用for,可以换一个思路。

for循环是要满足条件才可以跳出的,建议可以用adafruit_neopixel的库。

stpanzj 发表于 2021-8-31 11:17:41

刚好今年写了流水灯的程序。你这个delay基本一个循环要耗掉1s,再循环20-30次,就不可能同时更新其他LED的显示了。整个结构的设计不支持,你只能做一个大循环,每次检查是否到了该更新状态的时间点,是就做相应的更新,不是就检查下一个灯带。至于NEOpixel库,里面没有现成的流水控制。
页: [1]
查看完整版本: Arduino控制WS2812灯带问题,大神请来解惑?