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.