はじめに
RaspberryPi Pico WでMQTTを使う方法を解説します。
言語はMicroPython、ライブラリはumqtt.simpleを使用します。MQTTブローカーにはWindows版のMosqittoを使用します。
~ この記事の内容 / Contents ~
環境
この記事で使用する環境は以下の通りです。
環境 | 内容・バージョンなど | 備考 |
開発用/ブローカー用のOS | Windows11 | |
言語 | MicroPython | |
開発環境 | Thonny Ver.3.3.13 | |
ボード | RaspberryPi Pico | |
Mosquitto | Ver.2.0.15 |
システム構成
MQTTのシステム構成は以下の通りです。
WindowsPC内にMQTT(Mosquitto)のブローカーを起動し、トピック「test/topic」に対してクライアント(PicoW・WindowsPC)から、Pub/Subの通信を行います。
※ Windows側のクライアントはMosquitto付属の「mosquitto_sub.exe」を使用します。
RaspberryPi Pico W との接続
配線は必要ありません。Pico W本体搭載のWi-Fiモジュールで通信します。
使用する部品
Pico W 本体
Raspberry Pi Pico W本体です。技適対応品かどうか心配…という方は、以下のページで出品者を「共立エレショップAセレクト」(国内の有名ショップ)にして購入してください。
USBケーブル Micro-B
本体にUSBケーブルが付属していないので、別途購入が必要です。PicoW側の形状は「Micro-B」、ひと昔前のスマホと同じタイプを使います。現在主流のTypeCではないので注意が必要です。
Mosquittoのインストール
WindowsPCにMosquittoをインストールします。手順についてはこちらのQiitaの記事が分かりやすいです。
リンク先に記載はありませんが、Mosquittoを手動起動する際は、「-c」オプションで設定ファイルのパスを指定してください。設定ファイルをカレントフォルダに置いておいても、デフォルトでは読み込んでくれないので注意が必要です。
"C:\Program Files\mosquitto\mosquitto.exe" -v -c "C:\Program Files\mosquitto\mosquitto.conf"
上記のコマンドは、手動起動では問題ありませんが、Windowsのサービスとして起動させると、一定時間内に起動できないということで、エラーになります。サービスとしての起動方法は、分かり次第追記します。
プログラム概要
今回のプログラムの概要は以下の通りです。
- Pico WをWi-Fi・ブローカーに接続する
- Pico W から温度情報をブローカーに送る
- ブローカーからのPubを確認する。
- Pico Wで文字列を表示する
Mosquittoブローカー・クライアントの起動
後述するプログラムを実行する前にWindowsでブローカーとクライアントを起動します。コマンドプロンプトを「3つ」起動して、それぞれ以下のコマンドを入力してください。
ブローカーの起動
"C:\Program Files\mosquitto\mosquitto.exe" -v -c "C:\Program Files\mosquitto\mosquitto.conf"
クライアント(Sub)の起動
"C:\Program Files\mosquitto\mosquitto_sub.exe" -h localhost -t test/topic
クライアント(Pub)の起動
"C:\Program Files\mosquitto\mosquitto_pub.exe" -h localhost -t test/topic -m "test"
実行結果
後述するプログラムの実行結果です。
Mosquitto(ブローカー)・Mosquitto_pub/subを実行した状態で、Pico Wのプログラムを起動するとThonnyのコンソールに以下のように温度と文字列が表示されます。
Mosquitto各種の表示
Mosquitto各種(ブローカー・Pub・Sub)の実行時の表示は以下の通りです。
Mosquitto(ブローカー)
Mosuquitto_sub
Mosquitto_pub
※Mosquitto_pubは特に画面表示されません。
全体コード
全体コードは以下の通りです。詳細な内容は後述する「コードのポイント」で解説します。
import time
import network
from umqtt.simple import MQTTClient
import machine
from picozero import pico_temp_sensor,
import sys
#
# Wi-Fi ルーターのSSIDとパスワードです。
# お使いの設定に書き換えてください。
#
ssid = 'NAME OF YOUR WIFI NETWORK'
password = 'YOUR SECRET PASSWORD'
#
# Wi-Fiに接続する関数です
#
def connect():
#Connect to WLAN
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
while wlan.isconnected() == False:
print('Waiting for connection...')
time.sleep(1)
ip = wlan.ifconfig()[0]
print(f'Connected on {ip}')
return ip
#
# 受信(Subscribe)したメッセージを表示する関数です
#
def printMessage(topic, message):
# 受信データはbytes型なのでUTF-8の文字列に変換してから表示します
print("topic:" + topic.decode("utf-8") )
print("message:" + message.decode("utf-8") )
#
# メインの処理部です
#
# ブローカーのIPやトピック名を定義します。
mqttBroker = '192.168.10.9'
myId = 'esu'
topic= b'test/topic1'
# MQTTのオブジェクト(変数)を定義します
client = MQTTClient(myId, mqttBroker, keepalive=3600)
# 受信(Subscribe)した時に呼ぶ関数を設定します
client.set_callback(printMessage)
# Wi-Fiに接続します
connect()
try:
# ブローカーに接続します
client.connect()
# Subscribeするトピックを登録します。(注:接続前はエラー)
client.subscribe(topic)
except:
# ブローカーへの接続に失敗した場合は、プログラムを終了します
print("Could not connect to mqtt server.")
sys.exit()
print("mqqtt connect done ")
#
# 温度センサの情報を3秒ごとにPublishします
#
while True:
# Pico W 本体の温度情報を取得します
temp = pico_temp_sensor.temp
# 送信(Publish)用のメッセージに温度を代入します
msg = " \"temp\":" + str(temp)
# 送信(Publish)します。
client.publish(topic, msg)
# ブローカーからのPublishをチェックします。
client.check_msg()
time.sleep(3)
コードのポイント
MQTTオブジェクトの作成
クライアント(Pico W) で使うId、ブローカーのIP、keepAliveを設定します。keepaliveは指定時間クライアントから送信がない場合、自動的にブローカーが切断するための時間です。指定時間の1.5倍の秒数が適応されます。
# MQTTのオブジェクト(変数)を定義します
client = MQTTClient(myId, mqttBroker, keepalive=3600)
Subscribe用関数の登録
登録したトピックからの受信をチェックし、受信がった場合に、呼び出してもらう関数を指定します。
# 受信(Subscribe)した時に呼ぶ関数を設定します
client.set_callback(printMessage)
Wi-Fiへの接続
Wi-Fiへ接続するためのconnect関数を呼び出します。
端末モード(STA_IF)でWi-Fiへ接続します。wlan.connect関数は接続完了を待たずに処理が進むため、isConnect関数で接続が完了するまでループで待機します。
この関数はPico Wのチュートリアルと同じコードです。詳細はチュートリアル解説の記事をご覧ください。
#
# Wi-Fiに接続する関数です
#
def connect():
#Connect to WLAN
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
while wlan.isconnected() == False:
print('Waiting for connection...')
time.sleep(1)
ip = wlan.ifconfig()[0]
print(f'Connected on {ip}')
return ip
# ~~~~~ 中略 ~~~~~
# Wi-Fiに接続します
connect()
ブローカーへの接続とSubscribeの登録
umqttconnect関数を使ってブローカーと接続します。接続が完了したら受信(Subscribe)したい、トピックを設定します。
# ブローカーに接続します
client.connect()
# Subscribeするトピックを登録します。(注:接続前はエラー)
client.subscribe(topic)
ブローカーに”接続する前”にトピックの登録を行うと、以下のエラーが発生します。ブローカーへの接続完了後に登録するようにしてください。
AttributeError: 'NoneType' object has no attribute 'write'
温度情報取得と配信(Publish)
picozeroライブラリのico_temp_sensor.tempを使って、Pico W 本体に搭載されている温度センサの温度情報を取得します。
「”temp”:25.000 」とJSON形式になるようにメッセージを作成し、ブローカー(トピック)に向けて送信(Publish)します。
#
# 温度センサの情報を3秒ごとにPublishします
#
while True:
# Pico W 本体の温度情報を取得します
temp = pico_temp_sensor.temp
# 送信(Publish)用のメッセージに温度を代入します
msg = " \"temp\":" + str(temp)
# 送信(Publish)します。
client.publish(topic, msg)
# ブローカーからのPublishをチェックします。
client.check_msg()
time.sleep(3)
MQTTのプロトコルには、フォーマットの取り決めはない(アプリケーション側に委ねる) ため、JSON形式は必須ではありません。
まとめ
RaspberryPi Pico WでMQTTを使う方法を解説しました。
IOTでよく使われるMQTTですが、HTTPに比べて通信内容が簡単なのがうれしいですよね。Pico Wを使って他のデバイスと通信をしたいという方は、ぜひMQTTによる通信も候補にいれてみてください。
参考になればうれしいです。
お知らせ
MicroPythonのプログラミングガイドブックが遂に発売!
「MicroPython」の本が遂にでました。
この一冊で、MicroPythonの言語仕様から、プログラミングの仕方まで”ガッツリ”学べます!
内容は、普段別言語で開発している人や、これからマイコンを始める(工学系の)学生を対象としているので「初心者向け」ではありません。しかし、「自前のライブラリの作成」が目標なので、これ一冊で「ガッツリ」とMicroPythonを学ぶことができます。
全ての内容はここでは紹介しきれないので、詳細は以下のAmazonページをご覧ください。目次だけでも”ガッツリ”なのが確認できると思います。
Pico/Pico W関連のおすすめ本
RaspberryPi Pico / Pico W関連のおすすめ本を独断と偏見で3つ選んでみました。Picoやるならとりあえずこれ買っとけ的な本や、電子工作全般で使える本などを厳選しています。
質問・要望 大歓迎です
「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。
使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。