Arduinoと戯れる!

Arduino 入門 Lesson 50 【Real Time Clock モジュール その1】

arduino-lesson50-00Arduino入門編
スポンサーリンク
子供と一緒に始める マイコンプログラム
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はオープンソースであり複製して販売するのもライセンス的に問題なし。

そのため互換品の品質も悪くなく、それでいて値段は安いです。

正規品本体の値段程度で豊富な部品が多数ついています。

 

正規品の本体単品がほしい方はこちらとなります。

 

スポンサーリンク

はじめに

本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で検索)

Attention Required! | Cloudflare

 

Lesson 50 目標

本Lessonの目標は以下です。

1.RTCモジュールの使い方を学習する
2.RTCモジュールから日時を取得するスケッチを描く
3.RTCモジュールで遊ぶ

いつものように、遊ぶことが重要です。

 

今回のセンサ、ライブラリを使えばスケッチは簡単。

ただし動作の理屈を理解するためにはデータシートを読み込む必要があり!

回路がわからなくても遊べる、使える、作れるのがArduino の良いところ。

もちろん、データシート読めなくても遊べます。

 

準備

ではLessonの準備に取り掛かりましょう。

部品は「RTCモジュール」のみ。

LCDに日時を表示させたい場合は、LCDも追加で準備。

 

必要なもの

※ブレッドボードはセンサとUNOを直接つなぐ場合不要です。
※ジャンパワイヤーは「M-M」「M-F」を必要に応じて使い分けてください。

 

Jumper wire、抵抗は今後も頻繁に利用します。

Jumper wireはできれば、「オス-メス オス-オス メス –メス」の3種類を揃えておくことをお勧めします。

短めが使いやすい場合も。

 

使用部品説明

RTCモジュール」のモジュールについて説明していきます。

※RTC:Real Time Clock(リアル タイム クロック)

 

RTCモジュール「DS1302」 実物写真

下の写真が「RTCモジュール」の実物写真です。

本Lessonで使用するものは、回路が基板実装されたもの。

DS1302 IC」「水晶振動子」「電池フォルダー」で構成されています。

arduino-lesson50-01

 

 

  • 水晶振動子:32.768kHz
  • 供給電源:2.0V~5.5V
  • 電池フォルダー:CR2032
電源供給について
「DS1302」は充電モードがあります。
デフォルト設定であれば充電なしのモードのため、通常の電池使用でOK。
充電モード(トリクルチャージモード)の場合、充電用の電池が必要となります。

 

RTCモジュール「DS1302」 仕様

RTCモジュールの仕様は、DS1302 ICの仕様ということになります。

データシートに記載されていますので詳細はそちらをご確認ください。

ここでは、重要箇所のみ紹介します。

 

■「DS1302」のピン配置

arduino-lesson50-02

 

■PIN仕様

Pin No.Pin NameFunction
1VCC2デュアル電源構成のプライマリ電源ピン
VCC1またはVCC2の大きい方で動作
VCC2 > VCC1 + 0.2V:VCC2電力供給
VCC2 < VCC1           :VCC1電力供給
※モジュールのVCCピンがVCC2
2X1水晶振動子の接続
※32.768kHz
3X2
4GNDグランド
5CE入力ピン:read/write時にHighにする
プルダウン抵抗付き(40kΩ)
※モジュールのRSTピンがCEピン
6I/O入出力ピン(出力はプッシュプル)
プルダウン抵抗付き(40kΩ)
※モジュールのDATピンがI/Oピン
7SCLK入力ピン
シリアルインターフェースの同期用のクロック
プルダウン抵抗付き(40kΩ)
※モジュールのCLKピンがSCLKピン
8VCC1バックアップ用の電源:CR2302(3V)供給
主電源がない場合に時刻と日付を維持

 

■レジスタアドレス(レジスタマップ)

最初の8bitにてRead/Writeのコマンドを指定します。

次の8bitはデータの読み出し、書き込みのビットになります。

データ8bitは上位4ビット、下位4ビットに分かれており、各4ビットで0~9までの10進数で表現されます。

よって、表現できる数値は00~99となります。

■Read動作

  • 読み出したいデータのREADアドレスを指定しデータbitを読み出す
  • シリアルモニタに日時を表示させる

■Write動作

  • 書き込みたいデータのWriteアドレスを指定しデータを書き込む
READWRITEBITRANGE
76543210
81h80hCH10ss00 – 59
83h82h10mm00 – 59
85h84h12/24010
am/pm
hh1 – 12/0 -23
87h86h0010 dd1 -31
89h88h00010mm1 – 12
8Bh8Ah00000day1 – 7
8Dh8Ch10yy00 – 99
8Fh8EhWP0000000
91h90hTCSTCSTCSTCSDSDSDSDS

※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を使用。

