简体   繁体   English

使用暂停按钮 ARDUINO 创建灯光序列时出现问题

[英]Issues creating light sequence with pause button ARDUINO

So I am trying to create a program that runs various light sequences using an Arduino board.所以我正在尝试使用 Arduino 板创建一个运行各种光序列的程序。 I am not very familiar with C++ so I feel that my lack of syntax knowledge is preventing me from accomplishing my goal.我对 C++ 不是很熟悉,所以我觉得我缺乏语法知识阻碍了我实现目标。

My idea is to have various light sequences that are played depending on what button is pressed on an infrared remote.我的想法是根据红外遥控器上按下的按钮来播放各种光序列。 The amount of time that a light is on or off may or may not be the same as that of another light.一盏灯打开或关闭的时间可能与另一盏灯的时间相同,也可能不同。 Unfortunately, the sequences do not seem to be working which indicates that the issue is likely with the toggleLight function.不幸的是,这些序列似乎不起作用,这表明该问题可能与toggleLight function 相关。

I also wanted there to be a button that allows the user to pause the sequence (no matter where along the sequence it is).我还希望有一个按钮,允许用户暂停序列(无论它在序列的哪个位置)。 And once the button is pressed again, then the sequence continues where it left off.一旦再次按下按钮,序列就会从中断的地方继续。 I read something about an interrupter and sleep mode using C++ but I am unfamiliar with this so it is not included in my code.我使用 C++ 阅读了一些关于中断器和睡眠模式的内容,但我对此并不熟悉,因此它不包含在我的代码中。

The rest of my goals I have included within my code.我的目标的 rest 已包含在我的代码中。 I created an object "light" because I was trying to create the sequence without using the delay function as the interrupt does not work well with the delay function (as far as I am aware).我创建了一个 object “light”,因为我试图在不使用延迟 function 的情况下创建序列,因为中断在延迟 function 下无法正常工作(据我所知)。 Then I am able to call the function toggleLight on the specific light object.然后我可以在特定的灯 object 上调用 function toggleLight However, as I previously stated the sequences are not working.但是,正如我之前所说,这些序列不起作用。

I am more familiar with OOP languages so perhaps creating an object is not the best for Arduino.我更熟悉 OOP 语言,所以创建 object 可能不是 Arduino 的最佳选择。 If anyone has any ideas for how I can accomplish my goal it would be much appreciated.如果有人对我如何实现我的目标有任何想法,将不胜感激。

unsigned long previousMillis = 0;
unsigned long currentMillis = millis();

//sets up the Infrared receiver for the remote controller
const int RECV_PIN = 1;
IRrecv irrecv(RECV_PIN);
decode_results results;

//Sets up the LED's pin number and light status
class light{
   private:
   int _pinNumber;
   byte _Lstatus;

  public:
 //function that creates the objects with the parameters
  light(int pinNum, byte Lstat){
  _pinNumber = pinNum;
  _Lstatus = Lstat;}

  void toggleLight(long interval){
    //ensures that the "interval" amount of time has passed between the last LED blink
    if ((currentMillis - previousMillis) >= interval) {

    // if the LED is off turn it on and vice-versa:
    if (_Lstatus == LOW) {
      _Lstatus = HIGH;
    } else if (_Lstatus == HIGH) {
      _Lstatus = LOW;
    }
    // set the LED with the ledState of the variable:
    digitalWrite(_pinNumber, _Lstatus);
    // save the last time you blinked the LED
    previousMillis = currentMillis;
  }
  }
};
//creating four light objects with the pins and initial status of off.
light J1(13, LOW);
light J2(11, LOW);
light P1(12, LOW);
light P2(10, LOW);


void setup()
{
    pinMode(13, OUTPUT);
    pinMode(12, OUTPUT);
    pinMode(11, OUTPUT);
    pinMode(10, OUTPUT);

}
//Sequence 1 is a mock sequence. It will probably be longer and the intervals would not all be 1000
void seq1(){
  currentMillis = millis();
  J1.toggleLight(1000);
  P1.toggleLight(1000);
  J1.toggleLight(1000);
  P1.toggleLight(1000);
  J2.toggleLight(1000);
  P2.toggleLight(1000);
}

