リアルタイムクロック DS3231 を使った ZS-042 というモジュールを調べる(その2)
前回に続いて DS3231 を使った RTC モジュールの ZS-042 の話です。
▼RTC のデーターを 0.96インチ OLED に表示

実験中の様子です。黄色と青のOLED に表示すると、なかなか綺麗です。
前の記事の最後に面白い調査結果があると書いたのですが、その話に入る前に基板の回路図を見ておきます。
▼ZS-042の回路図
ネットを探すとZS-042の回路図が見つかりますが、なんだか判り難かったです。ということで、接続状態が判り易いように書き直しました。もちろん現物の回路も追って確認しています。

以下しばらく、この回路図で話を進めて行きます。
◆バックアップ用バッテリの回路
バックアップ用のバッテリーは、上の回路図の右上に示すように DS3231 の Pin14 に直結されています。また、抵抗 (R1) とダイオードを通して充電されるようになっています。CR2032 のような一次電池を使う場合は、充電してはいけないので充電回路を切断する必要があります。この回路図で Charge Jumper と書いたのがその部分です。なお、実際にジャンパー用の部品がある訳では無く、この位置でパターンをカットします。
なお、Vcc = 3.3V で使うなら、ダイオードの電圧降下を考えると CR2032 はほとんど充電されないはずです。ということで、充電回路の改造はしなくても良いのではないかと思います。まあ、万一の状況(ダイオードのショート、電源電圧の異常上昇など)まで考えると、充電回路を殺しておいた方が安全ではあります。
▼充電回路のパターンカット

この写真の位置のパターンをカットしました。
◆I2Cバスのレベル
I2C バスや 32K、SQW の信号は 4.7kΩの集合抵抗を使って Vcc にプルアップされています。ということは、Arduino UNO で使う時は 5V にプルアップされるので、信号レベルは 5V になります。もし0.96 インチの OLED を同時に使う場合、このデバイスの I2C バスは、4.7kΩの抵抗で 3.3V にプルアップされているので信号レベルは 3.3V です。つまりレベルが違うので、両者を直結するのはよろしくありません。なお状況は少し違いますが、このあたりの話は以前の記事で触れています。
うーん、実はこのことに今頃になって気付きました。前の記事の回路図では直結しているので、注意書きを追加しておきます。まあ試しに動かすくらいなら、たぶん大丈夫でしょう。
◆ちなみに、Raspberry Pi で使うなら
ネットを見ると、Raspberry PI でこの RTC を使う場合、「充電回路を外せ」、さらに「多重プルアップになるので RA-2 も外せ」なんて書いてある記事を見かけたことがあります。でも Raspberry Pi の電源電圧は 3.3V なので、上に書いたように CR2032 が充電されることはないはずです。それに、I2C のバスにプルアップ抵抗が複数存在、つまり多重プルアップになっても問題ありません。(合成抵抗が許容値以下になるなら話は別)。ということで、何もしなくて良いのではないかと思います。
◆特性測定結果
さて、お待ちかね?の特性の測定結果です。

3 個あるのでA,B,Cと名前を付け、それぞれの特性を表にまとめました。前の記事と重複する部分もありますが、順に見て行きます。
◆32Kの周波数
Aは理想値 (32.768kHz) に僅かな誤差があるだけで、ほぼぴったり合っています。
BとCの周波数には大きな誤差がありますが、これでも時計として問題無い精度で動くのが面白いところです。
◆SQWピンの周波数
仕様書によると、このピンは 1Hz、1024Hz、4096Hz、8192Hz をプログラムで切り替えて出力出来ることになっています。しかし、その通りに動作したのはAだけで、BとCはプログラムの設定にかかわらず1Hzだけが出力されていました。
BとCは水晶の発振周波数が正確ではないので、これを単純に分周しても正確な周波数にはなりません。ということで、(ボロ隠しのために) 1Hzだけを出力するような動作にしたのではないかと思います。まあ一番需要がありそうなのは 1Hz信号で、他はあまり使うことは無さそうなので、ほとんどの場合こういう動作でも困らないと思います。
ちなみにBとCは水晶の発振周波数は不正確ですが、1Hz はそこそこの精度で出力されています。ただ、この 1Hz 出力には微小なジッタがあり、周波数カウンタで見ていると値が少しバラついていました。たぶん内部でパルスの間引きや追加などの補正を行って、平均的には1Hz が出るような仕組みになっているのだと思います。
◆温度測定間隔
TXCO の補正用の温度計の値をインターフェイス側から読めるようになっています。その更新頻度(=温度測定頻度)は、表のように、Aは64秒で仕様書通り。BとCは何と 1秒になっていました。( RTC に触ると温度表示が1秒間隔で更新されます)
◆バッテリーからのバックアップ電流
Vcc が OFF の時にバッテリーから時計を動かし続けるため電流です。BとCは電流が多くAの2倍くらいになっています。またこれ以外に、1秒周期で 20μA くらいの電流が流れているようです(DMM の表示が一瞬ちらつく)。これは温度測定を行うために消費電流が増えているのだと思いますが、高頻度で温度測定を行うとバッテリーの寿命が短くなる可能性があります。そんなことで、BとCの基板のバッテリーバックアップ日数はAの半分以下になりそうです。
あと、動作時 (Vcc がONの時)に Pin14 からバッテリーへ流入する電流は、うちの DMM では測れないくらい小さな値でした。
▼バッテリー電流の測定

