본문 바로가기
임베디드/Arduino

신호등 동작 처리 200903_TrafficLights-1polling_2외부interrupt_3timer

by sj0020 2020. 9. 3.
#define BUTTON_PIN1 2
#include <MsTimer2.h>

const int buttonPin1 = 2; // 인터럽트 0 buttonInterrupt1
const int buttonPin2 = 3; // 인터럽트 1 
const int buttonPin3 = 4;

int LED_R = 11;
int LED_Y = 9;
int LED_G = 10;

volatile long preTime = 0;
volatile long curTime = 0;
const int deBounce = 200;
int buttonState; 

volatile int checkBtn;
volatile int flag=0;

volatile int output = HIGH;

void setup() {
 Serial.begin(9600);
 attachInterrupt(digitalPinToInterrupt(buttonPin1), buttonInterrupt1, FALLING);
 attachInterrupt(digitalPinToInterrupt(buttonPin2), buttonlnterrupt2, FALLING);
  
 pinMode(buttonPin1, INPUT);
 pinMode(buttonPin2, INPUT);
 pinMode(buttonPin3, INPUT);
 pinMode(LED_R, OUTPUT);
 pinMode(LED_Y, OUTPUT);
 pinMode(LED_G, OUTPUT);
 digitalWrite(LED_R, LOW);
 digitalWrite(LED_Y, LOW);
 digitalWrite(LED_G, LOW);

 MsTimer2::set(500, flash); // 500ms period
 

}

void loop() {
  int reading = digitalRead(buttonPin3); // 폴링 방식 //클럭주파수 때문에 쫙 떨어지면서 뜬다.
 

  // if the button state has changed:
  if (reading != buttonState) { // buttonState의 값은 전역변수 0 => reading이 1일 때,
    buttonState = reading; // buttonState 값을 0으로 바꿔라

  if (buttonState == 1) {// if 버퍼 -> 시간차 조정
     flag=1;
     checkBtn = 1;
     output=0;
     MsTimer2::stop();
     Serial.println("1번 버튼: red5s - yellow1s - green5s 무한반복");
     Serial.println(checkBtn);
     
    } 

  if(flag)
    {
    if (checkBtn == 1) {
      while(1){
        Serial.println("1번 flag 내 시작");
        digitalWrite(LED_R, HIGH);
        digitalWrite(LED_Y, LOW);
        digitalWrite(LED_G, LOW);
        delay(500);
        digitalWrite(LED_R, LOW);
        digitalWrite(LED_Y, HIGH);
        digitalWrite(LED_G, LOW);
        delay(100);
        digitalWrite(LED_R, LOW);
        digitalWrite(LED_Y, LOW);
        digitalWrite(LED_G, HIGH);
        delay(500);
        }
      }
      
    if (checkBtn == 2) {
      Serial.println("2번 flag 내 시작");
      Serial.println(checkBtn);
      digitalWrite(LED_R, LOW);
      digitalWrite(LED_Y, LOW);
      digitalWrite(LED_G, LOW);
      Serial.println("flag btn2");
      }
      
    if (checkBtn == 3) {
      Serial.println("3번 flag 내 시작");
      Serial.println(checkBtn);     
      }
    flag=0;
     
    }

  }     
} 

void buttonInterrupt1() {
  curTime = millis();
  if(curTime - preTime >= deBounce) {
    uint8_t oldSREG = SREG;
    cli();
    MsTimer2::stop(); 
    output=0;
    checkBtn = 2;   
    flag=1;
    Serial.println("2번버튼 : 신호등 중지. all LEDs off"); 
    Serial.println(checkBtn); 
    Serial.println(flag); 
    preTime = curTime;
    SREG = oldSREG;
  }
}

void buttonlnterrupt2() {
  
  curTime = millis();
  if(curTime - preTime >= deBounce) {
    uint8_t oldSREG = SREG;
    cli();
    MsTimer2::start();
    checkBtn = 3;
    flag=1;
    Serial.println("3번버튼 : 신호등 에러 : 1초 주기로 3개 all LEDs on/off");
    Serial.println(checkBtn);
    preTime = curTime;
    SREG = oldSREG;
    
  }
}

void flash()
{
  digitalWrite(LED_R, output);
  digitalWrite(LED_Y, output);
  digitalWrite(LED_G, output);
  output = !output;
}

1. 버튼1: 신호등 동작기능 - "빨강5초 - 노랑1초 - 녹색5초"  반복

2. 버튼2: 신호등 중지 :  LED all off

3. 버튼3: 신호등 에러 : 1초 주기로 3개 all LEDs on/off

 

 

작동은 되나 문제점:

1. 모든 작동에서 다 if 내부를 다  돌고 동작함 

  - 1에서 빨간색일 때 2를 누르면 그 순간 바로 꺼지는 것이 아니라 빨-노-초 끝까지 다 간 뒤에 led 꺼짐..

  - 1에서 3 눌러도 1 다 돌고나서 3 동작시작함

  -> 인터럽트가 제대로 동작 안하는 것인가?

 

2. 3->2

 2-1. 가끔  다 꺼지는 것이 아니라 모든 led 켜진 상태에서 멈춤 (이 상태일 때 2번 flag 내부로 안들어감. "2번 flag 시작" 출력 안됨)

 2-2. 작동 제대로 될때도 2번 flag 내부로 안들어감. "2번 flag 시작" 출력 안됨.. flag 내부로 안들어 갔는데 어떻게 왜 led가 다 꺼지는 ㄴ것인ㄱ ㅏ .......? digital write low는 다 flag 내부 if문 안에 있는ㅇ대..?

 

2->3 일때  flag 내부로 안들어감. "3번flag 내 시작" 안뜸. 1->3은 뜸

더보기

 

if (checkBtn == 2) {
      
      Serial.println("2번 flag 내 시작");
      Serial.println(checkBtn);
       //while(1){  
      // MsTimer2::stop();
        digitalWrite(LED_R, LOW);
        digitalWrite(LED_Y, LOW);
        digitalWrite(LED_G, LOW);
        Serial.println("flag btn2");
//        if (checkBtn == 1 || checkBtn == 3){
//          Serial.println("flag btn2llllllllllllllll"); 
//          flag=0;
       //   break; 
 //         }
        //}
      }

// 주석 처리된 부분은 필요가 없음.  -> 필요함 !!!!!

if문 안의 if 문  if (checkBtn == 1 || checkBtn == 3) 이거..  넣은 이유는 : 2번을 상태에서 라이트가 계속 꺼진 상태로 유지되고 1이나 3을 눌렀을 때 다시 led가 켜지지 않아서.. 저걸 넣어서  flag 를 0으로 만들고 break를 넣으면 되나?!! 했는데 애초에 저 if 안으로 들어갈 수가 없음 .. 위의 if가 checkbtn이 2일 때만 들어오는 거니까.. 말이안되는 코드를 짠것임;

현재 있는 곳이  if 내부라서 .. if 안으로 들어갈 수 있땅

'임베디드 > Arduino' 카테고리의 다른 글

서보모터  (0) 2020.09.09
0909 신호등 동작 처리 선생님코드  (0) 2020.09.09
타이머 인터럽트 Timer interrupt  (0) 2020.09.03
키입력인터럽트 + LED + buzzer  (0) 2020.09.02
키입력 인터럽트  (0) 2020.09.02