(2025年7月22日のできごと)
例のプロジェクト、展示していない間の節電対策として日時によって自動でLEDをオン・オフする事を考えていたところ
ラズパイPico で使うのにちょうどいいRTCボードを教えていただき取り寄せてみました。
Raspberry Pi Pico用DS3231 高精度リアルタイムクロックモジュール(Switch Scince での販売名)
外観はこんな感じ。

Picoを上に載せるのにちょうど良い大きさになっています

サンプルコードを参考にしつつ、日時の設定と読み出しを行ってみました。
まずは日時の設定。
#class ds3231内
def set_time_to_RTC_hhmmss(self, YY, MM, DD, WW, hh, mm, ss):
setTimeStr = "%02d%02d%02d%02d%02d%02d%02d" % (ss, mm, hh, WW, DD, MM, YY)
setRTCstr = binascii.unhexlify(setTimeStr)
self.bus.writeto_mem(int(self.address), int(self.start_reg), setRTCstr)
def copy_time_to_RTC():
rtc_pico = machine.RTC()
dti = rtc_pico.datetime()
if dti[3] == 6: # sunday
week = 1
else:
week = dti[3] + 2
rtc.set_time_to_RTC_hhmmss(dti[0] - 2000, dti[1], dti[2], week, dti[4], dti[5], dti[6])
class ds3231内の set_time_to_RTC_hhmmss()は、年月日、曜日、時分秒を引数に取ってRTCに日時を設定します。曜日は日曜始まりで日曜=1です。
実際に使う時はPicoのクロックからのコピーが基本になると思ったので copy_time_to_RTC()関数も作りました。Picoのクロックを読んで外部RTCに現在の日時を設定します。
Picoの曜日は月曜はじまりなので曜日の場合分けをやってるけど、他は machine.RTC の datetime()関数で得たデータを copy_time_to_RTC にほぼそのまま渡してるだけです。
つづいて読み出し。はじめにサンプルコードを読んだ時は何をやっているのかよくわかりませんでした。慣れてる C のソースも読みながらなんとか形に。
def dec2hex(numDec):
strHex = hex(numDec)
if (len(strHex) == 4):
s10 = strHex[2]
s1 = strHex[3]
else:
s10 = "0"
s1 = strHex[2]
return (int(s10)*10+int(s1))
#class ds3231内
def read_time(self, t2):
t = self.bus.readfrom_mem(int(self.address),int(self.start_reg),7)
t2.append(dec2hex(t[6]))
t2.append(dec2hex(t[5]))
t2.append(dec2hex(t[4]))
t2.append(dec2hex(t[2]))
t2.append(dec2hex(t[1]))
t2.append(dec2hex(t[0]))
読み出したデータを引数として渡した配列に積んでいるのですが、データそのままだと意味不明な数字です。
これを hex() 関数で16進数の文字列にしたものを、10進数の数字として読む
という不思議な仕様になっています。なにか意味があるんだろうけど。。。
ともかく、上記を行う dec2hex()関数を作って正しいデータを読む事ができるようになりました。
今回は曜日データは取得していませんが、read_time()関数内の t[3]に曜日データ(日曜はじまりで、日曜 = 1)が入っています。
8月5日朝の実行結果
内蔵RTC:(2025, 8, 5, 1, 6, 8, 21, 0) 外部RTC:2025/08/05, 06:08:16
約2週間で6秒の誤差。これなら2ヶ月間、再設定なしで使えそうです。


コメント