참고 : [Arduino] ButtonClickCheck - 버튼 상태 저장 및 확인 라이브러리
버튼 처리가 귀찮아서 라이브러리를 만들었습니다.
버튼을 누르고 있을 때, 누르지 않을 때, 눌리고 첫 이벤트를 구분하여 리턴해주는 라이브러리입니다.
버튼이 플로팅(floating)상태라면 당연하게도 제대로 동작하지 않습니다.
(참고 : [Arduino] 버튼(Button)의 값이 정확하지 않을때 - 풀 업(Pull Up), 풀 다운(Pull Down) 사용 방법 )
아두이노는 게임 루프처럼 무한루프가 돌면서 여러 가지 상태를 판단하여 동작하게 됩니다.
이 상태에서 그냥 버튼을 눌렸다고 동작을 시키면 버튼이 몇 번 눌렸는지, 언제 눌렸는지 판단을 할 수 없습니다.
결국 상태가 변한 처음 한 번(버튼 업 -> 버튼 다운, 버튼 다운 -> 버튼 업)을 판단하여 동작해야 합니다.
이것을 구현하려면 처음 상태 값이 변했을 때를 기록했다가 다시 변하면 그걸 신호를 주면 됩니다.
버튼이 눌리지 않았을 때 상태 값을 클래스가 생성될 때 받아서 저장해둡니다.
버튼의 값을 '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;
}
위에서 만든 라이브러리를 로드하고 테스트 코드를 작성합니다.
(참고 : [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);
}
이제 테스트용 회로를 만들어 봅시다.
이제 펌웨어를 올리고 테스트해봅시다.
눌렀을 때 값이 잘 나오네요.
GitHub - https://github.com/dang-gun/ArduinoSample/tree/master/ButtonClickCheck
라이브러리 다운로드 -
이거.....아마 찾으면 있을 거 같은데......찾는것 보다 만든 게 빠른가? 해서 만들었습니다 ㅎㅎㅎㅎ
근데 다 만들고 나니까 손댈 게 더 보이네요;;;
2023-05-15 :
주석 정리
2023-05-11 :
'4=First Up' 기능 추가