Arduino 如何优化此代码,使其暂停正在循环的主函数?

Arduino 如何优化此代码,使其暂停正在循环的主函数?,arduino,arduino-uno,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

所以我有这个为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;
}
const int redLedPin=5;
常数int yellowLedPin=6;
常数int greenLedPin=4;
常数int redLedPin1=10;
常数int yellowLedPin1=9;
常数int greenLedPin1=8;
常数int blueLed=11;
常数int按钮=3;
const int button2=2;
volatile int num=0;
volatile int val=0;
无效设置(){
引脚模式(红色引脚,输出);
引脚模式(黄色LED引脚,输出);
引脚模式(绿色引脚,输出);
引脚模式(红色引脚1,输出);
引脚模式(黄色LED引脚1,输出);
引脚模式(绿色LED引脚1,输出);
引脚模式(蓝色LED,输出);
pinMode(按钮、输入\上拉);
pinMode(按钮、输入\上拉);
连接中断(数字插针中断(按钮2),闪烁1,上升);
连接中断(数字插针中断(按钮)、循环、上升);
}
void循环(){
//按下按钮时运行,然后在while循环结束后结束
//执行一次并重置按钮的值
while(val==1){
数字写入(绿色,高);
数码写入(红色1,高);
数字写入(红色引脚,低电平);
数码写入(蓝色,高亮度);
延迟(4000);
数字写入(绿色,低电平);
数字写入(红色,高);

对于(int i=0;i而不是使用
delay(ms)
阻塞(直到时间结束才会返回),您可以重新构造代码以使用非阻塞方法等待一定时间。通过使用
millis()
function,您可以获取自Arduino重置以来的毫秒数,从而测量连续调用之间经过的时间

因此,如果您执行类似的操作,则每隔1000毫秒将调用
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
    }
}
unsigned long prev_millis,curr_millis,interval;
int state,下一个;
void循环(){
开关(状态){
案例0:
间隔=4000;//在更改状态之前等待4s
next=1;
打破
案例1:
间隔=500;//更改状态前等待0.5s
next=2;
打破
案例2:
间隔=100;//更改状态前等待0.1s
next=0;//循环返回开始
打破
}
curr_millis=millis();
如果((当前毫秒-上一毫秒)>间隔){
状态=下一个;
}
//检查按钮是否按下
if(num){
state=3;//状态3是按钮1序列的开始位置
}
if(val){
state=7;//状态7是按钮2序列开始的位置
}
}
使用这种类型的结构,状态3可以启动序列3-4-5-6,在状态6
next
中设置为0,0-1-2序列持续发生,直到按下按钮。状态7可以启动序列7-8-9-7-8-9…持续重复,直到再次按下按钮(您需要将
状态设置回0)


希望这有帮助:D

好的,那么这个代码很好,但我还有一个问题。那么对于持续运行的按钮,我该如何摆脱循环。我尝试了,但代码失控,LED开始混乱。那么,每当按下按钮时,我该如何将next设置为0?@Rafael我想你应该做的是创建一个按下按钮时,一个变量如
int in_-button_-sequence=0
,切换此变量。切换后,执行类似
if(in_-button_-sequence){state=7}或{state=0}
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
    }
}