RTCの実力を調査

# RTCであるDS1307の実力を調査
秋月電子で入手できる[リアルタイムクロックモジュール](https://akizukidenshi.com/catalog/g/gM-09276/)の実力を調査。時刻を設定してから、81日後までのインターネット時刻との差を調べた。
（本当は100日後までのつもりだったが、ミスがあって、泣く泣く81日経過後で終了、、。）

## 環境
Arduino IDEでM5Stack利用。本モジュールがGroveコネクタを用いていたため、同コネクタを持つM5Stackを選択。

## ソースコード
[こちら](https://github.com/Seeed-Studio/RTC_DS1307/blob/master/examples/SetTimeAndDisplay/SetTimeAndDisplay.ino)にあるソースコードをほぼそのまま利用。

### 時刻のセット
```c++
#include <Wire.h>
#include "DS1307.h"

DS1307 clk;//define a object of DS1307 class
void setup() {
    Serial.begin(9600);
    clk.begin();
    Serial.println("Waiting new line ...");
}

int done = 0;
void loop() {
    while (!done) {
      if (Serial.available()) {
        clk.fillByYMD(2021, 5, 31);
        clk.fillByHMS(18, 52, 00);
        clk.fillDayOfWeek(MON);
        clk.setTime();//write time to the RTC chip
        (void)Serial.readStringUntil('\n'); 
        done = 1;       
      }
      delay(1);
    }
   
    printTime();
}
/*Function: Display time on the serial monitor*/
void printTime() {
    clk.getTime();
    Serial.print(clk.hour, DEC);
    Serial.print(":");
    Serial.print(clk.minute, DEC);
    Serial.print(":");
    Serial.print(clk.second, DEC);
    Serial.print("	");
    Serial.print(clk.month, DEC);
    Serial.print("/");
    Serial.print(clk.dayOfMonth, DEC);
    Serial.print("/");
    Serial.print(clk.year + 2000, DEC);
    Serial.print(" ");
    //Serial.print(clk.dayOfMonth);
    //Serial.print("*");
    switch (clk.dayOfWeek) { // Friendly printout the weekday
        case MON:
            Serial.print("MON");
            break;
        case TUE:
            Serial.print("TUE");
            break;
        case WED:
            Serial.print("WED");
            break;
        case THU:
            Serial.print("THU");
            break;
        case FRI:
            Serial.print("FRI");
            break;
        case SAT:
            Serial.print("SAT");
            break;
        case SUN:
            Serial.print("SUN");
            break;
    }
    Serial.println(" ");
    delay(3000);
}
```

シリアルから何か入力があったときに、「2021年5月31日18時52分」にセット。

### 時刻の表示
```c++
#include <Wire.h>
#include "DS1307.h"

DS1307 clk;//define a object of DS1307 class
void setup() {
    Serial.begin(9600);
    clk.begin();
}
void loop() {
    printTime();
}
/*Function: Display time on the serial monitor*/
void printTime() {
    clk.getTime();
    Serial.print(clk.hour, DEC);
    Serial.print(":");
    Serial.print(clk.minute, DEC);
    Serial.print(":");
    Serial.print(clk.second, DEC);
    Serial.print("	");
    Serial.print(clk.month, DEC);
    Serial.print("/");
    Serial.print(clk.dayOfMonth, DEC);
    Serial.print("/");
    Serial.print(clk.year + 2000, DEC);
    Serial.print(" ");
    //Serial.print(clk.dayOfMonth);
    //Serial.print("*");
    switch (clk.dayOfWeek) { // Friendly printout the weekday
        case MON:
            Serial.print("MON");
            break;
        case TUE:
            Serial.print("TUE");
            break;
        case WED:
            Serial.print("WED");
            break;
        case THU:
            Serial.print("THU");
            break;
        case FRI:
            Serial.print("FRI");
            break;
        case SAT:
            Serial.print("SAT");
            break;
        case SUN:
            Serial.print("SUN");
            break;
    }
    Serial.println(" ");
    delay(1000);
}

```

自明。

### 結果
インターネット時刻は、[こちらの](https://www.nict.go.jp/JST/JST5.html)情報を利用。例えば、10日後の結果は下記のとおり。
![サンプル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/13afde42-54ff-c01b-2de7-00bab29a28f4.png)

10日後には、インターネット時刻から6秒ほどずれていることがわかる。81日後までの結果は下記のとおり。

|経過日数|10|20|30|40|50|60|70|81|
|---|---|---|---|---|---|---|---|---|
|差（秒）|6|10|16|22|27|33|38|43|

当初目的としていた100日経過後には、1分弱程度のズレ（差）が生じると推測。このRTCは、それほど精度はいいとは言えない。ただ、所持するiPhone6で機内モードのまま相当日数放置したとき（とは言っても1ヶ月も経過していない）、1分以上ずれていた覚えがある。所詮、RTCの実力はその程度のものかもしれない。

インターネットやGPSから正確な時刻を取得するのが通常なので、RTCの意義自体が微妙な気がする。