Menu
CoddyTech

버튼 디바운싱하기

Coddy Arduino 여정의 입력 섹션에 포함된 레슨. 22개 중 6번째.

이 레슨의 버튼은 실제 버튼이며, 시작 코드는 지난 레슨의 카운터입니다. 실행한 다음 버튼을 한 번 눌러 보세요. 카운트가 한 번보다 더 많이 올라갑니다.

버튼 안에서는 두 개의 금속 접점이 맞닿습니다. 접점이 맞닿으면 튀어 오릅니다: 약 1밀리초 동안 접점이 맞닿았다가 튕겨 떨어지고 다시 맞닿습니다. 손을 떼도 똑같은 일이 일어납니다. loop()는 그 1밀리초 동안 핀을 여러 번 읽고 튀어 오를 때마다 버튼을 누른 것으로 셉니다.

이를 해결하는 방법을 디바운싱이라고 합니다. 읽은 값이 바뀌면 한 번만 처리한 다음, 접점이 안정될 때까지 약 20 ms 기다렸다가 다시 읽습니다. 사람은 20 ms를 알아차리지 못합니다.

if (reading != lastReading) {
  if (reading == LOW) {
    presses++;
    Serial.println(presses);
  }
  delay(20);
}
lastReading = reading;

버튼을 누른 후뿐만 아니라 값이 바뀔 때마다 기다리세요. 버튼에서 손을 뗄 때도 접점이 튀며, 놓이는 과정에서 튀는 동작 하나하나가 새로운 버튼 누름처럼 보입니다.

challenge icon

챌린지

중급

카운터를 수정하여 버튼을 누를 때마다 한 번씩만 세도록 하세요:

  • reading이 lastReading과 다를 때, 버튼을 누른 경우(LOW) 카운트한 다음 20 ms 기다리세요
  • loop()의 끝에서 계속 lastReading을 저장하세요

Run을 누르고 버튼을 몇 번 눌러 카운트를 확인한 다음 Check를 누르세요.

직접 해보기

const int buttonPin = 2;

int presses = 0;
int lastReading = HIGH;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  int reading = digitalRead(buttonPin);
  if (reading == LOW && lastReading == HIGH) {
    presses++;
    Serial.println(presses);
  }
  lastReading = reading;
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

입력의 모든 레슨

직접 연습해 보세요: Arduino 플레이그라운드