| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- from Debug import Debug
- from machine import Pin
- from machine import RTC
- import utime as time
- from JJYDecoder import JJYDecoder
- from micropython import schedule
- from machine import Timer
- from TimeSyncer import TimeSyncer
- # 定数定義
- STATE_IDLE = 0
- STATE_TRY = 1
- STATE_RETRY = 2
- class JJYReceiver(Debug,TimeSyncer):
- def __init__(self, jjydec: JJYDecoder, pon_pin: int, pon_pol: int, band_sel_pin:int, preferred_band:int, retry_minute=10, sync_indicator_pin=17):
- """
- コンストラクタ
- Args:
- jjydec: JJYDecoderのインスタンス
- pon_pin: 電源制御(PON)を接続しているGPIO番号
- pon_pol: 電源制御の極性(電源オンになる値)
- band_sel_pin: バンド選択を接続しているGPIO番号
- preferred_band: 優先したいバンド(1か0)
- retry_minute: JJYデコード試行のリトライ時間(分)
- sync_indicator_pin: 同期インジケーターLEDのGPIO
- """
- # JJYデコーダーにコールバックを設定
- self.jjy = jjydec
- self.jjy.add_callback(self.decoded)
- # 電源制御
- self.pon = Pin(pon_pin, Pin.OUT)
- # まず電源を切っておく
- self.pon.value(pon_pol ^ 1)
- self.pon_polality = pon_pol
- # バンド選択
- self.band_select = Pin(band_sel_pin, Pin.OUT)
- self.estimated_band = preferred_band
- self.band_select.value(self.estimated_band)
- self.retry_count = retry_minute # リトライ分
- self.first_try = True # 初回試行
- self.try_counter = 0 # 試行カウンタ
- self.idle_counter = 0 # アイドリングカウンタ
- # 現在のステート
- self.state = STATE_TRY
- # 同期インジケーター
- self.sync_indicator = Pin(sync_indicator_pin,mode=Pin.OUT)
- self.sync_indicator.value(0) # まず消灯
- # タイマー
- self.tm = Timer()
- # タイマーハンドラ起動時呼び出し
- self._timer_handler(self.tm)
-
- def sync_start(self):
- """強制同期スタート"""
- if self.state == STATE_IDLE:
- self.idle_counter = 0 # カウンタリセット
- self.state = STATE_TRY
-
- def sync_stop(self):
- """同期停止"""
- if self.state == STATE_TRY or self.state == STATE_RETRY:
- self.state = STATE_IDLE
- self.try_counter = 0 # カウンタリセット
- self.idle_counter = 0
- self.jjy.stop() # 一旦停止
- self.pon.value(self.pon_polality ^ 1) # 一旦電源を切る
- def _tick(self, arg):
- """
- タイマー割り込みからスケジュールされる状態遷移・制御ロジック
- """
- self.dprint("--- tick %d---" % (self.idle_counter))
- if self.state == STATE_TRY or self.state == STATE_RETRY:
- if self.try_counter == 0: # 試行開始
- self.dprint("--- Try start ---")
- # JJY起動
- self.band_select.value(self.estimated_band) # バンド設定
- self.pon.value(self.pon_polality) # 電源オン
- self.jjy.restart()
- # インジケーターLED消灯
- self.sync_indicator.value(0)
- self.try_counter += 1
- # 試行回数を超えている
- if self.try_counter > self.retry_count:
- self.try_counter = 0 # カウンタリセット
- self.jjy.stop() # 一旦停止
- self.pon.value(self.pon_polality ^ 1) # 一旦電源を切る
- if self.state == STATE_TRY:
- self.state = STATE_RETRY
- self.dprint("--- Retry start ---")
- self.estimated_band ^= 1 # バンドを変えてみる
- time.sleep(5) # 少し待つ
- elif self.state == STATE_RETRY:
- self.estimated_band ^= 1 # バンドを戻す
- if self.first_try: # バンドを変えて試行を繰り返す
- self.state = STATE_TRY
- time.sleep(5) # 少し待つ
- else:
- self.state = STATE_IDLE # 諦める
- self.sync_indicator.value(0) # インジケータ消灯
- elif self.state == STATE_IDLE:
- self.idle_counter += 1
- if self.idle_counter >= 60: # アイドル1時間経過
- self.idle_counter = 0
- self.try_counter = 0
- self.state = STATE_TRY # 時間合わせの試行を開始
- def _timer_handler(self, t):
- """
- 1分周期のハードウェアタイマーハンドラ。
- MicroPythonのGCストールを避けるため、実際の処理はschedule()に委譲する。
- """
- schedule(self._tick, 0)
- self.tm.init(mode=Timer.ONE_SHOT, period=1000*60, callback=self._timer_handler)
- def decoded(self, args):
- """
- JJY信号のデコード成功時に呼ばれるコールバック
- """
- self.first_try = False
- self.state = STATE_IDLE # 成功したのでアイドルに切り替える
- self.try_counter = 0 # カウンタリセット
- self.idle_counter = 0
- self.dprint("--- Succeeded JJY signal decode ---")
- # インジケーター点灯
- self.sync_indicator.value(1)
- # 電源を切る
- self.jjy.stop()
- self.pon.value(self.pon_polality ^ 1)
|