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

リアルタイムクロック 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に合わせた水晶振動子を作るのは大変、つまりコストがかかりますが、ここは適当に作っておいてソフト的に?補正している気がします。中華な偽物メーカー、なかなかやるものです。

まだ面白い調査結果があるのですが、長くなったので次の記事にまわすことにします。
関連記事

コメントの投稿

管理者にだけ表示を許可する

こりゃ面白い

なるほど!
水晶発振周波数の追い込みは置いといて、別の方法で補正すると・・・なんと強引!
温度変化や電源電圧変動に対する挙動も気になります。

「まだ面白い調査結果」を楽しみにしておきます。

re:こりゃ面白い

なんだか予想外のことがやられていて、面白いです。

ちなみに、この記事の回路図のARDUINO_UNOの部品は以前そちらのサイトから頂いたもので、コンパクトにまとまっているので重宝させて頂いてますす。
入力する時に居酒屋ガレージ店主さんを思い出しましたです。
カレンダー
08 | 2019/09 | 10
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コード