ArduinoとRTCモジュールRX8900を使ったLCD時計の製作(1)

ArduinoとRX8900CE UAを搭載したRTC(リアルタイムクロック)モジュールを使ってLCD(液晶ディスプレイ)時計を作りました。

ArduinoとRTCモジュールRX8900を使ったLCD時計の製作
目次

集めたパーツ (2021/12/12追加)

ネット通販(秋月電子通商など)でパーツを集めてブレッドボードで組み立てました。RTCモジュールはRX8900を搭載したAE-RX8900(DIP化モジュール)です。温度補償発振器(DTCXO)を内蔵しており高精度で時刻を管理できます。

#パーツ仕様個数備考
1Arduino Uno Rev3ATmega3281【M-07385】
2RTCモジュールRX8900CE UA
DIP化モジュール
1【K-13009】
3LCDモジュールI2C接続 16×2行
白色バックライト
[ACM1602NI-FLW-FBW-M01]
1【P-05693】
4半固定ボリューム3362P 10KΩ1【P-03277】
5電気二重層コンデンサ1.5F 耐電圧 5.5V(タテ型)1【P-04300】
6保護抵抗手持ちの200Ωを利用1 
7ブレッドボードEIC-8011【P-00315】
8ジャンパーワイヤオス-オス 10cmセット適量【C-05371】
9スイッチングACアダプタ
※PCとUSB接続のみの場合は不要
9V 1.3A 100~240V【M-00030】

Arduinoの開発環境「Arduino IDE」のセットアップ手順

Arduinoの公式サイトからArduino IDEをダウンロードしてPCにインストールします。 

Arduinoボードの開発環境となる「Arduino IDE」のインストール、各種センサやLCDといったモジュールとArduinoとの接続を容易にする「ライブラリ」を活用したスケッチ作成までの手順メモです。

あわせて読みたい
Arduinoの開発環境「Arduino IDE」のセットアップ手順 Arduinoボードの開発環境となる「Arduino IDE」のインストール、各種センサや液晶ディスプレイといったモジュールとArduinoとの接続を容易にする「ライブラリ」を活用し...

ブレッドボードでArduinoとRTCモジュールの動作確認、スケッチ実行

RX8900モジュールの組み立て(2021/12/12更新)

RTCモジュールからのI2C線(SDAとSCLの2線)、3.3V線とGND線をArduino Uno Rev3の該当ピンに接続して、サンプルスケッチで動作確認を行います。RTCモジュールのI2Cアドレスは0x32です。RTCモジュール基板上のJ1をショートすると I2C プルアップ抵抗(10kΩ)が有効になります。

RX8900を使ったLCD時計の結線図
RX8900を使ったLCD時計の結線図 (2021/12/12更新)
LCDモジュールを実装する前のRX8900とArduino Uno Rev3
LCDモジュールを実装する前のRX8900とArduino Uno Rev3
※この段階では写真中の電気二重層コンデンサによるバックアップは機能していません。スケッチ(3)で対応しました

LCDモジュールを実装する前のRX8900とArduino Uno Rev3で動作確認を行いました。Arduino IDEでスケッチ1、スケッチ2を実行してシリアルモニタに表示します。

スケッチ1:シリアルモニタに表示(1)

秋月電子通商のWebサイトでRTCモジュールのサンプルスケッチ(RX8900_SAMPLE.zip)が提供されています。このスケッチを実行すると、シリアルモニタから年月日、時分を入力後に、日時、曜日、時刻、チップ内部温度(外気温ではない)が出力されます。
シリアルモニタからの入力時には、画面右下の改行を「CRのみ」にしました。

秋月電子通商のサンプルスケッチの実行結果
秋月電子通商のサンプルスケッチの実行結果

スケッチ2:シリアルモニタに表示(2)

秋月電子通商のライブラリをもとに作られた GitHub:citrienaサイトのスケッチを利用させていただきました。このスケッチはシリアル出力なのは同じですが、PCとつないでArduino IDEを実行すると時刻合わせができます。

