Wi-Fiを使って標準時刻を取得/表示。

2024年9月6日

【 当サイトには広告リンクが含まれています。 】


ラズパイPicoW(Raspberry Pi Pico W)に搭載されている2.4GHz無線LAN(Wi-Fi)を使って、 NTP(Network Time Protocol)サーバに接続し、標準時刻を取得した後、液晶ディスプレイ(LCD)に日付/時刻を表示させます。


実験準備

実験に必要な機器と部品を準備します。

機器とプログラム

「I2C通信で液晶ディスプレイ(LCD)に文字表示。」の回路を使い、プログラムを改造して実験します。


標準時刻の取得/表示プログラムの実行

Wi-Fiを使ってネットワークに接続し、指定したNTP(Network Time Protocol)サーバから、標準時刻データを取得します。

取得した標準時刻データを、ラズパイPicoW(Raspberry Pi Pico W)内のローカル時刻(内臓のリアルタイム・クロック)と同期させます。

同期させたローカル時刻は、協定世界時(UTC)であるため、日本標準時 (JST)に変換し、日付、時刻の形式に整形した後。液晶ディスプレイ(LCD)に表示させます。

Raspi4BのThonnyを起動し、次のコードを「エディタ」に入力するか、リストをコピーしてペーストします。


##################################################
#
#      モジュールの読み込み
#
##################################################

#I2C
from machine import Pin, I2C
from pico_i2c_lcd import I2cLcd

#Network/NTP
import network
import rp2
import ntptime
import time


##################################################
#
#      Wi-Fi接続/時刻パラメータ
#
##################################################

#Wi-Fi接続パラメータ
ssid = "Wi-FiルータのSSIDを設定します。"
password = "Wi-Fiルータのパスワードを設定します。"

#日本標準時(UTC+9時間)
UTC_OFFSET = 9

#NTPサーバ ドメイン
NTP_SRV = "ntp.nict.jp"


##################################################
#
#      液晶ディスプレイ(LCD)初期設定
#
##################################################

#I2Cを利用するため、オブジェクト(i2c)を作成
i2c = I2C(0,sda=Pin(16), scl=Pin(17), freq=400000)


#LCDのパラメータを設定
ADR = 0x27
ROW = 2
COL = 16


#LCDを利用するため、オブジェクト(lcd)を作成
lcd = I2cLcd(i2c, ADR, ROW, COL)

##################################################
#
#      【関数】Wi-Fiに接続
#
##################################################

def wifi_connect():
    #Wi-Fi地域(日本)の設定
    rp2.country('JP')

    #ステーションインタフェースの有効化
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)

    #Wi-Fiの省電力をオフに設定
    wlan.config(pm = 0xa11140)
    
    #液晶ディスプレイ画面を消去
    lcd.clear()

    #Wi-Fiに接続
    wlan.connect(ssid, password)
    while not wlan.isconnected() and wlan.status() >= 0:

        #LCDに文字表示
        lcd_disp("Wait for", "connection...")       
        time.sleep(1)
    
    ip_add = wlan.ifconfig()[0]
    lcd_disp("Connected on", f' {ip_add}')
    
    #ダミー
    time.sleep(2)

    return ip_add


##################################################
#
#      【関数】NTPサーバから日時取得
#
##################################################

def get_ntp_time():

    #NTPサーバ
    ntptime.server = NTP_SRV
    
    #NTPサーバへの接続待ち
    time.sleep(1)
    
    #ローカル時刻をUTC標準時刻に同期
    ntptime.settime()
      
    #液晶ディスプレイ画面を消去
    lcd.clear()
    
    #LCDに文字表示
    lcd_disp("Connected to", "NTP server.")
    
    #ダミー
    time.sleep(2)
   

##################################################
#
#      【関数】日付・時刻整形
#
##################################################

def format_dttm(day_tm):
    
    #日付
    dat = ("%4d/%02d/%02d" % (day_tm[0:3]))
    
    #時刻
    tm = ("%2d:%02d:%02d" % (day_tm[3:6]))
    
    return dat ,tm


##################################################
#
#      【関数】LCDに文字表示
#
##################################################

def lcd_disp(msg1, msg2):
    
    #LCDに文字を表示
    lcd.move_to(0, 0)
    lcd.putstr(msg1) 
    lcd.move_to(0, 1)
    lcd.putstr(msg2)