基板に実装されている電池ホルダでは測定がやり難いので、この写真のようにコイン電池を外付けして電流測定を行いました。
◆動作時の消費電流
これは ZS-042 全体の消費電流なので、LED やプルアップ抵抗で消費される電流がほとんどだと思います。ということであまり意味があるデーターではありません。
◆I2C アドレス
RTC のアドレスはどれも 0x68 になっていて問題ありません。しかし、EEPROM のアドレスが何だか変です。Bの基板は正常な値 (0x57) ですが、AとCは 0x50 から 0x5F の範囲で反応があります。
自作の I2C アドレススキャンプログラムで調べたのですが、具体的には以下のような結果になりました。
▼Bの基板

アドレスの 0x3C は OLED、0x57 はEEPROM、0x68 は RTC が見えているのでこれは正常です。なお、A0, A1, A2 のジャンパーをショートするとそれに応じて EEPROM のアドレスが変化することを確認しています。
▼AとCの基板

OLED (0x3C) とRTC (0x68) は良いのですが、EEPROM が 0x50 から 0x5F までのアドレスを占有しています。
私はシリアル EEPROM を使ったことが無いのでよく判りませんが、この状態は明らかにおかしいと思います。ちなみに、こうなる EEPROM のマーキングは、ATHYC382 と同じ番号になっているので、このあたりに何かヒントがありそうです。
◆まとめ
AliExpress で売っている DS3231 を使った格安の RTCモジュール、ZS-042 を調べてみました。なかなか面白い特性というか仕掛けになっていて楽しめました。水晶の周波数はいい加減な物を使い、回路(ソフト?)の工夫で正確な時計に仕立て上げるなんて、ちょっと思い付かないです。
ZS-042 の基板として見た場合、RTC が仕様通りに動いているのはAの基板だけでした。一方で EEPROM がちゃんと動いているのはBの基板だけでした。つまり両方ちゃんと動いている基板は無かった、という残念な結果でした。
まあ、ちょっと難点はあるけど RTC として使えなくは無いし、値段を考えれば仕方ないんでしょうね。中華なパーツを使う場合、これくらいのことは覚悟していないといけないんでしょう。
この RTC は TXCO になっているので、温度補正機能がうまく動いているか確認したかったのですが、そこまで手が廻りませんでした。指で触って温めると一旦周波数が変わり、その後引き戻すような動きをするので、温度補正が行われていることは間違いなさそうです。でも制御周期(温度測定間隔)が64秒と長いので、きちんと調べるのは大変そうです。
電源電圧に対する周波数の変動も調べてみましたが、こちらは目立った影響は無かったです。バッテリーバックアップ中は2.7Vくらいまで電源電圧が下がるので、そういう時でも大丈夫なように作ってあるのだと思います。
今回の調査で使った、プログラムはソフトで作った1秒周期のループでRTCを読みに行っていますが、ちゃんとやるなら割り込みでタイミングを合わせた処理にすべきです。ということで、時間のある時に作り直してみたいと思います。
あと、これ以外に格安の RTC ということで、DS1302 も買ってあります。こちらもそのうちに調べてみたいと思います。
▼RTC のデーターを 0.96インチ OLED に表示

