瀏覽代碼

Add: NTP examples

Satoshi Yoneda 2 周之前
父節點
當前提交
fcd2cbed94

+ 1 - 1
PseudoJJY/README.md

@@ -16,7 +16,7 @@ JJYの電波は、PCやディスプレイなどが発するノイズにより受
 
 ## WIFI_CONFIG.py
 
-pseudo_jjy.pyと同時に下のような`WIFI_CONFIG.py`を作成し、Pico W/Pico 2 Wにアップロードして利用してください。
+pseudo_jjy.pyと同時に下のような`config.py`を作成し、Pico W/Pico 2 Wにアップロードして利用してください。
 
 ```python
 WIFI_CONFIG = {

+ 1 - 0
WaveClock/NTP_examples/.gitignore

@@ -0,0 +1 @@
+NTP_CONFIG.py

+ 26 - 0
WaveClock/NTP_examples/NTPClock.py

@@ -0,0 +1,26 @@
+"""
+NTPClock.py
+
+Pico W/Pico2 Wを利用したNTP時計のメインプログラム。
+"""
+from Debug import Debug
+from NTPSource import NTPSource
+from RTCClockApp import RTCClockApp
+from tm1637 import TM1637
+# 設定ファイル
+from NTP_CONFIG import NTP_CONFIG
+
+# 表示器
+disp = TM1637(sda_pin=NTP_CONFIG["tm1637_sda_pin"],contrast=4)
+# NTP時刻ソース
+ntp = NTPSource(NTP_CONFIG["ssid"], NTP_CONFIG["pass"],sync_indicator_pin=NTP_CONFIG["sync_indicator_pin"])
+
+# 時計アプリケーションクラス
+app = RTCClockApp(disp, ntp, ntp, 
+                  mode_select_pin=NTP_CONFIG["mode_select_pin"],
+                  force_sync_pin=NTP_CONFIG["force_sync_pin"])
+
+# 時計スタート
+app.run()
+# 終了処理
+disp.release()

+ 86 - 0
WaveClock/NTP_examples/NTPSource.py

@@ -0,0 +1,86 @@
+from TimeSource import TimeSource
+from TimeSyncer import TimeSyncer
+from Debug import Debug
+import utime as time
+import network
+import ntptime
+from machine import Timer
+from machine import Pin
+from micropython import schedule
+
+# Wi-Fi接続
+def wifi_connect(ssid, passkey, timeout=20):
+    conn = network.WLAN(network.STA_IF)
+    if conn.isconnected():
+        return conn
+    conn.active(True)
+    conn.connect(ssid, passkey)
+    while not conn.isconnected() and timeout > 0:
+        time.sleep(1)
+        timeout -= 1
+    if conn.isconnected():
+        return conn
+    else:
+        return None
+
+class NTPSource(Debug, TimeSyncer, TimeSource):
+    """NTP時刻ソース"""
+
+    def __init__(self, ssid, passwd, sync_indicator_pin=18, sync_interval=120):
+        """
+        Args:
+        sync_indicator_pin: 同期インジケーターのGPIO
+        sync_interval: 同時間隔(分)
+        """
+        # Wi-Fi関連
+        self.ssid = ssid        # SSID
+        self.passwd = passwd    # パスフレーズ
+        # 同期インジケーター
+        self.sync_led = Pin(sync_indicator_pin, Pin.OUT)
+        self.sync_led.value(0)      # 消灯
+        # 同時間隔(デフォルト2時間)
+        self.interval = sync_interval
+        # タイマー1分
+        self.tm = Timer()
+        self.tm.init(mode=Timer.PERIODIC, period=60*1000, callback=self._timer_handler)
+        # タイマーカウンタ
+        self.tick_counter = self.interval + 1
+        # コールバック関数
+        self._callbacks = []
+    
+    def _timer_handler(self, t):
+        self.tick_counter += 1
+        if self.tick_counter > self.interval:   # 同時間隔
+            self.tick_counter = 0   # カウンタリセット
+            schedule(self.sync_start, 0)
+
+    def sync_start(self, arg=0):
+        # まずWi-Fi接続
+        conn = wifi_connect(self.ssid, self.passwd)
+        if conn is not None:
+            conn.ifconfig()     # IP設定
+            time.sleep(1)       # 安定するまで待つ
+            ntptime.host = "ntp.nict.jp"
+            now = ntptime.time() + 9 * 60 * 60  # 日本時間
+            data = (now, time.ticks_ms())       # (UNIXエポックタイム, 受信ticks_ms)
+            conn.active(False)      # 電源を切る
+            self.sync_led.value(1)  # 同期LED点灯
+            try:
+                for callback in self._callbacks:
+                    if callback is not None:
+                        schedule(callback, data)
+            except RuntimeError:
+                self.dprint("--- schedule() queue full ---")
+        else:
+            self.dprint("--- Cant connect to %s", self.ssid)
+    
+    def sync_stop(self):
+        """特にすることはなにもない"""
+        return
+
+    def add_callback(self, callback):
+        """
+        時刻を通知するコールバック関数
+        """
+        if callback is not None:
+            self._callbacks.append(callback)

+ 30 - 0
WaveClock/NTP_examples/README.md

@@ -0,0 +1,30 @@
+# おまけ~NTPサンプル
+
+`TimeSource`/`TimeSyncer`の実装例として、NTPを日時ソースとして使うサンプルを用意しました。このソースはWi-Fi接続ができるPico WおよびPico 2 W用で、Wi-FiがないPico/Pico 2では利用できません。
+
+## NTP時計の使い方
+
+まず、次のような`NTP_CONFIG.py` を環境に合わせて作成してください。
+
+```python
+NTP_CONFIG = {
+    "ssid": "your_wifi_ssid",       # 接続するアクセスポイント名
+    "pass": "your_accesspass",      # 接続パスワード
+    "tm1637_sda_pin": 2,            # TM1637モジュールのDIO(SDA)が接続されているGPIO
+    "sync_indicator_pin": 18,       # 強制同期スイッチのGPIO
+    "mode_select_pin": 16,          # 表示モード切替スイッチのGPIO
+    "force_sync_pin": 17,           # 同期インジケーターLEDのGPIO
+}
+```
+
+このディレクトリにある2つのソースと、1つ上のディレクトリにある次のソースを合わせてPico W/Pico 2 Wにアップロードします。
+
+* RTCClockApp.py: 時計アプリクラス
+* NTPSource.py: NTP時刻ソース
+* TimeSource.py: 基底クラスTimeSource
+* TimeSyncer.py: 基底クラスTimeSyncer
+* NTPClock.py: メインプログラム
+* NTP_CONFIG.py: 設定ファイル(上記)
+* tm1637.py: TM1637ライブラリ
+
+NTPClock.pyを実行します。少し待つとTM1637のLEDディスプレイに時刻が表示されるでしょう。デフォルトでは120分おきにNTPに接続してRTCの補正を行います。