0

我正在制作一个 LED 控制程序(当然是使用 FastLED)并使用串行(带有串行监视器)来控制它。只需通过 USB 连接,大多数情况下都可以正常工作。然而,我注意到长时间闪烁的程序让我无法阻止它们并让 LED 做其他事情。我的代码中的 flash 例程非常简单:

void flash(CRGB color, int count, int del){
  for(int i = 0; i < count; i++){
    if(pause){
      break;
    }
    fillLeds(color.r, color.g, color.b);
    milliDelay(del);
    fillLeds(0,0,0);
    milliDelay(del);
  }
}

作为fillLeds(r,g,b)一个for循环,循环并将所有LED设置为某种颜色,并且milliDelay只是delay()使用millis而不是delay()功能。我需要的是不仅能够暂停这个,还能够暂停其他功能(可能使用break;),然后执行其他代码。看起来很容易对吧?好吧,我注意到当我通过串行发送一个字节时,如果你愿意的话,它会进入这个“队列”,然后被顺序读取。我不能让这种事情发生。我需要的是输入 Serial 的下一个字节来激活某种事件,该事件会暂停其他flash()功能的运行,然后再使用。我实现这个的方式是这样的:

void loop()
{
    if (Serial.available() > 0) {
      int x = Serial.read();
      Serial.print(x);
      handleRequest(x);
    }

    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}

wherehandleRequest(x);只是一个很长的 switch 语句,其中调用了 flash 方法,使用了不同的颜色等。

每当收到新字节时,如何让 Arduino 暂停其他循环,而不是将其添加到此“队列”中以便稍后执行?如果这是不可能的,无论如何感谢您的阅读。我试过使用serialEvent()which 似乎不起作用。

4

2 回答 2

0

据我了解,当新字节到达时,您想要类似中断的功能吗?

不幸的是,serialEvent并不是真正的中断。loop如果有可用的串行数据,它只会在 结束时运行。

但是,serialEvent它只是一个函数,没有理由不能在代码中随心所欲地调用它。这有效地尽可能频繁地轮询新的串行数据。因此,当您的循环正在运行时,请serialEvent在您的延迟期间调用并在那里处理串行数据。

您可能需要重组代码以避免递归。如果flash调用serialEvent,调用flash,调用serialEvent等等......那么你最终可能会溢出堆栈。

于 2019-01-21T12:11:18.627 回答
0

我认为你需要2个循环。您有一个,这是您的主循环,您可以使用 TimerOne 库添加另一个(如多线程)。像这样:

Timer1.initialize(your desired delay in this loop);
Timer1.attachInterrupt( your desired function in this loop);

因此,您可能可以在第二个循环中添加带有 var 的 if 语句,以防止某些功能并在第一个循环中更新 var 或类似的东西。

于 2019-01-22T20:45:42.040 回答