switch bounce, 스위치 바운싱이란?
채터링, 또는 진동 잡음이라고 한다. 스위치에서 발생하는 필연적인 하드웨어 결함이다. 스위치를 누르면 회로의 접점이 붙는데 그 점접이 붙었다가 떨어지는 순간에 발생하는 것이 바운스이다. 말그대로 통통 튀는.. 이렇게 눌렀다 떼는 것이 우리 입장에서는 그냥 한번 눌렀다가 떼었으니 한번 접점이 붙는거라고 생각할 수 있지만 위에 말한것 처럼 진동 잡음으로 인해 접점이 붙는 순간에 우리가 생각한 것 보다 더 많은 붙고 떨어짐이 발생한다.
이러한 현상으로 인해 스위치를 사용할 때 제대로 인식을 못하는 경우가 있다. 따라서 아두이노 회로에서 스위치를 사용하려면 반드시 디바운싱을 해주고 사용해야 오류없이 사용할 수 있다.
debounce란?
위에서 말한 하드웨어 결함으로 필연적으로 발생하는 바운싱을 해결하는 것이다. 가장 간단한 방법은 스위치에 양 전극에 "캐퍼시터"를 달아주는 것이라고 한다. 캐퍼시터가 전압 변화를 흡수하기 때문에 간단히 해결이 가능하다는데... 없으니 그럼 당연히 다른방법을 사용해야한다. 그래서 사용하는 것이 소프트웨어적으로 해결하는 것이다.
나는 무진장 간단한 방법을 사용한다. 누르고 진짜 찰나를 기다리는 것이다... 처음의 버튼 상태를 저장하고 버튼을 누른 후 1~5ms정도 기다리고 나서 버튼 상태를 저장하면 그 사이에 많은 진동으로 인해 발생할 오류를 방지할 수 있을 것이다.
따라서 디바운싱을 위해서는 코드에서 이전 버튼 상태를 저장할 변수와, 이후 버튼 상태를 저장할 변수 두가지가 필요하다.
회로는 풀다운 저항때랑 똑같이 구성한다.
const int led = 9;
const int btn = 2;
boolean lastBtn = LOW;
boolean currentBtn = LOW;
boolean isLedOn = false;
void setup() {
// put your setup code here, to run once:
pinMode(led, OUTPUT);
pinMode(btn, INPUT);
}
boolean debouncing(boolean last){
boolean current = digitalRead(btn);
if(last != current){
delay(5);
current = digitalRead(btn);
}
return current;
}
void loop() {
currentBtn = debouncing(lastBtn);
if(lastBtn == LOW && currentBtn == HIGH){
isLedOn = !isLedOn;
}
lastBtn = currentBtn;
digitalWrite(led, isLedOn);
}
간단하다.. 먼저 초기값은 이전버튼상태도 최근버튼상태도 모두 LOW로 해놓는다. 그리고 loop를 돌면서 매번 버튼 상태를 체크하는 것이다. debouncing 함수를 보면 일단 이전버튼상태를 가져온다. 그리고 이를 current에 넣어 주고, 이전버튼상태와 비교해서 다르면 현재 버튼 상태로 업데이트를 해준다.
그리고 다시 루프로 돌아오면 이전버튼상태가 LOW고 현재버튼상태가 HIGH면 불을 껐다 켰다 할 수 있게 한다. 이로써 이 코드는 버튼을 누를 때 마다 led의 상태가 토글되는 것이다.
이렇게 디바운싱도 간단히 할 수 있다. 이렇게 두개의 아두이노 관련 글은 모두 스위치를 사용하기 위해 필요한 것들이었다!
'Programming' 카테고리의 다른 글
[InfluxDB] 마주했던 몇가지 오류 (2) | 2021.11.01 |
---|---|
[Arduino] Pull-down 저항 (0) | 2020.05.10 |
[Qt] QCustomPlot (0) | 2020.03.15 |
[Data Structure] Linked list(Stack/Queue push and pop) (0) | 2020.02.04 |