본문 바로가기
아두이노 응용

[프로젝트] 전자시계 / 실시간 시계 모듈(RTC breakout/DS1307 or DS3231)과 4 digits 디스플레이로 구현하자

by 작동미학 2015. 4. 17.
반응형

4 digits LED와 실시간 시간 모듈을 통해 시계를 만드는 응용 프로젝트

 

▶ 이 가이드를 따라하면

- TM1637 4 digits 디스플레이를 활용할 수 있다

- RTC breakout(DS1307 or DS3231칩 탑재)모듈로부터 시간을 얻을 수 있다.

- 두 가지를 결합하여 언제나 시간이 맞는 전자 시계를 제작할 수 있다.

 

▶ 먼저 읽으면 좋은 글

- 라이브러리 설치 방법 : http://bbangpan.tistory.com/1

- TM1637 4 digit 강의 : http://bbangpan.tistory.com/31

- RTC Breakout 강의 : http://bbangpan.tistory.com/30

- Aliexpress에서 부품 저렴하게 구매하는 방법 : http://bbangpan.tistory.com/5

 

▶ 부품 설명 및 회로 구성

TM1637 4 digits 디스플레이는 밝기조절과 4가지의 숫자 표기를, 두 개의 핀으로 제어할 수 있는 값싼($3) LED 디스플레이다. 손톱만한 크기의 숫자를 보여주기 때문에 제법 멀리서도 시간을 확인할 수 있다. DS1307이나 DS3231(DS1307보다 온도영향을 덜받아 10배 정확하다) 칩을 탑재한 RTC breakout 모듈($2)은 수은전지에 기반에 시간을 계산하고 있다가, 필요할 때 I2C 통신을 통해 전달받을 수 있는 모듈이다. Arduino에도 자체 clock이 내장되어 있지만 껐다 켜면 리셋되기 때문에, 언제나 정확한 시간을 파악하고 싶을 때 사용한다. 여기서는 ZS-042라는 중국산 보드를 사용했다. 보드 이름과 별도로 DS1307이나 DS3231 칩으로 조회하면 유사 기능 보드를 찾을 수 있다.

두 모듈의 사용법은 매우 간단해서, 여기서는 한꺼번에 사용법을 다루어보자. 두 모듈 모두를 5V/GND에 연결하려면 작은 빵판이 필요하다.(그림 참조. 선이 복잡해보이지만 5V/GND연결외에는 둘다 직접 아두이노 보드에 연결 가능하다.)

<DS3231 RTC breakout과 TM1637 4 digits를 활용한 전자 시계>

<TM1637 4digit LED CLK/DIO를 D3/D4에, VCC/GND는 5V/GND에 연결>

<DS3231 RTC모듈이다. I2C통신용 SCL/SDA를 UNO의 SCL/SDA에 연결하고 VCC/GND는 5V/GND에 연결>

TM1637의 경우에는 http://www.seeedstudio.com/wiki/Grove_-_4-Digit_Display 과 호환되며, DS3132/DS1307 RTC 모듈은 https://github.com/adafruit/RTClib 과 호환된다.


▶ 라이브러리 설치

시간 구동을 위해서는 라이브러리가 3종류가 필요하다.

http://www.seeedstudio.com/wiki/File:DigitalTube.zip

https://code.google.com/p/arduino-timerone/downloads/detail?name=TimerOne-v9.zip&can=2&q= (TimerOne/Arduino로 검색)

https://github.com/adafruit/RTClib

를 모두 다운받아 라이브러리 폴더에 반영하자. 위 하나는 4 digits LED 디스플레이를 위한 것이고, 밑에 두가지는 시간처리를 위한 라이브러리다. 라이브러리 설치는 http://bbangpan.tistory.com/1 강의 맨 하단을 참조한다.

 

▶ 소스 코드 입력 및 구동

여기서는 seeedstudio의 RTC 모듈없이 출력하는 시계 모듈 소스에 해당 시간을 RTC 모듈로 얻어오는 형태로 바꾸었다.

GitHub 원본 소스 링크 / https://github.com/bbangpan/bbangpan.com/blob/master/neibc_zs042_4digit_clock/neibc_zs042_4digit_clock.ino

------------------------------------------------------------------------------------------------------------

// Author:Frankie.Chu

// Date:9 April,2012

//

// This library is free software; you can redistribute it and/or

// modify it under the terms of the GNU Lesser General Public

// License as published by the Free Software Foundation; either

// version 2.1 of the License, or (at your option) any later version.

//

// This library is distributed in the hope that it will be useful,