##################################################
#
#      【関数】日付時刻を取得
#
##################################################

def get_dattm():
     
    #ローカル時刻
    lcl_tm =  time.localtime(time.mktime(time.localtime()) + UTC_OFFSET * 60 * 60)          
   
    #日付・時刻整形
    dat ,tm = format_dttm(lcl_tm)
        
    return dat,tm
   
   
##################################################
#
#      メイン
#
##################################################


try:
    
    #Wi-Fiに接続
    ip_add = wifi_connect()
    
    #NTPサーバから日時取得
    get_ntp_time()
    
    #液晶ディスプレイ画面を消去
    lcd.clear()
    
    #液晶ディスプレイに日付・時刻表示
    while True:
        #日付・時刻を取得
        dat,tm = get_dattm()    
    
        #LCDに文字表示
        lcd_disp(dat, tm)
        
        #1秒待ち
        time.sleep(1)
        

except KeyboardInterrupt:
    # Turn off the display
    print("「Ctrl + c」キーが押されました。")
    
    #LCD消灯
    lcd.backlight_off()
    lcd.display_off()
    
    machine.reset()


Thonnyの「F5」キーを押して、標準時刻の取得/表示プログラムを実行すると、次のように液晶ディスプレイ(LCD)に表示されます。

「Wait for connection…」

 → 「Connected on xxx.xxx.xxx.xxx.」
   (xxxはラズパイPicoWのIPアドレス)

 → 「Connected to NTP server.」

 → 「YYYY/MM/DD hh/mm/ss 」



確認後、Thonnyの「Ctrl + c」キーを押すと、液晶ディスプレイ(LCD)が消灯し、処理が中断しますので、中断後、「Ctrl + F2」キーを押して、プログラムを終了させます。


任意のファイル名でラズパイPicoWに保存します。(ここでは「3_9wifintptm.py」で保存しました。)


標準時刻の取得/表示プログラムの仕組み

Wi-Fiに接続してNTPサーバから標準時刻を取得し、液晶ディスプレイ(LCD)に、日付/時刻を表示するまでのプログラムの動きを簡単に見ていきます。

【関数】は決められた処理を実行し、その結果を返す命令で、メインや他の関数から呼び出され、利用されます。

モジュールの読み込み

液晶ディスプレイ(LCD)との接続、ネットワーク及びNTPサーバーとの接続するためのモジュールをインポート(読み込み)ます。

#I2C ・・・・・・・・・・・・・・・・・・ 液晶ディスプレイ(LCD)との接続
from machine import Pin, I2C
from pico_i2c_lcd import I2cLcd

#Network/NTP ・・・・・・・・・・・・・・ネットワーク及びNTPサーバーとの接続
import network
import rp2
import ntptime
import time


Wi-Fi接続/時刻パラメータ

Wi-Fiルータに接続するための「SSID」、「パスワード」、協定世界時と日本標準時の時間差やNTPサーバのアドレスを設定します。

#Wi-Fi接続パラメータ
ssid = "Wi-FiルータのSSIDを設定します。"
password = "Wi-Fiルータのパスワードを設定します。"

#日本標準時(UTC+9時間)
UTC_OFFSET = 9

#NTPサーバ ドメイン
NTP_SRV = "ntp.nict.jp"


液晶ディスプレイ(LCD)初期設定

I2C通信を使って液晶ディスプレイ(LCD)を利用するため、I2C通信用のオブジェクト、LCD表示用のオブジェクトを作成します。

#I2Cを利用するため、オブジェクト(i2c)を作成
i2c = I2C(0,sda=Pin(16), scl=Pin(17), freq=400000)


#LCDのパラメータを設定
ADR = 0x27
ROW = 2
COL = 16


#LCDを利用するため、オブジェクト(lcd)を作成
lcd = I2cLcd(i2c, ADR, ROW, COL)


【関数】Wi-Fiに接続

Wi-Fi接続/時刻パラメータで設定した「SSID」と「パスワード」を使って、Wi-Fiネットワークに接続し、正常に接続された場合は、関数の呼び出し元に、ラズパイPicoWのIPアドレスを返します。

接続の状況、IPアドレスを液晶ディスプレイ(LCD)に表示します。

