참고 : [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' 기능 추가