文章類型
開發平台
解決方案
關注主題
文章類型
開發平台
解決方案
關注主題

【自造學堂】如何用Arduino x RTC完成LCD時間顯示?

作者:黃小棟

這次自造學堂的教學文主題是「用Arduino x RTC完成LCD時間顯示」。在這一章節裡除了介紹RTC模組外,也會教大家如何將RTC模組與上一章節中提到的I2C_LCD模組和Arduino做系統上的整合,讓大家不再只會使用一塊Arduino控制一個模組,或者看到Arduino IDE內資料庫一堆的範例程式,卻一頭霧水,不知該如何整合使用。

學習目標:

大家研讀完這篇文章並且實際操作之後,將會了解下列兩點:

  1. 對 DS3231_RTC模組有初步的認識,並且能夠將時間顯示在Arduino IDE的序列埠監控視窗上。
  2. 學會使用I2C匯流排,讓Arduino、RTC模組和LCD模組做結合,並且整合Arduino的範例程式來完成此專案的控制。

學習背景:

在研讀實作之前,必須知道下面幾點:

  1. 會安裝第三方資料庫libraries。(依然很重要)
  2. 了解麵包板的特性,並且知道如何使用。
  3. 知道I2C匯流排的特性。(可參考【自造學堂】Arduino如何透過I2C控制LCD模組的介紹)

好~話不多說,立刻進入我們的主題吧!

基礎認識:什麼是RTC?

我們可以在Google搜尋到,RTC是Real-time clock的縮寫,指的是負責記錄時間的積體電路元件。它可以跟時鐘一樣輸出實際時間,通常會出現在個人電腦、伺服器或嵌入式系統,因此大家的桌機和筆電內就有這個元件。RTC具有以下特性:

  1. 消耗功率低。
  2. 讓主系統處理更需時效性的工作。
  3. 有時會比其他方式的輸出要更準確。

以上資料皆來自於網路資源,若有興趣深入研究的也可再自行查找。

模組規格及腳位介紹

首先,我們這次所使用的模組為DS3231高精密RTC模組(iCShop貨號:368030500595)。筆者這次所使用的模組,依然要感謝iCShop的贊助提供。這次我們所使用的模組是下圖這顆:

RTC模組正面與電池組裝

RTC模組背面

接著來看官方所給的相關介紹資料分析:

“DS3231是低成本、高精度I2C即時時鐘(RTC),具有嵌入式的溫補晶振(TCXO)和晶體。該器件包含電池輸入端,斷開主電源時仍可保持精確的計時。嵌入晶振提高了器件的長期精確度,並減少了生產線的元件數量。DS3231提供商用級和工業級溫度範圍,採用16引腳300mil的SO封裝。”

我們可以自文中得知此模組是用I2C傳輸控制的,所以它裡面也會有SDA和SCL與我們Arduino UNO內的A4和A5的接腳做連接,並且會引用<Wire.h>的函式庫。關於RTC的時間格式及設置說明如下:

“RTC保存秒、分、時、星期、日期、月和年資訊。少於31天的月份,將自動調整月末的日期,包括閏年的修正。時鐘的工作格式可以是24小時或帶/AM/PM指示的12小時格式。它提供兩個可設置的日曆鬧鐘和一個可設置的方波輸出。位址與資料通過I2C雙向匯流排序列傳輸。”

也因此,它可以做電子時鐘相關的專案。想更進一步了解這顆RTC模組的話,請見iCShop本頁說明

總而言之,這塊模組內部還包含一溫度感測,除了有主電源輸入外,還有備用電源(電池)輸入,但根據筆者測試的結果,它的備用電源僅供內部晶片繼續計時,不會提供訊號的輸出。最後是模組參數與接線說明介紹:

  1. 尺寸:38mm(長)*22mm(寬)*14mm(高)
  2. 工作電壓:3.3–5.5V
  3. 時鐘晶片: DS3231
  4. 存儲晶片:AT24C32(存儲容量32K)
  5. 可聯結其它IIC設備,24C32位址可通過短路A0/A1/A2修改,默認地址為0x57。
  6. 帶可充電電池LIR2032,保證系統斷電後,時鐘任然正常走動。
  7. 接線說明(以Arduino Uno為例):SCL→A5、SDA→A4、Vcc→5V、GND→GND。

模組硬體接線圖

