[Arduino] Counter with Push Button

스윗포테이토·2022년 11월 25일
1

아두이노

목록 보기
5/5

지난 글에서 푸시버튼에 대해 간단히 서술했는데, 이번에는 푸시버튼을 이용해 카운터를 만드려고 한다. 간단히 버튼을 한번씩 누를 때마다 숫자를 1씩 증가시켜 시리얼로 출력하는 기능을 구현해보자.

내부 PULL_UP 저항을 사용한다고 가정하면 회로는 아래와 같다.

pin Map

2: Push Button - input
13: LED - output

#define BUTTON 2
#define LED 13
void setup(){
	pinMode(BUTTON, INPUT_PULLUP);
	pinMode(LED, OUTPUT);
    
    Serial.begin(9600);
}

우선 단순하게 생각하면 아래와 같은 코드를 짤 수 있다.

// 전역변수
int count = 0;

void loop(){
	if (digitalRead(BUTTON) == LOW){ // pull-up 이므로 LOW가 버튼 눌렀을 떄!
    	count++;
        digitalWrite(LED, HIGH);
        Serial.println(count);
    } else {
    	digitalWrite(LED, LOW);
    } 
}

그러나 이렇게 짠 경우 실행을 해보면 버튼을 한번 누르는데 출력값이 20~30씩 커지는 것을 볼 수 있다.

이유는 우리가 얼핏 생각한 것보다, 아두이노의 동작이 훨씬 빠르기 때문이다. 따라서 빠르게 눌렀다 떼는 그 찰나에도 loop()가 20~30번 실행되었던 것이다.

그렇다면 원하는 동작을 어떻게 수행할 수 있을까?
버튼을 누르는 과정을 조금 자세히 구분하면 버튼을 누르는 순간(A), 버튼이 계속 눌리고 있는 구간(B), 버튼에서 손을 떼는 순간(C)가 있다.

구간 B에서 루프 함수가 여러번 실행되므로, 이 때 카운트가 한번만 높아지도록 코드를 수정할 필요가 있다.
따라서 이미 카운트 했다는 것을 표기하는 플래그 변수를 사용할 것이다.

bool flag = false;

void loop(){
	bool isPushed = !digitalRead(BUTTON); // pull-up 이므로 LOW가 눌린 순간
	if (isPushed == LOW && !flag){ // 아직 표시하지 않은 경우만
    	count++;
        flag = true; // 이미 카운트를 했음
        Serial.println(count);
        digitalWrite(LED, HIGH);
    }
    if (!isPushed){
    	isPushed = false; // 버튼에서 손을 뗐다면 다시 플래그 변수를 flase로 돌려줌
        digitalWrite(LED, LOW);
    }
}

이런식으로 고치면 이제 한번에 하나씩만 숫자가 올라가는 것을 볼 수 있다.

참고로 저 A인 순간과 C인 순간을 포착하는 방식도 있는데 관련해서는 이후에 포스팅 할 예정이다.

profile
나의 삽질이 미래의 누군가를 구할 수 있다면...

0개의 댓글