PR

Arduino UNO R4 MinimaのRTCはどのくらいいい加減か?

Arduino UNO R4にはRTCが載っているけれど、精度が悲惨。1分で1秒くらいズレる。原因は、時計用のクリスタルを載せていないため。CPU内蔵の発振器をRTCでも使っているので、時計として使えるレベルじゃない。ついでにいうと、バックアップ電池も実装していない。RTCはあっても使い物にはならない。このあたりの話は、トラ技2024年1月号にも書いた。

今回、外付けのRTCモジュールを入手したので、それとArduino UNO R4 Minima内蔵のRTCを比べてみることにした。外付けRTCモジュールはDS3231というチップを使ったもので、マイコンとの接続はI2C。広く使われているスタンダードのなものらしい。

他のタイプもある。

いずれもとても安価なのだけど、それゆえ偽物も少なくないようでやや不安ではあるが。

では、実際に両者の比較。

やることは、Arduino UNO R4内蔵のRTCとDS3231で、同時に計時を始めて両者の差を求めて表示する。

接続は上の写真のように、RTCモジュールとLCDモジュールをI2Cのラインにつないだだけ。両方のモジュールにI2Cのプルアップ抵抗が入っているような気がして、ちょっと不安ではあるけれど、動いているので良しとする。

LCDの表示内容は、上がArduino UNO R4内蔵のRTC、下がDS3231モジュール。右端が両者の差。DS3231の方を基準にした(Arduino UNO R4内蔵RTCはいい加減なことはわかっているので)。

RTCではあるけれど、現在時刻ではなくて、00:00:00をセットしてスタートさせる。これだと経過時間を示してくれることになってわかりやすい。

まず、起動から1分後。Arduino UNO R4内蔵のほうが1秒ほど進んでいる。

このあと、時間が経つと両者の差がどんどん開く。

8時間20分後、つまり、500分後には528秒進んだという結果。概ね1分で1秒ほど進んでいる。

その後、現在時刻を設定して様子を見てみたところ、DS3231の方はわずかに遅れ気味のようなので、それを差し引く必要はありそう。ただ、一定していなくて、計測開始から数分で1秒くらい遅れていて、一時間経ってもやっぱり1秒くらい遅れているような状況。なので、先程のように8時間とかそれくらいだと数秒くらい遅れるかもしれない。時計としてはかなり問題だとは思うが、少なくともArduino UNO R4内蔵のものよりは遥かにマシ。← これは原因がわかった。この記事の下の方に追記

DS3231については、本物・偽物の問題以外に、使いこなしによっても精度がだいぶ変わるらしい。

今回は出来合いのモジュールを適当なワイヤでつないだだけなので、精度も良くないのかもしれない。

なお、今回使ったプログラムはこれ。

生成AIを使って作ったもの。私は「ああしてくれ、こうしてくれ」と指示しただけで、コードは1行も書いていない。こんな感じのやり取り。

中身は詳しくは見ていないけれど、実験に使えるレベルのものはこうやって作ってくれるのでものすごく楽。こうやって作ったプログラムの著作権ってどうなるんだろう?コーディングしたのは生成AIだけど、指示した(仕様を定義したとも言える)のは私。さて?

Arduino UNO R4の内蔵RTCの精度を上げるために、水晶を外付けするという方法(荒業)などもあるらしい。

どう考えても大変そうだし、ハードウェアの改造だけでなくてソフトウェアもいじらなきゃいけないようで面倒そう。結局のところ、Arduino UNO R4でも時計機能が欲しければ外付けRTCを使うのが現実的なようで。

せめて、CPUクロックにクリスタルを使ってくれていれば(UNO R3のように)。CPUクロックの精度が低いので、delay()やmills()の精度も当然悪い。


【追記】

DS3231が遅れているように見えている原因がわかった。スタートしたあと、割とすぐに実際の時刻から1秒くらい遅れた値が表示され、その後も1秒遅れが続いていた。24時間以上経過しても1秒遅れで、遅れが広がることもなかった。

プログラムを眺めていたら、一度表示したあと、1秒(1000ms)経過すると表示を更新するようになっていた。この1000msがmillis()で取得した経過時間を使って判定しているので、Arduinoのクロックに依存する。つまり、進み気味の計時。これを基準にDS3231の時刻を取得するとまだ前の秒数が得られるのは当然。そのため、「1秒遅れている」ように見える。具体的に言えば、実際には約983ms経過していないのに(1分で1秒進むのだから、(59/60)*1000=983ms)、その時点でDS3231の時刻を取得するため、まだ秒の単位では更新されていない値(前の秒数)が得られるということ。

プログラムを修正して、200ms経過ごとに表示を更新するようにしてみた。これで、DS3231による時刻は実際の時刻と一致した値が表示されるようになった。半日以上経過したところで遅れや進みはなく、割と良い精度の時刻が得られているようだ。


【追々記】互換機と言うか、同じプロセッサを使ったボードが出ているらしい。こちらはシステムクロック用のクリスタルと、RTC用のクリスタルも載っているようだ。


【さらに追記】RTCだけでなく、当然、CPUクロックも外付けクリスタルではなくてプロセッサ内蔵の発振器を使っている。そのため、時間が関係するものの精度はすべて悪い。

ジッタもかなりひどいようだ。

自作
この記事のタイトルとURLをコピーする
スポンサーリンク
スポンサーリンク
スポンサーリンク
スポンサーリンク
スポンサーリンク

コメント