WS2812B的第一个led在代码进入for循环时开始点亮
Posted
技术标签:
【中文标题】WS2812B的第一个led在代码进入for循环时开始点亮【英文标题】:First led of WS2812B starts to light when the code enters the for loop 【发布时间】:2020-04-10 22:32:17 【问题描述】:我正在做这个项目,它应该是一个车棚的灯。有两种方法可以打开灯,通过运动传感器或通过开关。 LED灯条开始一个接一个地打开。它将保持一段时间,然后开始反转动画并将所有 LED 变为黑色。我正在为这个动画使用一个 for 循环(它与 FastLed 在第一个灯光示例中使用的循环相同)。只有当运动传感器被激活并且 for 循环正在运行时,才会出现错误。我很抱歉整数名称不好,可能会造成混淆。 非常感谢!
代码如下: (如果你不懂德语, - Bewegungsmelder = 运动传感器 - Schalter = 开关
// für die Leds
#define NUMfront_LEDS 150 //150 Leds
#define NUMinner_LEDS 35 //35 Leds
#define rightPIN 6 //Pin 6
#define leftPIN 5
#define innerrightPIN 8
#define innerleftPIN 7
#define CLOCK_PIN 13
// für die Schalter
#define schalter 2 //Pin 2
#define Bewegungsmelder 4 //Pin 4
int schalterval = 0;
int Bewegungsval = 0;
long Time = 0;
long Wait = 900000;
int On = 0;
CRGB leftLeds[NUMfront_LEDS];
CRGB rightLeds[NUMfront_LEDS];
CRGB innerleftLeds[NUMinner_LEDS];
CRGB innerrightLeds[NUMinner_LEDS];
void setup()
// sanity check delay - allows reprogramming if accidently blowing power w/leds
Serial.begin(115200);
delay(2000);
FastLED.addLeds<WS2812B, rightPIN, RGB>(rightLeds, NUMfront_LEDS); // GRB ordering is typical
FastLED.addLeds<WS2812B, leftPIN, RGB>(leftLeds, NUMfront_LEDS);
FastLED.addLeds<WS2812B, innerrightPIN, RGB>(innerrightLeds, NUMinner_LEDS);
FastLED.addLeds<WS2812B, innerleftPIN, RGB>(innerleftLeds, NUMinner_LEDS);
Time = millis();
void loop()
Serial.println("----------------------------------------------");
Serial.print(Wait);
Serial.print("----");
Serial.print(millis());
Bewegungsval = digitalRead(Bewegungsmelder);
schalterval = digitalRead(schalter);
Serial.println(Bewegungsval);
Serial.println(schalterval);
Serial.println("Space");
Schalter:
if (digitalRead(schalter) == 1)
On = 0;
for (int blackLed = NUMfront_LEDS; blackLed > -1; blackLed = blackLed - 1)
leftLeds[blackLed] = CRGB::White;
rightLeds[blackLed] = CRGB::White;
delay(19);
FastLED.show();
// Carport innen
fill_solid( innerrightLeds, NUMinner_LEDS, CRGB::White);
fill_solid( innerleftLeds, NUMinner_LEDS, CRGB::White);
//Leds aus
//Carport aussen
while (digitalRead(schalter) == 1)
for (int whiteLed = 0; whiteLed < NUMfront_LEDS; whiteLed = whiteLed + 1)
leftLeds[whiteLed] = CRGB::Black;
rightLeds[whiteLed] = CRGB::Black;
delay(19);
FastLED.show();
// Carport innen
fill_solid( innerrightLeds, NUMinner_LEDS, CRGB::Black);
fill_solid( innerleftLeds, NUMinner_LEDS, CRGB::Black);
FastLED.show();
else if (Bewegungsval == 1)
//Carport aussen
if (On == 1)
goto Skip;
for (int blackLed = NUMfront_LEDS; blackLed > -1; blackLed = blackLed - 1)
leftLeds[blackLed] = CRGB::White;
rightLeds[blackLed] = CRGB::White;
delay(19);
FastLED.show();
// Carport innen
fill_solid( innerrightLeds, NUMinner_LEDS, CRGB::White);
fill_solid( innerleftLeds, NUMinner_LEDS, CRGB::White);
FastLED.show();
//Leds aus
On = 1;
Skip:
Time = millis();
Wait = Time + 10000; // + 5min. 300000
Bewegungsval = digitalRead(Bewegungsmelder);
goto Schalter;
Time = millis();
if (Time >= Wait)
On = 0;
for (int whiteLed = 0; whiteLed < NUMfront_LEDS; whiteLed = whiteLed + 1)
leftLeds[whiteLed] = CRGB::Black;
rightLeds[whiteLed] = CRGB::Black;
delay(19);
FastLED.show();
// Carport innen
fill_solid( innerrightLeds, NUMinner_LEDS, CRGB::Black);
fill_solid( innerleftLeds, NUMinner_LEDS, CRGB::Black);
```
【问题讨论】:
【参考方案1】:虽然德语流利,但程序结构有点混乱。因为我们在 C++ 中
你不应该使用 goto 据我了解,switch 和 IR 的灯光例程是相同的,此代码应该只存在一次 您的时间测量例程不安全,请参阅 blinkwithoutdelay 示例如何操作所以使用以下结构清理代码:
unsigned long startTime = 0;
unsigned long myTimer = 10000;// 10 sec
bool lightIsOn = false;
setup()....
loop()
....
// We check wether switch or IR are triggerd AND we are not already in a light sequence
if ((digitalRead(schalter) == 1 || Bewegungsval == 1) && lightIsOn == false)
lightIsOn = true; // change state so we know that a light sequence is running
startTime = millis(); // reset the timer
// this part runs as long lighIsOn == true and time is not up
if(millis() - startTime <= myTimer && lighIsOn == true)
// Carport aussen
your light sequence .....
// Here we run the time is up sequence
if(millis() - startTime > myTimer && lighIsOn == true) // rollover safe
light sequence for time is up
........
lightIsOn = false; // change state so we know that a light sequence is over
这种技术称为有限状态机,不会通过 goto 进行“跳跃”。 如果您需要更多状态,您只需扩展序列 - 没有别的,因为例如在最后两个组合的 if 语句中,我们检查 lightIsON == true ==> else 意味着 lightIsON ==第二个是 false ,这在这里没有任何意义,因为我们只是按时间将它们区分为状态。 请永远不要在面向对象编程中使用 goto,它会使您的代码不可读和不可追踪。重写程序,如果有“新”问题在此处编辑或打开一个新问题
【讨论】:
好的,谢谢,我会按照这个结构尽可能地重写它。以上是关于WS2812B的第一个led在代码进入for循环时开始点亮的主要内容,如果未能解决你的问题,请参考以下文章
WLED and WS2812B RGB LEDs Strip All In One