進行模組接線之前,我們先來了解這次所要準備的材料:

  1. Arduino開發板 1塊(iCShop商品編號:368030500683
  2. 麵包板 1塊(iCShop商品編號:368090200061
  3. DS3231_RTC模組 1塊(iCShop商品編號:368030500595
  4. I2C_LCD模組 1塊(iCShop商品編號:368030100095
  5. 杜邦線(公-公、公-母) 數條(iCShop商品編號:3681101000389368110100159

本專案所需要的材料

再來是模組的接線方式,只需將「DS3231_RTC」模組和「I2C_LCD模組」Vcc接腳接至Arduino的5V接腳,模組們GND接腳接至Arduino的GND接腳,緊接著將模組們SDA接腳接至Arduino的A4接腳,最後是模組們SCL接腳接至Arduino的A5接腳即可完成接線。是不是非常容易呢?

本專案模組接線(DS3231_RTC模組和I2C_LCD 模組接法一樣)

模組程式範例

步驟1:

在講解程式之前,大家除了要先去網路上下載I2C_LCD的第三方資料庫以外(可參考【自造學堂】Arduino如何透過I2C控制LCD模組),還要下載「DS3231_TEST」這個第三方資料庫,雖然網路有眾多相關資料庫,然而經筆者測試,還是這個最簡單好用。

步驟2:

安裝好第三方資料庫後,請先開啟Arduino IDE,並且點選「檔案」→「範例」→「DS3231_TEST」→「Examples」→「DS3231_TEST」範例程式。

開啟DS3231_TEST範例程式

步驟3:

#include <DS3231.h>
#include <Wire.h>

DS3231 Clock;
bool Century=false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;

byte year, month, date, DoW, hour, minute, second;

在程式範例介紹的部分,我們可以了解在程式宣告的區域裡,它一開始同樣引用了<DS3231.h>和<Wire.h>這兩個函式庫,並且做了相關函式的定義。所謂的函式定義,好比我們國高中數學所學,會先假設「蓮霧的數量為X,芭樂的數量為Y……」是一樣的意思,引用函式庫即相當於「這個算式要引用二元一次方程式」之意。

void setup() {
// Start the I2C interface
Wire.begin();
Clock.setSecond(50);//Set the second
Clock.setMinute(59);//Set the minute
Clock.setHour(11); //Set the hour
Clock.setDoW(5); //Set the day of the week
Clock.setDate(31); //Set the date of the month
Clock.setMonth(5); //Set the month of the year
Clock.setYear(13); //Set the year (Last two digits of the year)
// Start the serial interface
Serial.begin(115200);
}

在初始化設定裡,此處做了秒、分、時、週、日、月、年的設定,大家可以任意改括弧裡面的數值測試看看。接著設定Baud Rate為115200。

(註:綠色文字部分為「函式定義的設定」橘色文字部分為「序列埠監控視窗訊息的輸出」。)

void ReadDS3231()
{
int second,minute,hour,date,month,year,temperature;
second=Clock.getSecond();
minute=Clock.getMinute();
hour=Clock.getHour(h12, PM);
date=Clock.getDate();
month=Clock.getMonth(Century);
year=Clock.getYear();

temperature=Clock.getTemperature();

Serial.print(“20”);
Serial.print(year,DEC);
Serial.print(‘-‘);
Serial.print(month,DEC);
Serial.print(‘-‘);
Serial.print(date,DEC);
Serial.print(‘ ‘);
Serial.print(hour,DEC);
Serial.print(‘:’);
Serial.print(minute,DEC);
Serial.print(‘:’);
Serial.print(second,DEC);
Serial.print(‘\n’);
Serial.print(“Temperature=”);
Serial.print(temperature);
Serial.print(‘\n’);
}

這個範例程式比較特別的地方,是在主程式迴圈之前,先設定好一個「ReadDS3231()」這個副程式。副程式的好處是:當程式很多很雜,可藉由副程式的設定,使主程式迴圈乾淨簡潔好閱讀。這個副程式會先設定函式定義,如同X=1,Y=2一樣,再來即可進行序列埠監控視窗訊息的輸出。

void loop()
{
ReadDS3231();
delay(1000);
}

最後就是主程式迴圈,一直執行「ReadDS3231()」這個副程式,並且中間延遲1秒。當然我們也可以把副程式跟主程式迴圈做結合,也是一樣的意思,以下為結合後的全部程式。

#include <DS3231.h>
#include <Wire.h>

DS3231 Clock;
bool Century=false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;
byte year, month, date, DoW, hour, minute, second;

void setup() {
// Start the I2C interface
Wire.begin();
Clock.setSecond(50);//Set the second
Clock.setMinute(59);//Set the minute
Clock.setHour(11); //Set the hour
Clock.setDoW(5); //Set the day of the week
Clock.setDate(31); //Set the date of the month
Clock.setMonth(5); //Set the month of the year
Clock.setYear(13); //Set the year (Last two digits of the year)
// Start the serial interface
Serial.begin(115200);
}
void loop()
{
int second,minute,hour,date,month,year,temperature;
second=Clock.getSecond();
minute=Clock.getMinute();
hour=Clock.getHour(h12, PM);
date=Clock.getDate();
month=Clock.getMonth(Century);
year=Clock.getYear();
temperature=Clock.getTemperature();

Serial.print(“20”);
Serial.print(year,DEC);
Serial.print(‘-‘);
Serial.print(month,DEC);
Serial.print(‘-‘);
Serial.print(date,DEC);
Serial.print(‘ ‘);
Serial.print(hour,DEC);
Serial.print(‘:’);
Serial.print(minute,DEC);
Serial.print(‘:’);
Serial.print(second,DEC);
Serial.print(‘\n’);
Serial.print(“Temperature=”);
Serial.print(temperature);
Serial.print(‘\n’);
delay(1000);
}

步驟4:

最後我們要與LCD程式做整合,讓LCD顯示時間。其實很簡單,我們先開啟【自造學堂】Arduino如何透過I2C控制LCD模組最後的程式,並且在宣告區域引用<LiquidCrystal_I2C.h>這個函數式。再來將於初始化設定該設定的,以及想在主程式迴圈顯示的,通通複製貼上並修改即可。程式如下:

#include <DS3231.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

DS3231 Clock;
bool Century=false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;
byte year, month, date, DoW, hour, minute, second;

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup() {
// Start the I2C interface
Wire.begin();
Clock.setSecond(59);//Set the second
Clock.setMinute(10);//Set the minute
Clock.setHour(12); //Set the hour
Clock.setDoW(5); //Set the day of the week
Clock.setDate(17); //Set the date of the month
Clock.setMonth(3); //Set the month of the year
Clock.setYear(17); //Set the year (Last two digits of the year)
// Start the serial interface
Serial.begin(115200);

// 初始化 LCD,一行 16 的字元,共 2 行,預設開啟背光
lcd.begin(16, 2);

// 閃爍三次
for(int i = 0; i < 3; i++) {
lcd.backlight(); // 開啟背光
delay(250);
lcd.noBacklight(); // 關閉背光
delay(250);
}
lcd.backlight();

// 輸出初始化文字
lcd.setCursor(0, 0); // 設定游標位置在第一行行首
lcd.print(“ICshop&MakerPRO”);
delay(1000);
lcd.setCursor(0, 1); // 設定游標位置在第二行行首
lcd.print(“Hello, Maker!”);
delay(8000);
lcd.clear();
}

void loop() {
int second,minute,hour,date,month,year,temperature;
second=Clock.getSecond();
minute=Clock.getMinute();
hour=Clock.getHour(h12, PM);
date=Clock.getDate();
month=Clock.getMonth(Century);
year=Clock.getYear();

temperature=Clock.getTemperature();

Serial.print(“20”);
Serial.print(year,DEC);
Serial.print(‘-‘);
Serial.print(month,DEC);
Serial.print(‘-‘);
Serial.print(date,DEC);
Serial.print(‘ ‘);
Serial.print(hour,DEC);
Serial.print(‘:’);
Serial.print(minute,DEC);
Serial.print(‘:’);
Serial.print(second,DEC);
Serial.print(‘\n’);
Serial.print(“Temperature=”);
Serial.print(temperature);
Serial.print(‘\n’);

lcd.setCursor(0, 0); // 設定游標位置在第一行行首
lcd.print(“ICshop&MakerPRO”);
lcd.setCursor(0, 1);
lcd.print(“Time=”);
lcd.setCursor(5, 1); // 設定游標位置在第二行行首
lcd.print(hour,DEC);
lcd.setCursor(7, 1);
lcd.print(‘:’);
lcd.setCursor(8, 1);
lcd.print(minute,DEC);
lcd.setCursor(10, 1);
lcd.print(‘:’);
lcd.setCursor(11, 1);
lcd.print(second,DEC);

delay(1000);
}

最後這個程式的流程,一樣是啟動Arduino時,會先引用Wire、DS3231與LiquidCrystal_I2C函式庫。之後於初始化設定,則會先控制LCD模組閃爍背光三次,並在第一行顯示「ICshop&MakerPRO」,延遲一秒後在第二行顯示「Hello, Maker!」,並且延遲八秒,再清除所有顯示。

最後進入主程式迴圈裡面,在第一行顯示「ICshop&MakerPRO」等字,而後在第二行開頭先顯示「Time=」等字,在第6位元顯示「時」並且十進位(DEC)輸出,在第8位元顯示「:」,後面以此列推,最後延遲1秒,再進入下一個迴圈。

結語

相信做到這裡,大家都已經完成LCD模組的時間顯示了吧!如果沒有的話,還是要檢查一下,是否接錯哪條線路了,或者程式有打錯(比如有分號未打之類的)。最後,不用太介意自己沒有相關背景與技術,只需要了解其原理原則,就能夠享受當Maker的樂趣,這也是Arduino的魅力所在!

(責任編輯:林佳盈)

黃 小棟

黃 小棟

機電整合工程師,喜歡遊山玩水。多次參與Maker活動;曾自行設計和製作水下無人載具,現在則是平日手縫泰迪熊。
黃 小棟

上一篇: | 下一篇:

468 ad

我想回應

你的電子郵件位址並不會被公開。 必要欄位標記為 *

成城共創股份有限公司版權所有、轉載必究.Copyright(c) 2017 MakerPRO