본문 바로가기
개발이야기

[C언어/API] 버튼 입력 채터링 관련한 팁

by 코저씨 2021. 8. 1.
728x90

 

펌웨어나 GPIO 관련한 프로그램을 짤 때, 스위치나 버튼 관련된 입력이 생각보다 힘든 부분이 있다.

 

출력은 한 번만 하면 되지만, 사용자의 입력을 받는 입력은 노이즈가 튈 가능성이 있기 때문이다.

 

(빠르게 누르고 땐다거나, 마구 누르거나 보드 자체 노이즈가 들어가거나...)

 

그래서 입력을 처리할 때는 채터링 또는 디바운스라해서 단순히 한 번만 핀/포트 읽는 것으로

 

처리하지 않고 수차례 읽어서 처리하곤 한다.

for(cnt=0,i=0;i<10;i++)
{
    if(PINA & 0x01) cnt++;
}

if(cnt > 7) BUTTON_IN = 1;
else        BUTTON_IN  = 0;

 

보통 위와 같이 심플하게 여러 번 읽어서 처리하는데,

이는 제품마다 편차가 있을 수도 있어서 튜닝을 해야 하는 코드이다. 또, 입력이 여러 개인 경우, 그만큼 처리가 복잡해지기도 한다.

 

내가 작업했던 어느 장비는 스위치가 4개였다. 4개의 스위치를 위처럼 하기 복잡해서 아래와 같이 설계해서 적용했다.

 

uint8_t keyBuf[16];
memset(keyBuf,0,sizeof(keyBuf));
for(i=0;i<10;i++) 
{
	tmpKey = ReadKeyIn4Bit(stSetupData.cMultiInput) & 0x0f; // 버튼 4개 읽기
	USTIMER_DelayIntSafe(delay_cnt*10); //딜레이 함수
	keyBuf[tmpKey]++; //버튼이 4개임으로,4개의 버튼이 눌러지는 조합수는 16개	
}

oldKey = 0;
for(i=1;i<16;i++)
{
    if(keyBuf[oldKey] <keyBuf[i] ) //가장 많이 눌러진 키 값을 찾는다.
	        oldKey = i;
}
return oldKey;

 

버튼이 4개가 복합적으로 눌러지는 입력 조합수는 16개 이여서 16길이의 배열을 준비한다.

ReadKeyIn4Bit 함수는 4개의 스위치를 읽는 함수이며 1번 스위치가 눌러지면 0x01, 4번 스위치는 0x08,

둘 다 눌러지면 0x9 가 나온다.

 

눌러지는 값을 배열의 인덱스로 사용하고, 해당 인덱스는 눌러진 스위치가 몇 회 눌러졌는지, 누적 횟수를 기록한다.

 

그리고 마지막에 배열에서 가장 값이 큰 값을 찾는데,

해당 값의 인덱스는 많이 눌러진 버튼의 값을 의미한다.

 

728x90