-1

我买了一个 WS2812B LED 灯条。我正在尝试用红外遥控器控制它。它全部由 arduino uno 控制。
我知道 LED 工作,我知道远程工作。我正在尝试在遥控器上预编程一些动画。
下面的代码是据我所知。我可以显示一个动画,但我必须等到它结束才能将其更改为另一个。
当我按下按钮选择另一个动画时,是否可以中断这个(因为某些动画是无限的)?

#include <IRremote.h>
#include "FastLED.h"
#define NUM_LEDS 232
CRGB leds[NUM_LEDS];
#define PIN 7

const int RECV_PIN = 6;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long key_value = 0;

void setup(){
  FastLED.addLeds<WS2812B, PIN, RGB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  Serial.begin(9600);
  irrecv.enableIRIn();
  irrecv.blink13(true);
}

//switch case for remote
void loop(){
  if (irrecv.decode(&results)){

        if (results.value == 0XFFFFFFFF)
          results.value = key_value;

        switch(results.value){
          case 0xFF30CF:
          Serial.println("1");
          RGBLoop();
          break ;
          case 0xFF18E7:
          Serial.println("2");
          red();
          break ;
          case 0xFF7A85:
          Serial.println("3");
          break ;
        }
        key_value = results.value;
        irrecv.resume(); 
  }
}


void RGBLoop(){

  while(key_value==key_value){
  for(int j = 0; j < 6; j++ ) {
    // Fade IN
    for(int k = 0; k < 256; k++) {
      switch(j) {
        case 0: setAll(k,0,0); break;
        case 2: setAll(k,k,0); break;
        case 3: setAll(0,k,0); break;
        case 4: setAll(0,k,k); break;
        case 5: setAll(0,0,k); break;
      }
      showStrip();
      delay(3);
    }
    // Fade OUT
    for(int k = 255; k >= 0; k--) {
      switch(j) {
        case 0: setAll(k,0,0); break;
        case 2: setAll(k,k,0); break;
        case 3: setAll(0,k,0); break;
        case 4: setAll(0,k,k); break;
        case 5: setAll(0,0,k); break;
      }
      showStrip();
      delay(3);
    }
  }
}
}

void red(){
  irrecv.resume();
  setAll(0,255,255);
  showStrip();
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
 #endif
}


void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}


void showStrip() {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.show();
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   FastLED.show();
 #endif
}

void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } }

老实说,我上网的大部分时间。这是我第一次编写 arduino。但到目前为止我喜欢它

4

1 回答 1

0

您可以检查是否收到任何其他命令,而不是使用无限循环。

例如:

代替

while ( key_value == key_value ) //This is a weird infinite loop condition but whatever 
{
    // do stuff
}

你可以有

while ( decode() == condition_for_this_loop )
{
    // do stuff
}

或者

for(;;) //This also is just an infinite loop, but looks nicer.
{
    // do stuff

    if ( decode() != condition_for_this_loop ) {  break;  }
}

请注意,这是一个伪代码。您需要正确实施它。而且您可能需要稍微更改程序的逻辑。

由于您已经在全局范围内定义了 recv 对象,它将对下面的其他函数可见,这不会是一个问题。您的代码甚至可以通过替换循环条件来工作。但是如果你得到错误,你需要处理它们,我只是指出逻辑。最后,你可以有这样的东西:

irrecv.decode( &results );

switch ( results )
{
    case CONDITION_1:
        inf_loop1();
    break;

    case CONDITION_2:
        int_loop2();
    break;
}

...

void inf_loop1()
{
    for(;;) 
    {
        // do stuff

        irrecv.decode( &results );
        if ( results != CONDITION_1 ) {  break;  }
    }
}


void inf_loop2()
{
    for(;;) 
    {
        // do stuff

        irrecv.decode( &results );
        if ( results != CONDITION_2 ) {  break;  }
    }
}

顺便说一句,从相对较大的项目开始并不是一个好主意。根据您的问题,我假设这不仅是您的第一个 Arduino 程序,而且是您的第一个程序。走之前不要跑。慢慢开始,闪烁一些 LED,用 LED 实现一些有趣的算法,我不知道,有多个并以不同的顺序点亮它们,有一些按钮并将它们与 LED 组合。只是玩 LED。随着您获得更多经验,您将不会问这样的问题。如果你从一些大项目开始,很可能你将无法做到,并且感到失望,或者你只会被一些在线教程和复制粘贴代码,因此感觉不像你做过它。

于 2020-04-30T06:02:25.213 回答