[아두이노] 43. 병아리 부화기 및 육추기 겸용 만들기 (11) 버튼 소스 코드
임베디드/아두이노2024. 5. 31. 21:43
부화기 설정에 필요한 버튼 코드를 작성해 봅시다.
버튼은 총 5개로 이루어져 있으며, 소스 코드는 아래와 같습니다.
Incubator_Main.ino
...
#define BUTTON_SETUP 2 // 설정
#define BUTTON_UP 3 // ↑
#define BUTTON_DOWN 4 // ↓
#define BUTTON_SAVE 5 // SAVE
#define BUTTON_RESET 6 // RESET
extern unsigned long EggMoveTime;
extern unsigned long SaveTime; // 저장 시간
unsigned long beforeTime; // 이전시간
unsigned long nowTime = 0; // 현재타이머시간
int day, hour, min, sec;
bool b_Print = true;
long mode = 0; // 0 = 부화기, 1 = 육추기 모드
...
void setup()
{
...
// 버튼 (풀업 저항 사용)
pinMode(BUTTON_SETUP, INPUT_PULLUP); // 설정 버튼
pinMode(BUTTON_UP, INPUT_PULLUP); // ↑
pinMode(BUTTON_DOWN, INPUT_PULLUP); // ↓
pinMode(BUTTON_SAVE, INPUT_PULLUP); // MODE (SAVE로 사용)
pinMode(BUTTON_RESET, INPUT_PULLUP); // RESET
...
}
void loop()
{
// 모든 버튼 체크
SetupButton();
UpButton();
DownButton();
SaveButton();
ResetButton();
if(millis()-beforeTime>=1000)
{
nowTime++;
...
}
...
}
_button.ino
#define BUTTON_COUNT 5 // 버튼 갯수
boolean buttonState[BUTTON_COUNT] = {HIGH, HIGH, HIGH, HIGH, HIGH}; // 현재 스위치 상태
boolean lastButtonState[BUTTON_COUNT] = {HIGH, HIGH, HIGH, HIGH, HIGH};
unsigned long lastDebounceTime[BUTTON_COUNT] = {0, 0, 0, 0, 0};
bool b_reset = false;
bool yesno = true;
int b_day = 0;
int b_h1 = 0;
int b_h2 = 0;
int b_m1 = 0;
int b_m2 = 0;
int b_s1 = 0;
int b_s2 = 0;
int set_index = 0;
// 설정 버튼
void SetupButton()
{
// 버튼 체크
if(ButtonCheck(BUTTON_SETUP, 0) == true)
{
if(b_reset == true)
{
if(yesno == true)
{
mode = 0;
nowTime = 0;
EggMoveTime = 0;
EEPROM_Update(0, mode);
EEPROM_Update(1, nowTime);
EEPROM_Update(2, EggMoveTime);
}
lcd.noBlink();
lcd.clear();
b_reset = false;
yesno = true;
b_Print = true;
return;
}
b_Print = false;
lcd.blink();
switch(set_index)
{
case 0: // 모드 수정
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Mode:");
lcd.print(mode);
lcd.setCursor(0,1);
lcd.print("0:Egg 1:Grow");
lcd.setCursor(5,0);
break;
case 1: // 일 수정
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Day:0");
lcd.setCursor(0,1);
lcd.print("00:00:00");
lcd.setCursor(4,0);
break;
case 2: // 시1 수정
lcd.setCursor(0,1);
break;
case 3: // 시2 수정
lcd.setCursor(1,1);
break;
case 4: // 분1 수정
lcd.setCursor(3,1);
break;
case 5: // 분2 수정
lcd.setCursor(4,1);
break;
case 6: // 초1 수정
lcd.setCursor(6,1);
break;
case 7: // 초2 수정
lcd.setCursor(7,1);
break;
case 8:
day = b_day;
int tmp = (b_h1 * 10) + b_h2;
if(tmp > 24) hour = 24;
else hour = tmp;
min = (b_m1 * 10) + b_m2;
sec = (b_s1 * 10) + b_s2;
// 시간 재 설정
GetTimeDayToSec();
lcd.noBlink();
b_day = b_h1 = b_h2 = b_m1 = b_m2 = b_s1 = b_s2 = 0;
lcd.clear();
lcd.print("Setting OK!");
delay(1000);
lcd.clear();
b_Print = true;
EEPROM_Update(0, mode);
EEPROM_Update(1, nowTime);
EggMoveTime = nowTime%EGG_STEP_TIME;
EEPROM_Update(2, EggMoveTime);
break;
}
if(set_index >= 8) set_index = 0;
else set_index++;
}
}
// ↑ 버튼
void UpButton()
{
// 버튼 체크
if(ButtonCheck(BUTTON_UP, 1) == true)
{
if(b_reset == true)
{
if(yesno == true)
{
lcd.setCursor(9,1);
yesno = false;
}
else
{
lcd.setCursor(3,1);
yesno = true;
}
return;
}
switch(set_index - 1)
{
case 0: // 모드 수정
{
if(mode == 0)
{
lcd.setCursor(5,0);
lcd.print(1);
lcd.setCursor(5,0);
mode = 1;
}
else
{
lcd.setCursor(5,0);
lcd.print(0);
lcd.setCursor(5,0);
mode = 0;
}
}
break;
case 1: // 일 수정
lcd.clear();
lcd.print("Day:");
lcd.print(++b_day);
lcd.setCursor(0, 1);
lcd.print("00:00:00");
lcd.setCursor(4,0);
break;
case 2: // 시1 수정
lcd.clear();
lcd.print("Day:");
lcd.print(b_day);
lcd.setCursor(0, 1);
++b_h1;
if(b_h1 > 2) b_h1 = 0;
lcd.print(b_h1);
lcd.print("0:00:00");
lcd.setCursor(0,1);
break;
case 3: // 시2 수정
lcd.clear();
lcd.print("Day:");
lcd.print(b_day);
lcd.setCursor(0, 1);
lcd.print(b_h1);
if(b_h1 >= 2)
{
if(b_h2 >= 3) b_h2 = 0;
else ++b_h2;
}
else
{
++b_h2;
if(b_h2 > 9) b_h2 = 0;
}
lcd.print(b_h2);
lcd.print(":00:00");
lcd.setCursor(1,1);
break;
case 4: // 분1 수정
lcd.clear();
lcd.print("Day:");
lcd.print(b_day);
lcd.setCursor(0, 1);
lcd.print(b_h1);
lcd.print(b_h2);
lcd.print(":");
++b_m1;
if(b_m1 > 5) b_m1 = 0;
lcd.print(b_m1);
lcd.print("0:00");
lcd.setCursor(3,1);
break;
case 5: // 분2 수정
lcd.clear();
lcd.print("Day:");
lcd.print(b_day);
lcd.setCursor(0, 1);
lcd.print(b_h1);
lcd.print(b_h2);
lcd.print(":");
lcd.print(b_m1);
++b_m2;
if(b_m2 > 9) b_m2 = 0;
lcd.print(b_m2);
lcd.print(":00");
lcd.setCursor(4,1);
break;
case 6: // 초1 수정
lcd.clear();
lcd.print("Day:");
lcd.print(b_day);
lcd.setCursor(0, 1);
lcd.print(b_h1);
lcd.print(b_h2);
lcd.print(":");
lcd.print(b_m1);
lcd.print(b_m2);
lcd.print(":");
++b_s1;
if(b_s1 > 5) b_s1 = 0;
lcd.print(b_s1);
lcd.print("0");
lcd.setCursor(6,1);
break;
case 7: // 초2 수정
lcd.clear();
lcd.print("Day:");
lcd.print(b_day);
lcd.setCursor(0, 1);
lcd.print(b_h1);
lcd.print(b_h2);
lcd.print(":");
lcd.print(b_m1);
lcd.print(b_m2);
lcd.print(":");
lcd.print(b_s1);
++b_s2;
if(b_s2 > 9) b_s2 = 0;
lcd.print(b_s2);
lcd.setCursor(7,1);
break;
}
}
}
// ↓ 버튼
void DownButton()
{
// 버튼 체크
if(ButtonCheck(BUTTON_DOWN, 2) == true)
{
switch(set_index - 1)
{
case 0: // 모드 수정
{
if(mode == 0)
{
lcd.setCursor(5,0);
lcd.print(1);
lcd.setCursor(5,0);
mode = 1;
}
else
{
lcd.setCursor(5,0);
lcd.print(0);
lcd.setCursor(5,0);
mode = 0;
}
}
break;
case 1: // 일 수정
lcd.clear();
lcd.print("Day:");
--b_day;
if(b_day < 0) b_day = 0;
lcd.print(b_day);
lcd.setCursor(0, 1);
lcd.print("00:00:00");
lcd.setCursor(4,0);
break;
case 2: // 시1 수정
lcd.clear();
lcd.print("Day:");
lcd.print(b_day);
lcd.setCursor(0, 1);
--b_h1;
if(b_h1 < 0) b_h1 = 2;
lcd.print(b_h1);
lcd.print("0:00:00");
lcd.setCursor(0,1);
break;
case 3: // 시2 수정
lcd.clear();
lcd.print("Day:");
lcd.print(b_day);
lcd.setCursor(0, 1);
lcd.print(b_h1);
if(b_h1 >= 2)
{
if(b_h2 < 0) b_h2 = 3;
else --b_h2;
}
else
{
--b_h2;
if(b_h2 < 0) b_h2 = 9;
}
lcd.print(b_h2);
lcd.print(":00:00");
lcd.setCursor(1,1);
break;
case 4: // 분1 수정
lcd.clear();
lcd.print("Day:");
lcd.print(b_day);
lcd.setCursor(0, 1);
lcd.print(b_h1);
lcd.print(b_h2);
lcd.print(":");
--b_m1;
if(b_m1 < 0) b_m1 = 5;
lcd.print(b_m1);
lcd.print("0:00");
lcd.setCursor(3,1);
break;
case 5: // 분2 수정
lcd.clear();
lcd.print("Day:");
lcd.print(b_day);
lcd.setCursor(0, 1);
lcd.print(b_h1);
lcd.print(b_h2);
lcd.print(":");
lcd.print(b_m1);
--b_m2;
if(b_m2 < 0) b_m2 = 9;
lcd.print(b_m2);
lcd.print(":00");
lcd.setCursor(4,1);
break;
case 6: // 초1 수정
lcd.clear();
lcd.print("Day:");
lcd.print(b_day);
lcd.setCursor(0, 1);
lcd.print(b_h1);
lcd.print(b_h2);
lcd.print(":");
lcd.print(b_m1);
lcd.print(b_m2);
lcd.print(":");
--b_s1;
if(b_s1 < 0) b_s1 = 5;
lcd.print(b_s1);
lcd.print("0");
lcd.setCursor(6,1);
break;
case 7: // 초2 수정
lcd.clear();
lcd.print("Day:");
lcd.print(b_day);
lcd.setCursor(0, 1);
lcd.print(b_h1);
lcd.print(b_h2);
lcd.print(":");
lcd.print(b_m1);
lcd.print(b_m2);
lcd.print(":");
lcd.print(b_s1);
--b_s2;
if(b_s2 < 0) b_s2 = 9;
lcd.print(b_s2);
lcd.setCursor(7,1);
break;
}
}
}
// 저장 버튼
void SaveButton()
{
// 버튼 체크
if(ButtonCheck(BUTTON_SAVE, 3) == true)
{
EEPROM_Update(0, mode);
EEPROM_Update(1, nowTime);
EEPROM_Update(2, EggMoveTime);
b_Print = false;
lcd.clear();
lcd.setCursor(1,0);
lcd.print("Data Save OK!");
delay(1000);
lcd.clear();
b_Print = true;
}
}
// 리셋 버튼
void ResetButton()
{
// 버튼 체크
if(ButtonCheck(BUTTON_RESET, 4) == true)
{
b_Print = false;
b_reset = true;
lcd.blink();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Reset Setting?");
lcd.setCursor(0,1);
lcd.print(" YES NO");
lcd.setCursor(3,1);
}
}
// 토글 스위치 특성인 채터링 이슈 해결 위한 코드
// 채터링이란? 한번에 한번씩만 눌러져야 되는데 한번 누를때 여러번 누르는 현상
bool ButtonCheck(int BUTTON, int index)
{
// 버튼 체크
int reading = digitalRead(BUTTON);
if (reading != lastButtonState[index]) //스위치의 이전과 지금 상태가 다르면
lastDebounceTime[index] = millis(); //초를 기록합니다.
lastButtonState[index] = reading;
if ((millis() - lastDebounceTime[index]) > 50)
{//초가 기록되는 차이가 50ms보다 크면
if (reading != buttonState[index])
{
buttonState[index] = reading; //스위치를 누른 값과 다르면 대입합니다.
if (buttonState[index] == LOW)
{
return true;
}
}
}
return false;
}
'임베디드 > 아두이노' 카테고리의 다른 글
[아두이노] 45. 병아리 부화기 및 육추기 겸용 만들기 (13) 최종 소스코드 프로젝트 파일 첨부 (0) | 2024.05.31 |
---|---|
[아두이노] 44. 병아리 부화기 및 육추기 겸용 만들기 (12) EEPROM 저장 소스 코드 (0) | 2024.05.31 |
[아두이노] 42. 병아리 부화기 및 육추기 겸용 만들기 (10) 1602 I2C LCD 소스 코드 (0) | 2024.05.30 |
[아두이노] 41. 병아리 부화기 및 육추기 겸용 만들기 (9) 가습&팬 소스코드 (0) | 2024.05.30 |
[아두이노] 40. 병아리 부화기 및 육추기 겸용 만들기 (8) 전구 HEAT 소스 코드 (0) | 2024.05.29 |