あとは、5VGNDのみ。

 

回路図がこちら。

arduino-lesson50-03

 

こちらがブレッドボード図。

arduino-lesson50-04

 

 

回路図は「fritzing」を利用しています。

「fritzing」の使い方は下記を参照してください。

 

接続

下図に示すように、用意した部品を使用して接続しましょう。

部品は「RTCモジュール」のみとなります。
※DS1302が実装されたモジュール

部品は1個、接続は簡単です。

RTCモジュール」と接続するジャンパーワイヤーはF-Mを使用してます。

そのため、ブレッドボードもいりません。

 

使用するポートは、デジタル入出力ピンの8、9、10、5V、GND。

穴に挿入しづらいときは、ラジオペンチなどを使用してください。

arduino-lesson50-07

 

 

コードの書き込み

接続が終わったら、USBケーブルを使用してUNOにプログラムを書き込んで行きましょう。

コードを書き終えたら、いつでも利用できるように「ファイル」⇒「名前を付けて保存」で保存しておきましょう。

 

コマンド説明1 ライブラリ使用あり

サンプルコード1では、「ライブラリ」を使用します。

使いやすい、ライブラリがありましたのでこちらを使います。

下記からダウンロードしてzip形式のライブラリをインストールしてください。

Code -> Download ZIP でダウンロードできます。
https://github.com/msparks/arduino-ds1302

 

ライブラリについて知りたい方は下記を参照ください。

