Raspberry Pi Pico に内蔵のRTCを Arduino IDE で利用したい
Pico は RTC(リアルタイム・クロック)を内蔵している
Raspberry Pi Pico の MCUであるRP2040はRTC(リアルタイム・クロック)を内蔵していることを知りました。RTCのハードウェア、つまりIC(DS1307が有名)やモジュールが不要!! というのは嬉しいです。
これを Micro PythonやC/C++開発環境で使用した例はありますが、
Qiita「pi picoでmicropython その20」
github の hello_rtc.c
https://github.com/raspberrypi/pico-examples/blob/master/rtc/hello_rtc/hello_rtc.c
Arduino IDE での使用例は見当たりませんでした。
解決しました!
よく調べたらArduinoのホームページに RP2040_RTC というライブラリがありました。
(1) RP2040_RTC // https://www.arduino.cc/reference/en/libraries/rp2040_rtc/
(2) TimeLib.h // https://github.com/PaulStoffregen/Time
(3) Timezone_Generic.h // https://github.com/khoih-prog/Timezone_Generic
この3つのライブラリを入手してインストールし、動作確認した内容を「RaspberryPi Pico に内蔵のRTCを Arduino IDE で使用する」というタイトルで報告しました。1行追加する必要がありました。
サンプルプログラム(スケッチ)を実行するとシリアルモニタに下記のように表示されました。
Start RP2040_RTC_Time on MBED RASPBERRY_PI_PICO
RP2040_RTC v1.0.4
Timezone_Generic v1.7.0
============================
04:00:01 Wed 23 Jun 2021 UTC
00:00:01 Wed 23 Jun 2021 EDT
============================
04:00:11 Wed 23 Jun 2021 UTC
00:00:11 Wed 23 Jun 2021 EDT
============================
という訳で、以下はゴミです。興味ある方だけお読みください。
私は、Windows10 で Arduino IDE 1.8.15 を利用していますが Pico の Arduino IDE 開発環境(earlephilhower 版ではなく、Arduino Mbed OS RP2040 版のほう)で、RTCのライブラリ関数があるかもと思って調べたところ rtc_api.h と RealTimeClock.h というファイルを見つけました。それぞれ以下のような関数が定義されてます。
C:\Users\user\Documents\ArduinoData\packages\arduino\hardware\mbed_rp2040\2.2.0\cores\arduino\mbed\hal\include\hal\rtc_api.h
void rtc_init(void);
void rtc_free(void);
int rtc_isenabled(void);
time_t rtc_read(void);
void rtc_write(time_t t);
C:\Users\user\Documents\ArduinoData\packages\arduino\hardware\mbed_rp2040\2.2.0\cores\arduino\mbed\drivers\include\drivers\RealTimeClock.h
#include <chrono>
#include "hal/rtc_api.h"
namespace mbed {
class RealTimeClock {
public:
using duration = std::chrono::seconds;
using rep = duration::rep;
using period = duration::period;
using time_point = std::chrono::time_point<RealTimeClock>;
static const bool is_steady = false;
static void init() { return rtc_init(); }
static void free() { return rtc_free(); }
static bool isenabled() noexcept { return bool(rtc_isenabled()); }
static time_point now() noexcept { return from_time_t(rtc_read()); }
static void write(time_point t) noexcept { rtc_write(to_time_t(t)); }
static time_point from_time_t(time_t t) noexcept {
return time_point{std::chrono::duration_cast<duration>(std::chrono::duration<time_t>{t})};
}
static time_t to_time_t(const time_point &t) noexcept {
return std::chrono::duration_cast<std::chrono::duration<time_t>>(t.time_since_epoch()).count();
}
};
作成したテストプログラムと問題点
この RealTimeClock.h でRTCのクラスを定義しているので試しに以下のような簡単なテストプログラムを作成しました。(C++は学習中の段階で、よく理解できてません)
#include <RealTimeClock.h>
using namespace mbed;
RealTimeClock RP2040_RTC;
RealTimeClock::time_point tmdata;
int RTC_flag; // 0: RTCは動作してない。1:動作中
//-------------------------------------------------------------
void setup() {
Serial.begin(9600);
RP2040_RTC.init();
}
//-------------------------------------------------------------
void loop() {
RTC_flag = RP2040_RTC.isenabled();
Serial.println("RTC_flag = ");
Serial.println(RTC_flag);
tmdata = RP2040_RTC.now();
Serial.print("Now time = ");
Serial.println(tmdata.tm_sec);
}
【問題点1】これをコンパイルすると下記のエラーになりました。
RasPiePICO-RTC-Test:27:25: error: 'using time_point = struct std::chrono::time_point<mbed::RealTimeClock> {aka struct std::chrono::time_point<mbed::RealTimeClock>}' has no member named 'tm_sec'
Serial.println(tmdata.tm_sec);
^~~~~~
exit status 1
'using time_point = struct std::chrono::time_point<mbed::RealTimeClock> {aka struct std::chrono::time_point<mbed::RealTimeClock>}' has no member named 'tm_sec'
以下、調べたこと。
(1) time_t型は、1900年1月1日0時0分0秒からの経過秒数で「UNIX時刻、UNIX Time」という。
(2) time_point は、時間軸上の一点を表すクラス。
どこかで見た下記のtm構造体のような構成になっているのかな?と思ったのですが違うようです。(変数の順はソートしました)
int tm_year // 年:1900から数えた年
int tm_mon // 月:[0-11]
int tm_mday // 日:[1-31]
int tm_hour // 時:[0-23]
int tm_min // 分:[0-59]
int tm_sec // 秒:[0-61] 通常0-59だが、うるう年の調整用に60, 61がある。
int tm_wday // 曜日:[0-6]
int tm_yday // 年内通し日数:[0-365]
int tm_isdst // 夏時間フラグ(詳細略)
【問題点2】前記エラーが出ないようにと最後の Serial.println(tmdata.tm_sec); の行をコメントアウトすると以下のエラーになりました。
C:\Users\user\Documents\ArduinoData\packages\arduino\hardware\mbed_rp2040\2.2.0\cores\arduino/mbed/drivers/include/drivers/RealTimeClock.h:85: undefined reference to `rtc_isenabled'
C:\Users\user\Documents\ArduinoData\packages\arduino\hardware\mbed_rp2040\2.2.0\cores\arduino/mbed/drivers/include/drivers/RealTimeClock.h:96: undefined reference to `rtc_read'
collect2.exe: error: ld returned 1 exit status
exit status 1
RealTimeClock.h には、 #include "hal/rtc_api.h" という行があるのに何故 undefined ?
う~む、なんか基本的なところでつまづいているような気がします・・どうすればよいでしょうか?