32.768KHzの水晶振動子を使ってRTCを行ってみます

〔Seeeduino XIAOの使い方に戻る〕


"Seeeduino XIAO"ボードには、32.768KHzの水晶振動子が取り付けられています、
これでRTCを実験したいと思います。

「ほとんどのRTCは、周波数が32.768 kHzである水晶発振器(Arduino Zero等)を使用します
 (水晶時計や時計で使用されているのと同じ周波数)。
 つまり、これは毎秒2 ^ 15サイクルに等しい周波数なので、単純なバイナリカウンター回路で
 使用するのに便利なレートです。」

リファレンスより


《とにかくサンプルスケッチを動かす》

@ XIAOの"USB port"とPCをUSB Type-Cコネクターケーブルで繋ぎます。

A ArduinoIDEを起動させ、ボードとポート設定を"Seeeduino XIAO"に設定します。

B IDEのメニューバーから[ファイル]→[スケッチ例]→[RTC]→[RTC_simple]を順番にクリックします。
  ([RTC]ライブラリは"Arduino IDEに"Seeeduino XIAO"ボードを追加した時にインストール
  されている様だ。)

実行時のシリアルモニター図 C スケッチをコンパイルして書き込みます。

D IDEのシリアルモニタを起動させます。

左図の様に表示されるでしょう。
図は12時間表示ですね、何とも簡単に動作しました。

因みに、[RTC_simple_24H_mode]ファイルなら24時間表示です。

《リファレンス》

こちらのリファレンスと"Arduino IDE 1.8.12"の上記RTCライブラリは説明が若干異なる様なので
ここで上記RTCライブラリにそった説明を記述して置きます。
又、下記RTCライブラリ説明はここ(primo用)を参照して作成しているので若干異なるかもですぅ。

RTCライブラリを使用する場合は、"#include <RTCInt.h>"をインクルードします。
ここでは、"RTCInt rtc ;"でオブジェクトを作成した例で記述しています。

void rtc.begin(bool timeRep)
 内部RTCを初期化します。 begin()は、他のRTCライブラリメソッドの前に呼び出す必要があります。
 Parameters
  timeRep:"TIME_H24"(24時間表現モード)、又は"TIME_H12"(12時間表現モード)を指定します。

unsigned int rtc.getHour()
 時間を取得する為の関数。
 時間表現モードに従って、この値は0-24の範囲(TIME_H24の場合)、
 又は0-12の範囲(TIME_H12の場合)になります。
 Parameters
  Return:現在の時:hour(0-12/24)を返します。

unsigned int rtc.getMinute()
 分を取得する為の関数。この値は0-59の範囲で変化します。
 Parameters
  Return:現在の分:minute(0-59)を返します。

unsigned int rtc.getSecond()
 秒を取得する為の関数。この値は0-59の範囲で変化します。
 Parameters
  Return:現在の秒:second(0-59)を返します。

void rtc.getTime()
 時分秒の時刻を取得する為の関数。
 時刻はTIME型構造体に設定されます。
 Example
  char buf[10] ;
  rtc.getTime() ;
  sprintf(buf,"%d:%d:%d",rtc.time.hour,rtc.time.minute,rtc.time.second) ;
  SerialUSB.println(buf) ;
unsigned char rtc.getMeridian()
 現在の時間の12時間モード(AM/PM)を得ます。
 Parameters
  Return:時間がAMの時は"0"を返し、PM時は"1"を返します。

unsigned int rtc.getDay()
 日を取得する為の関数。この値は1-31の範囲で変化します。
 Parameters
  Return:現在の日:day(1-31)を返します。

unsigned int rtc.getMonth()
 月を取得する為の関数。この値は1-12の範囲で変化します。
 Parameters
  Return:現在の月:day(1-12)を返します。

