MicroPythonでTinyRTCを使う

時間でオンオフできるライトを作るため、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モジュールの形式ではないことでした。

Updated: 2026年1月11日 — 04:40

コメントを残す

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