時間でオンオフできるライトを作るため、TinyRTCというモジュールを買いました。
この記事では、ハードウェアにATOM LiteというESP32デバイスを、ソフトウェアにMicroPythonを使って、TinyRTCにNTCサーバから取得した時刻をセットするところまで行います。

【目次】
– 使用モジュール
– CR2032電池を使うための改造
– 時刻の設定
使用モジュール
設定時刻で自動的にオンオフするライトがつくりたく時刻を測るRTC(リアルタイムクロック)モジュールを買いました。
リアルタイムクロックモジュール (DS1307) ¥175
https://electronicwork.shop/items/66968597a18e8d095b23ae7c
200円以内で手に入る安価なRTCです。書いてないですが、TinyRTCというシリーズで、基板にはHW-111と記載されています。Gemini先生曰く、TinyRTCはシリーズ名で幾つかバージョンがあり、これはその型番の一つとのこと(コピー品?って思ってました)。レビューを見ると安価な分、精度は悪く、結構ずれていくらしいですが。入力電圧は5V限定です。
パーツ箱を開けると、別のRTCモジュールあったんですけどね。。。そういえば、数回前の記事がそれだったわー。今だと800円、しかも電池ホルダーをついていないし、そう考えると、めちゃお安いですね。
CR2032電池を使うための改造
TinyRTCは、充電ができるLIR2032を対象としていますが、100円ショップ等でも買える同形状の使い捨て電池CR2032を使えるようにする改造が、有志の方で行われているので、今回はそれに倣って改造します。
このモジュール、バッテリバックアップモードの消費電流は500nA以下とのことなので、CR2032の容量が220mAhとすると、50年もつことになります。Gemini先生によると、実際のところは5〜10年と予想されるとのことですが、十分でしょう。
このモジュールには充電回路が含まれており、そのまま使うと、CR2032を充電しようとして最悪は破裂する可能性もあるらしい。
ちなみに、充電回路がなくても、LIR2032は電圧が3.7V、CR2032は3.0Vと異なるため、互換性にも要注意です。
【参考サイト】
DS1307 RTC リアルタイムクロックモジュールを使ってみた
https://kenaka.xsrv.jp/kotapon/2021/09/06/ds1307tukate/
データシート(同一製品の保証なし)
https://pdf.direnc.net/upload/tinyrtc-i2c-modul-datasheet.pdf
【方法】
D1、R4、R5、R6を取り外し、R6をショートさせます。
【理由】
・D1は給電時の逆流防止ダイオードで、取り外すと、電池への給電回路が遮断されます。
・R6は電流制限抵抗?(分圧抵抗を兼ねてる?)で、取り外して短絡させることで、電圧降下を減らして給電を安定化させます。
・R4は分圧抵抗で、取り外すことで、電池の消費電力を抑えられます。
・R5は電池への給電の電流制限抵抗っぽいので、D1を取り外した時点で回路は遮断されてるはずで、取る必要もなさそうですが、いらないからってことなのかな。
回路図

Before

After

最初、R6をはんだだけでショートさせようとしてモリモリに盛ってしまった(途中で諦めた)。
【注意】
バージョンによって、対象の番号は異なる可能性があるとのこと。最初、Gemini先生は、取り外して短絡するのはR3抵抗との回答でした。確認方法として、短絡させる抵抗はDS1307の3番ピンに繋がっているはずなので、テスターで確認します。D1はバージョンによる違いは無さそうですが、電池のプラス側に繋がっているはずです。
時刻の設定
最初はラズパイで設定しようかと思ってたんですが、よりお手軽なESP32デバイス、ATOM Liteを使い、MicroPythonで時刻の設定をしました。
MicroPythonのSoftI2Cモジュールで通信します。
配線
SoftI2Cでは任意のピンを設定できます。今回は、G21をSCL、G25をSDAに使いました。
ATOM Lite TinyRTC G21 --------- SCL G25 --------- SDA 5V ---------- VCC GND --------- GND

ソースコード
インターネットから時刻を取得するプログラムは下記のサイトのコードを使わせてもらいました。
ntptime.pyを保存します。
micropython on ESP32 でNTPサーバから時刻取得
https://ippei8jp.hatenablog.jp/entry/2017/08/18/135755
TinyRTCとの通信には、下記のサイトのプログラムを使わせてもらいました。
ds1307.pyを保存します。
MicroPython TinyRTC I2C module
https://github.com/mcauser/micropython-tinyrtc-i2c/
以下が記述したメインプログラム。
main.py
import machine
from machine import Pin, SoftI2C
import neopixel
import utime
import network
import ntptime
import ds1307
def light_color_led(r,g,b):
pin = machine.Pin(27, machine.Pin.OUT)
np = neopixel.NeoPixel(pin, 1)
np[0] = (r, g, b)
np.write()
def connect_wifi():
print('connecting to network...',end=' ')
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
sta_if.active(True)
sta_if.connect('WIFI-NAME','PASSWORD') #要変更
st = utime.time()
while not sta_if.isconnected():
if utime.time()-st > 10: #timeout
print('cannot connect wifi')
return False
utime.sleep(0.1)
print('connected!')
else:
print('already connecting')
print('network config:', sta_if.ifconfig())
return True
def get_time_from_ntp():
dt = utime.localtime(ntptime.time())
#year,month,mday,hour,minute,secound,weekday,yearday
rt = [0,0,0,0,0,0,0,0]
rt[0] = dt[0] #year
rt[1] = dt[1] #month
rt[2] = dt[2] #day
rt[3] = dt[6] #weekday
rt[4] = dt[3] + 9 #hour
rt[5] = dt[4] #minute
rt[6] = dt[5] #secound
rt[7] = 0 #subsecound
return tuple(rt)
def set_time_to_rtc(dt):
i2c = SoftI2C(scl=Pin(21), sda=Pin(25), freq=100000)
ds = ds1307.DS1307(i2c)
ds.datetime(dt)
ds.halt(False)
def get_time_from_rtc():
i2c = SoftI2C(scl=Pin(21), sda=Pin(25), freq=100000)
ds = ds1307.DS1307(i2c)
return ds.datetime()
def main():
light_color_led(10,0,0)
connect_wifi()
utime.sleep(1)
light_color_led(0,0,10)
#dt = get_time_from_ntp()
#set_time_to_rtc(dt)
#print(dt)
#utime.sleep(3)
light_color_led(0,10,0)
dt = get_time_from_rtc()
print(dt)
utime.sleep(1)
light_color_led(0,0,0)
if __name__ == '__main__':
main()
簡単にできて感謝ですねー。
時刻設定部分はコメントアウトしています。
ちょっと戸惑ったのは、ds1307.pyの時刻データの配列がdatetimeモジュールの形式ではないことでした。
