6. @MQTTを使ったクラウドプレイヤー¶
このプロジェクトを始める前に、 5. @MQTTを使用したクラウド呼び出しシステム プロジェクトを先に完了させて、いくつかのモジュールのインストールとHiveMQプラットフォームの設定を完了することをお勧めします。
このプロジェクトでは、Pico Wは購読者として動作し、トピックの下で曲名を受信します。 曲名がコード内に既に存在する場合、Pico Wはブザーでその曲を演奏します。
1. 必要なコンポーネント
このプロジェクトでは、以下のコンポーネントが必要です。
こちらのリンクで一式を購入すると便利です:
名前 |
このキットに含まれるアイテム |
リンク |
---|---|---|
ケプラーキット |
450+ |
以下のリンクから個別に購入することもできます。
SN |
コンポーネント |
数量 |
リンク |
---|---|---|---|
1 |
1 |
||
2 |
マイクロUSBケーブル |
1 |
|
3 |
1 |
||
4 |
数本 |
||
5 |
1(S8050) |
||
6 |
1(1KΩ) |
||
7 |
受動型 ブザー |
1 |
|
8 |
1 |
||
9 |
18650バッテリー |
1 |
|
10 |
バッテリーホルダー |
1 |
2. 回路を作成する
キットには2つのブザーが含まれていますが、ここでは受動ブザー(裏側に露出したPCBがあるもの)を使用します。このブザーはトランジスタが必要です。ここではS8050を使用します。
警告
ダイアグラムに示されているように、Li-poチャージャーモジュールを接続してください。そうしないと、ショートしてバッテリーや回路が損傷する可能性があります。
3. コードを実行する
kepler-kit-main/iot
のパスでplay_music.py
ファイルをRaspberry Pi Pico Wにアップロードします。kepler-kit-main/iot
のパスで6_mqtt_subscribe_music.py
ファイルを開き、 現在のスクリプトを実行 ボタンをクリックするか、F5を押して実行します。注釈
コードを実行する前に、Pico Wに
do_connect.py
およびsecrets.py
スクリプトが存在することを確認してください。ない場合は、 1. ネットワークへのアクセス を参照して作成してください。ブラウザで HiveMQ Web Client を開き、「トピック」欄に
SunFounder MQTT Music
、 メッセージ 欄に曲名を入力します。 Publish ボタンをクリックすると、Pico Wに接続されたブザーが対応する曲を演奏します。このスクリプトを起動可能にしたい場合、Raspberry Pi Pico Wに
main.py
として保存できます。
どうやって動作するのか?
理解しやすくするために、MQTTのコードは他の部分から分離されています。 その結果、MQTTの購読に関する最も基本的な機能を3か所で実装する以下のコードが得られます。
import time
from umqtt.simple import MQTTClient
from do_connect import *
do_connect()
mqtt_server = 'broker.hivemq.com'
client_id = 'Jimmy'
# to subscribe the message
topic = b'SunFounder MQTT Music'
def callback(topic, message):
print("New message on topic {}".format(topic.decode('utf-8')))
message = message.decode('utf-8')
print(message)
try:
client = MQTTClient(client_id, mqtt_server, keepalive=60)
client.set_callback(callback)
client.connect()
print('Connected to %s MQTT Broker'%(mqtt_server))
except OSError as e:
print('Failed to connect to MQTT Broker. Reconnecting...')
time.sleep(5)
machine.reset()
while True:
client.subscribe(topic)
time.sleep(1)
MQTTブローカーに接続する際、 client.set_callback(callback)
関数を呼び出して、受信した購読メッセージのコールバックとして機能させます。
try:
client = MQTTClient(client_id, mqtt_server, keepalive=60)
client.set_callback(callback)
client.connect()
print('Connected to %s MQTT Broker'%(mqtt_server))
except OSError as e:
print('Failed to connect to MQTT Broker. Reconnecting...')
time.sleep(5)
machine.reset()
次に、フェッチされたトピックからのメッセージを出力するコールバック関数です。
MQTTはバイナリベースのプロトコルであり、制御要素もバイナリバイトです。したがって、これらのメッセージは message.decode('utf-8')
を使用してデコードする必要があります。
def callback(topic, message):
print("New message on topic {}".format(topic.decode('utf-8')))
message = message.decode('utf-8')
print(message)
While True
ループを使用して、このトピックに定期的にメッセージを取得します。
while True:
client.subscribe(topic)
time.sleep(1)
次に、音楽が演奏されます。この関数は play_music.py
スクリプトに配置され、主に3つの部分で構成されています。
Tone
: 基礎となる Piano key frequencies に基づいて特定の音をシミュレートします。NOTE_B0 = 31 NOTE_C1 = 33 ... NOTE_DS8 = 4978 REST = 0
Score
: プログラムが使用できる形式に楽曲を編集します。これらの楽譜は Robson Coutoの無料共有 からです。song = { "nokia":[NOTE_E5, 8, NOTE_D5, 8, NOTE_FS4, 4, NOTE_GS4, 4, NOTE_CS5, 8, NOTE_B4, 8, NOTE_D4, 4, NOTE_E4, 4,NOTE_B4, 8, NOTE_A4, 8, NOTE_CS4, 4, NOTE_E4, 4, NOTE_A4, 2], "starwars":[,,,], "nevergonnagiveyouup":[,,,], "gameofthrone":[,,,], "songofstorms":[,,,], "zeldatheme":[,,,], "harrypotter":[,,,], }
Play
: この部分は基本的に 3.2 カスタムトーン と同じですが、上記の楽譜に適合するようにわずかに最適化されています。import time import machine tempo = 220 wholenote = (60000 * 4) / tempo def tone(pin,frequency,duration): if frequency is 0: pass else: pin.freq(frequency) pin.duty_u16(30000) time.sleep_ms(duration) pin.duty_u16(0) def noTone(pin): tone(pin,0,100) def play(pin,melody): for thisNote in range(0,len(melody),2): divider = melody[thisNote+1] if divider > 0: noteDuration = wholenote/divider elif divider < 0: noteDuration = wholenote/-(divider) noteDuration *= 1.5 tone(pin,melody[thisNote],int(noteDuration*0.9)) time.sleep_ms(int(noteDuration)) noTone(pin)
メイン関数に戻って、MQTTが音楽の再生をトリガーするようにします。
コールバック関数で、送信されたメッセージが含まれている曲の名前であるかどうかを判断します。
そうであれば、曲名を変数 melody
に割り当て、 play_flag
を True
に設定します。
def callback(topic, message):
print("New message on topic {}".format(topic.decode('utf-8')))
message = message.decode('utf-8')
print(message)
if message in song.keys():
global melody,play_flag
melody = song[message]
play_flag = True
メインループでは、 play_flag
が True
であれば、 melody
を演奏します。
while True:
client.subscribe(topic)
time.sleep(1)
if play_flag is True:
play(buzzer,melody)
play_flag = False