google-site-verification: google3bd66dd162ef54c7.html
FC2ブログ

リアルタイムクロック DS3231 を使った ZS-042 というモジュールを調べる(その2)

前回に続いて DS3231 を使った RTC モジュールの ZS-042 の話です。

▼RTC のデーターを 0.96インチ OLED に表示
DS3231の内容をOLEDに表示
実験中の様子です。黄色と青のOLED に表示すると、なかなか綺麗です。

前の記事の最後に面白い調査結果があると書いたのですが、その話に入る前に基板の回路図を見ておきます。

▼ZS-042の回路図
ネットを探すとZS-042の回路図が見つかりますが、なんだか判り難かったです。ということで、接続状態が判り易いように書き直しました。もちろん現物の回路も追って確認しています。
ZS-042の回路図
以下しばらく、この回路図で話を進めて行きます。

◆バックアップ用バッテリの回路
バックアップ用のバッテリーは、上の回路図の右上に示すように DS3231 の Pin14 に直結されています。また、抵抗 (R1) とダイオードを通して充電されるようになっています。CR2032 のような一次電池を使う場合は、充電してはいけないので充電回路を切断する必要があります。この回路図で Charge Jumper と書いたのがその部分です。なお、実際にジャンパー用の部品がある訳では無く、この位置でパターンをカットします。

なお、Vcc = 3.3V で使うなら、ダイオードの電圧降下を考えると CR2032 はほとんど充電されないはずです。ということで、充電回路の改造はしなくても良いのではないかと思います。まあ、万一の状況(ダイオードのショート、電源電圧の異常上昇など)まで考えると、充電回路を殺しておいた方が安全ではあります。

▼充電回路のパターンカット
ZS-042のパターンカット
この写真の位置のパターンをカットしました。

◆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の基板
I2Cアドレスの状況
アドレスの 0x3C は OLED、0x57 はEEPROM、0x68 は RTC が見えているのでこれは正常です。なお、A0, A1, A2 のジャンパーをショートするとそれに応じて EEPROM のアドレスが変化することを確認しています。

▼AとCの基板
I2Cアドレスの状況-EEPROMのアドレスが変
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 も買ってあります。こちらもそのうちに調べてみたいと思います。

リアルタイムクロック DS3231 を使った ZS-042 というモジュールを調べる(その1)

面白いネタが入ったので記事で紹介します。Arduino でリアルタイムクロックをいくつか使ったことがありますが、これまでは秋月で買った物を使っていました。しかし、AliExpress だとえらく安く手に入るので試しに買ってみました。

▼DS3231 リアルタイムクロックモジュール (ZX-042)  AliExpress のこの商品のページはこちら
DS3231 @ aliexpress

ZS-042 という名前の基板で、RTC と32kシリアルEEPROM が入っています。EEPROM は特にいらないのですが、あれば何かに使えるでしょう。RTC の DS3231 の内部には水晶が入っていて、更に TCXO 付きという優れものです。これが $0.84 なんだからたまりません。まあこの値段で本物のチップを使っているとは思えないので、偽物なんでしょうが、とにかく面白そうなので買ってみました。

▼到着したZS-042モジュール
RTCモジュールZS-042
3個買ってみました。左からA,B,Cと呼ぶことにします。大きい方の16ピンのチップが RTC の DS3231 で、小さい方の 8 ピンのチップが EEPROM です。

この写真をよく見ると、Aの基板の DS3231 には方向を示す切り欠きが入っていますが、他の二つには入っていません。また、1番ピンを示すマークもAのチップだけ形が違っています。ということで、どうもAのチップはB,Cとは違う物のようです。ちなみにの違いに気付いたのは、もっと後になってからでした。

ともあれ回路を組んで動かしてみます。いろいろ確認するのに表示があった方がいいので、128x32 画素の OLED ディスプレイを付けました。

▼回路図
ZS-0402をArduinoへ接続する回路
(追記:この回路ではI2Cバスの信号レベルは DS3231は5V、OLEDは3.3Vと違っているので、直結するのはちょっと問題がありました。)
どちらも I2Cインターフェイスなので配線は簡単です。

なお、この基板にはバックアップ用に CR2032 のコイン電池を取り付けていますが、オリジナルの回路だと、電池が充電されてしまうので、充電回路の配線をパターンカットしています。このあたりの話はまた別の記事で紹介予定です。

▼動かしている様子
ZS-0402の動作テスト
この写真の OLED は128x32 画素のものですが、0.96インチの128x64 画素の OLED でもソフトの修正なしでそのまま動きます。この場合、縦方向が2倍に拡大されて画面いっぱいに表示されるので、見易いかも知れません。

▼ソフト
DS3231 というライブラリを使いました。ちなみに、このライブラリのようにデバイスの名前をそのままライブラリ名に使うやり方は嫌いなのですが、最初に試して問題無く動いたのでとりあえず使っています。
Rinky-Dink Electronix の Kibrary:DS3231のページはこちら、ここにあるマニュアルのページが秀逸です。github には多くのソフトが登録されていますが、このライブラリのようにマニュアルがきちっと書かれているものは少ない感じで、いつも残念に思っています。(きちっと書かれたマニュアルはあるけど、私がその置き場所を知らないだけかも知れません)

