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

0909 신호등 동작 처리 선생님코드

by sj0020 2020. 9. 9.
#include <MsTimer2.h>
#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

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

const int ledRed = 11;
const int ledYellow = 9;
const int ledGreen = 10;

volatile int errFlag = FALSE;
volatile int timerCnt;
volatile int timerCnt2;
volatile long preTime = 0;
volatile long curTime = 0;
const int deBounce = 200;

int lastButtonState = LOW;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50; //50ms
boolean buttonState;


void setup() {
  Serial.begin(9600);
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);

  pinMode(ledRed, OUTPUT);
  pinMode(ledYellow, OUTPUT);
  pinMode(ledGreen, OUTPUT);

  MsTimer2::set(1, ledStart);  //1ms 마다 ledStart란 함수 호출 

  //////////////////////////////////////////
 // 0 :인터럽트 번호 (UNO 0,1 인터럽트 번호)
 // buttonInterrupt : ISR (인터럽트 핸들러)
 // mode : Falling, Rising, Change, Low
 //+++++++++++++++++++++++++++++++++++++++++
 //Falling : 신호가 High 에서 Low로 바뀔 때 인터럽트 발생 #눌렀다 뗐을 때
 //Rising : 신호가 Low 에서 High로 바뀔 때 인터럽트 발생 #눌렀을 때
 //Change : 신호가 바뀔 때 인터럽트 발생 (핀입력값이 변경될 때)
 //Low : 신호가 Low 일 때 인터럽트 발생, Low인 동안 반복 호출 됨
 //++++++++++++++++++++++++++++++++++++++++++

 attachInterrupt (digitalPinToInterrupt (buttonPin1), buttonInterrupt1,  FALLING);
 attachInterrupt (digitalPinToInterrupt (buttonPin2), buttonInterrupt2,  FALLING);
}

void loop() {
 int reading = digitalRead(buttonPin3);
 if (reading != lastButtonState){
  lastDebounceTime = millis();
  }

 if ((millis() - lastDebounceTime) > debounceDelay){
  if (reading != buttonState){
    buttonState = reading;
    if (buttonState == HIGH){
      Serial.println("신호중지");
      MsTimer2::stop();
      timerCnt = 0;
      timerCnt2 = 0;
      digitalWrite(ledRed, LOW);
      digitalWrite(ledYellow, LOW);
      digitalWrite(ledGreen, LOW);    
      }
    }
  }
  lastButtonState = reading;
}

void buttonInterrupt1(){
  curTime = millis();
  if(curTime - preTime >= deBounce){
    uint8_t oldSREG = SREG;
    cli();
    MsTimer2::stop();
    Serial.println("신호시작");
    preTime = curTime;
    errFlag = FALSE;
    MsTimer2::start();
    SREG = oldSREG;
    }
  }

void buttonInterrupt2(){
  curTime = millis();
  if(curTime - preTime >= deBounce){
    uint8_t oldSREG = SREG;
    cli();
    MsTimer2::stop();
    Serial.println("신호에러");
    preTime = curTime;
    errFlag = TRUE;
    MsTimer2::start();
    SREG = oldSREG;
    }
  }

void ledStart(){
  if (!errFlag){
    int1Func();
    }
  else{
    int2Func();
    }  
  }

void int1Func(){
  timerCnt++;
  if (timerCnt > 0 && timerCnt <= 1000){
    digitalWrite(ledGreen, LOW);
    digitalWrite(ledRed, HIGH);
    }
  else if (timerCnt > 1000 && timerCnt <= 1500){
    digitalWrite(ledRed, LOW);
    digitalWrite(ledYellow, HIGH);
    }
  else if (timerCnt > 1500 && timerCnt <= 2500){
    digitalWrite(ledYellow, LOW);
    digitalWrite(ledGreen, HIGH);
    }
  else if (timerCnt > 2500){
    timerCnt = 0;
    }        
  }

void int2Func(){
  timerCnt2++;
  if (timerCnt2 > 0 && timerCnt2 <= 1000){
    digitalWrite(ledGreen, HIGH);
    digitalWrite(ledRed, HIGH);
    digitalWrite(ledYellow, HIGH);
    }
  else if (timerCnt2 > 1000 && timerCnt2 <= 2000){
    digitalWrite(ledGreen, LOW);
    digitalWrite(ledRed, LOW);
    digitalWrite(ledYellow, LOW);
    }
  else if (timerCnt2 > 2000){
    timerCnt2 = 0;
    }        
  }  

버그 - 3->1 갈 때 . intfunc에 나머지 하나 라이트도 넣어주면 될걸? - 아직 안해봄