// but WITHOUT ANY WARRANTY; without even the implied warranty of

// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

// Lesser General Public License for more details.

//

// You should have received a copy of the GNU Lesser General Public

// License along with this library; if not, write to the Free Software

// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

// http://www.seeedstudio.com/wiki/Grove_-_4-Digit_Display

// Modified record:

//

// - Added by bbangpan.com RTClib( https://github.com/adafruit/RTClib ) combined

//

/*******************************************************************************/

#include <Wire.h>

#include "RTClib.h"

#include <TimerOne.h>

#include "TM1637.h"

#define ON 1

#define OFF 0

 

RTC_DS1307 RTC;

 

int8_t TimeDisp[] = {0x00,0x00,0x00,0x00};

unsigned char ClockPoint = 1;

unsigned char Update;

unsigned char halfsecond = 0;

unsigned char second;

unsigned char minute = 0;

unsigned char hour = 24;

 

#define CLK 4//pins definitions for TM1637 and can be changed to other ports

#define DIO 3

TM1637 tm1637(CLK,DIO);

 

void setup()

{

Wire.begin();

RTC.begin();

tm1637.set();

tm1637.init();

Timer1.initialize(500000);//timing for 500ms

Timer1.attachInterrupt(TimingISR);//declare the interrupt serve routine:TimingISR

DateTime now = RTC.now();

 

hour = (unsigned char)now.hour();

minute = (unsigned char)now.minute();

second = (unsigned char)now.second();

}

void loop()

{

if(Update == ON)

{

TimeUpdate();

tm1637.display(TimeDisp);

}

 

}

void TimingISR()

{

halfsecond ++;

Update = ON;

if(halfsecond == 2){

second ++;

if(second == 60)

{

minute ++;

if(minute == 60)

{

hour ++;

if(hour == 24)hour = 0;

minute = 0;

}

second = 0;

}

halfsecond = 0;

}

// Serial.println(second);

ClockPoint = (~ClockPoint) & 0x01;

}

void TimeUpdate(void)

{

if(ClockPoint)tm1637.point(POINT_ON);

else tm1637.point(POINT_OFF);

TimeDisp[0] = hour / 10;

TimeDisp[1] = hour % 10;

TimeDisp[2] = minute / 10;

TimeDisp[3] = minute % 10;

/*

TimeDisp[0] = minute / 10;

TimeDisp[1] = minute % 10;

TimeDisp[2] = second / 10;

TimeDisp[3] = second % 10;

*/

Update = OFF;

}

------------------------------------------------------------------------------------------------------------

소스를 upload 버튼을 눌러 실행하면 지금 시간이 출력된다. 단, 수은전지를 맨 처음 연결한 RTC모듈의 경우에는 첫 시간 셋팅이 필요한데,

 

RTC.adjust(DateTime(__DATE__, __TIME__));

 

를 void setup(){} 에 포함시켜 컴파일/실행하자. 이러면 Arduino Sketch가 컴파일 한 시간을 자동으로 셋팅해서(__DATE__, __TIME__ 에 반영) 실행되자마자 RTC breakout의 시간을 셋팅한다. 한번만 이렇게 해주면 수은전지가 살아있는 한 시간이 지속 저장/유지된다.( https://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/overview 참조)

 

참조로, 소스 맨 하단의 주석을 실제 소스코드로 변경함으로 hour/minute을 minute/second로 변경하여 출력할 수 있다.

 

/* ß 주석을 제거하고 실행

TimeDisp[0] = minute / 10;

TimeDisp[1] = minute % 10;

TimeDisp[2] = second / 10;

TimeDisp[3] = second % 10;

*/ ß 주석을 제거하고 실행

 

▶ 구매 가이드

RTC breakout : http://www.aliexpress.com/premium/arduino-RTC.html?ltype=wholesale&SearchText=arduino+RTC&d=y&origin=y&initiative_id=SB_20150417064154&isViewCP=y&catId=0

TM1637 : http://www.aliexpress.com/premium/arduino-TM1637.html?ltype=wholesale&SearchText=arduino+TM1637&isPremium=y&d=y&origin=y&initiative_id=SB_20150417065125&isViewCP=y&catId=0

DS1307, DS3231 두가지 모두 비슷하나 DS1307의 오차도 월 5분 미만이다. 미리 납땜이 되어 있는 것을 사면 더 편하다.

 

강의 키워드

DS1307, DS3231, TM1637, Arduino RTC breakout, 아두이노 시계, 아두이노 4자리 디스플레이, Arduino 4 digits display, RCTlib, TimerOne, DigitalTube

 

반응형