아두이노프로세싱 프로그래밍

초보자를 위한 아두이노 우노 0.96 모노크롬 OLED 시계/타이머 코딩

coding art 2017. 6. 5. 20:16
728x90


아두이노용으로 해상도가 128x64인 0.96인치 OLED 디스플레이 사용법에 대해서 이미 알아보았다. 4디지트 7세그먼트 FND(Finite Numeric Display)가 전원공급과 디지털 데이터 핀 1번에 연결하고 간단하게 serial.print() 명령을 사용하여 출력할 수 있음에 비해 OLED는 일종의 일종의 그래픽 명령을 사용해야 한다는 점을 지적하였다.




I2C 배선은 그림과 같다. OLED의 SCL 은 A5, SDA는 A4 전원은 3V3과 GND 에 연결하였다.



아두이노에서 시계/타이머를 코딩하기 위해서는 아두이노에 전원을 공급하자마자 시간을 millisecond 즉 천분의 일초 단위로 체크하는 millis() 명령을 사용하면 편리하다.

I2C 인터페이스를 지원하도록 Wire.h 라이브러리와 OLED 디스플레이 폰트를 지원하는 Adafruit_GFX.h와 그래픽 처리를 지원하는 Adafruit_SH1106.h 라이브러리를 설치한다.


일단 시계를 실행시키게 되면 경과 시간을 밀리세컨드 단위로 아두이노 내부에서 클럭 주파수를 이용하여 지속적으로 셈을 하게 된다. 5일 정도까지 카운팅이 가능하다고 하며 이 값을 정수로 표현해 보게 되면 대단히 큰 수가 된다.
따라서 아두이노 코딩 문법을 참고하여 가장 큰 정수를 사용하려면 unsigned long int 변수를 사용할 필요가 있다.

아울러 아두이노 자체는 시간을 카운트하는 타이머 기능은 가능하나 현재 시간을 알아낼 수 있는 기능이 없으므로 시계 프로그램을 실행 시에 일바 시계 사용때와 마찬가지로 사용자가 현재의 시간을 시간 분 단위로 입력을 해 줄 필요가 있다. 컴파일 업로딩함에 어느장도 시간이 소요되므로 초 단위까지 맞출 필요는 없을 듯하다.
setup() 문에서는 통신 속도를 9600 으로 설정하고 OLED 구동을 위해서 dis

play.begin() 명령을 실행한다. 이 명령은 Adafruit 사의 라이브러리을 사용하는 SH1106  구동 OLED 코딩에 필수적이다.
전원을 끄기 전까지 무한 반복되어야 하는 시간 계산을 위한 loop() 문이 시작되자마자 millis() 명령을 실행하여 currentMillis 변수에 저장하고 경과된 시간 분 초를 연산한다.
한 시간이 60분 3600초 즉 3,600,000 밀리세컨드이므로 경과 시간을 계산 후 코드 초반에 입력해 둔 현재 시간과 합산한다.

입력해둔 현재 시간 값이 없다면 시계가 아니라 타이머가 되는 것이다.

경과된 millis를 3,600,000으로 나눈 나머지로 경과된 분을 계산하

고 현재의 분을 합산한다.
경과된 millis를 6,000 으로 나눈 나머지가 경과된 millisecond이므로 1000으로 나누어 초를 계산한다.





시간 분 초 가 준비 되면 OLED 디스플레이에 출력 처리를 해야 한다.
한가지  주의할 점은 경과된 분 체크 시 60 분이 출력 되는 경우가 있는데  이때는 if 문을 사용하여 시간을 +1 하고 분에서 –60 하도록 하여 출력한다.
모든 준비가 끝났으면 버퍼의 내용을 OLED 화면에 출력한다.







oled_03

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>

#define OLED_RESET 4
Adafruit_SH1106 display(OLED_RESET);

 unsigned long currentHr = 16;
 unsigned long currentMin = 30;
 
void setup()   {               
  Serial.begin(9600);
  display.begin(SH1106_SWITCHCAPVCC, 0x3C);
}

void loop() {

    unsigned long currentMillis = millis();
    unsigned long hr = currentHr + currentMillis/3600000;
    currentMillis = currentMillis%3600000;
    unsigned long minute = currentMin + currentMillis/60000;
    unsigned long second = currentMillis%60000;
    unsigned long sec = second/1000;
  
    display.clearDisplay();
    display.setTextColor(WHITE);
    display.setTextSize(2);
    display.setCursor(5,10);
    if( hr <12 ) {
      display.println("AM");
    }
    else if( hr <24 ) {
      display.println("PM");
    }
    else {
      hr = hr -24;
      display.println("AM");
    }
    display.setTextSize(2);
    display.setCursor(5,30);
    if( minute >= 60 ) {
      hr = hr + 1;
      minute = minute - 60;
    }
    display.print((unsigned long)hr);
    display.print(":");
    display.print((unsigned long)minute);
    display.print(":");
    display.print((unsigned long)sec);   
    display.display();
    delay(500);
}//끝