使用红外遥控器在功能之间切换

switching between functions using an IR remote

我买了一个WS2812B灯带。我正在尝试用红外遥控器控制它。它全部由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 编程。但到目前为止我喜欢它

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

例如:

而不是

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

注意这是伪代码。您需要正确实施它。你可能需要稍微改变一下程序的逻辑。

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

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 组合。只是玩 LED。随着你获得更多的经验,你不会问这样的问题。而且,如果您从某个大项目开始,很可能您将无法完成并感到失望,或者您将只是按照一些在线教程和复制粘贴代码进行操作,因此您不会觉得自己做到了它。