ATMEGA 2560 PCINT를 이용한 바운스 해결

디지털회로의 물리적 접점 (스위치)에서 발생하는 바운싱은 별도의 회로가 없어도, 시간지연을 통해 무시하여 우회할 수 있다.

디지털 회로에서 스위치 입력을 사용할 때 항상 골치 아프게 하는 것 중 하나는 바로 바운스(bounce) 또는 채터링 (chattering) 이라고 불리우는 접점단속(接點斷屬)현상.

기본적으로 스위치는 떨어진 두 지점을 물리적인 방법을 이용하여 하나로 붙여 주는 역할을 한다. 여기서 '물리적'이란 게 중요한데, 사람은 스위치를 한번 꾸~~욱 하고 누른것 같으나, 실제로는 스위치가 눌려서 두 접점이 붙는 그 찰나의 순간에, 물리적(기계적)인 반동으로 인해 튕겨 나왔다 다시 붙는 현상이 발생한다.

이 현상을 없에는 가장 좋은 방법은. 비싸고 좋은 스위치를 사는것! 비싸고 좋은 스위치는 싸구려 스위치보다 채터링의 발생이 덜 하다. 또 다른 방법은, 스위치에 병렬로 콘덴샤(cap)을 달아주는 것. 전압이 튀는 동안 콘덴샤가 일종의 버퍼 역할을 해 주며, 마구 튀어대는 전압을 잡아 준다.

하지만 문제는, 콘덴샤를 달고 스위치를 바꿔도, 근본적으로 그 해결이 안된다는 것.. 어찌 되었든 결국엔 소프트웨어에서 채터링으로 인한 오류를 막기위한 방법을 마련해 두어야 한다. 그렇지 않으면 나는 분명 버튼을 한번 눌렀는데, 결과는 수~수십 번 누른 결과가 나온다. 게다가 이건 랜덤인지라.. 내가 만든 기계가 어떻게 동작할 지 전혀 예상 할 수 없는 랜덤박스가 되어 버린다.

오실로스코프로 본 접점의 바운싱 파형
오실로스코프로 본 접점의 바운싱 파형

대략 이런식으로...
이거 토글식 푸시스위치를 '딱 한 번' 누른거다... 노란색은 스위치의 출력, 하늘색은 스위치와 연결된 인터럽트 루틴이 실행된 것... 몇번 실행된건지 세기도 싫다...

여러가지 방법이 존재하나, 내가 즐겨 사용하는 방법은 인터럽트를 이용하는 방법.

ISR(PCINT0_vect)
{
	PCICR = PCICR & 0xFE;	// 하는동안 딴 짓 못하게 인터럽트 백터 막고
	PORTA=0xff;				// 불을 켜 보고

							// 할거 하고

	_delay_ms(1);			// 스위치를 입력을 1msec 동안 씹는다. 
	
	PCIFR = (1<<PCIF0);		// 기다릴만큼 기다렸으니, 인터럽트 플래그 해제
	PCICR = PCICR | 0x01;	// 인터럽트 다시 활성화
	PORTA=0x00;				// 불을 꺼 보자
}

결과는 아래 그림과 같다.

오실로스코프로 본 바운스 회피
오실로스코프로 본 바운스 회피

처음 인터럽트가 발생하고 1msec 동안 (PORTA 가 HIGH) 십수차례 채터링으로 인한 전압변화가 있었지만, 추가적인 실행 없이, 1번만 실행된다.

전체적인 시스템의 동작속도를 깎아 먹지만, 가장 간단하게, 추가적인 돈을 들이지 않고 바운싱 현상을 해결할 수 있는 방법 되겠다.

이 글은 2020. 1. 7. 14:18 작성 되었습니다.