Thinking Different




부화기 설정에 필요한 버튼 코드를 작성해 봅시다.

 

버튼은 총 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;
}