자작 정수기용 컨트롤러 5, 초기 화면 및 메뉴 구성

2015. 9. 20. 16:44

Project/Water Purifier

자작 정수기용 컨트롤러 5, 초기 화면 및 메뉴 구성



  이제 메뉴를 만들 차례입니다. 필요한 메뉴는 실제 사용량과 유효정수량을 확인하는 부분과 흐름센서(Flow meter)의 정밀도를 수정(Calibration)할 수 있는 부분입니다. 그 외 필요한 메뉴는 그때그때 추가할 예정이구요!


  우선, 메뉴 작성에 앞서서 초기 대기화면을 먼저 만들었습니다. 소스는 이전글에서 테스트한 예제를 그대로 가져와서 왔고,  standby_message(); 함수를 만들어서 처음 부팅 후 초기화면을 표시하도록 했습니다.



void standby_message()

{

  display.fillScreen(BLACK); // 화면 전체를 검정색으로 채운다. 화면 지움 효과

  display.setTextSize(2); // 글자 크기 지정, 한 화면에 4줄 들어가는 크기입니다. 64/4해서 16픽셀 정도.

  display.setCursor(0,0); // 처음부터 입력되도록 커서를 옮깁니다.

  

  display.setTextColor(GREEN); // 글자 색상 변경, 전체를 검정색으로 채웠기 때문에 배경색은 생략.

  display.print("Push for");

  display.setTextColor(BLUE);

  display.print("Water");

  display.setTextColor(GREEN);

  display.print(" or");

  display.print("press ");

  display.setTextColor(RED);

  display.print("OK");

  display.setTextColor(GREEN);

  display.print("for");

  display.setTextColor(YELLOW);

  display.print("Setup");

}


  대기 화면을 출력하는 함수입니다. 색상을 몇가지 조합했습니다. setup() 함수 내에서 호출하여 초기 구동시 표시합니다.



  대기화면이 출력된 모습입니다. 대기 화면에서 리모컨의 "OK"버튼을 누르면 셋업 메뉴로 들어갑니다. EnterSetup() 함수를 만들어서 처리했으며, "#"키를 누르면 다시 대기화면으로 빠져 나옵니다. 메뉴속에선 좌, 우 화살표키를 이용해 이동을 합니다. 이를 위해서 menu, selected 두 개의 변수를 두어 구현했습니다. 현재 총 4개의 메뉴가 있는데, 왼쪽 화살표를 누르면 이전 메뉴로, 오른쪽 화살표는 다음 메뉴로 이동합니다.

  첫번째 메뉴에서 왼쪽 화살표를 누를 경우 더 이상의 이전 메뉴는 없기 때문에 메뉴 출력을 안하고 화면을 그대로 두도록 처리했습니다. 마찬가지로 4번째 메뉴 보다 다음 메뉴는 없기에 동일한 처리를 했습니다.

 


void EnterSetup() // 셋업 메뉴 구현

{

  int menu = 0; // 현재 선택된 메뉴

  int selected = 1; // 좌, 우 화살표키를 이용해 이동한 값

  boolean looping = true; // "#"키를 이용해 메뉴를 탈출하기 위한 체크 변수

  

  while(looping) { // "#"키를 누르기 전까지 반복


    if ( menu != selected ) // 키 입력이 있고 현재 메뉴가 아닐 경우

    {

      switch(selected) // 키 입력이 있으나 

      {

        case 0: // 오른쪽 화살표 입력시

          selected = selected + 1; // 첫번째 메뉴보다 이전 메뉴는 없으므로 

          break;

        case 1:

          mainMenu(selected); // 해당 메뉴를 표시하는 함수 호출

          menu = 1; // 다음 값 비교를 위해 현재 메뉴값 저장

          break;

        case 2:

          mainMenu(selected);

          menu = 2;

          break;

        case 3:

          mainMenu(selected);

          menu = 3;

          break;

        case 4:  // 네번째 메뉴보다 이후 메뉴는 없으므로

          selected = selected - 1;

          break;

      }

    }


 irrecv.resume(); // 다음 IR 키값을 입력 받을 준비를 합니다

    delay(500);

      

    if (irrecv.decode(&results))  // IR 입력값이 있을 경우 처리합니다.

    {

      switch(results.value)

      {

        case 0xFF22DD: // 왼쪽 화살표

          selected = selected - 1; // 현재보다 이전 메뉴 표시하도록

          break;

        case 0xFFC23D: // 오른쪽 화살표

          selected = selected + 1; // 현재보다 이후 메뉴 표시

          break;

        case 0xFF02FD: // "OK" 키, 현재 메뉴로 이동(메인에서 서브로...)

          subMenu(menu);

          break;

        case 0xFF52AD: // "#" 키, 대기화면 출력 후, 반복문을 빠져나간다

          standby_message();

          looping = false;

          break;

      }

      

    }

  }

}


  위 소스에서 if (menu != selected ) 비교문은 키 값이 입력되더라도 메뉴 이동이 없으면 화면 출력을 다시 하지 않도록 처리하기 위함입니다. 즉, 첫번째 메뉴에서 왼쪽 화살표 입력시, 마지막 네번째 메뉴에서 오른쪽 화살표 입력시 아무 일도 안하도록 합니다.