話を戻して、テストに使ったプログラムは以下の通りです。
// DS3231 test

#include <DS3231.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

DS3231 rtc(SDA, SCL); // DS3231の設定

String ymd = "yyyy/mm/dd";
String hms = "hh:MM:ss";
float rtcTemp;

void setup() {
Serial.begin(115200);
rtc.begin();
rtc.setSQWRate(SQW_RATE_1); // 1秒パルスを、
rtc.setOutput(OUTPUT_SQW); // SQWピンに出力
rtc.enable32KHz(true); // 32kHz出力も出す

if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // アドレスス 0x3C (0x78)
for (;;); // だめならここで停止
}
oled.setTextColor(WHITE); // 白文字で描く

// RTCに値をセット(時刻合わせで使用)
// rtc.setDOW(WEDNESDAY); // Set Day-of-Week to SUNDAY
// rtc.setTime(17, 8, 0); // Set the time to 12:00:00 (24hr format)
// rtc.setDate(24, 6, 2019); // Set the date to January 1st, 2014
}

void loop() {
ymd = rtc.getDateStr(FORMAT_LONG, FORMAT_BIGENDIAN, '/'); // 年月日をyyyy/mm/dd 形式で取得
hms = rtc.getTimeStr(FORMAT_LONG); // 時刻を hh:mm:dd 形式で取得
rtcTemp = rtc.getTemp(); // 温度を取得

Serial.print(ymd); Serial.print(", "); // シリアルに出力
Serial.print(hms); Serial.print(", temp=");
Serial.println(rtcTemp);

oled.clearDisplay(); // 0.96インチOLEDに表示
oled.setCursor(0, 0);
oled.setTextSize(1);
oled.print(ymd); // 年月日表示
oled.print(" Temp:");
oled.println(rtcTemp, 1); // 温度表示
oled.setCursor(12, 15);
oled.setTextSize(2); // 倍角で、
oled.println(hms); // 時刻表示
oled.display();

delay (1000); // ここは割り込みにしたいところ
}
OLEDへの表示もやっているので少しごちゃごちゃしていますが、順番に処理しているだけなので難しいところはありません。

▼動作状態
OLEDの表示
年月日と時分秒以外に温度測定機能があるのでその値も画面右上に表示させています。

ここまで動けば、めでたしめでたしです。せっかく TCXO が付いているのでその実力を見たくなって、時計の精度を測定してみました。

32K のピンに水晶オシレーターの出力の 32.768kHz が出ているので、この周波数。あと、1Hz の信号が SQWピンから出ているのでその周波数も確認してみます。

まずはAの基板から、

▼Aの基板の32K出力
32768Hzで合っている 周期はほぼ1秒
左が 32K ピンで水晶の発振周波数、右が SQW ピンから出ている 1Hz 信号の周波数です。なお、周波数カウンタの上に乗っているのはルビジウムオシレーターで、今回の測定では正確を期すために基準クロックをここから供給しました。ちなみに確度は10桁以上あるはずです。

目標値である 32.768Hz に対し、測定結果は 32.767987kHz で、その差は -0.013Hz です。これは僅か 0.4ppm の誤差しかないことになります。念のために 1Hzパルスの周波数を測定したのが上の右側の写真で、こちらの誤差も -0.39ppm となっています。流石は TCXO です。この測定結果から計算すると、月差は1.01秒となり、すばらしい精度です。

この結果に気を良くしてBの基板を測定してみると、、、

▼Bの基板の測定結果
周波数が異常に低い なのに周期はほとんど合っている
あらら、周波数が 135Hz もズレています。誤差に換算すると 0.4% もずれている訳で、とてもじゃないけど時計として使える精度ではありません。これだったら機械式の安物の時計の方がずっとマシです。

こりゃまいった、ゴミを掴まされたかと思ったのですが、念のために 1Hz の出力を見たのが上の右の写真です。これはパルスの周期を測っている写真ですが、その値は 1.0000026 秒です。つまりこちらの誤差は 2.6ppm で、月差に換算すると 6.7 秒で、まずまずの精度です。

◆ここまでのまとめ
Aの基板の測定結果はすごく納得できるのですが、問題はBの基板です。水晶の周波数がめちゃめちゃズレているのに、時計としては問題無い精度で動いています。実はCの基板も同じでした。

本来の DS3231 の回路ならこんなことはあり得ないので、中で何らか細工がしてあってこういう結果になっているのだと思います。つまり偽物であることは間違いなさそうです。

偽物ではありますが、時計として普通に使っている限りは問題が出ない(バレない)ように作られている感じです。周波数をぴったり 32.768 kHzに合わせた水晶振動子を作るのは大変、つまりコストがかかりますが、ここは適当に作っておいてソフト的に?補正している気がします。中華な偽物メーカー、なかなかやるものです。

まだ面白い調査結果があるのですが、長くなったので次の記事にまわすことにします。
カレンダー
05 | 2019/06 | 07
- - - - - - 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 - - - - - -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード