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;
*/ ß 주석을 제거하고 실행
▶ 구매 가이드
DS1307, DS3231 두가지 모두 비슷하나 DS1307의 오차도 월 5분 미만이다. 미리 납땜이 되어 있는 것을 사면 더 편하다.
▶ 강의 키워드
DS1307, DS3231, TM1637, Arduino RTC breakout, 아두이노 시계, 아두이노 4자리 디스플레이, Arduino 4 digits display, RCTlib, TimerOne, DigitalTube
'아두이노 응용' 카테고리의 다른 글
[아두이노] cds sensor와 servo motor로 t-rex game 스페이스키 자동으로 누르게하기 (0) | 2020.04.09 |
---|---|
[아두이노/Blynk] 스마트폰 앱으로 인터넷을 통해 Arduino를 제어해보자 (0) | 2019.08.07 |
[아두이노/초음파센서/숫자LED] Arduino 초음파 센서와 TM1637 4 digit 거리 표시기 (0) | 2019.08.04 |
[아두이노/WiFi/서보모터] Arduino WeMos D1 WiFi (ESP8266) 호환 보드와 휴대폰 브라우저를 통한 서보 모터 구동 (6) | 2019.08.04 |
[응용/접근 감지 전등] 초음파 센서를 통해 전등을 켜보자 (0) | 2016.04.19 |
[응용/전자기장검출] 전자기장 감지기(EMF detector)를 만들어보자 (2) | 2015.11.11 |
[프로젝트] HM-10모듈과 수은전지+배터리 홀더로 만드는 초소형 iBeacon (10) | 2015.07.17 |
[프로젝트] 간단한 단거리 무선 통신(433/315Mhz)으로 구현하는 실내외 원격 온습도계 디스플레이 프로젝트 (2) | 2015.02.09 |