프로그래밍/하드웨어

[Arduino] 버튼 처리를 위한 라이브러리 - ButtonClickCheck

당근천국 2019. 7. 28. 15:30

* 공개프로젝트로 전환된 포스팅입니다. *

참고 : [Arduino] ButtonClickCheck - 버튼 상태 저장 및 확인 라이브러리

 

버튼 처리가 귀찮아서 라이브러리를 만들었습니다.

 

버튼을 누르고 있을 때, 누르지 않을 때, 눌리고 첫 이벤트를 구분하여 리턴해주는 라이브러리입니다.

버튼이 플로팅(floating)상태라면 당연하게도 제대로 동작하지 않습니다.

(참고 : [Arduino] 버튼(Button)의 값이 정확하지 않을때 - 풀 업(Pull Up), 풀 다운(Pull Down) 사용 방법 )

 

연관글 영역

 

 

1. 버튼 구현하기

아두이노는 게임 루프처럼 무한루프가 돌면서 여러 가지 상태를 판단하여 동작하게 됩니다.

이 상태에서 그냥 버튼을 눌렸다고 동작을 시키면 버튼이 몇 번 눌렸는지, 언제 눌렸는지 판단을 할 수 없습니다.

결국 상태가 변한 처음 한 번(버튼 업 -> 버튼 다운, 버튼 다운 -> 버튼 업)을 판단하여 동작해야 합니다.

 

이것을 구현하려면 처음 상태 값이 변했을 때를 기록했다가 다시 변하면 그걸 신호를 주면 됩니다.

 

 

2. 코드 작성

버튼이 눌리지 않았을 때 상태 값을 클래스가 생성될 때 받아서 저장해둡니다.

버튼의 값을 'ClickCheck'함수로 넘기면 버튼 상태를 판단하여

1 : (Up) 버튼이 눌려있지 않음

2 : (Down) 버튼이 눌림

3 : (First Down) 버튼이 처음 눌림

값을 리턴합니다.

 

'ButtonClickCheck.h'

#include "arduino.h"

class ButtonClickCheck
{ 
public:
	/// @brief 핀번호
	uint8_t Pin;
	/// @brief 버튼이 눌리지 않았을때 판단값
	int ButtonUpLevel;
private:
	/// @brief 버튼 값이 바뀌였는지 여부1
	bool bBtnPush1;
	/// @brief 버튼 값이 바뀌였는지 여부2
	bool bBtnPush2;
	
public:
	/// @brief 버튼 판단을 위한 라이브러리
	/// @param nButtonUpLevel 버튼이 눌리지 않았을때 판단값. LOW or HIGH
	ButtonClickCheck(int nButtonUpLevel)
	{
		Pin = 0;
		ButtonUpLevel = nButtonUpLevel;
		
		bBtnPush1 = false;
		bBtnPush2 = false;
	}
	
	/// @brief 버튼 판단을 위한 라이브러리
	/// @param uintPin 핀을 미리 지정한다.
	/// @param nButtonUpLevel 버튼이 눌리지 않았을때 판단값. LOW or HIGH
	ButtonClickCheck(uint8_t uintPin, int nButtonUpLevel)
	{
		Pin = uintPin;
		ButtonUpLevel = nButtonUpLevel;
		
		bBtnPush1 = false;
		bBtnPush2 = false;
	}
	~ButtonClickCheck()
	{
	}


public:
  int ClickCheck();
  int ClickCheck(int nDigitalRead);
};

 

 

버튼 상태를 판단하도록 함수를 작성합니다.

'ButtonClickCheck.cpp'

#include "arduino.h"
#include "ButtonClickCheck.h"

/// @brief 저장된 핀번호의 값을 읽어 클릭정보를 판단한다.
/// @return 1=Up, 2=Down, 3=First Down, 4=First Up
int ButtonClickCheck::ClickCheck()
{
	//결과
	int nReturn = 0;
	
	if(0 < Pin)
	{//핀번호가 있다.
		nReturn = ClickCheck(digitalRead(Pin));
	}
	
	return nReturn;
}

/// @brief 전달된 값을 읽어 클릭정보를 판단한다.
/// @param nDigitalRead 입력된 디지털 값(전달된 값)
/// @return 1=Up, 2=Down, 3=First Down, 4=First Up
int ButtonClickCheck::ClickCheck(int nDigitalRead)
{
	//결과
	int nReturn = 0;
	
	//1.버튼 값이 기존과 다른지 여부 확인
	//1-1. 입력값 확인
	if( ButtonUpLevel != nDigitalRead)
	{//버튼이 눌림
		bBtnPush1 = true;
	}
	else
	{//버튼이 안눌림
		bBtnPush1 = false;
	}

	//1-2. 기존 입력값 확인
	if(bBtnPush2 == true)
	{//기존에 버튼이 눌려있었음
		//기존 상태 먼저 저장
		nReturn = 2;

		if(bBtnPush1 == false)
		{//이번엔 버튼이 안눌림
		  bBtnPush2 = false;
		  nReturn = 4;
		}
	}
	else if(bBtnPush2 == false)
	{//기존 버튼이 눌려있지 않음
		//기존 상태 먼저 저장
		nReturn = 1;
		
		if(bBtnPush1 == true)
		{//이번엔 버튼이 눌림
		  bBtnPush2 = true;
		  nReturn = 3;
		}
	}
	
	return nReturn;
}

 

 

3. 테스트용 코드 작성

위에서 만든 라이브러리를 로드하고 테스트 코드를 작성합니다.

(참고 : [Arduino] 라이브러리 작성하기

#include <ButtonClickCheck.h>
 
#define Button01 2
#define Button02 4
 
//테스트 1
ButtonClickCheck BCC_1(HIGH);
//테스트 2
ButtonClickCheck BCC_2(LOW);
 
void setup() 
{
  Serial.begin(9600);
  
  pinMode(Button01, INPUT);
  pinMode(Button02, INPUT);
}
 
void loop() 
{
  
  //컴퓨터에 신호를 준다.
  int nBtnState01 = BCC_1.ClickCheck(digitalRead(Button01));
  int nBtnState02 = BCC_2.ClickCheck(digitalRead(Button02));
  
  Serial.print(nBtnState01);
  Serial.print(" : ");
  Serial.println(nBtnState02);
  
  delay(500);
}

 

이제 테스트용 회로를 만들어 봅시다.

ButtonClickCheck.fzz
다운로드

 

 

이제 펌웨어를 올리고 테스트해봅시다.

 

눌렀을 때 값이 잘 나오네요.

 

 

마무리

GitHub - https://github.com/dang-gun/ArduinoSample/tree/master/ButtonClickCheck

라이브러리 다운로드 -

ButtonClickCheck.zip
0.00MB

 

이거.....아마 찾으면 있을 거 같은데......찾는것 보다 만든 게 빠른가? 해서 만들었습니다 ㅎㅎㅎㅎ

근데 다 만들고 나니까 손댈 게 더 보이네요;;;

 

 

 

2023-05-15 : 

주석 정리

 

2023-05-11 : 

'4=First Up' 기능 추가