この記事でわかること
ラズパイ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サーバから日時を取得する方法を学びました。