実験中の様子です。黄色と青のOLED に表示すると、なかなか綺麗です。
前の記事の最後に面白い調査結果があると書いたのですが、その話に入る前に基板の回路図を見ておきます。
▼ZS-042の回路図
ネットを探すとZS-042の回路図が見つかりますが、なんだか判り難かったです。ということで、接続状態が判り易いように書き直しました。もちろん現物の回路も追って確認しています。

以下しばらく、この回路図で話を進めて行きます。
◆バックアップ用バッテリの回路
バックアップ用のバッテリーは、上の回路図の右上に示すように DS3231 の Pin14 に直結されています。また、抵抗 (R1) とダイオードを通して充電されるようになっています。CR2032 のような一次電池を使う場合は、充電してはいけないので充電回路を切断する必要があります。この回路図で Charge Jumper と書いたのがその部分です。なお、実際にジャンパー用の部品がある訳では無く、この位置でパターンをカットします。
なお、Vcc = 3.3V で使うなら、ダイオードの電圧降下を考えると CR2032 はほとんど充電されないはずです。ということで、充電回路の改造はしなくても良いのではないかと思います。まあ、万一の状況(ダイオードのショート、電源電圧の異常上昇など)まで考えると、充電回路を殺しておいた方が安全ではあります。
▼充電回路のパターンカット

この写真の位置のパターンをカットしました。
◆I2Cバスのレベル
I2C バスや 32K、SQW の信号は 4.7kΩの集合抵抗を使って Vcc にプルアップされています。ということは、Arduino UNO で使う時は 5V にプルアップされるので、信号レベルは 5V になります。もし0.96 インチの OLED を同時に使う場合、このデバイスの I2C バスは、4.7kΩの抵抗で 3.3V にプルアップされているので信号レベルは 3.3V です。つまりレベルが違うので、両者を直結するのはよろしくありません。なお状況は少し違いますが、このあたりの話は以前の記事で触れています。
うーん、実はこのことに今頃になって気付きました。前の記事の回路図では直結しているので、注意書きを追加しておきます。まあ試しに動かすくらいなら、たぶん大丈夫でしょう。
◆ちなみに、Raspberry Pi で使うなら
ネットを見ると、Raspberry PI でこの RTC を使う場合、「充電回路を外せ」、さらに「多重プルアップになるので RA-2 も外せ」なんて書いてある記事を見かけたことがあります。でも Raspberry Pi の電源電圧は 3.3V なので、上に書いたように CR2032 が充電されることはないはずです。それに、I2C のバスにプルアップ抵抗が複数存在、つまり多重プルアップになっても問題ありません。(合成抵抗が許容値以下になるなら話は別)。ということで、何もしなくて良いのではないかと思います。
◆特性測定結果
さて、お待ちかね?の特性の測定結果です。

3 個あるのでA,B,Cと名前を付け、それぞれの特性を表にまとめました。前の記事と重複する部分もありますが、順に見て行きます。
◆32Kの周波数
Aは理想値 (32.768kHz) に僅かな誤差があるだけで、ほぼぴったり合っています。
BとCの周波数には大きな誤差がありますが、これでも時計として問題無い精度で動くのが面白いところです。
◆SQWピンの周波数
仕様書によると、このピンは 1Hz、1024Hz、4096Hz、8192Hz をプログラムで切り替えて出力出来ることになっています。しかし、その通りに動作したのはAだけで、BとCはプログラムの設定にかかわらず1Hzだけが出力されていました。
BとCは水晶の発振周波数が正確ではないので、これを単純に分周しても正確な周波数にはなりません。ということで、(ボロ隠しのために) 1Hzだけを出力するような動作にしたのではないかと思います。まあ一番需要がありそうなのは 1Hz信号で、他はあまり使うことは無さそうなので、ほとんどの場合こういう動作でも困らないと思います。
ちなみにBとCは水晶の発振周波数は不正確ですが、1Hz はそこそこの精度で出力されています。ただ、この 1Hz 出力には微小なジッタがあり、周波数カウンタで見ていると値が少しバラついていました。たぶん内部でパルスの間引きや追加などの補正を行って、平均的には1Hz が出るような仕組みになっているのだと思います。
◆温度測定間隔
TXCO の補正用の温度計の値をインターフェイス側から読めるようになっています。その更新頻度(=温度測定頻度)は、表のように、Aは64秒で仕様書通り。BとCは何と 1秒になっていました。( RTC に触ると温度表示が1秒間隔で更新されます)
◆バッテリーからのバックアップ電流
Vcc が OFF の時にバッテリーから時計を動かし続けるため電流です。BとCは電流が多くAの2倍くらいになっています。またこれ以外に、1秒周期で 20μA くらいの電流が流れているようです(DMM の表示が一瞬ちらつく)。これは温度測定を行うために消費電流が増えているのだと思いますが、高頻度で温度測定を行うとバッテリーの寿命が短くなる可能性があります。そんなことで、BとCの基板のバッテリーバックアップ日数はAの半分以下になりそうです。
あと、動作時 (Vcc がONの時)に Pin14 からバッテリーへ流入する電流は、うちの DMM では測れないくらい小さな値でした。
▼バッテリー電流の測定