def wifi_connect():
    #Wi-Fi地域(日本)の設定
    rp2.country('JP')

    #ステーションインタフェースの有効化
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)

    #Wi-Fiの省電力をオフに設定
    wlan.config(pm = 0xa11140)
    
    #液晶ディスプレイ画面を消去
    lcd.clear()

    #Wi-Fiに接続
    wlan.connect(ssid, password)
    while not wlan.isconnected() and wlan.status() >= 0:

        #LCDに文字表示
        lcd_disp("Wait for", "connection...")       
        time.sleep(1)
    
    ip_add = wlan.ifconfig()[0]
    lcd_disp("Connected on", f' {ip_add}')
    
    #ダミー
    time.sleep(2)

    return ip_add


【関数】NTPサーバから日時取得

Wi-Fi接続/時刻パラメータで設定したNTPサーバから、標準時刻を取得し、ラズパイPicoWのローカル時刻(内臓のリアルタイム・クロック)に同期させます。

接続の状況を液晶ディスプレイ(LCD)に表示します。

def get_ntp_time():

    #NTPサーバ
    ntptime.server = NTP_SRV
    
    #NTPサーバへの接続待ち
    time.sleep(1)
    
    #ローカル時刻をUTC標準時刻に同期
    ntptime.settime()
      
    #液晶ディスプレイ画面を消去
    lcd.clear()
    
    #LCDに文字表示
    lcd_disp("Connected to", "NTP server.")
    
    #ダミー
    time.sleep(2)


【関数】日付・時刻整形

タプル形式で保存されている、日付・時刻データ(西暦の年、月、日、時、分、秒、曜日、年内の通算日数)を引数として受け取り、「西暦の年、月、日、時、分、秒」を「西暦の年/月/日」と「時:分:秒」の形式に整形します。

整形した結果を、呼び出し元に「西暦の年/月/日」と「時:分:秒」の形式で返します。

def format_dttm(day_tm):
    
    #日付
    dat = ("%4d/%02d/%02d" % (day_tm[0:3]))
    
    #時刻
    tm = ("%2d:%02d:%02d" % (day_tm[3:6]))
    
    return dat ,tm


【関数】LCDに文字表示

2つのメッセ―ジを引数として受け取り、それぞれ、液晶ディスプレイ(LCD)の上段と下段に表示します。

def lcd_disp(msg1, msg2):
    
    #LCDに文字を表示
    lcd.move_to(0, 0)
    lcd.putstr(msg1) 
    lcd.move_to(0, 1)
    lcd.putstr(msg2)


【関数】日付時刻を取得

標準時刻に同期したローカル時刻を、日本標準時(秒数)へ変換し、【関数】日付・時刻整形の引数として渡します。

【関数】日付・時刻整形で戻された、「西暦の年/月/日」と「時:分:秒」の形式データを、呼び出し元に戻します。

def get_dattm():
     
    #ローカル時刻
    lcl_tm =  time.localtime(time.mktime(time.localtime()) + UTC_OFFSET * 60 * 60)          
   
    #日付・時刻整形
    dat ,tm = format_dttm(lcl_tm)
        
    return dat,tm
   


メイン

上記で作成した関数を呼び出して、液晶ディスプレイ(LCD)の上段に、「西暦の年/月/日」を下段に「時:分:秒」を一秒ごとに表示します。

「Ctrl + c」キーを押すと、液晶ディスプレイ(LCD)が消灯し、ラズパイPicoWをリセットします。


try:
    
    #Wi-Fiに接続
    ip_add = wifi_connect()
    
    #NTPサーバから日時取得
    get_ntp_time()
    
    #液晶ディスプレイ画面を消去
    lcd.clear()
    
    #液晶ディスプレイに日付・時刻表示
    while True:
        #日付・時刻を取得
        dat,tm = get_dattm()    
    
        #LCDに文字表示
        lcd_disp(dat, tm)
        
        #1秒待ち
        time.sleep(1)
        

except KeyboardInterrupt:
    # Turn off the display
    print("「Ctrl + c」キーが押されました。")
    
    #LCD消灯
    lcd.backlight_off()
    lcd.display_off()
    
    machine.reset()


まとめ

ラズパイPicoW(Raspberry Pi Pico W)に搭載されている2.4GHz無線LAN(Wi-Fi)を使って、 NTP(Network Time Protocol)サーバに接続し、標準時刻を取得した後、液晶ディスプレイ(LCD)に日付/時刻を表示させました。

Wi-Fiを使ったネットワークへの接続方法、NTPサーバから日時を取得する方法を学びました。