ライブラリとして「TimeLib.h」と「RX8900RTC.h」がincludeされているので、GitHubサイトから「Time-master.zip」と「RX8900RTC-master.zip 」をPCにダウンロードして保存(「Code」ボタンをクリックして「Download ZIP」)。
Arduino IDEのメニューの「スケッチ」→「ライブラリをインクルード」→「.ZIP形式の ライブラリを インストール」で ダウンロードしたZIPファイルを選んで追加します。

ライブラリを追加すると、 Arduino IDEのメニュー の「スケッチ例」→ 「カスタムライブラリのスケッチ例」に「RX8900RTC」が出てくるので 「RX8900RTC_TimeSet」 を開きます。
このスケッチを実行すると、シリアルモニタには実行した時刻(年月日、時分秒)が表示されます。

Arduino IDEでスケッチ「RX8900RTC_TimeSet」を実行
Arduino IDEでスケッチ「RX8900RTC_TimeSet」を実行
シリアルモニタに表示されたスケッチ実行結果
シリアルモニタに表示されたスケッチ実行結果

LCDモジュールを組み込んでバッテリーバックアップ対応のスケッチ修正

LCDモジュールの追加

ブレッドボードにLCDモジュール(ACM1602NI-FLW-FBW-M01)とコントラスト調整用の半固定抵抗を実装し、I2C線(SDAとSCLの2線)、3.3V線とGND線を延長して配線します。

電気二重層コンデンサ によるバッテリーバックアップの追加 (2021/12/12追加)

RX8900チップにはバックアップバッテリの充電、VDD電圧の低下を検出してバッテリーに自動切換えする「電源切替機能」が搭載されています。

RX8900モジュールにはVDD~GND間(C1)とVBATT~GND間(C2)に0.1μFのコンデンサが入っているので、今回の試作ではVBATT端子に電気二重層コンデンサ(1.5F)と手持ちの抵抗(200Ω)を追加しました。

電気二重層コンデンサによるバッテリーバックアップ回路
電気二重層コンデンサによるバッテリーバックアップ回路
ArduinoとRTCモジュールRX8900を使ったLCD時計
ArduinoとRTCモジュールRX8900を使ったLCD時計。抵抗には手持ちの200Ω、1Wを使っていますが1/4Wで良いです。

スケッチ3:LCD表示、バッテリーバックアップ対応 (2021/12/17修正)

スケッチ2「RX8900RTC_TimeSet.ino」のシリアルポート出力部分をLCDモジュールへの出力に変更しました。

時刻設定にはArduino DS3232RTC Library sample sketchのcompileTime()を利用させていただきました。「add fudge factor to allow for compile time」とあるように正確な時刻設定には微調整が必要です。

電気二重層コンデンサ によるバッテリーバックアップが行われているので電源が復旧した際にスケッチ実行時刻:compileTimeに初期化されないように、RTC.getよりもcompileTimeが新しい時のみcompiletimeをRTC.setするように if 文を挿入しました。

ツェラー(Zeller)の公式を使って年月日から演算して曜日表示を追加。月、日、時、分、秒が0~9の1桁の場合、1桁目に 空白 もしくは 0 を追加して、右寄りの2桁で表示するように修正しました。

LCDモジュールのI2Cアドレスは0xa0。LCDモジュール用のI2Cライブラリは「構想100年」サイトの LcdCore_20120528.zip と LCD_ACM1602NI_20120528.zip を利用させていただきました。

[2021/12/17] 曜日の演算に不具合があったのでスケッチを修正しました。

RX8900RTC_TimeSet_LCD.ino
※ここをクリックするとコード表示を開閉できます。
#include <Arduino.h>
#include <Wire.h>            // Arduino IDE のI2Cライブラリ
#include <TimeLib.h>         // https://github.com/PaulStoffregen/Time
#include <RX8900RTC.h>       // https://github.com/citriena/RX8900RTC
#include <LcdCore.h>         // LCDコアライブラリ
#include <LCD_ACM1602NI.h>   // 秋月I2C液晶用のI/Oライブラリ

RX8900RTC RTC;
LCD_ACM1602NI lcd(0xa0);  // 0xa0は液晶モジュールのI2Cアドレス

