Arduino Tiny RTC I2C Module
最近在學習Arduino和RTC的使用,看了葉難先生寫的「輕鬆入門Arduino範例分析與實作設計」一書,其中提到DS1307即時時鐘晶片的使用。就很有興趣的想買一顆來試試,到ICSHOP網站一看,哇!一顆要79塊台幣。這這也不算便宜,而且還要買石英晶體和其他小零件,特別是要一個CR2032電池座,還要把這些東西焊在一起。想想自己手藝不精,眼力也不行了,只怕這些零件到時玩過就散在一邊,浪費了。
沒想到,看到他們也賣另一個[DS1307時鐘模組],而且只要60塊台幣,內含DS1307晶片、石英晶體、CR2032電池座等,還都焊的好好的。
那就先來試試了。
貨到了,看了一下電路圖和文件。哈,除了DS1307外,還有一顆24C32 32K I2C EEPROM,還留了3個接點給DS18B20溫度感測器。太多東西可以玩了,當下不知由那裡玩起啊。
先Google一下好了,果然有一大堆的資料。首先由Matthew的Arduino RTC: TinyRTC v1 with Arduino Mega 2560開始看。
他說只要接Vcc, GND, SCL, SDA這四條線就好了。然後他不知由那裡找到的三支草稿碼:SetRTC,GetRTC,I2CScanner。首先用I2CScanner來找DS1307的位址,嗯,是0x68。
然後再用SetRTC這支來設定日期時間,嘔,要直接改程式才能設定哦!再來就是可以用GetRTC這支來讀取日期時間了。試了一下,沒問題,都可以正常運作的。而且,這三支都只用到內建的Wire程式庫。
可是第一個問題,就是要設定日期時間,還要改草稿碼,然後再上傳,實在有點不方便啊!
此時回頭看看葉難的書,發現他用的是另外的方法,是別的程式庫。不過葉先生寫的設定日期時間的程式很好用的,我就先直接把Matthew的草稿碼GetRTC改成可以設定日期時間。
跑起來的樣子,如下圖:
設定日期時間的方法和葉先生書上寫的一樣,在上圖上方的文字框內輸入y2017後,再按Enter就可以把年份設成2017。要設定月份就用M09之類,日期就用d01之類,小時就用h12之類,分鐘就用m20之類,秒數就用s30之類。
沒想到一個RTC就有這許多玩意可以玩,模組上還有24C32 晶片,放在那裡沒用到呢!下次有時間,再來研究了。
沒想到,看到他們也賣另一個[DS1307時鐘模組],而且只要60塊台幣,內含DS1307晶片、石英晶體、CR2032電池座等,還都焊的好好的。
那就先來試試了。
貨到了,看了一下電路圖和文件。哈,除了DS1307外,還有一顆24C32 32K I2C EEPROM,還留了3個接點給DS18B20溫度感測器。太多東西可以玩了,當下不知由那裡玩起啊。
先Google一下好了,果然有一大堆的資料。首先由Matthew的Arduino RTC: TinyRTC v1 with Arduino Mega 2560開始看。
他說只要接Vcc, GND, SCL, SDA這四條線就好了。然後他不知由那裡找到的三支草稿碼:SetRTC,GetRTC,I2CScanner。首先用I2CScanner來找DS1307的位址,嗯,是0x68。
然後再用SetRTC這支來設定日期時間,嘔,要直接改程式才能設定哦!再來就是可以用GetRTC這支來讀取日期時間了。試了一下,沒問題,都可以正常運作的。而且,這三支都只用到內建的Wire程式庫。
可是第一個問題,就是要設定日期時間,還要改草稿碼,然後再上傳,實在有點不方便啊!
此時回頭看看葉難的書,發現他用的是另外的方法,是別的程式庫。不過葉先生寫的設定日期時間的程式很好用的,我就先直接把Matthew的草稿碼GetRTC改成可以設定日期時間。
/* Downloaded from http://projectsfromtech.blogspot.com/ *Connect SCL, SDA, Vcc, and GND *Open Serial Monitor and enjoy! */ //Arduino 1.0+ Only #include "Wire.h" #define DS1307_ADDRESS 0x68 void setDateTime(byte second, byte minute, byte hour, byte weekDay, byte monthDay, byte month, byte year); void setup(){ Wire.begin(); Serial.begin(9600); } void loop(){ printDate(); delay(1000); } void pf(const char *fmt, ...) { char tmp[128]; // max 128 chars va_list args; va_start(args, fmt); vsnprintf(tmp, 128, fmt, args); va_end(args); Serial.print(tmp); } byte decToBcd(byte val){ // Convert normal decimal numbers to binary coded decimal return ( (val/10*16) + (val%10) ); } byte bcdToDec(byte val) { // Convert binary coded decimal to normal decimal numbers return ( (val/16*10) + (val%16) ); } void printDate(){ // Reset the register pointer Wire.beginTransmission(DS1307_ADDRESS); byte zero = 0x00; Wire.write(zero); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS, 7); int second = bcdToDec(Wire.read()); int minute = bcdToDec(Wire.read()); int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time int weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday int monthDay = bcdToDec(Wire.read()); int month = bcdToDec(Wire.read()); int year = bcdToDec(Wire.read()); //print the date EG 3/1/11 23:59:59 Serial.print(month); Serial.print("/"); Serial.print(monthDay); Serial.print("/"); Serial.print(year); Serial.print(" "); Serial.print(hour); Serial.print(":"); Serial.print(minute); Serial.print(":"); Serial.println(second); } void serialEvent() { int type = Serial.read(); int v = 0; int temp; while ((temp = Serial.read()) > '0' - 1) { pf("temp - 0 : %d\n", temp - '0'); v = v * 10 + (temp - '0'); pf("v : %d\n", v); } pf("type: %c\n", type); pf("v : %d\n", v); // ------------------------------- // Reset the register pointer Wire.beginTransmission(DS1307_ADDRESS); byte zero = 0x00; Wire.write(zero); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS, 7); byte s = bcdToDec(Wire.read()); byte m = bcdToDec(Wire.read()); byte h = bcdToDec(Wire.read() & 0b111111); //24 hour time byte weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday byte d = bcdToDec(Wire.read()); byte M = bcdToDec(Wire.read()); byte y = bcdToDec(Wire.read()); switch(type) { case 'y': y = v - 2000; break; case 'M': M = v; break; case 'd': d = v; break; case 'h': h = v; break; case 'm': m = v; break; case 's': s = v; break; default: Serial.println("Wrong\n"); break; } setDateTime(s, m, h, weekDay, d, M, y); } void setDateTime(byte second, byte minute, byte hour, byte weekDay, byte monthDay, byte month, byte year) { byte zero = 0x00; Wire.beginTransmission(DS1307_ADDRESS); Wire.write(zero); //stop Oscillator Wire.write(decToBcd(second)); Wire.write(decToBcd(minute)); Wire.write(decToBcd(hour)); Wire.write(decToBcd(weekDay)); Wire.write(decToBcd(monthDay)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year)); Wire.write(zero); //start Wire.endTransmission(); }
跑起來的樣子,如下圖:
設定日期時間的方法和葉先生書上寫的一樣,在上圖上方的文字框內輸入y2017後,再按Enter就可以把年份設成2017。要設定月份就用M09之類,日期就用d01之類,小時就用h12之類,分鐘就用m20之類,秒數就用s30之類。
沒想到一個RTC就有這許多玩意可以玩,模組上還有24C32 晶片,放在那裡沒用到呢!下次有時間,再來研究了。
留言