2012年7月23日月曜日

秋月のRTCモジュール

 今回は、秋月のRTCモジュール を試してみました。この秋月のRTCモジュールはセイコーのI2C接続リアルタイムクロックモジュールRTC-8564をDIPパッケージに実装したものです。今回、ArduinoでのI2C通信を使うのは初めてだったんですが、 RTC-8564のアプリケーションノートこちらのサイト を参考にさせてもらって、スムーズに動かす(とりあえず、動作を確認する)ことができました。
 レジスタの内容に関しては、アプリケーションノートなどが日本語なので助かりました。また、ArduinoでI2Cを使ってみるのが初めてだったので、前述のPIC AVR 工作室のサイトが大変参考になりました。実際、以下のテストに使ったスケッチも、当該サイトのものをほぼいただいてきたものです。感謝。

 まずは、接続。ブレッドボード(他の実験中の領域の隙間ですが・・・)にRTCモジュールを載せて、電源、GND、SDA、SDCをつなぐだけですが、SDA、SDCは1kとか2.2kの抵抗でプルアップしておきます。SDAはArduinoのAN4端子、同SDCはAN5端子に接続します。


 前述のサイトにあったソースを参考(というか、ほぼそのまま)にさせていただいたスケッチを書き込んで、動作確認。とりあえず、日時の初期値はスケッチ中で固定値(日付が変わる直前くらいの)を入れて、動きを見ました。


 時間の経過とともに、時間、日付、曜日などが更新されているところがわかります。流用元さんに感謝しつつ、以下、スケッチのソースです。

#include "Arduino.h"
#include "Wire.h"


#define RTC_ADDRESS (0xa2 >> 1)

int rtc[16];

void setup() {
 
 Serial.begin(9600);
 Serial.println("Initializing RTC unit...Please wait...");
 delay(1000);
 
 // Bus-MasterとしてI2Cを開始。
 Wire.begin();
 
 // RTCへの送信準備開始。
 Wire.beginTransmission(RTC_ADDRESS);
 // はじめにアドレス0x00を指定。次からはオートインクリメント。
 Wire.write(0x00);
 // コントロールレジスタ1。
 Wire.write(0x00);
 // コントロールレジスタ2。
 Wire.write(0x00);
 // 秒レジスタ。とりあえず、58秒。
 Wire.write(0x58);
 // 分レジスタ。とりあえず、59分。
 Wire.write(0x59);
 // 時レジスタ。とりあえず、23時。
 Wire.write(0x23);
 // 日レジスタ。とりあえず、23日。
 Wire.write(0x23);
 // 曜日レジスタ。とりあえず、月曜日。
 Wire.write(0x01);
 // 月レジスタ。とりあえず、7月。
 Wire.write(0x07);
 // 年レジスタ。取りあえず、12年。
 Wire.write(0x12);
 // アラーム設定。なし。
 Wire.write(0x00);
 Wire.write(0x00);
 Wire.write(0x00);
 // Clock出力設定。1Hz。
 Wire.write(0x83);
 // キューの送信。通信終了。
 Wire.endTransmission(); 
 
 delay(20);
 Serial.println("RTC Initialized.");
}

void loop() {
 
 // I2C通信開始。
 Wire.beginTransmission(RTC_ADDRESS);
 // レジスタアドレス0x00を指定。
 Wire.write(0x00);
 // キューの送信。
 Wire.endTransmission();
 
 // データ要求。
 Wire.requestFrom(RTC_ADDRESS, 16);
 // データ受信。
 for (int i = 0; i < 16; i++) {
  while (Wire.available() == 0);
  rtc[i] = Wire.read();
 }
 
 // (西暦)年。以下、数値類はBCD。
 Serial.print("20");
 Serial.print(rtc[8], HEX);
 Serial.print("/");
 // 月。下位9bit。
 Serial.print(rtc[7] & 0x1f, HEX);
 Serial.print("/");
 // 日。下位10bit。
 Serial.print(rtc[5] & 0x3f, HEX);
 Serial.print(" ");
 // 曜日。
 switch (rtc[6] & 0x07) {
  case 0:
   Serial.print("Sun");
   break;
  case 1:
   Serial.print("Mon");
   break;
  case 2:
   Serial.print("Tue");
   break;
  case 3:
   Serial.print("Wed");
   break;
  case 4:
   Serial.print("Thr");
   break;
  case 5:
   Serial.print("Fri");
   break;
  case 6:
   Serial.print("Sat");
   break;
  default:
   Serial.print("   ");
   break;
 }
 Serial.print("   ");
 // 時。
 Serial.print(rtc[4] & 0x3f, HEX);
 Serial.print(":");
 // 分。
 Serial.print(rtc[3] & 0x7f, HEX);
 Serial.print(":");
 // 秒。
 Serial.print(rtc[2] & 0x7f, HEX);
 Serial.println();
 
 delay(200);
 
}