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

リアルタイムクロック DS1302 をArduinoで動かしてみる

このところリアルタイムクロック(RTC)をいろいろいじっています。その一環として DS1302 をAliexpress で買ったので動かしてみました。DS1302のデーターシートはこちら

▼Aliexpress から買った DS1302 モジュール AliExpressのRTC DS1302の販売ページ
DS1302モジュール

DS1302モジュール(裏面)
送料込みで1個 $0.41 と嘘みたいな値段です。
左側のモジュールには 5.5V/1F の電気二重層キャパシタをはんだ付けしています。右側のモジュールには普通にリチウム電池の CR2032 を入れています。

試しに動かす場合は、シリアルに時刻を表示させるのが手っ取り早いです。でもそれではあまり面白くないので、128x32 の OLED に日付と時刻を表示させるようにしてみました。また、時刻合わせも市販の時計と同じようスイッチで行えるようにしました。

▼回路図 (クリックで別窓のもう少し大きな図が開きます)
DS1302を使った回路
▼ブレッドボードの様子
ArduinoでRTC(DS1302)

▼プログラム
20190629RtcDS1302Test.txtのプログラム (Shift JISエンコードです)

DS1302 とのインターフェイスはライブラリなど使わずに、プログラムの中で直接やっています。とは言ってもシリパラ変換に shiftIn/shiftOut 関数を使っています。

OLED への表示は Adafruit_SSD1306 ライブラリを使っています。なお、0.96インチ128x64 画素の OLED に差し替えても、画面が縦に2倍に引き伸ばされるだけでそのまま動きます。

時計合わせは、clockAdjust() 関数から呼んでいる、oledRW() 関数で画面を使った数値の入力/表示を行っています。このプログラムはいろいろなシーンで使えると思います。というか、元になったプログラム(関数)を作ったのはかなり前で、それ以来色々なところで便利に使っています。

▼動作中の画面
128x32のOLEDに表示
見ての通り、年月日、時分秒を表示します。

▼時刻合わせ中の画面
時刻合わせ中

リセット時に Enter ボタンを押しておくことで、時刻合わせモードに入ります(Entボタンを押した状態で電源ON,あるいはリセットスイッチ押し、その後リセットボタンを離す)。入力可能な位置を下線で示すので、そこの値を、+、-ボタンで増減して設定します。値が決まったら Enter ボタンを押すことで次の項目へ移動します。分の台の値を入力した後の Enter ボタンの入力で、そのタイミングを 00秒とした時刻が設定されます。

なお、前の項目に戻る機能は無いので、値を入れ直したい場合はリセットして最初から入れ直します。数値の上限(下限)を超えた場合は下限(上限)にサーキュレートします。また、月の日数は厳密にチェックしていないので、2月31日などと入力出来ちゃいますが、その場合の動作は無保証です。

◆電池を入れて時刻合わせをしている様子


◆DS1302について
このRTCについて調べるといろいろな情報が出てきて混乱しますが、私なりに調べた結果は以下の通りです。

1) バックアップ用電池
充電可能な LIR2032 を使わないと電池が爆発する恐れがある、なんて話がありますが、そんなことはありません。CR2032を使っても大丈夫です。但し、もし 充電モード(トリクルチャージモード)が選択されている場合は、LIR2032などの充電可能な電池を使う必要があります。

なお、特に何も指定しないデフォルトの状態では、充電無しのモードになります(トリクルチャージモードにはなりません)。また、誤動作などでトリクルチャージモードに入ってしまうことを防止するために、ソフト的に簡単な鍵がかかっています。ということで、意図的にそういう設定を行った場合以外は CR2032 を使っても大丈夫です。

ちなみに、プログラムの33行目でコメントアウトしている、下記
// writeDS1302(0x90, 0xA5); // トリクルチャージしたい時に使う(1ダイオード,2kΩ)
のコメントアウトを外せばトリクルチャージモードになります。この記事の2枚目の写真の左側に写っている電気二重層キャパシタはこのモードで充電しました。

2) 電源ピンの名前
DS1302 には電源ピンが二つあり、Vcc1 と Vcc2 があります。ここでややこしいのは、データーシートでプライマリー電源と呼ばれているのは Vcc1 ではなく Vcc2 の方で、ここには電池を接続します。
あと、DC 電源のピンが1番ピンになっているのもちょっと変わっています(8ピンDIPなので普通なら電源ピンは8番です)。まあ信号名やピンアサインをどうしようと、メーカーの勝手ではありますが、

3) 電源供給の順序とその反応
ややこしいですが、順を追うと以下のような動きをします。

a. 電源 OFF の状態つまり、Vcc2 に電源が入っていなくても、Vcc1 に電池を接続すると 32.768kHz のオシレーターが発振し、内部の時計が動き始めるようです。ちなみに 2000年1月1日00時00分00秒から動き始めます。

b. この状態から電源を入れる(Vcc2 に電源を入れる)と RTC としてデーターを読み出すことが可能になります。この時オシレーターの端子 (X1, X2) の波形を見ていると、振幅が増すので、電源が切り替わっていることが判ります。これが普通に RTC として使っている状態になります。

c. この状態で電池を抜いても RTC は影響を受けずに動き続けます。(また、再度電池を入れても影響を受けず動き続けます)

d. 電池を抜いた状態で電源をOFFにする (Vcc2をOFFにする) と、電源が全部切れるので当然ですが RTC は動作停止します。不揮発なレジスタは無いはずなので、全設定がクリアされると思います。

e. その状態(電池を抜いた状態)で電源をONに(Vcc2 を ONに)すると、時計は2000年01月01日 00時00分00秒で停止したままの状態です。

f. さらに電池を入れても時計は停止したままです。つまり、電源も電池も入っているのに、なぜか時計は動かないという不思議な状態になります。

g. その状態で、一旦電源を OFF→ON (Vcc2 を OFF→ON )すると時計が動き始めます。たぶん電源 OFF にした時点で計時開始していると思います。

なんだかややこしいですが、電源 OFFの状態で電池を入れる、つまりプライマリー電源を先に入れることが時計を起動させる条件になっている感じです。プライマリー電源という名前はこういう挙動から名付けられているのかも知れません。というか、英語がネイティブの人にとっては、そんなことはあらためて説明するまでも無い話なのかも知れません。ともかく、電池が確実に接続されてから時計を動かして、ということでしょう。

【7/2追記】
MAXIMのAN https://pdfserv.maximintegrated.com/en/an/app82.pdfの Figure 2a and 2b の説明に 「電源を片方だけに繋ぐ時は、使わない方をGNDに接続しておいてね、」 という意味の記述があります。ということは、上記の c. と e. 項みたいに電池を外すのはやってはいけないことになります。
想像ですが、未使用電源ピンがオープンになっていると、チップ内の思わぬパスで電流が流れたりする恐れがあるので、GNDに落としといてね、ということでは無いかと思います。CMOSロジックの入力空き端子処理と同じと思っても良いかと思います。

ちなみに、ここの記述は電源が片側だけ供給されていても問題無く動くように誤解しそうです。でもMAXIM に言わせると、「そういう状態だと、時計かインターフェイス回路のどちらか片方しか動きません、あたりまえでしょ。そもそも、そのくだりにRTCとして正常に動くなんて、一言も書いてませんよ!キリッ」 ということなんだと思います。
--追記終わり--

▼DS1302搭載基板
DS1302モジュール拡大
もう一度基板の全体写真を示します。この基板にはパスコンが入っていないので、長い配線の先で使ったりするのは危ないと思います。ちなみに aitendo で売っている基板は、同社の web資料を見る限りではパスコンが入っていました。

◆まとめ
DS1302 は古いチップなので、もうあまり使われることは無いのかも知れません。ただ、かなり安いのでそれなりの出番は残っていそうです。そういう時にこの記事が何かの参考になれば幸いです。

RTC の時刻合わせを行うために、プログラムの中に固定値を埋め込んでおいてその内容を書き込む方法がよく行われます。このやり方は簡単ですが、設定内容を変更するためには再コンパイルしないといけないので面倒です。この記事のように単独で時刻設定が出来るプログラムを作っておくと、重宝すると思います。

DS1302 の電源を入れる過程を見ていて気付いたのですが、記事にも書いたように電池バックアップ時とDC電源動作時で水晶発振の振幅が変わっていました。こうなっていると、発振周波数にも少なからぬ影響があるはずで、時間精度を悪くする要因になりそうです。

手元により高性能なRTCである DS3231 があるので、同じようなプログラムを作ってみたいと思います。こちらは割込みが使えるのでもう少しちゃんとした時計が作れるはずです。
関連記事

コメントの投稿

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

No title

DS1302の電源回路、こういう風な順序で給電する必要があったんですね。ありがとうございます。

以前実験してみたときに、なぜか通信できるのにチクタクしない状態が発生して、理由が判らず困っていました。

https://brown.ap.teacup.com/nekosan0/3932.html

Vcc2、Vcc1の電圧はデータシートどおりにしているのに、ボタン電池を繋いだときはちゃんと動いて、5Vから3.3Vに降圧した場合は動かなくて困ってました。

一旦、Vcc2をLow→Highにしないといけないんですね。

Vcc2に通電中なら電池交換できるっていうのは、良く作られているなぁ、と思うのですが(データシートでは、禁忌事項になっているんですかね)、バックアップ電池を先にオンにしておく必要があるのは、ちょっとした落とし穴な気がしました。

バックアップ電池つけておかないとチクタクしないモードを、わざわざ搭載したのは何故なんでしょうね?(あまり、あってもうれしくないような気がして)

DS1302は、タイマ割り込みのトリガに使えないので、マイコン側をディープスリープにしておいて、必要なときだけ起こして動かす、みたいな使い方には向いてないので、一般的な用途なら、やっぱりDS3231を使うほうが便利ですね。クロック精度も普通の水晶ですしね。

nekosan0さん、おはようございます

記事を読んでいただいてありがとうございます。

実は以前nekosanの記事でDS1302が出て来たのを読んでました。バッテリー端子の電源供給方法によって動かないことがある話が不思議。だけど何をしたいんだろう?と思ってました。

今回改めて読んでみて、そうか電池使わずに動かそうとしていたのか、と意図を理解しました。

あと、DS3231の方がいろいろと機能が多くて便利ですね。こっちも今あれこれやっているので、まとまったら記事にする予定です。

No title

Arduinoのようなメモリの小さいマイコンでは、割り込み回数→日時分秒(+曜日)といった変換処理も軽くは無いので(特にメモリ量)、どうせaliexで数十円で手に入るモジュールがあるなら、そっちに負荷を回してしまえばいいや、などともくろんでいました。

DS3231も安いので、私も1個手に入れて色々弄ってみようかと思います。色々とご解説ありがとうございます。
助かります。

re:nekosan0

Arduino で時刻を扱いたい場合の模範解答はtime ライブラリを使うのでしょうが、いろいろ心配ですよね。それに、UNOだとセラロックなので、時計を作るなんて、やっちゃいけないレベルの話だと思います。

だったらRTCを使って、「今何時?」とやるのが簡単確実ですよね。
カレンダー
07 | 2019/08 | 09
- - - - 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 31
プロフィール

ラジオペンチ

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

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