unsigned int rtc.getYear()
 年を取得する為の関数。年の値は2000-2063年で、下2桁で設定されます。
 Parameters
  Return:現在の年下2桁:year(0-63)を返します。
     (年の正しい表現を取得するには、この値にオフセット(2000)を追加してください。

void rtc.getDate()
 年月日の日付を取得する為の関数。
 日付はDATE型構造体に設定されます。
 Example
  char buf[12] ;
  rtc.getDate() ;
  sprintf(buf,"%d/%d/%d",rtc.date.year+2000,rtc.date.month,rtc.date.day) ;
  SerialUSB.println(buf) ;
void rtc.setHour(unsigned int hour, unsigned char meridian)
 時を設定する為の関数。
 Parameters
  hour  :時間表現モードに従って、この値の範囲は0-23又は0-12指定です。
  meridian:時刻がAMの時は"0"を、PM時は"1"を指定します。

void rtc.setMinute(unsigned int minute)
 分を設定する為の関数。
 Parameters
  minute:この値の範囲は0-59指定です。

void rtc.setSecond(unsigned int second)
 秒を設定する為の関数。
 Parameters
  second:この値の範囲は0-59指定です。

void rtc.setTime
  (unsigned int hour,unsigned char meridian, unsigned int minute, unsigned int second)

 時刻を設定する為の関数。
 Parameters
  hour  :時間表現モードに従って、"時"の範囲は0-23又は0-12指定です。
  meridian:時刻がAMの時は"0"を、PM時は"1"を指定します。
  minute :"分"の範囲は0-59指定です。
  second :"秒"の値の範囲は0-59指定です。

void rtc.setTime()
 時刻を設定する為の関数。
 時刻の設定指示はTIME型構造体で行います。
 Example
  rtc.time.Tmode = 1 ; // 12時間表現で"PM"指定
  rtc.time.hour = 4 ;
  rtc.time.minute = 30 ;
  rtc.time.second = 0 ;
  rtc.setTime() ;
void rtc.setDay(unsigned int day)
 日を設定する為の関数。
 Parameters
  day:この値の範囲は1-31指定です。

void rtc.setMonth(unsigned int month)
 月を設定する為の関数。
 Parameters
  month:この値の範囲は1-12指定です。

void rtc.setYear(unsigned int year)
 年を設定する為の関数。
 Parameters
  year:年の値は2000-2063年で、下2桁(0-63)で指示します。
     (プログラムでは"0"以上を有効としている様だ注意)

void rtc.setDate(unsigned int day, unsigned int month, unsigned int year)
 日付を設定する為の関数。
 Parameters
  day  :この値の範囲は1-31指定です。
  month:この値の範囲は1-12指定です。
  year :年の値は2000-2063年で、下2桁(0-63)で指示します。

void rtc.setDate()
 日付を設定する為の関数。
 日付の設定指示はDATE型構造体で行います。
 Example
  rtc.date.year = 20 ;
  rtc.date.month = 4 ;
  rtc.date.day = 1 ;
  rtc.setDate() ;
void rtc.enableAlarm(unsigned int mode, unsigned int type, voidFuncPtr callback)
 アラームを有効にする為の関数。
 Parameters
  mode  :OFF        アラームは無効
       SEC        秒単位のアラーム設定が一致
       MMSS       分と秒のアラーム設定が一致
       HHMMSS      時間、分、秒のアラーム設定が一致
       DDHHMMSS    日と時間、分、秒のアラーム設定が一致
       MMDDHHMMSS   月、日と時間、分、秒のアラーム設定が一致
       YYMMDDHHMMSS 年、月、日と時間、分、秒のアラーム設定が一致
  type  :ALARM_INTERRUPT アラーム一致が発生すると、割り込みが生成されます。
       ALARM_POLLED   アラームの一致はプログラムコードから監視する必要があります。
                  (常にループの中で監視します)
  callback:アラーム一致の割り込みルーチン(関数)へのポインターを指定します。
       (ALARM_POLLEDを使用する場合は"NULL"を書き込みます)

 ※ ALARM_INTERRUPTとALARM_POLLEDを操作したサンプルスケッチが[RTC]ライブラリの
   "スケッチ例"にあるので参考にしましょう。

void rtc.setAlarm()
 アラームの設定をする為の関数。
 この関数は、RTCIntクラスでアクセス可能な日時と呼ばれる2つのローカル構造体(TIME/DATE)に
 時間、日付を設定します。
 一致アラームタイプに応じて、時間、日付、又は両方の構造から値を取得します。
 Example
 rtc.enableAlarm(SEC,ALARM_POLLED,NULL); // ポーリングモードでアラームを有効にし、秒に一致させる
 rtc.time.second=10; // 一致する秒の設定(毎10秒が来ればアラームが発生します)
 rtc.setAlarm();   // アラームレジスタのsecondに書き込む

※ "Seeeduino XIAO"を省電力モード(スリープモード)に移行させ、RTCのアラーム機能でウエイクアップ
  させる記事はこちらを参照ください。

bool rtc.alarmMatch()
 アラームの一致ステータスを取得する為の関数。
 この関数は、ALARM_POLLEDモードを採用する時に使用されます。
 Parameters
  Return:アラーム発生(一致)で"true=1"を返し、それ以外は"false=0"を返します。

※ アラームフラグをクリアする為には、
  RTC->MODE2.INTFLAG.bit.ALARM0=1; //clearing alarm0 flag
 を実行します。
 このフラグは、時間表現モードに関係なくアラーム発生したら必ずクリアします。

unsigned int rtc.rdn(int y, int m, int d)
 Rata Die(R.D.)を使用して日付を整数に変換する関数。
 Parameters
  y   :年の値で、下2桁で指示します。
  m  :月の値で、範囲は1-12指定です。
  d   :日の値で、範囲は1-31指定です。
  Return:Rata Die(R.D.)の初日(起点)は1年1月1日を1とし指定日までの総日数を返します。

《曜日を求めるスケッチ》

上記の"RTCInt"ライブラリではどうも曜日表示までは出来ないぽい様なのでぇ、
曜日を表示するサンプルスケッチを書いてみました。
日付から曜日を求める関数(getDayWeek)を利用する場合は、コピーペーストして貼り付けて下さい。
又、ここから下記のスケッチをダウンロード出来ます。
---------------------------------------------------------------------
// Seeeduino XIAOボードでRTCを実行し日付から曜日を求めるサンプルスケッチ

#include <RTCInt.h>

char DayWeekData[7][4] = {"日","月","火","水","木","金","土"} ;

RTCInt rtc;  // RTCIntオブジェクトを作成する

void setup() {
  SerialUSB.begin(9600) ;
  rtc.begin(TIME_H24); // 24時間表現モード

  // 時刻を設定する(10:15:00)
  rtc.setHour(10,0);  // 時
  rtc.setMinute(15);  // 分
  rtc.setSecond(0);   // 秒
  // 日付を設定する(2020/05/01)
  rtc.setDay(1);      // 日
  rtc.setMonth(5);    // 月
  rtc.setYear(20);    // 年
  
}
void loop() {
  int day_week ;

  rtc.getDate();      // ローカル構造体(DATE)で日付を取得
  rtc.getTime();      // ローカル構造体(TIME)で時間を取得

  // 日付を表示する HH:MM:SS
  SerialUSB.print(rtc.time.hour);       // 時
  SerialUSB.print(':');
  SerialUSB.print(rtc.time.minute);     // 分
  SerialUSB.print(':');
  SerialUSB.println(rtc.time.second);   // 秒

  // 時間を表示する YYYY/MM/DD
  SerialUSB.print(rtc.date.year+2000);  // 年
  SerialUSB.print('/');
  SerialUSB.print(rtc.date.month);      // 月
  SerialUSB.print('/');
  SerialUSB.print(rtc.date.day);        // 日
  SerialUSB.print(' ');

  // 曜日を表示する
  day_week = getDayWeek(rtc.date.year,rtc.date.month,rtc.date.day) ;
  SerialUSB.print(DayWeekData[day_week]) ;
  SerialUSB.println("曜") ;

  delay(1000);
}
/*******************************************************************************
*  getDayWeek - 日付から曜日を求める処理                                       *
*    year   : 年の値は下2桁で指示します                                        *
*    month  : 月の値の範囲は1-12指定です                                       *
*    day    : 日の値の範囲は1-31指定です                                       *
*    return : 0=日曜  1=月曜  2=火曜  3=水曜  4=木曜  5=金曜  6=土曜           *
*******************************************************************************/
int getDayWeek(int year,int month,int day) {

     int w ;

     if(month < 3) {
         year-- ;
         month = month + 12 ;
     }
     w = 365 * year + year / 4 - year / 100 + year / 400 + 306 * (month + 1) / 10 + day - 428 ;

     return w % 7 ;
}
---------------------------------------------------------------------

《バッテリーのバックアップについて》

リファレンスにこう記事があります。
「ボードに電源が投入されるたびに、RTCはリセットされ、標準の日付から開始されます。
 時間とRTCを実行し続けるには、ボードの電源を入れ続ける必要があります。
 ボタンサイズのリチウム電池、又はダイオードを介して3.3Vピンに接続された3V範囲の任意の電池は、
 標準のUSB又はVIN電源が切断される前にCPUがスリープモードになった場合、RTCを維持するのに十分です。」

リファレンスでは"Arduino Zero"での記述ですが、"Seeeduino XIAO"も同様でしょう3V3ピンに電池を
同様に接続すれば良い様に思います。




【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.