在早期學習 Arduino時,有一篇筆記 Arduino筆記(4):在2x16 LCD上顯示 Hello World訊息,用到 2x16 LCD顯示模組時,需要接十幾條線,覺得有點麻煩。後來發現有一個模組 IIC/I2C/介面的 LCD1602轉接板,這個轉接板只佔用2個 IO ,如改接這個模組,只要 4條線就可以了。本實作就來看看如何連接這個轉接板,並將 RTC 時間顯示在 LCD上。可是筆記(4) 的作法是要先設定好時間,上傳程式,每次開機的日期、時間都一樣。想說再接兩個按鍵,加入時間設定,可以調整日期跟時間,比較方便。以下就看一下實作過程。
[安裝LiquidCrystal_I2C Library]
LiquidCrystal_I2C 程式庫提供顯示 LCD 1602 所需的功能。在 Arduino 選單, [Sketch 草稿碼] →下拉選擇 [Include Library 匯入程式庫] → [Manage Libraries 管理程式庫] 。在搜尋的地方輸入 LiquidCrystal_I2C,選擇以下紅色框線的 Library,按下右方的 [Install],出現 [Installed] 表示安裝完成。
[安裝DS1302 Library]
DS1302 程式庫提供 RTC時鐘所需的功能。在 Arduino 選單, [Sketch 草稿碼] →下拉選擇 [Include Library 匯入程式庫] → [Manage Libraries 管理程式庫] 。在搜尋的地方輸入 DS1302,選擇以下紅色框線的 Library,按下右方的 [Install],出現 [Installed] 表示安裝完成。
[材料]
- Arduino Uno x 1
- 1602 LCD模組 x 1
- DS1302 RTC模組 x 1
- IIC/I2C/介面 LCD1602轉接板 x 1
- 10K 電阻 x 2
- 按鍵 x 2
- 連接線 x 12
- 麵包板 x 1
[線路圖]
Arduino UNO | I2C 1602轉接板 | RTC1302 | 按鍵 |
---|---|---|---|
5V | VCC | VCC | - |
GND | GND | - | - |
A4(SDA) | SDA | - | - |
A5(SCL) | SCL | - | - |
Pin2 | - | RST | - |
Pin3 | - | DAT | - |
Pin4 | - | CLK | - |
Pin8 | - | - | 按鍵1 |
Pin9 | - | - | 按鍵2 |
按鍵1及2 一端VCC,另一端接 Arduino Pin8及Pin9 並連接電阻,電阻另一端接地。
[程式]
#include <Wire.h> #include <LiquidCrystal_I2C.h> #include <DS1302.h> uint8_t clock[8] = {0x0,0xe,0x15,0x17,0x11,0xe,0x0}; // DS1302 初始化設定 DS1302 rtc(2, 3, 4); Time t; bool adjust = false; // 調整 clock 模式 yes/no // 調整 hour, minute, day ... mode bool ahour, aminute, aday, amonth, ayear, rfin = false; int stareb1, stareb2 = 0; // 按鍵狀態 // 變數 hour, minute, day, month, year int hh, mm, dd, mo, yy; const int button1 = 8; // 按鍵執行 設定/下一步/儲存 const int button2 = 9; // 按鍵調整時間日期/不儲存 // 設定 LCD 位址為 0x27,有 16 個字元 2 列 LiquidCrystal_I2C lcd(0x27,16,2); void setup() { // buttons 1 and 2 are set as inputs pinMode (button1, INPUT); pinMode (button2, INPUT); lcd.init(); // 初始化 lcd lcd.backlight(); lcd.print("Initialising..."); lcd.createChar(2, clock); Wire.begin(); // 第一次設定寫入 DS1302 RTC時鐘,之後可以加上註解 // rtc.setDOW(SUNDAY); // 設定每週星期幾? // rtc.setTime(18, 39, 30); // 設定24小時時間 20:16:30 // rtc.setDate(26, 7, 2019); // 設定日期(日, 月, 年) } void loop() { // 在位置0,0 顯示時間 lcd.setCursor(0,0); lcd.print("Time: "); lcd.print(rtc.getTimeStr()); // 在位置0,1 顯示日期 lcd.setCursor(0,1); lcd.print("Date: "); lcd.print(rtc.getDateStr()); delay(1000); // 調整時間日期按鍵1 stareb1 = digitalRead(button1); if (stareb1 == HIGH) { adjust = true; // 調整時間模式開啟 t = rtc.getTime(); hh = t.hour; mm = t.min; dd = t.date; mo = t.mon; yy = t.year; int i = 1; // 跳到設定子畫面 delay(1000); lcd.clear(); while (adjust) { // 調整小時 if (i == 1){ // 小時的子畫面為 1 ahour = true; lcd.clear(); while(ahour) { lcd.setCursor(0,0); lcd.print(String("hour: ") + String(hh)); stareb1 = digitalRead(button1); stareb2 = digitalRead(button2); // 按鍵 2 用來增加小時數,只到 23 if (stareb2 == HIGH) { hh++; if (hh == 24) hh = 0; delay (1000); lcd.clear(); } // 按鍵 1被按下,跳到下一個子畫面 if (stareb1 == HIGH) { ahour = false; i++; delay (1000); } } } // 調整分鐘 if (i == 2){ aminute = true; lcd.clear(); while(aminute) { lcd.setCursor(0,0); lcd.print(String("MIN: ") + String(mm)); stareb1 = digitalRead(button1); stareb2 = digitalRead(button2); if (stareb2 == HIGH) { mm++; if (mm == 60) mm = 0; delay (1000); lcd.clear(); } if (stareb1 == HIGH) { aminute = false; i++; delay (1000); } } } // 調整日期的天 if (i == 3){ aday = true; lcd.clear(); while(aday) { lcd.setCursor(0,1); lcd.print(String("DATA: ") + String(dd)); stareb1 = digitalRead(button1); stareb2 = digitalRead(button2); if (stareb2 == HIGH) { dd++; if (dd == 32) dd = 1; delay (1000); lcd.clear(); } if (stareb1 == HIGH) { aday = false; i++; delay (1000); } } } // 調整月份 if (i == 4){ amonth = true; lcd.clear(); while(amonth) { lcd.setCursor(0,1); lcd.print(String("Month: ") + String(mo)); stareb1 = digitalRead(button1); stareb2 = digitalRead(button2); if (stareb2 == HIGH) { mo++; if (mo == 13) mo = 1; delay (1000); lcd.clear(); } if (stareb1 == HIGH) { amonth = false; i++; delay (1000); } } } // 調整年份 if (i == 5){ ayear = true; lcd.clear(); while(ayear) { lcd.setCursor(0,1); lcd.print(String("Year: ") + String(yy)); stareb1 = digitalRead(button1); stareb2 = digitalRead(button2); if (stareb2 == HIGH) { yy++; // 只能設定到 2030 年,回到 2019繼續 if (yy == 2030) yy = 2019; delay (1000); } if (stareb1 == HIGH) { ayear = false; i++; delay (1000); } } } // 調整結束,儲存設定值 if (i == 6){ rfin = true; lcd.clear(); while(rfin) { lcd.setCursor(0,0); lcd.print("Save values?"); lcd.setCursor(0,1); // 左邊按鍵 1,右邊按鍵 2 lcd.print(">>>> YES NO <<<<"); stareb1 = digitalRead(button1); stareb2 = digitalRead(button2); // 按鍵 2 不修改,回到初始畫面 if (stareb2 == HIGH) { adjust = false; rfin = false; delay (1000); } // 按鍵 1 儲存改變值,回到初始畫面 if (stareb1 == HIGH) { adjust = false; rfin = false; rtc.setTime(hh, mm, 0); rtc.setDate(dd, mo, yy); lcd.clear(); delay (1000); } } } } } }
[實作結果]
實作前,IIC / I2C轉接板是跟 LCD 分開的,我先找了排針座銲在 LCD模組上,方便轉接板拆卸。設定日期及時間的影片:
[參考資料]
- Instructables:Arduino Clock With DS3231 and LCD1602
大大您好:
回覆刪除調整時間的部分寫得很詳細,真正讚!
可否請教:
在我的電腦裡
#include 要改成
#include 要改成
然後要ThreeWire myWire(6,5,7);
再RtcDS1302 Rtc(myWire);
Time t;這行出錯:
'Time' does not name a type
目前卡在這裡,有空請指導,謝謝!
我覺得是不是沒有安裝正確的函數庫或是少了#include需要時間的函數庫?程式會用到跟時間有關的函數庫是DS1302.h,網路上有其他的DS1302函數庫,您留言的#include看不出來是哪個?您可以再檢查一下。
刪除張貼留言