2017-05-09 7 views
1

그래서 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

delay(ms)을 차단하는 대신 (시간이 끝날 때까지 돌아 오지 않음) 비 차단 방법을 사용하여 일정 시간 대기하도록 코드를 다시 구성 할 수 있습니다. millis() 함수를 사용하면 Arduino가 재설정 된 후 밀리 초 수를 얻을 수 있으므로 연속 호출간에 경과 된 시간을 측정 할 수 있습니다.

이와 같이하면 do_things() 함수가 1000ms마다 호출됩니다.

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 시퀀스를 시작할 수 있었다 것 (this 예에서 적응) 3-4- 5-6 및 상태 6 next은 0으로 설정되고 0-1-2 시퀀스는 버튼을 누를 때까지 계속 발생합니다. 그리고 상태 7은 버튼을 다시 누를 때까지 계속 반복됩니다 (state을 0으로 다시 설정해야 할 것입니다) 7-8-9-7-8-9 ... 시퀀스를 시작할 수 있습니다.

희망이 도움이 : D

+0

좋아,이 코드는 훌륭하지만 한가지 더 질문이 있습니다. 그래서 지속적으로 진행되는 버튼의 경우 루프에서 빠져 나옵니다. 나는 그 밖의 다른 것을 시도했지만 코드는 엉망이되었고 LED는 엉망이되기 시작했다. 버튼을 누를 때마다 다음에 0을 어떻게 설정합니까? – Rafael

+0

@Rafael 버튼을 누르면이 변수가 토글 될 때 'int in_button_sequence = 0'과 같은 변수를 생성하는 것으로 생각합니다. 토글 링 한 후 다음과 같이하십시오. if (in_button_sequence) {state = 7} else {state = 0}' – linzwatt