如何优化此代码以便暂停循环的主要功能?

时间:2017-05-09 14:15:55

标签: arduino arduino-uno

所以我有这个为Arduino制作的红绿灯代码,但是我无法尽可能提高效率。我只会展示我想要优化的部分,因此代码不会那么混乱。

const int redLedPin=5;
const int yellowLedPin=6;
const int greenLedPin=4;
const int redLedPin1=10;
const int yellowLedPin1=9;
const int greenLedPin1=8;
const int blueLed=11;
const int button=3;
const int button2=2;
volatile int num = 0;
volatile int val = 0;
void setup() {

  pinMode(redLedPin, OUTPUT);
  pinMode(yellowLedPin , OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  pinMode(redLedPin1, OUTPUT);
  pinMode(yellowLedPin1 , OUTPUT);
  pinMode(greenLedPin1, OUTPUT);
  pinMode(blueLed,OUTPUT);
  pinMode(button,INPUT_PULLUP);
  pinMode(button,INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(button2), blink1, RISING);
  attachInterrupt(digitalPinToInterrupt(button), cycle, RISING);
}



 void loop() {
  //runs when the button is pressed then ends after the while loop is 
  //executed once and resets the value of the button
  while(val==1){
    digitalWrite(greenLedPin, HIGH);
    digitalWrite(redLedPin1,HIGH);
    digitalWrite(redLedPin,LOW);
    digitalWrite(blueLed,HIGH);
    delay(4000); 
    digitalWrite(greenLedPin, LOW);
    digitalWrite(redLedPin, HIGH);
   for(int i=0; i<=4;i++)
   {
      digitalWrite(blueLed,LOW);
      delay(500);
      digitalWrite(blueLed,HIGH);
      delay(500);
   }
    for(int i=0; i<=9;i++)
    {
      digitalWrite(blueLed,HIGH);
      delay(100);
      digitalWrite(blueLed,LOW);
      delay(100);
    }
    digitalWrite(blueLed,HIGH);
    delay(1000);
    digitalWrite(blueLed,LOW);
    val=!val;
  }
  //blinks three leds repeatedly till the button is pressed again
  if(num){
    digitalWrite(redLedPin, HIGH);
    digitalWrite(yellowLedPin1,HIGH);
    digitalWrite(blueLed, HIGH);
    digitalWrite(redLedPin1, LOW);
    delay(500);
    digitalWrite(redLedPin, LOW);
    digitalWrite(yellowLedPin1, LOW);
    digitalWrite(blueLed,LOW);
    delay(500);}
      else{
        changeLights();
      }

}

// the main function that gets repeated throughout the code
void changeLights() {
digitalWrite(greenLedPin, HIGH);
digitalWrite(redLedPin1,HIGH);
digitalWrite(redLedPin,LOW);
delay(4000); 
digitalWrite(yellowLedPin, HIGH);
digitalWrite(redLedPin1,HIGH);
digitalWrite(greenLedPin, LOW);
delay(2000); 
digitalWrite(yellowLedPin, LOW);
digitalWrite(redLedPin, HIGH); 
delay(2000);
digitalWrite(greenLedPin1, HIGH);
digitalWrite(redLedPin1,LOW);
delay(4000); 
digitalWrite(greenLedPin1, LOW);
digitalWrite(yellowLedPin1, HIGH); 
delay(2000);
digitalWrite(redLedPin,HIGH);
digitalWrite(redLedPin1,HIGH);
digitalWrite(yellowLedPin1,LOW);
delay(2000);
}
void blink1()
{

num=!num;

}

void cycle()
{

 val=!val;
}

所以我使用按钮来执行一些循环,然后返回到changeLights()函数。我想做的就是这样做每次按下其中一个按钮时它会停止changeLights()函数,无论它在哪里并执行按钮代码。那么如何进行优化以便它不必等到循环结束才能执行其中一个按钮代码。对不起,如果我遇到麻烦,我真的想让代码更好。

1 个答案:

答案 0 :(得分:1)

您可以重新构造代码以使用非阻塞方法等待一段时间,而不是使用delay(ms)哪些块(直到时间到时才返回)。通过使用millis()函数,您可以获得自Arduino重置以来的毫秒数,因此可以测量连续调用之间经过的时间。

因此,如果您执行此类操作,则每1000毫秒调用do_things()函数。 (改编自this示例)

unsigned long prev_millis, curr_millis, interval = 1000;

void loop() {
    curr_millis = millis();
    if ((curr_millis - prev_millis) > interval) {
        do_things();
    }
}

我建议将代码重构为类似这个粗略的例子

unsigned long prev_millis, curr_millis, interval;
int state, next;

void loop() {
    switch (state) {
        case 0:
            <set LEDs to certain state here>
            interval = 4000; // wait 4s before changing state
            next = 1;
            break;
        case 1:
            <set LEDs to another state here>
            interval = 500; // wait 0.5s before changing state
            next = 2;
            break;
        case 2:
            <set LEDs to yet another state here>
            interval = 100; // wait 0.1s before changing state
            next = 0; // loop back to start
            break;

        <add more states here for button sequences>
    }

    curr_millis = millis();
    if ((curr_millis - prev_millis) > interval) {
        state = next;
    }

    // check if buttons were pressed
    if (num) {
        state = 3; // state 3 is where the button1 sequence starts
    }
    if (val) {
        state = 7; // state 7 is where the button2 sequence starts
    }
}

使用这种类型的结构,状态3可以启动序列3-4-5-6并且状态6 next设置为0,并且0-1-2序列连续发生,直到按钮为按下。并且状态7可以启动序列7-8-9-7-8-9 ...继续重复直到再次按下该按钮(您需要将state设置回0)。

希望这会有所帮助:D