void mainMenu(int Sel)

{

  display.fillScreen(BLACK);

  display.setTextSize(2);

  display.setCursor(0,0);

  

  display.setTextColor(GREEN);

  display.print(mainMenuList[Sel]);

  display.setTextColor(BLUE);

  display.print("--------");

  display.print("<-OK-> #");

}


void subMenu(int SelMenu)

{

  switch(SelMenu)

  {

    case 1:

      break;

    case 2:

      break;

    case 3:

      break;

  }


  메뉴 출력 함수와 해당 메뉴 선택시 호출되는 서브메뉴 함수입니다. 서브 메뉴는 아직 구현하지 않았습니다.


  메뉴 작동 화면은 아래 동영상 참고하시고, 전체 소스는 그 아래 있습니다. 





#define sclk 13

#define mosi 11

#define cs   10

#define rst  9

#define dc   8



// Color definitions

#define BLACK           0x0000

#define BLUE            0x001F

#define RED             0xF800

#define GREEN           0x07E0

#define CYAN            0x07FF

#define MAGENTA         0xF81F

#define YELLOW          0xFFE0  

#define WHITE           0xFFFF



#include <Adafruit_GFX.h>

#include <Adafruit_SSD1331.h>

#include <SPI.h>

#include <IRremote.h>


Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);


int RECV_PIN = 12;


IRrecv irrecv(RECV_PIN);


decode_results results;


#define MaxMenu   3


char* mainMenuList[] = {"",

                        "MaxValueSetting ",

                        "Used    Info    ",

                        "FlowRateAdjust  "};


void setup(void) {

  Serial.begin(9600);

  

  display.begin();

  

  standby_message();

  

  irrecv.enableIRIn(); // Start the receiver


  delay(1000);

}


void loop() {


  display.setTextColor(BLUE);

  display.setTextSize(2);


  if (irrecv.decode(&results)) {

    if (results.value == 0xFF02FD) EnterSetup();

    irrecv.resume(); // Receive the next value

  }

  delay(100);

}


void standby_message()

{

  display.fillScreen(BLACK);

  display.setTextSize(2);

  display.setCursor(0,0);

  

  display.setTextColor(GREEN);

  display.print("Push for");

  display.setTextColor(BLUE);

  display.print("Water");

  display.setTextColor(GREEN);

  display.print(" or");

  display.print("press ");

  display.setTextColor(RED);

  display.print("OK");

  display.setTextColor(GREEN);

  display.print("for");

  display.setTextColor(YELLOW);

  display.print("Setup");

}


void EnterSetup()

{

  int menu = 0;

  int selected = 1;

  boolean looping = true;

  

  while(looping) {


    if ( menu != selected )

    {

      switch(selected)

      {

        case 0:

          selected = selected + 1;

          break;

        case 1:

          mainMenu(selected);

          menu = 1;

          break;

        case 2:

          mainMenu(selected);

          menu = 2;

          break;

        case 3:

          mainMenu(selected);

          menu = 3;

          break;

        case 4:

          selected = selected - 1;

          break;

      }

    }

    

    irrecv.resume();

    delay(500);

      

    if (irrecv.decode(&results))

    {

      switch(results.value)

      {

        case 0xFF22DD:

          selected = selected - 1;

          break;

        case 0xFFC23D:

          selected = selected + 1;

          break;

        case 0xFF02FD:

          subMenu(menu);

          break;

        case 0xFF52AD:

          standby_message();

          looping = false;

          break;

      }

      

    }

  }

}


void mainMenu(int Sel)

{

  display.fillScreen(BLACK);

  display.setTextSize(2);

  display.setCursor(0,0);

  

  display.setTextColor(GREEN);

  display.print(mainMenuList[Sel]);

  display.setTextColor(BLUE);

  display.print("--------");

  display.print("<-OK-> #");

}


void subMenu(int SelMenu)

{

  switch(SelMenu)

  {

    case 1:

      break;

    case 2:

      break;

    case 3:

      break;

  }

  

}


이상입니다.


Comments