實驗說明:
Arduino uno本身沒有RTC,假如我們想要在Arduino沒電不運作時、仍然繼續計數計時,那麼就需要另一個RTC模組與額外的電池。時鐘(Real-time clock,RTC)是指可以像時鐘一樣輸出實際時間的電子裝置,當Arduino關機斷電時,還是會由一顆獨立的電池供應RTC電力,維持時間日期。
本篇以RTC晶片型號DS1302時鐘模組為範例,價格非常便宜,精確度算普通。(若想要更好更精準的,建議可改用DS3231時鐘模組)
材料:
- Arduino Uno R3
- USB 傳輸線
- DS1302時鐘模組
- 杜邦線
安裝 DS1302 程式庫
- 在 Arduino 整合環境功能表點選 草稿碼 / 匯入程式庫 / 管理程式庫。
- 在右上方搜尋框輸入「DS1302」,下方會列出所有符合條件的程式庫,不同程式庫使用的程式碼並不相同。此處點選「DS1302」,該項目右下角會出現「安裝」鈕,按「安裝」鈕開始安裝。
程式:
#include <RtcDS1302.h>
ThreeWire myWire(4,5,2); // IO, SCLK, CE
RtcDS1302 <ThreeWire> Rtc(myWire);
void setup ()
{
Serial.begin(9600);
Serial.print("compiled: ");
Serial.print(__DATE__);
Serial.println(__TIME__);
Rtc.Begin();
//compiled變數設為電腦的程式碼編譯時的日期和時間
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); //
printDateTime(compiled);
Serial.println();
//判斷DS1302是否接好
if (!Rtc.IsDateTimeValid())
{
// Common Causes:
// 1) first time you ran and the device wasn't running yet
// 2) the battery on the device is low or even missing
Serial.println("RTC lost confidence in the DateTime!");
Rtc.SetDateTime(compiled);
}
if (Rtc.GetIsWriteProtected())
{
Serial.println("RTC was write protected, enabling writing now");
Rtc.SetIsWriteProtected(false);
}
if (!Rtc.GetIsRunning())
{
Serial.println("RTC was not actively running, starting now");
Rtc.SetIsRunning(true);
}
/*如果程式編譯當時的時間與DS1302上的時間不同,
*將比較DS1302上紀綠的時間和編譯時的時間哪個比較新,
*若編譯時間比較新,則將DS1302模組內存的時間更改成編譯的時間
*/
//now:DS1302模組內存紀綠的時間,compiled:編譯時的時間
RtcDateTime now = Rtc.GetDateTime();
//編譯時間比較新,把DS1302模組內存的時間更改成編譯的時間
if (now < compiled) { Serial.println("RTC is older than compile time! (Updating DateTime)"); Rtc.SetDateTime(compiled); } else if (now > compiled)
{
Serial.println("RTC is newer than compile time. (this is expected)");
}
else if (now == compiled)
{
Serial.println("RTC is the same as compile time! (not expected but all is fine)");
}
}
void loop ()
{
RtcDateTime now = Rtc.GetDateTime();
printDateTime(now);
Serial.println();
if (!now.IsValid())
{
// Common Causes:
// 1) the battery on the device is low or even missing and the power line was disconnected
Serial.println("RTC lost confidence in the DateTime!");
}
delay(10000); // ten seconds
}
#define countof(a) (sizeof(a) / sizeof(a[0]))
void printDateTime(const RtcDateTime& dt)
{
char datestring[20];
snprintf_P(datestring,
countof(datestring),
PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
dt.Month(),
dt.Day(),
dt.Year(),
dt.Hour(),
dt.Minute(),
dt.Second() );
Serial.print(datestring);
}
結果: