Arduino UNO R4の登場で広がるArduinoの世界(5)RTCで現在時刻を得て時刻を表示
Arduino UNO R4に搭載されているルネサスのR7FA4M1AB3CFM#AA0に内蔵されているRTC(リアル・タイム・クロック)を利用すると、リアル・タイム・クロック機能を実現できます。このリアル・タイム・クロックの処理を行うためにRTCライブラリも用意されています。このRTCライブラリを利用すると、現在時刻の表示が容易に行えます。
●RTCライブラリのインストール
RTCライブラリは、ボードマネージャでArduino UNO R4ボードをArduino IDEにインストールするときにArduino UNO R4のコア・ライブラリの一つとしてインストールされます。
具体的には、ユーザのフォルダ下のAppData\LocalArduino15\packagesの中にインストールされます。具体的には次に示すように、¥arduino\hardwareフォルダの中にArduino UNO R4のボードのモジュールが格納されたrenesas_unoのフォルダがセットされます。この中にバージョンを示すフォルダに続いて、ライブラリとそのほかのArduino UNO R4のためのパッケージが格納されます。
●Arduino UNO R4のRTC
Arduino UNO R4のRTCはMinima、WiFi両ボード共に同じ機能をもっていて、RTCライブラリを利用して同じように活用できます。ただし、WiFiモデルはメイン電源の切断時にはRTCをバックアップするバッテリを接続する機能をもっています。Minimaはこの機能がないので、電源投入時に毎回時刻合わせを行う必要があります。
RTCライブラリのサンプル・スケッチ「RTC_AutomaticExample.ino」では、アップロード時のPCの示す時刻をRTCの設定値としています。スケッチのアップロード後すぐにスケッチが起動するので、大きな時刻の狂いは生じません。
●RTCの開始時刻の設定
WiFiモデルの場合は、インターネットのNTPから標準時を取得して時刻合わせを行うのが一般的です。国内でArduino UNO R4 WiFiが販売されるようになったら、購入し試してみます。
今利用しているMinimaの場合は、何らかの方法で時刻合わせを行う必要があります。電源をPCから得ている場合は、サンプルの「RTC_AutomaticExample.ino」の中で用いた、PCからアップロードした日時で時刻合わせを行う方法が一番簡単です。
●現在時刻をLCDモジュールに表示
ここでは、Arduino UNO R4用のRTCライブラリのサンプル・スケッチのRTC_AutomaticExample.inoの動作を確認し、シリアルモニタに表示された時刻をLCDモジュールに表示します。
●LCDモジュールを接続する
LCDモジュールに表示するために、次に示すようにAQM1602のI2CインターフェースのLCDモジュールを接続します。モジュールはピッチ変換基板とピンヘッダが付属した変換キットを購入します。
I2C接続小型キャラクタLCDモジュール(16×2行・3.3V/5V)ピッチ変換キット
https://akizukidenshi.com/catalog/g/gK-08896/
Arduino UNO R4の5VとGNDを図(右下)のように接続し、SDAとSCLのI2Cバスの信号線をそれぞれ接続します。この信号線は、図(左上)に示すようにLCDモジュールの側で10kΩくらいの抵抗でプルアップします。これでハードウェアの準備は終わります。
●I2Cインターフェース付きLCDモジュールを利用するための準備
I2Cインターフェース付きのLCDモジュールを利用するためのi2clcdaqmライブラリは、前回の次に示すWebページで詳しく説明しています。このテストを行う前には、次に示すページで示したi2clcdaqmライブラリのインストール動作の確認を行ってください。
Arduino UNO R4の登場で広がるArduinoの世界
(4)i2clcdaqmライブラリの作成
https://www.denshi.club/cookbook/arduino/r4/arduino-uno-r4arduino4.html
●サンプル・スケッチの名前を変えて保存
今回使用するサンプル・スケッチは「RTC_AutomaticExample.ino」です。このサンプル・スケッチにLCDへの書き込み処理を追加します。そのため、スケッチ名を「RTC_AutomaticLCD010.ino」としてスケッチを保存するフォルダに保存します。このフォルダには、事前にI2clcdaqmライブラリをインストールしておきます。
●サンプル・スケッチの追加修正
I2Cインターフェースを利用するためにはWireライブラリが必要となります。そのため、スケッチの最初の部分で、Wireライブラリとi2clcdaqmライブラリのインクルードを次に示すように設定します。
#include <Wire.h>
#include "i2clcdaqm.h"
i2clcdaqmのインスタンスをlcdとします。併せてArduino UNO R4の電源電圧が5Vでモジュールも5V電源電圧であることを5のパラメータが示します。次の32は輝度を示す値です。この値を中心に前後の値で調整します。
lcdDataは年月日と時刻をStringで格納するための変数です。lcdDataCは時刻の変数が変化したことをチェックするための変数です。時刻を取り出し表示した後にlcdDataCに格納します。次に取得したデータをこのlcdDataCと比較し、変化を確認したらLCDに表示します。
i2clcdaqm lcd(5, 32);
String lcdData, lcdDataC;
これらは次に示すように、スケッチの初めの部分に追加します。
●setup()関数内の追加分
setup()関数には、I2Cライブラリを起動するWire.begin()をセットします。これでI2Cインターフェースが利用できるようになります。
I2Cインターフェースが利用できるようになったので、I2C経由でLCDモジュールを初期化するためのコマンドをlcd.init_lcd()で送信します。つぎに、モジュールの1行目にlcd.i2cprint()でメッセージを表示し、データを2行目の先頭から表示するために lcd.lcdcu_set(0, 1);をセットします。
Wire.begin();
lcd.init_lcd();
lcd.i2cprint("The RTC was just set to: ");
lcd.lcdcu_set(0, 1);
以上の処理を次に示すように追加します。
●時刻取得の処理
サンプル・スケッチの年月日、時刻を取得する関数を利用します。
RTCライブラリで定義されたRTCTimeクラスのインスタンスを利用してcurrentTimeを生成し、年月日を取得するメソッドと組み合わせて、年はcurrentTime.getYear()で4桁の西暦年を得ます。2000の減算は年数を二桁表示にするためのものです。月のデータはgetMonth()メソッドで得たjan~Decの値を1~12に変換するMonth2int()で変換します。そのため、月はMonth2int(currentTime.getMonth())で取得します。日にちの値はgetDayOfMonth()メソッドで用いてcurrentTime.getDayOfMonth()で得ます。
それぞれ得た値を、Stringオブジェクトにして連結し、表示するための文字列オブジェクトlcdDataに格納します。時分秒の値も同様に取得し表示データに格納します。
lcdData = String(currentTime.getYear()-2000)+"-"+String(Month2int(currentTime.getMonth()))+"-"; lcdData = lcdData+String(currentTime.getDayOfMonth())+" "+String(currentTime.getHour());
lcdData = lcdData+":"+String(currentTime.getMinutes())+":"+String(currentTime.getSeconds());
表示データをLCDモジュールに表示します。カーソルが2行目左端にセットされているので、その位置から表示されます。
lcd.i2cprint(lcdData);
サンプル・スケッチではデータの取得ごとにシリアルモニタに出力しています。データが連結されているので、一回の出力で表示します。
Serial.println(lcdData);
新しく取得したデータが前のデータから変化しているか確認します。そのため、表示したデータをlcdDataCに保存します。
lcdDataC = lcdData;
以上追加修正を行ったsetup()を次に示します。
●定期的に起動し表示する処理
次に示すalarmCallback()は、時刻が0秒に割り込みが発生しその割り込み処理によって起動されるCallback関数です。
見出しを表示し、その後にその時点の時刻を表示しています。Setup()関数では見出しのセットされた開始時刻、割り込み処理ではアラームにより起動された時刻となっています。表示される時刻は同じ処理となっています。
Callback関数の処理中は割り込み禁止で処理されるので、I2Cの処理が正しく実行されません。そのためLCDへの表示は、割り込み処理ルーチンでは行わず、loop()関数内で行います。
●割り込み処理の結果のLCDへの表示
LcdDataの値が現在表示されているデータを示すlcdDataCの値と一致しないときに、lcdDataの値を表示します。そのため、次に示すようにlcdData != lcdDataCが成立するとき、LCDモジュールをクリアし、見出しを表示し、新しい日時を表示します。表示したデータをledDataCに保存して処理を終わります。
if (lcdData != lcdDataC) {
lcd.lcdclear();
lcd.i2cprint("An alarm was triggered at:");
lcd.lcdcu_set(0, 1);
lcd.i2cprint(lcdData);
lcdDataC = lcdData;
}
Loop()関数は、次に示すようにこの処理を繰り返すだけです。必要な事項は割り込み処理で行っているので、このエリアにはほかの処理を追加できます。
写真は、LCDモジュールに表示されたデータです。
WiFiモデルが利用できると、インターネット上のNTPからの時刻で容易に時刻合わせができるようになります。Arduino UNO R4 WiFiが国内で発売されるようになりましたら購入しいろいろ試します。それまでは時刻の必要な処理はArduino MKR WiFi 1010などで対応します。
(2023/10/9)
<神崎 康宏>