void setup() {
Wire.begin();       // I2C初期化
lcd.begin(16, 2);   // ディスプレイの行数(16)と桁数(2)
RTC.init();         // RTC初期化
//RTC.get()よりcompileTime()が新しい時はcompiletimeをRTC.set
time_t time_now, compiletime;;
time_now = RTC.get();
compiletime = compileTime();
if (time_now < compiletime)
 {
RTC.set(compiletime);  // set compiled time to RTC
//tmElements_t tm = {0, 0, 12, 2, 5, 5, CalendarYrToTm(2020)}; // second, minute, hour, week, day, month, year
//RTC.write(tm);
 }
}

void loop() {
serialTime(RTC.read());
delay(1000);
}

// 秋月I2C液晶ディスプレイに表示
void serialTime(tmElements_t tm) {
//  年月日の表示
lcd.setCursor(0, 0);
lcd.print(tmYearToCalendar(tm.Year));
lcd.setCursor(4, 0);
lcd.print("/");
lcd.setCursor(5, 0);
lcdzeroSup(tm.Month);
lcd.setCursor(7, 0);
lcd.print("/");
lcd.setCursor(8, 0);
lcdzeroSup(tm.Day);
// 曜日の表示 0=日曜  1=月曜  2=火曜  3=水曜  4=木曜  5=金曜  6=土曜
int day_week ;
char DayWeekData[7][4] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"} ;
day_week = getDayWeek(tmYearToCalendar(tm.Year), tm.Month, tm.Day) ;
lcd.setCursor(11, 0);
lcd.print("(");
lcd.print(DayWeekData[day_week]) ;
lcd.print(")");
//時分秒の表示
lcd.setCursor(0, 1);
lcdzeroSup(tm.Hour);
lcd.setCursor(2, 1);
lcd.print(":");
lcd.setCursor(3, 1);
lcdzeroSup(tm.Minute);
lcd.setCursor(5, 1);
lcd.print(":");
lcd.setCursor(6, 1);
lcdzeroSup(tm.Second);
}

// 曜日の計算(ツェラー(Zeller)の公式)
int getDayWeek(int year,int month,int day) {
int w ;
if(month < 3) {
year = year - 1;
month = month + 12 ;
 }
w = (year + (year/4) - (year/100) + (year/400) + (13*month+8)/5 + day ) % 7;
return w;
}

// 月、日、時、分、秒が0~9の場合、1桁目を 空白 もしくは 0 に置換
void lcdzeroSup(int digit) {
if(digit < 10)
lcd.print(' ');   // 現在「空白」
lcd.print(digit);
}

// function to return the compile date and time as a time_t value
// from alarm_ex1.ino in Arduino DS3232RTC Library sample sketch by Jack Christensen.
time_t compileTime() {
const time_t FUDGE(10);    //fudge factor to allow for upload time, etc. (seconds, YMMV)
const char *compDate = __DATE__, *compTime = __TIME__, *months = "JanFebMarAprMayJunJulAugSepOctNovDec";
char compMon[4], *m;
strncpy(compMon, compDate, 3);
compMon[3] = '\0';
m = strstr(months, compMon);
tmElements_t tm;
tm.Month = ((m - months) / 3 + 1);
tm.Day = atoi(compDate + 4);
tm.Year = atoi(compDate + 7) - 1970;
tm.Hour = atoi(compTime);
tm.Minute = atoi(compTime + 3);
tm.Second = atoi(compTime + 6);
time_t t = makeTime(tm);
return t + FUDGE;        //add fudge factor to allow for compile time
}

電波時計モジュールで受信した日時データとRTCを同期させて時刻合わせ(2023/03/26追記)

今回のスケッチでは、起動時にArduino IDEのコンパイル時間を使って時刻合わせを行いました。このLCD時計に電波時計モジュールを追加することでJJY信号の日時情報を使ってPC接続なしで時刻合わせできました。
ビルやマンション内など電波を良好に受信できない環境では、疑似JJY電波を発生させるスマートフォンアプリを使っていつでも時刻合わせができます。

あわせて読みたい
ArduinoとRTCモジュールRX8900を使ったLCD時計の製作(2):電波時計モジュールで時刻合わせ 電波時計モジュールで受信したJJYタイムコードを復号した日時データとRTCモジュールRX8900を同期させて時刻合わせを行うLCD時計を作りました。ビル内など電波を良好に受...
よかったらシェアしてね!
  • URLをコピーしました!
目次