#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 |