Arduino 入門 Lesson 01 【ライブラリインストールおよびPCとの接続編】
ライブラリはセンサなどの部品を簡単にArduinoに接続して使用するためのコードの集まりです。接続はArduinoにコードをアップデートするために、COMポートを設定し、PCとArduinoを接続する作業です。ここではライブラリの追加方法(…

 

サンプルコード1 ライブラリ使用あり

まずは、「ライブラリを使ったサンプルコード」です。

ダウントードしたライブラリに一緒にサンプルが梱包されています。

ファイル -> スケッチ例 -> arduino-ds1302-master -> set_clock

で遊ぶことができます。

 

本Lessonの回路図はデジタル入出力ピンの8、9、10を使用しています。

本Lessonの回路図結線を利用する場合は、スケッチのピン定義を8,9,10に修正ください。

const int kCePin = 10; // Chip Enable
const int kIoPin = 9; // Input/Output
const int kSclkPin = 8; // Serial Clock

 

また、スケッチの中に下記の記載があります。

合わせたい時刻に下記を設定すれば、その時刻から時計が刻まれます。

例 2021年4月10日 23時20分30秒 土曜日 に設定
Time t(2021, 4, 10, 23, 20, 30, Time::kSaturday);

 

サンプル例になりますのでスケッチは省略します。
※掲載して良いかわからなかったので・・・。

 

サンプルコード1 動作確認

では、さっそく動作を確認していきます。

シリアルモニタに下記のように時刻が表示されます。

■時刻の表示

arduino-lesson50-06

 

設定した時刻から時間が経過していることがわかります。

 

補足
タイミングチャートがわからない。
そんなときは「ライブラリを使用することで遊べます。
機能を使いたいだけであれば、これでOK!

 

コマンド説明2 ライブラリ使用なし

サンプルコード2では、データシートを理解してライブラリを使わずにスケッチを描くことに挑戦。

これまで学習してきた、関数しか使わないため新しいコマンドはありません

データーシートのアドレスマップ、タイミングチャート、Readモードを理解することが重要になります。

そこまでは、という場合はすっ飛ばしてください。

ライブラリを使ったスケッチで十分に色々な用途に応用可能です。

 

ライブラリを使わずにRead/Writeを制御するためには「shiftOut関数」がとて便利です。

 

サンプルコード2 ライブラリ使用なし

ライブラリを使用せずに日時を書き込み、読み出すスケッチになります。

書き込み部分、読み出し部分は関数化しています。

Single-Byte Writeモード部分を関数化

この部分で、日時の初期値設定をするようにしています。

// Single-Byte Write関数 「時刻の初期値設定」
void s_b_write(int command, int data){

}

 

Single-Byte Readモード部分を関数化

この部分で、レジスタに格納されている日時を読み出しています。

//Single-Byte Read関数 「時刻の読み出し」
int s_b_read(int command){

}

 

■その他 補足

補足1
読み出したデータは、上位4bit、下位4bitのバイナリデータです。
上位4bitを10の位、下位4bitを1の位として数値に変換し統合する必要があります。
補足2
曜日に関しては、1~7の数値のため曜日変換して出力する必要があります。
補足3
始めに、設定時刻を読み出さない場合
電池によって保持されているレジスタ値の日時が読み出されます。
上記結果からCR2032の電池で日時が保持されることがわかります。

 

上記をふまえて、下記サンプルスケッチを確認ください。

データシートを理解することができるかどうか?が重要です。

//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 動作確認

では、さっそく動作を確認していきます。

シリアルモニタを開いてください。

左側にレジスタのバイナリデータ、右側に変換表示した日時を表示しています。
左側の2進数のデータと右側の時刻の10進数の数値が一致している
ことに注目してください。

 

■時刻を設定値にしますか? [y or n] -> y を選択した場合

スケッチ内で設定した「2021年4月11日 23時59分55秒 日曜日」から始まります。

arduino-lesson50-08

 

ここで一度、電源からArduinoを外してください!
CR2032の電池は入れておくこと。

 

■時刻を設定値にしますか? [y or n] -> n を選択した場合

CR2032の電池から電源が供給されることでDS1302のレジスタ値は保持されています。

そのため、前回設定した時刻からDS1302で刻まれた日時が表示されます。

設定値ではなく、「2021年4月12日 0時6分37秒 月曜日」から始まっていることがわかります。

電池でレジスタのデータが保持され時間が刻まれていたということです。

arduino-lesson50-09

 

ライブラリを使わなくても、時刻を設定し日時を表示することができました。

LCDディスプレイにつなげればデジタル時計が作れます。

挑戦してみましょう!

 

まとめ

本Lessonは、以下を目標としました。

1.RTCモジュールの使い方を学習する
2.RTCモジュールから日時を取得するスケッチを描く
3.RTCモジュールで遊ぶ

 

■ライブラリ使用あり

ライブラリを使用する場合、本Lessonで紹介したサンプル以外にも色々とあります。

自分の使いやすいライブラリを検索して試してみるのも良いと思います。

 

■ライブラリ使用なし

本Lesson、データーシートのアドレスマップ、Read、Write動作を理解する必要があります。

ちょっと、敷居が高いかもしれませんがデーターシートを読み慣れるためにも挑戦してみることをおすすめします。

管理人、それなりのスケッチを描くのに時間がかかりました。

まだまだですね・・・。

 

Lesson 50 【Real Time Clock モジュール】 はここまで。

水晶振動子」「DS1302」のみ入手してブレッドボード上へ組むことも可能です。

値段も高くないので、モジュール化したものを購入した方が遊ぶには簡単ですが・・・。

 

RTCモジュールを使えば、時刻で何かをさせるといったことも可能。

また、ディスプレイと組み合わせてデジタル時計の作成もできます。

管理人もデジタル時計を作ってみたいと思っています。

 

作ってみます。といった手前・・・

次回、Lesson 51は 【Real Time Clock モジュール その2】。

デジタル時計を作って遊びます。

Arduino 入門 Lesson 51 【Real Time Clock モジュール その2】
本記事はLesson 51 【Real Time Clock モジュール その2】。デジタル時計を作ります。RTCモジュールと組み合わせる対象は表示器ならなんでもOK。本LessonではLesson 25で使用した「4桁7セグメントLED」…

 

最後に

疑問点、質問などありましたら気軽にコメントください。

この電子部品の解説をしてほしい!などなどなんでもOKです。

リンク切れ、間違いなどあればコメントいただけると助かります。

 

Arduino入門編、番外編、お役立ち情報などなどサイトマップで記事一覧をぜひご確認ください。

 

Arduino入門編で使用しているUNOはAmazonにて購入可能です。

互換品とは言え、Arduinoはオープンソース。

複製して販売するのもライセンス的に問題なし。

 

そのため互換品の品質も悪くなく、それでいて値段は安いです。

正規品本体の値段程度で豊富な部品が多数ついています。

 

学習用、遊び用、お試し用には安価な互換品がおすすめです。

 

 

上記のものでも十分に多数の部品が入っていますが、最初からもっと多数の部品が入っているこちらもお勧めです。

 

Amazonでお得に買う方法

Amazonでお得に購入するなら、Amazonギフト券がおすすめです。

現金でチャージするたびに、チャージ額に応じたポイントが付与されます。

最大2.5%!!!(Amazonプライム会員ならさらにお得)

チャージ額(一回分)一般プライム会員
5,000円~19,999円0.5%1.0%
2,0000円~39,999円1.0%1.5%
40,000円~89,999円1.5%2.0%
90,000円~2.0%2.5%

さらに、初回チャージで2000ポイントもらえるキャンペーンも実施中!
※いつもは1000ポイント、今なら2000ポイントです!

\Amazonギフト券 2000ポイントキャンペーン/
Amazonチャージ 初回購入で2000ポイントキャンペーン

 

補足情報
コンビニ・ATM・ネットバンクが対象
購入は1円単位で可能

コメント

  1. omoroyaomoroya より:

    Lesson50、ライブラリを使用しないスケッチを追記しました。
    試して、遊んでみてください!

タイトルとURLをコピーしました