はじめに
前回の記事では、Raspberry Pi を使用して、シリアル通信を介した HDMI 切替器の制御方法についてご紹介しました。今回はその続編として、MQTT を利用してインターネット経由で遠隔操作する仕組みについて詳しく解説します。
前回の記事はこちら
MQTT は、軽量で効率的な通信プロトコルとして広く使用されており、特に IoT デバイスとの通信に適しています。弊社では、このプロトコルを活用することで、リモートからの HDMI 切替操作を低遅延かつ安定した通信環境で実現しました。
本記事では、Raspberry Pi によるシリアル通信プログラムに加え、MQTT 通信の設定や実装方法について順を追って説明します。
関連記事
- 第1弾 Raspberry Pi を使って HDMI スイッチャーをシリアル通信で制御
- 第2弾 MQTT を使って HDMI スイッチャーをシリアル通信で制御
- 第3弾 映像エンコーダー、デコーダーを使ってRS-232CでHDMI スイッチャーを遠隔制御
MQTT とは
MQTT(Message Queuing Telemetry Transport) とは、軽量な通信プロトコルであり、主に IoT(モノのインターネット)デバイス間でのデータ送受信に利用されます。低帯域幅や不安定なネットワーク環境でも効率的に動作するよう設計されています。
MQTT を使った理由は以下の通りです。
- 軽量であり、通信量が非常に少ないため。
- SSH によるリモート操作も検討したが、不正ログインによる内部ネットワークへの侵入のリスクを懸念したため
- 現地に設置する際、Wi-Fi 接続のみで煩雑なネットワーク設定が不要となるため。
この切替器は設置場所の Wi-Fi につなぐだけで簡単に使用できるので非常にお手軽です。
また弊社の映像伝送装置には RS-232 信号を映像と一緒に送る機能がついております。その機能を使って遠隔地から HDMI 切替器に切替制御信号を送るといった事も可能です。
MQTT による HDMI スイッチャーのチャンネル変更プログラム
前回の記事では、Raspberry Pi を使用して、HDMI スイッチャーの USB ポートにシリアル通信でコマンドを送信し、複数の映像を切り替える方法を紹介しました。
今回は、2 台の Raspberry Pi を使い、送信側からの信号を MQTT を介して受信側に伝達し、HDMI スイッチャーのチャンネルを遠隔で切り替える仕組みについて解説します。
送信側の Raspberry Pi にはキーボードが接続されており、キー「1,2,3,4」のいずれかが押されると、その数字が MQTT を通じて受信側に送信されます。
受信側の Raspberry Pi では、受信した数字を基に、HDMI スイッチャーにチャンネル変更コマンドをシリアル通信で送信します。
注意
本記事では、MQTT のトピック名をkeyboard/switch
として設定しました。EMQX でのトピック設定方法に関する詳細は、こちらの記事のEMQX ブローカーのセットアップ手順
>アクセス権限の付与
をご参照ください。
送信機のプログラム
import evdev
import paho.mqtt.client as mqtt
import json
# MQTTブローカーの設定
MQTT_BROKER = 'xxxx1234.ala.asia-southeast1.emqxsl.com'
MQTT_PORT = 8883
MQTT_TOPIC = 'keyboard/switch'
MQTT_USER = 'zero-1'
MQTT_PASSWORD = 'password'
MQTT_CAFILE = '/home/pi/emqxsl-ca.crt'
# MQTTクライアントの設定
client = mqtt.Client()
client.username_pw_set(MQTT_USER, MQTT_PASSWORD)
client.tls_set(MQTT_CAFILE, tls_version=mqtt.ssl.PROTOCOL_TLSv1_2)
client.connect(MQTT_BROKER, MQTT_PORT, 60)
# デバイスのevent番号を指定(キーボードのイベントデバイス)
device = evdev.InputDevice('/dev/input/event0')
# キーボードイベントの読み取りと送信
try:
for event in device.read_loop():
if event.type == evdev.ecodes.EV_KEY:
if event.value == 1: # キーが押された
if event.code in [2, 3, 4, 5]: # 1, 2, 3, 4キー
# データの送信 (JSON形式)
data = json.dumps({'code': event.code})
client.publish(MQTT_TOPIC, data)
print(f"Sent: {data}") # 送信したデータを表示
except Exception as e:
print(f"An error occurred: {e}")
finally:
client.disconnect()
受信機のプログラム
シリアル通信の仕様
製造元から提供された情報によると、以下のコマンドを使用して HDMI スイッチャーのチャンネルを変更できます。
EZS OUTx VS INy : Set Output x To Input y {x=1, y=[1~4]}
また、ボーレートは 57600
と指定されています。
シリアルポートの確認方法
Raspberry Pi ではシリアルポートは通常 /dev/ttyUSB0
に割り当てられますが、確認するためには以下のコマンドを使用します。
ls /dev/ttyUSB*
これにより、接続されているシリアルデバイスを確認できます。
import paho.mqtt.client as mqtt
import json
import serial
# MQTTブローカーの設定
MQTT_BROKER = 'xxxx1234.ala.asia-southeast1.emqxsl.com'
MQTT_PORT = 8883
MQTT_TOPIC = 'keyboard/switch'
MQTT_USER = 'zero-2'
MQTT_PASSWORD = 'password'
MQTT_CAFILE = '/home/pi/emqxsl-ca.crt'
# シリアルポートの設定(ttyUSB0を使用)
ser = serial.Serial('/dev/ttyUSB0', 57600, timeout=1)
# シリアル信号を送る関数
def send_command(x, y):
command = f'EZS OUT{x} VS IN{y}\r\n'
ser.write(command.encode())
print(f'Sent: {command}')
# MQTTメッセージのコールバック関数
def on_message(client, userdata, msg):
try:
obj = json.loads(msg.payload)
code = obj['code']
if code == 2: # '1'キー
send_command(1, 1)
elif code == 3: # '2'キー
send_command(1, 2)
elif code == 4: # '3'キー
send_command(1, 3)
elif code == 5: # '4'キー
send_command(1, 4)
print(f"Received: {obj}")
except json.JSONDecodeError:
pass
# MQTTクライアントの設定
client = mqtt.Client()
client.username_pw_set(MQTT_USER, MQTT_PASSWORD)
client.tls_set(MQTT_CAFILE, tls_version=mqtt.ssl.PROTOCOL_TLSv1_2)
client.on_message = on_message
# MQTTブローカーに接続し、トピックを購読
client.connect(MQTT_BROKER, MQTT_PORT, 60)
client.subscribe(MQTT_TOPIC)
# メインループ
try:
print("Waiting for MQTT messages...")
client.loop_forever()
except KeyboardInterrupt:
client.disconnect()
ser.close()
print("終了しました。")
まとめ
今回の記事では、Raspberry Pi を使用してインターネット経由で HDMI スイッチャーを遠隔操作する仕組みを解説しました。MQTT を活用することで、シンプルかつ効率的な通信が可能となり、遠隔からの指示に基づいて HDMI スイッチャーのチャンネルを変更できるシステムを実現しました。