基板に実装されている電池ホルダでは測定がやり難いので、この写真のようにコイン電池を外付けして電流測定を行いました。
◆動作時の消費電流
これは ZS-042 全体の消費電流なので、LED やプルアップ抵抗で消費される電流がほとんどだと思います。ということであまり意味があるデーターではありません。
◆I2C アドレス
RTC のアドレスはどれも 0x68 になっていて問題ありません。しかし、EEPROM のアドレスが何だか変です。Bの基板は正常な値 (0x57) ですが、AとCは 0x50 から 0x5F の範囲で反応があります。
自作の I2C アドレススキャンプログラムで調べたのですが、具体的には以下のような結果になりました。
▼Bの基板

アドレスの 0x3C は OLED、0x57 はEEPROM、0x68 は RTC が見えているのでこれは正常です。なお、A0, A1, A2 のジャンパーをショートするとそれに応じて EEPROM のアドレスが変化することを確認しています。
▼AとCの基板

OLED (0x3C) とRTC (0x68) は良いのですが、EEPROM が 0x50 から 0x5F までのアドレスを占有しています。
私はシリアル EEPROM を使ったことが無いのでよく判りませんが、この状態は明らかにおかしいと思います。ちなみに、こうなる EEPROM のマーキングは、ATHYC382 と同じ番号になっているので、このあたりに何かヒントがありそうです。
◆まとめ
AliExpress で売っている DS3231 を使った格安の RTCモジュール、ZS-042 を調べてみました。なかなか面白い特性というか仕掛けになっていて楽しめました。水晶の周波数はいい加減な物を使い、回路(ソフト?)の工夫で正確な時計に仕立て上げるなんて、ちょっと思い付かないです。
ZS-042 の基板として見た場合、RTC が仕様通りに動いているのはAの基板だけでした。一方で EEPROM がちゃんと動いているのはBの基板だけでした。つまり両方ちゃんと動いている基板は無かった、という残念な結果でした。
まあ、ちょっと難点はあるけど RTC として使えなくは無いし、値段を考えれば仕方ないんでしょうね。中華なパーツを使う場合、これくらいのことは覚悟していないといけないんでしょう。
この RTC は TXCO になっているので、温度補正機能がうまく動いているか確認したかったのですが、そこまで手が廻りませんでした。指で触って温めると一旦周波数が変わり、その後引き戻すような動きをするので、温度補正が行われていることは間違いなさそうです。でも制御周期(温度測定間隔)が64秒と長いので、きちんと調べるのは大変そうです。
電源電圧に対する周波数の変動も調べてみましたが、こちらは目立った影響は無かったです。バッテリーバックアップ中は2.7Vくらいまで電源電圧が下がるので、そういう時でも大丈夫なように作ってあるのだと思います。
今回の調査で使った、プログラムはソフトで作った1秒周期のループでRTCを読みに行っていますが、ちゃんとやるなら割り込みでタイミングを合わせた処理にすべきです。ということで、時間のある時に作り直してみたいと思います。
あと、これ以外に格安の RTC ということで、DS1302 も買ってあります。こちらもそのうちに調べてみたいと思います。