XIAO ESP32C3を使ってみる その7(RTC、ネットワークの時刻取得)

はじめに

 今回はマイコンでRTCとネットワークを利用した時刻の取得について試してみました。

 IoT用途として、水やりなどに使いたいなと思っています。

▼家でトマトを育てていたのですが、自動化したいなと思いつつ特に進展が無いまま実が成りました。

▼以前の記事はこちら

XIAO ESP32C3を使ってみる その5(Bluefluit Connect、iPhoneとBLE通信)

はじめに  今回はXIAO ESP32C3とBluefluit Connectというスマートフォン向けのアプリで、BLE通信を試してみました。  以前Light Blueというアプリを使って通信していま…

XIAO ESP32C3を使ってみる その6(DUALSHOCK 4との通信、Node-RED)

はじめに  今回はDUALSHOCK 4でXIAO ESP32C3を用いた小型ロボットを操作してみました。  以前調べていたときに、DUALSHOCK 4とXIAO ESP32C3はBluetoothの規格が違うので…

回路を組む

 RTCはRX8900を利用したモジュールです。

▼秋月電子通商で購入しました。

https://akizukidenshi.com/catalog/g/g113009

 マイコンはXIAO ESP32C3です。

▼ピン配置も掲載されています。

 I2C通信で利用できるので、SDAとSCLをそれぞれつなぎます。RTCのVCCはマイコンの3.3Vにつないで、GNDを共有しました。

▼小さいブレッドボードに配線しました。

プログラムを書き込むときの注意点

 久しぶりにArduino IDEでプログラムを書き込んでいると、アップロードのエラーが出ていました。

 対処法についておさらいしておこうと思います。

▼Seeed Studio公式が、bootloaderモードについてポストしています。

 ESP32系のマイコンだとよくあるのですが、ブートボタンを長押ししたままリセットボタンを押すと、書き込みモードになります。

 最近Node-RED MCUの環境を構築したり、Arduino IDEのESP32のバージョンを変更したりしていた影響なのかもしれませんが、書き込み後にエラーが起きていました。

▼OSErrorが起きていました。

 書き込み自体は成功していて、プログラムは動作しているようでした。ただしすぐにシリアルモニタに表示されないことがあって、適当に文字を送ると表示されるということがありました。

サンプルプログラムを試してみる

 秋月電子通商のサンプルプログラムがサイト上にあったので試してみました。

▼こちらのページにありました。

https://akizukidenshi.com/catalog/g/g113009

 プログラムを書き込んで実行してみました。

▼シリアルモニタで数値を入力して、最初の時刻を設定するようになっていました。

▼1秒ごとに表示されました。

▼温度も測っているようだったので、モジュールに指を乗せていたら温度が上がっていきました。

 サンプルプログラムが長かったので、今回は使わない部分を削除して、ヘッダファイルに定数や関数を分けました。

▼プログラムはこちら。メインのinoファイルはコンパクトになっています。

 アラームの処理などを省いていますが、同じように動作しました。

インターネットに接続して時刻を取得する

 XIAO ESP32C3はWi-Fiを利用できるので、ネットワークに接続して時刻を取得できるか試してみました。

 以下のコードをChatGPTに生成してもらいました。

#include <WiFi.h>
#include "time.h"

const char* ssid     = "あなたのSSID";  // Wi-Fi SSID
const char* password = "あなたのパスワード";  // Wi-Fi パスワード

const char* ntpServer = "pool.ntp.org";  // NTPサーバー
const long  gmtOffset_sec = 9 * 3600;    // 日本時間 (GMT+9)
const int   daylightOffset_sec = 0;      // 夏時間なし

void setup() {
    Serial.begin(115200);
    
    // Wi-Fi接続
    WiFi.begin(ssid, password);
    Serial.print("WiFiに接続中");
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println(" 接続完了");

    // NTPの設定
    configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
}

void loop() {
    struct tm timeinfo;
    if (!getLocalTime(&timeinfo)) {
        Serial.println("時刻情報を取得できませんでした");
        return;
    }
    
    // 時刻の表示
    Serial.printf("現在時刻: %04d-%02d-%02d %02d:%02d:%02d\n",
                  timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday,
                  timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
    
    delay(10000);  // 10秒ごとに更新
}

▼スマートフォンのインターネット共有でマイコンをネットワークにつないで、時刻を取得することができました。

 このコードの年月日、時分秒を利用できそうです。

ネットワークとRTCで時刻を取得する

 RTCのサンプルプログラムを読んでいたのですが、アドレス周りの処理がややこしくて、結局READ_AND_TX()で一秒ごとに処理を行っていることが分かりました。

 そこで、RTCは1秒ずつ時間を進めるためだけに使って、年月日や時分秒は別のライブラリで管理することにしました。

 秒だけ増やして時刻を管理するために、以下のプログラムをChatGPTに書いてもらいました。

#include <TimeLib.h>

void setup() {
    Serial.begin(115200);

    // 初期時刻を設定(2025年2月12日 14:30:00)
    setTime(14, 30, 0, 12, 2, 2025);
}

void loop() {
    static unsigned long lastUpdate = 0;
    
    if (millis() - lastUpdate >= 1000) { // 1秒ごとに更新
        lastUpdate = millis();
        Serial.print(year());
        Serial.print("/");
        Serial.print(month());
        Serial.print("/");
        Serial.print(day());
        Serial.print(" ");
        Serial.print(hour());
        Serial.print(":");
        Serial.print(minute());
        Serial.print(":");
        Serial.println(second());

        // 時間を進める(1秒加算)
        adjustTime(1);
    }
}

▼2秒ずつですが、時刻が増えています。adjustTime(1)で1秒加算しているようですが、0.5にすることにしました。

 これまでのプログラムをまとめて、初回だけネットワークの時刻に合わせて、RTCで1秒ずつ増やしていきます。

 以下のプログラムを作成しました。

 実行してみました。初回は5回だけネットワークの時刻を取得します。

▼時刻を取得できています。

▼夜中放置して朝確認したのですが、まだずれていませんでした。

 何日か放置して、どれぐらいずれるか検証してみようと思います。

 何を真値にするのかが悩みどころで、時報が確実なのでしょうか。

最後に

 RTCとネットワークを利用して、簡単に時刻を設定できるようにしてみました。

 ライブラリの使い方などで間違っているところがあるかもしれませんが、長い間動作させて検証してみようと思います。

 ChatGPTはちょっとした動作確認用のプログラムなら生成できますが、ライブラリによっては存在しないメソッドを使っていたりしました。ある程度はまだ人が調整する必要がありそうです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です