버튼이 눌리거나 놓이거나 스위치가 전환될 때, 초보자들은 보통 그 상태가 LOW에서 HIGH로 혹은 HIGH에서 LOW로 바뀐다고 단순하게 생각합니다. 실제로는 그렇지 않습니다. 기계적이고 물리적 특성 때문에 버튼(또는 스위치)의 상태는 여러 번 LOW와 HIGH 사이를 전환할 수 있습니다. 이 현상을 채터링이라고 합니다. 채터링 현상은 단일 누름이 여러 번 눌린 것처럼 읽히게 하여, 어떤 종류의 애플리케이션에서는 오작동을 일으킬 수 있습니다. 이 튜토리얼에서는 이 현상(입력을 디바운스(debounce)한다고 불림)을 없애는 방법을 보여줍니다.
/* * 이 아두이노 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-button-debounce */// 상수는 변경되지 않습니다. 핀 번호를 설정하는 데 여기서 사용됩니다:constint BUTTON_PIN = 7; // 푸시버튼 핀의 번호// 변수는 변경될 것입니다:int lastState = LOW; // 입력 핀의 이전 상태int currentState; // 입력 핀에서의 현재 읽기 값voidsetup() {// 초당 9600비트의 속도로 시리얼 통신을 초기화합니다:Serial.begin(9600);// 풀업 입력으로 푸시버튼 핀을 초기화합니다// 풀업 입력 핀은 스위치가 열려있을 때 HIGH이고, 스위치가 닫혔을 때 LOW입니다.pinMode(BUTTON_PIN, INPUT_PULLUP);}voidloop() {// 스위치/버튼의 상태를 읽습니다: currentState = digitalRead(BUTTON_PIN);if(lastState == HIGH && currentState == LOW)Serial.println("The button is pressed");elseif(lastState == LOW && currentState == HIGH)Serial.println("The button is released");// 마지막 상태를 저장합니다 lastState = currentState;}
아두이노 IDE에서 코드를 아두이노에 업로드하려면 Upload 버튼을 클릭하세요.
시리얼 모니터 열기
버튼을 몇 초간 계속 누르고 나서 놓으세요.
시리얼 모니터에서 결과를 확인하세요.
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Uno
Newbiely.ino
···
8Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno' on 'COM15')
New Line
9600 baud
The button is pressed
The button is pressed
The button is pressed
The button is released
The button is released
Ln 11, Col 1
Arduino Uno on COM15
2
⇒ 보시다시피, 단 한 번만 버튼을 누르고 놓았습니다. 그러나 아두이노는 이를 여러 번 누르고 놓은 것으로 인식합니다.
디바운스를 가진 읽기 버튼
사용 방법
아래 코드를 복사하고 아두이노 IDE로 열기
/* * 이 아두이노 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-button-debounce */// 상수는 변경되지 않습니다. 여기서는 핀 번호를 설정하는 데 사용됩니다:constint BUTTON_PIN = 7; // 버튼 핀의 번호입니다constint DEBOUNCE_DELAY = 50; // 디바운스 시간; 출력이 깜박이면 증가시킵니다// 변수는 변경될 것입니다:int lastSteadyState = LOW; // 입력 핀에서 이전의 안정된 상태입니다int lastFlickerableState = LOW; // 입력 핀에서 이전의 깜박일 수 있는 상태입니다int currentState; // 입력 핀에서의 현재 읽기 값입니다// 다음 변수들은 시간이 밀리초 단위로 측정되고, // 그 값이 int에 저장될 수 있는 것보다 빠르게 커질 것이기 때문에 unsigned long입니다.unsignedlong lastDebounceTime = 0; // 출력 핀이 토글된 마지막 시간입니다voidsetup() {// 초당 9600비트로 시리얼 통신을 초기화합니다:Serial.begin(9600);// 풀업 입력으로 버튼 핀을 초기화합니다// 스위치가 열려 있으면 풀업 입력 핀이 HIGH이고 스위치가 닫혀 있으면 LOW입니다.pinMode(BUTTON_PIN, INPUT_PULLUP);}voidloop() {// 스위치/버튼의 상태를 읽습니다: currentState = digitalRead(BUTTON_PIN);// 버튼을 눌렀는지 확인합니다// (즉, 입력이 LOW에서 HIGH로 바뀌었고) 충분히 오래 기다렸다면// 마지막 누름 이후로 잡음을 무시합니다:// 스위치/버튼이 변경되었는지 (노이즈 또는 누르기 때문에):if (currentState != lastFlickerableState) {// 디바운싱 타이머를 리셋합니다 lastDebounceTime = millis();// 마지막 깜박일 수 있는 상태를 저장합니다 lastFlickerableState = currentState; }if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY) {// 어떤 읽기 값이든, 디바운스 지연 시간보다 더 오래 그 상태에 있었다면// 실제 현재 상태로 받아들입니다:// 버튼 상태가 변경되었다면:if (lastSteadyState == HIGH && currentState == LOW)Serial.println("The button is pressed");elseif (lastSteadyState == LOW && currentState == HIGH)Serial.println("The button is released");// 마지막 안정된 상태를 저장합니다 lastSteadyState = currentState; }}
아두이노 IDE에서 Upload 버튼을 클릭하여 아두이노에 코드를 업로드하세요.
시리얼 모니터를 엽니다.
몇 초 동안 버튼을 계속 누르고 있다가 놓으세요.
시리얼 모니터에서 결과를 확인하세요.
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Uno
Newbiely.ino
···
8Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno' on 'COM15')
New Line
9600 baud
The button is pressed
The button is released
Ln 11, Col 1
Arduino Uno on COM15
2
⇒ 보시다시피, 버튼을 단 한 번만 누르고 놓았습니다. 아두이노는 이를 단일 누르기와 놓기로 인식합니다. 따라서 잡음이 제거됩니다.
/* * ArduinoGetStarted.com에 의해 생성됨 * * 이 예제 코드는 공용 도메인에 있습니다 * * 튜토리얼 페이지: https://arduinogetstarted.com/tutorials/arduino-button-library * * 이 예제는 디바운스와 함께 버튼의 상태를 읽고 시리얼 모니터에 출력합니다. */#include <ezButton.h>ezButtonbutton(7); // 핀 7에 연결된 ezButton 객체를 생성합니다.voidsetup() {Serial.begin(9600);button.setDebounceTime(50); // 디바운스 시간을 50 밀리초로 설정합니다.}voidloop() {button.loop(); // loop() 함수를 먼저 호출해야 합니다.if(button.isPressed())Serial.println("The button is pressed");if(button.isReleased())Serial.println("The button is released");}
아두이노 다중 버튼 디바운스 코드
/* * 이 아두이노 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-button-debounce */#include <ezButton.h>ezButtonbutton1(6); // 핀 6에 연결된 ezButton 객체를 생성합니다.ezButtonbutton2(7); // 핀 7에 연결된 ezButton 객체를 생성합니다.ezButtonbutton3(8); // 핀 8에 연결된 ezButton 객체를 생성합니다.voidsetup() {Serial.begin(9600);button1.setDebounceTime(50); // 디바운스 시간을 50 밀리초로 설정합니다.button2.setDebounceTime(50); // 디바운스 시간을 50 밀리초로 설정합니다.button3.setDebounceTime(50); // 디바운스 시간을 50 밀리초로 설정합니다.}voidloop() {button1.loop(); // loop() 함수를 먼저 호출해야 합니다.button2.loop(); // loop() 함수를 먼저 호출해야 합니다.button3.loop(); // loop() 함수를 먼저 호출해야 합니다.if(button1.isPressed())Serial.println("The button 1 is pressed");if(button1.isReleased())Serial.println("The button 1 is released");if(button2.isPressed())Serial.println("The button 2 is pressed");if(button2.isReleased())Serial.println("The button 2 is released");if(button3.isPressed())Serial.println("The button 3 is pressed");if(button3.isReleased())Serial.println("The button 3 is released");}