|
|
# RTC MODULE
|
|
|
|
|
|
## DS1302 RTC Module
|
|
|
|
|
|
RTC라는 것은 Real Time Clock 으로, DS1302 RTC 모듈은실제 시간을 기록해 두었다가 필요시 읽을 수 있도록 해줍니다.
|
|
|
전원이 차단되어도 계속해서 시간을 기록할 수 있도록 DS1302칩 옆에는 배터리가 있는 것을 알 수 있습니다.
|
|
|
|
|
|
## DS1302 Library
|
|
|
|
|
|
DS1302 RTC Module을 사용하기 위해서 필요한 라이브러리를 설치했습니다.
|
|
|
|
|
|
제가 사용한 라이브러리의 출처 주소입니다.
|
|
|
|
|
|
주소 : [https://playground.arduino.cc/Main/DS1302RTC/](https://playground.arduino.cc/Main/DS1302RTC/)
|
|
|
|
|
|
다운 받은 zip파일을 이용해서 라이브러리를 설치하기 위해선
|
|
|
|
|
|
아두이노 IDE의 툴바에서 [스케치] - [라이브러리 포함하기] - [.ZIP 라이브러리 추가] 순으로 클릭하여, 다운 받은 파일을 선택해주시면 됩니다.
|
|
|
|
|
|
라이브러리 설치 및 예제 사용은 해당 글을 참고했습니다.
|
|
|
|
|
|
[https://turtleshell.kr/88](https://turtleshell.kr/88)
|
|
|
|
|
|
해당 글에 정리가 잘 되어 있어, 저는 예제 코드에 주석 위주로 정리하였습니다.
|
|
|
|
|
|
|
|
|
### 1. RTC Module Time Read
|
|
|
|
|
|
```c++
|
|
|
#include <DS1302RTC.h>
|
|
|
#include <TimeLib.h>
|
|
|
// DS1302 RTC 모듈의 핀들을 Arduino UNO 보드의 핀에 연결하기 위해 디지털 핀 번호를 지정합니다.
|
|
|
const int CLK = 2;
|
|
|
const int DAT = 3;
|
|
|
const int RST = 4;
|
|
|
|
|
|
// DS1302 rtc(ce_pin(RST), io_pin(DAT),sck_pin(CLK));
|
|
|
DS1302RTC rtc(RST, DAT, CLK);
|
|
|
|
|
|
void setup() {
|
|
|
// Serial 통신 threh 9600으로 설정
|
|
|
Serial.begin(9600);
|
|
|
Serial.println("DS1302 RTC Module Read Test");
|
|
|
Serial.println("---------------------------");
|
|
|
|
|
|
// RTC 모듈이 정지 상태인지 작동 상태인지 확인합니다.
|
|
|
// haltRTC()함수가 0을 리턴하면 작동 중지 상태이고, 1을 리턴하면 작동 중인 상태입니다.
|
|
|
if (rtc.haltRTC()) { // 만약 1 이면 정지된 상태
|
|
|
Serial.println("The DS1302 is stopped.");
|
|
|
rtc.haltRTC(0); // haltRTC() 함수를 매개변수를 0으로 호출합니다. 즉, 모듈을 실행시킵니다.
|
|
|
Serial.println("The DS1302 is started."); // 모듈이 실행된 후 작동하고 있다는 메세지 출력
|
|
|
delay(100);
|
|
|
} else { // 0 이면 실행 상태
|
|
|
Serial.println("The DS1302 is working.");
|
|
|
}
|
|
|
|
|
|
// RTC 모듈이 아두이노에게 전달하는 기준 시간데이터가 중간 중간 변경이 되지 않도록 쓰기 금지 모드를 제공하고 있습니다.
|
|
|
// RTC 모듈이 쓰기 가능 모드인지 확인 합니다.
|
|
|
// writeEN() 함수가 0을 반환하면 쓰기 금지 상태이고, 1을 반환하면 쓰기 가능 상태로 시간을 사용자가 설정할 수 있는 상태입니다.
|
|
|
if (rtc.writeEN() == 0) {
|
|
|
Serial.println("The DS1302 is write protected.");
|
|
|
} else {
|
|
|
Serial.println("The DS1302 can write.");
|
|
|
rtc.writeEN(false);
|
|
|
Serial.println("Write protected is started.");
|
|
|
}
|
|
|
|
|
|
Serial.println("-------------------------------");
|
|
|
Serial.println("-------------------------------");
|
|
|
|
|
|
delay(5000);
|
|
|
}
|
|
|
|
|
|
void loop() {
|
|
|
time_t t; // Time 라이브러리(TimeLib.h)에 선언된 타입으로, unsigned long 정수를 담는 변수입니다.
|
|
|
tmElements_t tm; // uint8_t(부호없는 8비트 정수) 타입의 초,분,시간,요일(일요일이 1),달, 연도를 갖고있는 구조체입니다.
|
|
|
|
|
|
Serial.print("rtc.get() 함수 실행 결과 : ");
|
|
|
Serial.println(rtc.get()); // get()함수는 기준 시점인 1970년 1월 1일 0시 0분 0초를 기준으로
|
|
|
// 모듈에 설정된 현재 시점 까지의 초를 계산하여 unsigned long type으로 반환합니다.
|
|
|
|
|
|
setSyncProvider(rtc.get); // 현재 Time 라이브러리에서 관리하는 시간데이터를 get()함수로 RTC 모듈에서 가져온 시간테이터(정수 값)와 동기화 시킵니다.
|
|
|
// setSyncProvider()함수는 외부 시간(RTC 모듈의 시간)을 가져와서 동기화 시킵니다.
|
|
|
// 동기화가 잘 이루어지면 내부적으로 "timeSet"이라는 열거형 데이터로 상태값을 설정합니다.
|
|
|
// 동기화가 잘 이루어졌는지 확인하는 부분입니다.
|
|
|
if(timeStatus() == timeSet){ // timeStatus()함수는 상태값을 읽어오는 함수입니다. "timeSet"을 리턴한다면 동기화가 잘된 것 입니다.
|
|
|
Serial.println("Sync is good!");
|
|
|
} else {
|
|
|
Serial.println("Sync is fail.");
|
|
|
setSyncProvider(rtc.get);
|
|
|
}
|
|
|
|
|
|
if(rtc.read(tm) == 0){ // read()함수는 tmElements_t 구조체를 인수로 받아서 시,분,초 등을 알아서 구분하여 해당 구조체에 저장해줍니다.
|
|
|
// read()함수는 실행이 성공하면 0을 반환하고, 실패하면 1을 반환함으로 리턴 값을 확인하는 부분이 필요합니다.
|
|
|
|
|
|
Serial.print(tmYearToCalendar(tm.Year)); // 읽어 온 연도 값에 항상 1970년을 더해야하기 때문에 tmYearToCalendar()를 통해서 이를 수행하고 있습니다.
|
|
|
Serial.print("(=");
|
|
|
Serial.print(tm.Year); // 1970년을 더하지 않은 연도의 값을 읽어옵니다.
|
|
|
Serial.print("+1970");
|
|
|
Serial.print(")");
|
|
|
Serial.print("/");
|
|
|
Serial.print(tm.Month);
|
|
|
Serial.print("/");
|
|
|
Serial.print(tm.Day);
|
|
|
Serial.print(" - ");
|
|
|
Serial.print(tm.Hour);
|
|
|
Serial.print(" : ");
|
|
|
Serial.print(tm.Minute);
|
|
|
Serial.print(" : ");
|
|
|
Serial.println(tm.Second);
|
|
|
}
|
|
|
|
|
|
Serial.println("-------------------------------");
|
|
|
|
|
|
// 현재 시간 데이터의 월과 요일명을 영문으로 제공하는 함수들입니다.
|
|
|
Serial.println(monthStr(month()));
|
|
|
Serial.println(monthShortStr(month()));
|
|
|
Serial.println(dayStr(month()));
|
|
|
Serial.println(dayShortStr(month()));
|
|
|
|
|
|
Serial.println("-------------------------------");
|
|
|
Serial.println("-------------------------------");
|
|
|
|
|
|
delay(5000);
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 2. RTC Module Time Write
|
|
|
|
|
|
```c++
|
|
|
#include <DS1302RTC.h>
|
|
|
#include <TimeLib.h>
|
|
|
|
|
|
// DS1302 RTC 모듈의 핀들을 Arduino UNO 보드의 핀에 연결하기 위해 디지털 핀 번호를 지정합니다.
|
|
|
const int CLK = 2;
|
|
|
const int DAT = 3;
|
|
|
const int RST = 4;
|
|
|
|
|
|
// DS1302RTC 객체 생성
|
|
|
DS1302RTC rtc(RST, DAT, CLK);
|
|
|
|
|
|
void setup() {
|
|
|
// Serial 통신 시작 설정
|
|
|
Serial.begin(9600);
|
|
|
Serial.println("DS1302 RTC Module Write Test");
|
|
|
Serial.println("----------------------------");
|
|
|
|
|
|
// RTC 모듈이 정지 상태인지 작동 상태인지 확인합니다.
|
|
|
// haltRTC()함수가 0을 리턴하면 작동 중지 상태이고, 1을 리턴하면 작동 중인 상태입니다.
|
|
|
if (rtc.haltRTC()) {
|
|
|
Serial.println("The DS1302 is stopped.");
|
|
|
rtc.haltRTC(0);
|
|
|
Serial.println("The DS1302 is started.");
|
|
|
delay(100);
|
|
|
} else {
|
|
|
Serial.println("The DS1302 is working.");
|
|
|
}
|
|
|
|
|
|
// RTC 모듈이 쓰기 가능 모드인지 확인 합니다.
|
|
|
// writeEN() 함수가 0을 반환하면 쓰기 금지 상태이고, 1을 반환하면 쓰기 가능 상태로 시간을 사용자가 설정할 수 있는 상태입니다.
|
|
|
if (rtc.writeEN() == 0) {
|
|
|
Serial.println("The DS1302 is write protected.");
|
|
|
} else {
|
|
|
Serial.println("The DS1302 can write.");
|
|
|
rtc.writeEN(false);
|
|
|
Serial.println("Write protected is started");
|
|
|
}
|
|
|
|
|
|
Serial.println("-------------------------------");
|
|
|
Serial.println("-------------------------------");
|
|
|
|
|
|
// RTC 모듈에 새로운 시간 데이터를 설정하는 부분입니다.
|
|
|
tmElements_t tm;
|
|
|
|
|
|
// 작성 중인 현재 시간을 기준으로 합니다.
|
|
|
// 2020년 1월 15일 수요일 오후 15시 03분 30초
|
|
|
tm.Year = CalendarYrToTm(2020); // 입력한 연도에서 1970을 빼주기 위해 CalendarYrToTm()함수를 이용합니다.
|
|
|
tm.Month = 1;
|
|
|
tm.Day = 15;
|
|
|
tm.Wday = 4; // 요일의 영문명을 설정합니다. 일요일 = 1, 월요일 = 2, 화요일 = 3...
|
|
|
tm.Hour = 15;
|
|
|
tm.Minute = 03;
|
|
|
tm.Second = 30;
|
|
|
|
|
|
// 작성한 구조체 tm을 인수로 하여, write()함수를 통해 RTC 모듈의 시간을 설정합니다.
|
|
|
// write()함수가 0을 반환하면 시간 설정이 성공한 것입니다.
|
|
|
if (rtc.write(tm) == 0){
|
|
|
Serial.println("Time is set.");
|
|
|
time_t t = makeTime(tm); // makeTime()함수로 입력한 정수 값들을 이용해 time_t 타입의 값을 생성합니다.
|
|
|
setTime(t); // Time라이브러리의 시간도 동일하게 setTime()함수를 이용해서 시간을 설정합니다.
|
|
|
}
|
|
|
|
|
|
// // 시간 변수 time_t타입을 인수로 하여, set()함수를 통해 RTC 모듈에 시간을 설정합니다.
|
|
|
// // 위의 구조체와 write()함수를 사용해 시간을 설정하는 것과 동일한 결과를 보여줍니다.
|
|
|
// time_t ts = makeTime(tm);
|
|
|
// if(rtc.set(ts) == 0){
|
|
|
// setTime(ts);
|
|
|
// }
|
|
|
|
|
|
// Time 라이브러리의 시간을 출력합니다.
|
|
|
Serial.print(year());
|
|
|
Serial.print("/");
|
|
|
Serial.print(month());
|
|
|
Serial.print("/");
|
|
|
Serial.print(day());
|
|
|
Serial.print(" - ");
|
|
|
Serial.print(hour());
|
|
|
Serial.print(":");
|
|
|
Serial.print(minute());
|
|
|
Serial.print(":");
|
|
|
Serial.println(second());
|
|
|
|
|
|
// RTC 모듈과 Time 라이브러리의 시간을 동기화 시킵니다.
|
|
|
setSyncProvider(rtc.get);
|
|
|
if(timeStatus() == timeSet)
|
|
|
Serial.println(" Ok!");
|
|
|
else
|
|
|
Serial.println(" FAIL!");
|
|
|
|
|
|
// 동기화 후의 시간 데이터를 출력합니다.
|
|
|
Serial.print(year());
|
|
|
Serial.print("/");
|
|
|
Serial.print(month());
|
|
|
Serial.print("/");
|
|
|
Serial.print(day());
|
|
|
Serial.print(" - ");
|
|
|
Serial.print(hour());
|
|
|
Serial.print(":");
|
|
|
Serial.print(minute());
|
|
|
Serial.print(":");
|
|
|
Serial.print(second());
|
|
|
|
|
|
delay(5000);
|
|
|
}
|
|
|
|
|
|
void loop() {
|
|
|
|
|
|
}
|
|
|
``` |
|
|
\ No newline at end of file |