아두이노 바운싱(bouncing) 현상 이해와 해결하기(디바운싱)

앞서 플로팅 현상에 대해서 설명했는데 이와 비슷하지만 원인은 다른 바운싱 현상에 대해 설명하겠다.

바운싱 역시 전압이 순간적으로 불규칙하게 들어가는 현상이다. 이 현상의 설명에 앞서 앞에서 공부했던 아주 간단한 회로를 잠시 살펴보자.

우리가 앞에서 만든 회로를 보면 하나의 스위치가 있고 이 스위치를 누르면 입력핀으로 전압이 걸리거나(풀다운 저항) 이미 걸리고 있던 전압이 없어진다(풀업 저항). 그리고 누르고 있던 버튼을 때면 다시 원상태로 돌아간다. 

이 회로를 업그레이드 해서 버튼을 누르고 있을 때  LED가 켜지고 버튼을 누르지 않을 때 LED가 꺼지도록 회로를 구성해 보겠다.

다음은 위 회로의 스케치 코드다.

제어문(if문)을 사용해서 조건 cur(현재 입력핀 2번에 걸린 전압의 상태)가 1(HIGH)일 때 7번 핀에 HIGH를 출력해서 LED를 켠다. cur의 상태가 1이 아니면 7번 핀에 LOW를 출력해서 LED를 끈다.

아직 바운싱 현상이 무엇인지 설명은 안했지만 이 회로처럼 버튼은 누르고 있는 상태와 누르지 않은 상태를 구별하여 전압을 거는 경우는 굳이 바운싱 현상을 신경 쓸 필요가 없다. 하지만 실생활에서 불을 켜기위해서 버튼을 누르고 있는 경우는 거의 없다.

그리고 우리가 신경써야 하는 회로는 가령 버튼을 한번 눌렀다 땔 때마다 LED의 상태가 변하는 회로 같은 것이다.

바운싱 현상은 버튼을 누를 때와 땔 때 발생된다. 버튼을 누르는 순간 버튼 내부에서는 전기의 흐름의 매개가 되는 전도체가 물리적으로 맞물리게 된다. 이 순간이 슬로우 모션으로 진행된다고 상상해보고 전기의 흐름은 언제부터 발생할지 생각해보자.

바운싱(bouncing) 현상바운싱(bouncing) 현상

두 전도체가 물리적으로 정확히 맞닿는 순간 전기의 흐름이 생기면 좋겠지만 전기의 흐름은 그 전에 불규칙적으로 발생하기 시작한다. 아주 초 근접한 두 전도체 사이에서는 불완전하게 전기의 흐름이 발생하거나 발생하지 않는 바운싱 현상이 생기는데 이런 장면은 몇몇 영화에서 고압전류가 끊어진 전선 사이에 공기중으로 간헐적으로 흐르는 것을 상상하면 쉽게 이해될 것이다.

따라서 제어문을 사용해서 단순하게 버튼의 상태를 체크하는 코드를 만들어 보면 문제가 발생한다. (다음은 문제의 코드다.)

cur은 현재 버튼의 상태며 before는 바로 이전의 버튼의 상태다. if문을 보면 cur가 HIGH 이고 before가 LOW인 상태, 즉 버튼을 누른 경우에 대해서만 생각하기로 한다. (버튼은 때는 상태에 대해서는 생각하지 않는다.)

state = !state;

따라서 버튼을 누르는 순간 현재 상태에 대한 변수 state는 반전(0이었다면 1로 1이었다면 0으로 바뀐다.)한다. (!은 부정(not)의 의미)

그리고 위 스케치 코드를 아두이노에 업로드해 보고 스케치 창도 띄어서 버튼을 눌러보자. 대체로 잘 동작하는 듯 보이지만 버튼을 아주 살짝 살짝 빠르게 눌러보면 먼가 불안정하다는 것을 알 수 있을 것이다. (살짝 켜지는 듯 안켜지고, 꺼지는듯 안꺼지는 현상)

디바운싱

이 현상을 해결하는 방법은 하드웨어적인 방법과 소프트웨어 적인 방법이 있다. 하드웨어적인 방법이 더 확실하겠으나 여기에서는 소프트웨어적인 방법으로 해결한다.

바운싱 현상은 대략 5ms 정도간 지속된다.(0.005초) 아주 짧은 시간이므로 이 시간동안 코드 실행을 지연시킨 후에 현재 버튼의 상태를 검사하면 되겠다.

추가된 코드를 설명하면, if문의 조건은 버튼의 상태가 변했을 때(버튼을 누르거나 땠을 때)이지만 두 번째 if문에서 cur가 HIGH인 경우(버튼을 누른 경우)에 대해서만 state의 상태를 변경시키므로 버튼을 때는 경우는 아무 의미가 없다. 따라서 추가된 if문의 조건은 버튼을 누른 경우라고 봐도 무방하다.

버튼을 누르면 바운싱 현상이 일어나는 시간 5ms 정도를 지연한 후 현재 버튼의 상태를 다시 검사한다. 

아주 간단한 코드지만 바운싱 현상을 해결해주는 코드다.

이 댓글을 비밀 댓글로