void seq2(){
  currentMillis = millis(); //I found that placing currentMillis = millis() here allows the lights to at least turn on
  J1.toggleLight(2000);
  J1.toggleLight(10);
  P1.toggleLight(1000);
  P1.toggleLight(0);
  J2.toggleLight(1500);
  J2.toggleLight(1);
  P2.toggleLight(2000);
  P2.toggleLight(1);
}

void loop()
{
      /* So once i get the sequences working, my idea is to have different sequences play
    depending on what button on the remote is pressed. However, first I want to get the sequences and
    interrupter
For now I have just tried running sequence #2 but it does not work.. Neither does Sequence #1. */
      seq2();



      //I MADE THESE LINES OF CODE COMMENTS FOR NOW. UNTIL I GET THE REST OF THE PROGRAM WORKING
      /*if (irrecv.decode(&results))
      {
        switch (results.value) {
          case : 0xf00000 // When button #1 sequence one plays
            seq1();
            break;
          case : 0xf00000 // when button #2 is pressed, sequence two plays
            seq2();
            break;
    */

    }

I can see that you haven't yet got around to understanding the flow of code inside the Arduino.我可以看到您还没有开始了解 Arduino 中的代码流。 Here's a quick tutorial to get you up and running.这是一个快速教程,可帮助您启动和运行。

Basically, your code is not being processed sequentially.基本上,您的代码没有按顺序处理。 So when the processor is moving through seq() and gets to the first if statement in 'J1.toggleLight(2000);'因此,当处理器通过 seq() 并到达“J1.toggleLight(2000);”中的第一个 if 语句时and finds that the condition is not met (ie the 2000 milliseconds have not yet passed,) it immediately moves on to the second line in seq().并发现条件不满足(即 2000 毫秒还没有过去),它立即转到 seq() 中的第二行。 The issue with this is that when it does meet the condition at the second line it will reset the 'previousMillis' value which all the lights depend on.这样做的问题是,当它确实满足第二行的条件时,它将重置所有灯所依赖的“previousMillis”值。

Thus you should dedicate a clock for each light by moving in 'previousMillis' into the class as a member.因此,您应该通过将“previousMillis”作为成员移入 class 来为每个灯指定一个时钟。

   class light{
       private:
       int _pinNumber;
       byte _Lstatus;
       unsigned long previousMillis = 0;

This way each light will be able to keep track of its own time without conflicting with the other lights.这样,每盏灯都可以跟踪自己的时间,而不会与其他灯发生冲突。 This will lead to your lights flickering at a frequency of 1/interval which I doubt is what you want.(it wont even do that with each light getting toggled twice in the seq() functions. Try removing the second calls and see hat happens) This brings me to the second issue.这将导致您的灯以 1/interval 的频率闪烁,我怀疑这是您想要的。(它甚至不会在 seq() 函数中切换每个灯两次时做到这一点。尝试删除第二个调用,看看会发生什么) 这让我想到了第二个问题。

The second issue is with the way you set up your sequences.第二个问题是您设置序列的方式。 Since you want to the lights to operate sequentially you'll need to find the accumulated time which crosses out the chance of using a class, unless you're willing to implement a scheduling mechanism that takes account the interval and arrangement of each instance.由于您希望灯按顺序运行,您需要找到累积时间,以消除使用 class 的机会,除非您愿意实施考虑到每个实例的间隔和安排的调度机制。 Seems a bit impractical imo.似乎有点不切实际imo。

I think you should ditch the class and use a simple function that that accepts the eight values that each sequence requires.我认为您应该放弃 class 并使用一个简单的 function 来接受每个序列所需的八个值。 Then you could utilize if statements to manipulate the states of the lights.然后你可以利用 if 语句来操纵灯的状态。

I hope the answer made some sense.我希望答案是有意义的。 Good luck.祝你好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM