Arduino 入門
Lesson 50
【Real Time Clock モジュール その1】
こにんちは、管理人のomoroyaです。
センサーの使い方の基本を学習する入門編。
世の中には、まだまだ色々なセンサーがあります。
これからも、色々なセンサーで遊んでいきます。
本記事はLesson 50 【Real Time Clock モジュール】です。
実は脈拍・心拍センサ その4を考えていたのですが急遽変更。
その4では、コロナで話題の「血中酸素飽和度を測定できるセンサ」を解説する予定でした・・・。
しかし、手元にある購入した電子部品が外れ。
実装されているチップコンデンサが隣のチップコンデンサとショートしていて使い物にならず。
ということで、【Real Time Clock モジュール】に変更です。
Real Time Clock(リアルタイムクロック)とは?
※以下、RTCと記載
RTCとは、時刻を告げることを目的とした電子デバイスが搭載されている時計。
その機能を実装したIC(集積回路)のことを言っています。
パソコンのマザーボードに電池がついていますよね。
あの部分と同じです。
あれは、電源の供給がなくなっても電池があることで正確に時間を刻んでいます。
ところが、どっこい各種電子機器に通常搭載されているRTCの機能がArduinoにはありません。
そのため、時計を使いたい場合にはRTCモジュールが必要。
その機能を果たす電子部品が「Real Time Clock モジュール」となります。
本Lessonで使用する「Real Time Clock モジュール」は以下が同等品となります。
※搭載IC:DS1302 prime対応品 出荷元:Amazon
電池はCR2032 をご用意ください
Arduino入門編の解説にて使用しているArduinoは互換品です。
互換品とは言え、Arduinoはオープンソースであり複製して販売するのもライセンス的に問題なし。
そのため互換品の品質も悪くなく、それでいて値段は安いです。
正規品本体の値段程度で豊富な部品が多数ついています。
正規品(Arduino UNO R3)の本体単品がほしい方はこちらとなります。
Arduino入門編2では「Arduino UNO R4 Minima」「Arduino UNO R4 WIFI」にて遊ぶため今のところは正規品を使用。(まだ互換品が・・・ほぼない)
はじめに
本Lessonで使用する「Real Time Clock モジュール」は「DS1302 IC」の動作を理解する必要があります。
「DS1302」はの」ICには下記に示す時間のデータが格納されたレジスタ(各8bit)が存在します。
上位4ビットと下位4ビットに分割し、各4ビットで0~9を表現。
そのため、8bitで00~99通りを表現できるようになっています。
- 秒レジスタ:00~59
- 分レジスタ:00~59
- 時レジスタ:01~12(12時間制)/00~23(24時間制)
- 日レジスタ:01~31
- 月レジスタ:01~12
- 曜日レジスタ:1~7
- 年レジスタ:00~99
- ライトプロテクトレジスタ
要は、
- ArudinoでICを制御する
- 上記レジスタに格納されている値をArduinoで受け取ってシリアルモニタで表示
させるということです。
ちなみに、シリアルモニタではなくLCDなどへ表示させれば電子時計のできあがりです。
言うは易しです。
このレジスタ値を読むスケッチ描くのは大変そうだ・・・と思いますが。
そこは、Arduinoの良いところ「library」を使って手を抜いてしまいましょう。
世の中、さがせば有志の方々が作ってくれたLibraryが転がっています。
時間があれば、libraryを使わないで学習するのもあり。
そこは、好みです。
興味のあるかたはデータシートをお読みください。
秋月電子で「DS1302」を検索するれば閲覧可能です。
もしくは、直接メーカーページを確認。(※メーカーページでDS1302で検索)
Lesson 50 目標
本Lessonの目標は以下です。
2.RTCモジュールから日時を取得するスケッチを描く
3.RTCモジュールで遊ぶ
いつものように、遊ぶことが重要です。
今回のセンサ、ライブラリを使えばスケッチは簡単。
ただし動作の理屈を理解するためにはデータシートを読み込む必要があり!
回路がわからなくても遊べる、使える、作れるのがArduino の良いところ。
もちろん、データシート読めなくても遊べます。
準備
ではLessonの準備に取り掛かりましょう。
部品は「RTCモジュール」のみ。
LCDに日時を表示させたい場合は、LCDも追加で準備。
必要なもの
- USB接続用のPC(IDE統合環境がインストールされたPC)
→管理人が勝手に比較したBTOメーカーを紹介しています。 - UNO R3(以下UNO)、おすすめUNO互換品(ELEGOO)
- PCとUNOを接続するUSBケーブル
- ブレッドボード安価(大)、ブレッドボード安価(中)
※おすすめブレッドボード(大)、おすすめブレッドボード(中) - RTC リアル タイム クロック モジュール
- M-M Jumper wire(UNOと部品をつなぐための配線)
- M-F Jumper wire(UNOと部品をつなぐための配線)
※ブレッドボードはセンサとUNOを直接つなぐ場合不要です。
※ジャンパワイヤーは「M-M」「M-F」を必要に応じて使い分けてください。
Jumper wire、抵抗は今後も頻繁に利用します。
Jumper wireはできれば、「オス-メス オス-オス メス –メス」の3種類を揃えておくことをお勧めします。
短めが使いやすい場合も。
抵抗も単品で揃えるよりはセットをおすすめします。
抵抗、LEDなどを個別でセット品を購入しても、そんなに使わない!
という方は、「電子工作基本部品セット」が使い勝手が良い。
使用部品説明
「RTCモジュール」のモジュールについて説明していきます。
※RTC:Real Time Clock(リアル タイム クロック)
RTCモジュール「DS1302」 実物写真
下の写真が「RTCモジュール」の実物写真です。
本Lessonで使用するものは、回路が基板実装されたもの。
「DS1302 IC」「水晶振動子」「電池フォルダー」で構成されています。
- 水晶振動子:32.768kHz
- 供給電源:2.0V~5.5V
- 電池フォルダー:CR2032
RTCモジュール「DS1302」 仕様
RTCモジュールの仕様は、DS1302 ICの仕様ということになります。
データシートに記載されていますので詳細はそちらをご確認ください。
ここでは、重要箇所のみ紹介します。
■「DS1302」のピン配置
■PIN仕様
Pin No. | Pin Name | Function |
---|---|---|
1 | VCC2 | デュアル電源構成のプライマリ電源ピン VCC1またはVCC2の大きい方で動作 VCC2 > VCC1 + 0.2V:VCC2電力供給 VCC2 < VCC1 :VCC1電力供給 ※モジュールのVCCピンがVCC2 |
2 | X1 | 水晶振動子の接続 ※32.768kHz |
3 | X2 | |
4 | GND | グランド |
5 | CE | 入力ピン:read/write時にHighにする プルダウン抵抗付き(40kΩ) ※モジュールのRSTピンがCEピン |
6 | I/O | 入出力ピン(出力はプッシュプル) プルダウン抵抗付き(40kΩ) ※モジュールのDATピンがI/Oピン |
7 | SCLK | 入力ピン シリアルインターフェースの同期用のクロック プルダウン抵抗付き(40kΩ) ※モジュールのCLKピンがSCLKピン |
8 | VCC1 | バックアップ用の電源:CR2302(3V)供給 主電源がない場合に時刻と日付を維持 |
■レジスタアドレス(レジスタマップ)
最初の8bitにてRead/Writeのコマンドを指定します。
次の8bitはデータの読み出し、書き込みのビットになります。
データ8bitは上位4ビット、下位4ビットに分かれており、各4ビットで0~9までの10進数で表現されます。
よって、表現できる数値は00~99となります。
■Read動作
- 読み出したいデータのREADアドレスを指定しデータbitを読み出す
- シリアルモニタに日時を表示させる
■Write動作
- 書き込みたいデータのWriteアドレスを指定しデータを書き込む
READ | WRITE | BIT | RANGE | |||||||
---|---|---|---|---|---|---|---|---|---|---|
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
81h | 80h | CH | 10s | s | 00 – 59 | |||||
83h | 82h | 10m | m | 00 – 59 | ||||||
85h | 84h | 12/24 | 0 | 10 am/pm |
h | h | 1 – 12/0 -23 | |||
87h | 86h | 0 | 0 | 10 d | d | 1 -31 | ||||
89h | 88h | 0 | 0 | 0 | 10m | m | 1 – 12 | |||
8Bh | 8Ah | 0 | 0 | 0 | 0 | 0 | day | 1 – 7 | ||
8Dh | 8Ch | 10y | y | 00 – 99 | ||||||
8Fh | 8Eh | WP | 0 | 0 | 0 | 0 | 0 | 0 | 0 | – |
91h | 90h | TCS | TCS | TCS | TCS | DS | DS | DS | DS | – |
※s:秒、m:分、h:時間、d:日、m:月、y:年、day:曜日
■バッテリバックアップ付きRAM
31バイトのRAMが搭載されています。
記録用?とかでしょうか・・・。
■READ/WRITE
以下の読み出し、書き込みのモードがあります。
- シングルバイトリード
- シングルバイトライト
- バーストモード
詳細はデータシートにタイミングチャートが記載されていますのでご確認ください。
ここの動作を理解すれば、ライブラリを使わずにスケッチを描くことができます。
スケッチでDS1302のRead/Writeを制御するためには「shiftOut関数」がとて便利です。
今一度、復習しておきましょう!
実践 回路作成とコード作成
本Lessonでは、「ライブラリ」を使用したスケッチと使わないスケッチに挑戦したいと考えます。
まずは、「ライブラリ」を使用したスケッチから。
最初に回路図を確認してください。
次に、回路図に合わせて部品を接続します。
最後にコードを書いて、RTCモジュールを動かしていきましょう。
Arduinoのピン配置を確認したい方は番外編02を参照してください。
回路図
「DS1302」が実装されたモジュール端子を接続していきます。
Arduinoはデジタル入出力ピンの8、9、10を使用。
あとは、5VとGNDのみ。
回路図がこちら。
こちらがブレッドボード図。
回路図は「fritzing」を利用しています。
「fritzing」の使い方は下記を参照してください。
接続
下図に示すように、用意した部品を使用して接続しましょう。
部品は「RTCモジュール」のみとなります。
※DS1302が実装されたモジュール
部品は1個、接続は簡単です。
「RTCモジュール」と接続するジャンパーワイヤーはF-Mを使用してます。
そのため、ブレッドボードもいりません。
使用するポートは、デジタル入出力ピンの8、9、10、5V、GND。
穴に挿入しづらいときは、ラジオペンチなどを使用してください。
コードの書き込み
接続が終わったら、USBケーブルを使用してUNOにプログラムを書き込んで行きましょう。
コードを書き終えたら、いつでも利用できるように「ファイル」⇒「名前を付けて保存」で保存しておきましょう。
コマンド説明1 ライブラリ使用あり
サンプルコード1では、「ライブラリ」を使用します。
使いやすい、ライブラリがありましたのでこちらを使います。
下記からダウンロードしてzip形式のライブラリをインストールしてください。
Code -> Download ZIP でダウンロードできます。
https://github.com/msparks/arduino-ds1302
ライブラリについて知りたい方は下記を参照ください。
サンプルコード1 ライブラリ使用あり
まずは、「ライブラリを使ったサンプルコード」です。
ダウントードしたライブラリに一緒にサンプルが梱包されています。
ファイル -> スケッチ例 -> arduino-ds1302-master -> set_clock
で遊ぶことができます。
本Lessonの回路図はデジタル入出力ピンの8、9、10を使用しています。
本Lessonの回路図結線を利用する場合は、スケッチのピン定義を8,9,10に修正ください。
const int kIoPin = 9; // Input/Output
const int kSclkPin = 8; // Serial Clock
また、スケッチの中に下記の記載があります。
合わせたい時刻に下記を設定すれば、その時刻から時計が刻まれます。
Time t(2021, 4, 10, 23, 20, 30, Time::kSaturday);
サンプル例になりますのでスケッチは省略します。
※掲載して良いかわからなかったので・・・。
サンプルコード1 動作確認
では、さっそく動作を確認していきます。
シリアルモニタに下記のように時刻が表示されます。
■時刻の表示
コマンド説明2 ライブラリ使用なし
サンプルコード2では、データシートを理解してライブラリを使わずにスケッチを描くことに挑戦。
これまで学習してきた、関数しか使わないため新しいコマンドはありません。
データーシートのアドレスマップ、タイミングチャート、Readモードを理解することが重要になります。
そこまでは、という場合はすっ飛ばしてください。
ライブラリを使ったスケッチで十分に色々な用途に応用可能です。
ライブラリを使わずにRead/Writeを制御するためには「shiftOut関数」がとて便利です。
サンプルコード2 ライブラリ使用なし
ライブラリを使用せずに日時を書き込み、読み出すスケッチになります。
書き込み部分、読み出し部分は関数化しています。
■Single-Byte Writeモード部分を関数化
この部分で、日時の初期値設定をするようにしています。
void s_b_write(int command, int data){
~
}
■Single-Byte Readモード部分を関数化
この部分で、レジスタに格納されている日時を読み出しています。
int s_b_read(int command){
~
}
■その他 補足
上記をふまえて、下記サンプルスケッチを確認ください。
データシートを理解することができるかどうか?が重要です。
//Lesson 50 RTCモジュール(Real Time Clock Module) //RTCモジュールの制御(ライブラリ使用なし) //https://omoroya.com/ // ピン番号の設定 const int clkPin = 8; //DS1302:SCLKピン const int datPin = 9; //DS1302:I/Oピン const int rstPin = 10; //DS1302:CEピン // Single-Byte Write関数 「時刻の初期値設定」 void s_b_write(int command, int data){ pinMode(datPin,OUTPUT); //DAT(I/O)のOUTPUT指定 digitalWrite(clkPin, LOW); //クロック "L" L始まりを確定させるため digitalWrite(rstPin, HIGH); //RSTピン(CE) "H" アクセスを許可 shiftOut(datPin, clkPin, LSBFIRST, command); //コマンド送信(日時格納アドレス) shiftOut(datPin, clkPin, LSBFIRST, data); //データ書き込み(設定日時のデータ) digitalWrite(rstPin, LOW); //RSTピン(CE) "L" アクセス終了 pinMode(datPin, INPUT); //DAT(I/O)をINPUTへ戻す } //Single-Byte Read関数 「時刻の読み出し」 int s_b_read(int command){ int bit = 0; int data = 0; digitalWrite(clkPin, LOW); //クロック "L" L始まりを確定させるため digitalWrite(rstPin, HIGH); //RSTピン(CE) "H" アクセスを許可 shiftOut(datPin, clkPin, LSBFIRST, command); //コマンド送信(日時格納アドレス) //data(日時)の読み取り動作 8回繰り返し8bitぶん読み出す for (int i = 0; i < 8; ++i) //8回繰り返し { bit = digitalRead(datPin); //DAT(I/O)の値を読み取り Serial.print(bit); //シリアルモニタに表示 //データの統合処理 data |= (bit << i); //bitシフトさせて、前のデータとのORどり //clkをH->Lさせてトグルさせる digitalWrite(clkPin, HIGH); //クロック "H" delayMicroseconds(1); //クロック "H"期間 1usに設定 digitalWrite(clkPin, LOW); //クロック "L" } digitalWrite(rstPin, LOW); //RSTピン(CE) "L" アクセス終了 Serial.print(" "); //シリアルモニタにスペースの表示 // int t = (10 * (data >> 4))+(data & 0b1111); //上位4bit + 下位4bitを統合 ※数値に変換 return(t); //戻り値 } void setup() { //PINモード設定 pinMode(clkPin,OUTPUT); //OUTPUT指定 pinMode(rstPin,OUTPUT); //OUTPUT指定 Serial.begin(9600); //データ転送レートを指定 Serial.println("時刻を設定値にしますか? [y or n]"); while(Serial.available() == 0){} //データが入るまでループ int val = Serial.read(); //受信データの読み込み if(val == 0x79){ //y,nの判定(ASCIIコード y = 0x79 //アドレスの値に関してはdatasheetで確認。※下記は16進数表示 s_b_write(0x80,0x55); //秒の設定 ※55秒 s_b_write(0x82,0x59); //分の設定 ※59分 s_b_write(0x84,0x23); //時間の設定 ※23時 s_b_write(0x86,0x11); //日付の設定 ※11日 s_b_write(0x88,0x04); //月の設定 ※4月 s_b_write(0x8c,0x21); //年の設定 ※21年 s_b_write(0x8a,0x01); //曜日の設定 ※日曜日 }else{ pinMode(datPin, INPUT); //時刻を設定値にしない場合、INPUT指定 } Serial.println("### 2進数表示 ###"); Serial.println("|second |minutes |hour |date |month |year |day |"); Serial.println("01234567|01234567|01234567|01234567|01234567|01234567|01234567|"); } void loop(){ int v_s = s_b_read(0x81);//read 秒レジスタ int v_mi = s_b_read(0x83);//read 分レジスタ int v_h = s_b_read(0x85);//read 時レジスタ int v_date = s_b_read(0x87);//read 日レジスタ int v_mo = s_b_read(0x89);//read 月レジスタ int v_y = s_b_read(0x8d);//read 年レジスタ int v_day = s_b_read(0x8b);//read 曜日レジスタ Serial.print(" "); Serial.print(v_s); Serial.print("秒 "); Serial.print(v_mi); Serial.print("分 "); Serial.print(v_h); Serial.print("時 "); Serial.print(v_date); Serial.print("日 "); Serial.print(v_mo); Serial.print("月 "); Serial.print("20"); Serial.print(v_y); Serial.print("年 "); //数値を曜日としてシリアルモニタに表示 char day_week; switch (v_day) { case 1: Serial.print("日"); break; case 2: Serial.print("月"); break; case 3: Serial.print("火"); break; case 4: Serial.print("水"); break; case 5: Serial.print("木"); break; case 6: Serial.print("金"); break; case 7: Serial.print("土"); break; } Serial.println("曜日 "); delay(1000); }
サンプルコード2 動作確認
では、さっそく動作を確認していきます。
シリアルモニタを開いてください。
■時刻を設定値にしますか? [y or n] -> y を選択した場合
スケッチ内で設定した「2021年4月11日 23時59分55秒 日曜日」から始まります。
■時刻を設定値にしますか? [y or n] -> n を選択した場合
CR2032の電池から電源が供給されることでDS1302のレジスタ値は保持されています。
そのため、前回設定した時刻からDS1302で刻まれた日時が表示されます。
設定値ではなく、「2021年4月12日 0時6分37秒 月曜日」から始まっていることがわかります。
電池でレジスタのデータが保持され時間が刻まれていたということです。
ライブラリを使わなくても、時刻を設定し日時を表示することができました。
LCDディスプレイにつなげればデジタル時計が作れます。
挑戦してみましょう!
まとめ
本Lessonは、以下を目標としました。
2.RTCモジュールから日時を取得するスケッチを描く
3.RTCモジュールで遊ぶ
■ライブラリ使用あり
ライブラリを使用する場合、本Lessonで紹介したサンプル以外にも色々とあります。
自分の使いやすいライブラリを検索して試してみるのも良いと思います。
■ライブラリ使用なし
本Lesson、データーシートのアドレスマップ、Read、Write動作を理解する必要があります。
ちょっと、敷居が高いかもしれませんがデーターシートを読み慣れるためにも挑戦してみることをおすすめします。
管理人、それなりのスケッチを描くのに時間がかかりました。
まだまだですね・・・。
Lesson 50 【Real Time Clock モジュール】 はここまで。
「水晶振動子」「DS1302」のみ入手してブレッドボード上へ組むことも可能です。
値段も高くないので、モジュール化したものを購入した方が遊ぶには簡単ですが・・・。
RTCモジュールを使えば、時刻で何かをさせるといったことも可能。
また、ディスプレイと組み合わせてデジタル時計の作成もできます。
管理人もデジタル時計を作ってみたいと思っています。
作ってみます。といった手前・・・
次回、Lesson 51は 【Real Time Clock モジュール その2】。
デジタル時計を作って遊びます。
最後に
疑問点、質問などありましたら気軽にコメントください。
この電子部品の解説をしてほしい!などなどなんでもOKです。
リンク切れ、間違いなどあればコメントいただけると助かります。
Arduino入門編、番外編、お役立ち情報などなどサイトマップで記事一覧をぜひご確認ください。
Arduino入門編、Arduino入門編2で使用しているUNOはAmazonにて購入可能です。
Arduino入門編では互換品を使用。
Arduinoはオープンソース。
複製して販売するのもライセンス的に問題なし。
そのため互換品の品質も悪くなく、それでいて値段は安いです。
正規品本体の値段程度で豊富な部品が多数ついています。
学習用、遊び用、お試し用には安価な互換品がおすすめです。
ELEGOO UNO キット レベルアップ チュートリアル付 uno mega2560 r3 nanoと互換 Arduino用
上記のものでも十分に多数の部品が入っていますが、最初からもっと多数の部品が入っているこちらもお勧めです。
Arduino入門編2では「Arduino UNO R4 Minima」「Arduino UNO R4 WIFI」にて遊ぶため今のところは正規品を使用。(まだ互換品が・・・ほぼない)
Amazonでお得に買う方法
Amazonでお得に購入するならAmazon Mastercard、Amazonギフト券がおすすめです。
時期により異なりますが、様々なキャンペーンを実施しています。
\Amazonギフト券/
Amazonギフトカード キャンペーン
\Amazon Mastercard お申込み/
Amazon Mastercard 申し込み
いずれの場合もプライム会員である方がお得!!
\Amazon Prime 30日間の無料会員を試す/
無料会員登録
コメント
Lesson50、ライブラリを使用しないスケッチを追記しました。
試して、遊んでみてください!