极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 37950|回复: 4

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

[复制链接]
发表于 2020-11-28 20:03:02 | 显示全部楼层 |阅读模式
各位大神请帮忙看看,谢谢!!!

手机蓝牙控制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[NUM_LEDS_A];            // 建立光带leds
CRGB leds_B[NUM_LEDS_B];
CRGB leds_C[NUM_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[0] = CRGB::Yellow;    // 设置光带中第一个灯珠颜色为黄色,leds[0]为第一个灯珠,leds[1]为第二个灯珠

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

  leds_A[1] = CRGB::Yellow;

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

  leds_A[2] = CRGB::Yellow;

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

  leds_A[3] = CRGB::Yellow;   

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

  leds_A[4] = CRGB::Yellow;

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

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

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

  leds_A[1] = CRGB::Black;

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

  leds_A[2] = CRGB::Black;

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

  leds_A[3] = CRGB::Black;   

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

  leds_A[4] = CRGB::Black;

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


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

   if(getstr=='B')

   break;
*/
  
}
   }
  
  
   void led1off()
{
  
    leds_A[0] = CRGB::Black;    // 设置光带中第一个灯珠颜色为黑色,leds[0]为第一个灯珠,leds[1]为第二个灯珠

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

  leds_A[1] = CRGB::Black;

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

  leds_A[2] = CRGB::Black;

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

  leds_A[3] = CRGB::Black;   

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

  leds_A[4] = 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[0] = CRGB::Red;    // 设置光带中第一个灯珠颜色为红色,leds[0]为第一个灯珠,leds[1]为第二个灯珠

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

  leds_B[1] = CRGB::Red;

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

  leds_B[2] = CRGB::Red;

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

  leds_B[3] = CRGB::Red;   

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

  leds_B[4] = CRGB::Red;

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

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

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

  leds_B[1] = CRGB::Black;

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

  leds_B[2] = CRGB::Black;

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

  leds_B[3] = CRGB::Black;   

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

  leds_B[4] = CRGB::Black;

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


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

   if(getstr=='D')

   break;
*/
  
}
   }
  
  
   void led2off()
{
  
    leds_B[0] = CRGB::Black;    // 设置光带中第一个灯珠颜色为黑色,leds[0]为第一个灯珠,leds[1]为第二个灯珠

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

  leds_B[1] = CRGB::Black;

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

  leds_B[2] = CRGB::Black;

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

  leds_B[3] = CRGB::Black;   

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

  leds_B[4] = 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[0] = CRGB::Red;    // 设置光带中第一个灯珠颜色为红色,leds[0]为第一个灯珠,leds[1]为第二个灯珠

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

  leds_C[1] = CRGB::Red;

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

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

  leds_C[3] = CRGB::Red;

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

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

  

}

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

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

  leds_C[1] = CRGB::Black;

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

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

  leds_C[3] = CRGB::Black;

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

  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();
               }   
}

回复

使用道具 举报

发表于 2020-12-18 23:15:58 | 显示全部楼层
滥用 delay 的后果。 WS2812 有现成的库,不好用吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-12-21 10:56:02 | 显示全部楼层
kpj001 发表于 2020-12-18 23:15
滥用 delay 的后果。 WS2812 有现成的库,不好用吗?

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

使用道具 举报

发表于 2021-1-25 15:31:41 | 显示全部楼层
xiao_y 发表于 2020-12-21 10:56
做流水就是要用delay来实现呀、、
大神 有推荐的库吗?
可否分享,谢谢

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

for循环是要满足条件才可以跳出的,建议可以用adafruit_neopixel的库。
回复 支持 反对

使用道具 举报

发表于 2021-8-31 11:17:41 | 显示全部楼层
刚好今年写了流水灯的程序。你这个delay基本一个循环要耗掉1s,再循环20-30次,就不可能同时更新其他LED的显示了。整个结构的设计不支持,你只能做一个大循环,每次检查是否到了该更新状态的时间点,是就做相应的更新,不是就检查下一个灯带。至于NEOpixel库,里面没有现成的流水控制。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-20 14:47 , Processed in 0.043546 second(s), 20 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表