M5 Atom Liteで学ぶ MQTT通信入門 ~Beebotteを使ったマイコン間連携~
※このページは神奈川工科大学 電気電子情報工学科/ホームエレクトロニクス開発学科 コミュニケーションロボティクス研究室の平凡なチュートリアルを淡々と示したものです。過度な期待はしないでください。 1. はじめに
離れた場所にあるマイコン同士で、インターネットを通じて情報をやりとりしたい。
くらしの中で開発をしていると、そんな場面に出くわすことはよくあります。そんなときに便利なのが、MQTT通信です。
このチュートリアルでは、IoT向けのマイコンボード M5StackのAtom Lite を使って、インターネット経由でデバイス同士を連携させる方法を学びます。通信には、「MQTT(Message Queuing Telemetry Transport)」という、軽量でシンプルなプロトコルを使用します。MQTTは、IoT、スマートハウス、センサーネットワークなど、さまざまな分野で広く利用されています。
このチュートリアルでは、以下の構成で進めていきます:
第2章. 基礎編:MQTTのしくみ
MQTTの基本的な仕組みや用語について解説します。
第3章. 実践編:MQTTで複数のAtom Liteを連携させる
実際に複数のAtom Liteを使って、インターネット経由でメッセージを送受信しながらLEDを点灯させる仕組みをつくります。
※シリアル通信と関係ないチュートリアルをつくるのは趣味ではないのですが、学生さんがほしいというので、それならばとつくりました。趣味で教材をつくるな。 2. 基礎編:MQTTのしくみ
2.1 MQTTとは?
MQTT(Message Queuing Telemetry Transport)は、IoT機器向けに設計された軽量な通信プロトコルです。低帯域でも安定して動作し、小さな電力で情報の送受信ができます。
主な特徴:
軽量でシンプルな設計
TCP/IPベースの双方向通信
Pub/Sub(発行/購読)モデルを採用
2.2 基本構成:Pub/Subモデルの3要素
https://gyazo.com/a866eaf192264ce27453e090e31039e8
MQTT通信は、Pub/Sub(発行/購読)モデルという通信方式を採用しています。Pub/Sub(発行/購読)モデルは以下の3つの要素で構成されます。
table:MQTTのPub/Subモデル
役割 説明
Publisher(パブリッシャー) メッセージを「発行」する側。センサーやボタンなど。
Subscriber(サブスクライバー) メッセージを「購読」する側。受信して何か動作するデバイス。
Broker(ブローカー) 発行されたメッセージを受け取り、購読者に配信する中継サーバ。
Publisher(発行者)が特定のトピックに向けて発行したメッセージをBrokerが仲介し、そのトピックのSubscriber(購読者)に転送します。
補足: 本チュートリアルの例だと、ボタンを押すデバイスがPublisher、LEDを点灯するデバイスがSubscriberになります。
2.3 トピック
MQTTでは、「トピック(topic)」という宛先ラベルを使ってメッセージを管理します。
トピックは文字列で構成され、階層的に分類できます。Publisherは特定のトピックにメッセージを送信し、Subscriberは必要なトピックを購読して、対応するメッセージを受け取ります。
code:toicの例
/* 例:家のリビングの照明のtopic */
home/livingroom/light
2.4 通信の手順
MQTT通信の手順は次のとおりです。
①デバイスが Wi-Fi に接続し、MQTT ブローカーに接続
②Publisherは、指定のトピックにメッセージを「発行(Publish)」
③Brokerがメッセージを受信
④同じトピックを「購読(Subscribe)」しているデバイス(Subscriber)にメッセージを配信
⑤Subscriberはメッセージを受け取り、LED点灯などの処理を実行
以上で、Brokerを介して多対多の通信が可能になります。
次の章では、Beebotteを使ったMQTTの設定や、実際のサンプルコードを紹介します。
3. 実践編:MQTTで複数のAtom Liteを連携させる
https://gyazo.com/08edbc8547a1ea0bd4c6c86c105bd1db
このチュートリアルでは、2台以上の M5Stack Atom Lite を使って、以下のような動作を実現します:
ボタンを押すと 0〜5のランダムな数値を生成し、MQTTで送信(Publish)する
数値に応じた色でLEDを点灯する(例:0=赤、1=オレンジ…)
他のデバイスがそのメッセージを受信し、同じ色でLEDを点灯する(Subscribe)
すべてのAtom Lite が、ボタンを押したときはPublisher、それ以外のときはSubscriberとしてふるまいます。
3.1 用意するもの
3.2 Broker: Beebotte の事前準備
このチュートリアルではMQTTのBrokerサービスとしてBeebotteを用いました。 クラウド型のサービスで、WEB上でデータを可視化できるダッシュボード機能もあり、無料プランがあるのがメリットです。 Beebotte上では次のとおり設定します。
Beebotteに登録
「チャネル(channel)」を作成(例:atom_lite_test)
チャネル内にリソース(resource)を作成(例:buttonなど)
書き込み用のチャネルトークン(APIキー)を控えておく
なお、Beebotteではトピックはチャネル名とリソース名で構成されます(つまり、Beebotteでチャネル名とリソース名を設定するとトピック名が自動で決まります)。
code:Beebotteのトピック名
topic Name = Channel Name/Resource Name
3.3 Atom Liteの準備
下記のコードをAtom Liteに書き込んでください。
code:M5Atomlite_MQTT_test.ino
// --- Wi-Fi設定(自分の環境に書き換えてください) ---
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// --- Beebotte設定(事前に作成したチャネルとトークンを使う) ---
const char* mqtt_server = "mqtt.beebotte.com";
const char* channel = "atom_lite_test"; //作成したチャネル名
const char* resource = "button"; //作成したリソース名
const char* token = "token_8St4xxxxxxxx"; // チャネルトークン
WiFiClient wifiClient;
PubSubClient client(wifiClient);
bool lastBtn = false;
int my_id = random(1000, 9999); // デバイス識別用のIDをランダム生成
// 数字0〜5に対応するLEDの色(赤、オレンジ、黄、緑、青、紫)
uint32_t colors[] = {
0xff0000, // 0: 赤
0xffa500, // 1: オレンジ
0xffff00, // 2: 黄色
0x00ff00, // 3: 緑
0x0000ff, // 4: 青
0x4b0082 // 5: 紫
};
// --- Wi-Fi接続処理 ---
void setup_wifi() {
Serial.print("Wi-Fiに接続中...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWi-Fi接続完了!");
Serial.print("IPアドレス: ");
Serial.println(WiFi.localIP());
M5.dis.drawpix(0, 0xffffff); // Wi-Fi接続完了時に白色LED点灯
}
// --- MQTTメッセージ受信時の処理 ---
void callback(char* topic, byte* payload, unsigned int length) {
String message = (char*)payload;
Serial.print("トピック: ");
Serial.println(topic);
Serial.print("メッセージ: ");
Serial.println(message);
// JSONから"value"の抽出
int index = message.indexOf("\"data\":");
if (index >= 0) {
int value = message.substring(index + 7).toInt();
if (value >= 0 && value < 6) {
Serial.print("→ LED点灯色(値: ");
Serial.print(value);
Serial.println(")");
M5.dis.drawpix(0, colorsvalue); }
}
}
// MQTTブローカーへ再接続(接続されていない場合)
void reconnect() {
while (!client.connected()) {
String clientId = "M5Atom_" + String(my_id);
Serial.print("MQTT接続中...(クライアントID: ");
Serial.print(clientId);
Serial.println(")");
// MQTT接続(ユーザー名にtokenを使う)
if (client.connect(clientId.c_str(), token, "")) {
Serial.println("→ MQTT接続成功!");
String topic = String(channel) + "/" + resource;
client.subscribe(topic.c_str());
Serial.print("→ トピック購読: ");
Serial.println(topic);
} else {
Serial.print("× 接続失敗(コード: ");
Serial.print(client.state());
Serial.println(")、1秒後再試行");
delay(1000); // 接続失敗時は少し待つ
}
}
}
// --- メッセージをパブリッシュ(送信) ---
void publishValue(int value) {
String topic = String(channel) + "/" + resource;
String payload = "{\"channel\":\"" + String(channel) + "\",\"resource\":\"" + String(resource) + "\",\"write\":true,\"data\":" + String(value) + "}";
Serial.print("送信トピック: ");
Serial.println(topic);
Serial.print("送信データ: ");
Serial.println(payload);
client.publish(topic.c_str(), payload.c_str()); // メッセージをパブリッシュ
M5.dis.drawpix(0, colorsvalue); // 自分のLEDも点灯 }
// --- 初期化 ---
void setup() {
M5.begin(true, false, true); // ボタンON / スピーカーOFF / LED ON
M5.dis.clear(); // LED初期化
Serial.begin(115200); // シリアルモニタ開始
Serial.println("=== Atom Lite MQTTテスト開始 ===");
Serial.print("デバイスID: ");
Serial.println(my_id);
setup_wifi(); // Wi-Fi接続
client.setServer(mqtt_server, 1883); //ポート番号: 1883(固定)
client.setCallback(callback); // メッセージ受信時の処理設定
}
// --- メインループ ---
void loop() {
if (!client.connected()) {
reconnect(); // MQTT未接続なら再接続
}
client.loop(); // MQTT処理
M5.update(); // ボタン状態更新
if (M5.Btn.wasPressed()) {
int value = random(0, 6); // ランダムな数値(0〜5)を生成()
publishValue(value); // パブリッシュ&LED点灯
}
delay(10);
}
3.4 実行例
ひとつのAtom Liteのボタンを押すと、すべてのAtom LiteのLEDが同じ色になります。
挙動の流れは以下のとおりです。またシリアルモニタ上で、デバッグ用のメッセージを確認できます。
起動時
Wi-Fiに接続する(接続中はLEDを白色で点灯)。
MQTTブローカー(Beebotte)に接続。
Publisherとしての挙動:ボタンが押されると
ランダムな数字(0~5)を生成。
その数字をMQTTで「Publish(送信)」。
数字に対応したLEDの色を点灯。
Subscriberとしての挙動:他のマイコンから数字が届くと
「Subscribe(受信)」して数字を取得。
その数字に対応したLEDの色を点灯。
シリアルモニタ上の表示例
code:シリアル表示例(接続時)
=== Atom Lite MQTTテスト開始 ===
デバイスID: 7783
Wi-Fiに接続中.......
Wi-Fi接続完了!
IPアドレス: 192.168.xx.xxx
MQTT接続中...(クライアントID: M5Atom_7783)
→ MQTT接続成功!
→ トピック購読: M5AtomTest/button
code:シリアル表示例(ボタンを押したとき)
送信トピック: M5AtomTest/button
送信データ: {"channel":"M5AtomTest","resource":"button","write":true,"data":1}
トピック: M5AtomTest/button
メッセージ: {"channel":"M5AtomTest","resource":"button","write":true,"data":1}
→ LED点灯色(値: 1)
以上です。
送信するランダムな数字(0~5)をセンサ値に変更するなどして、応用してください。
https://gyazo.com/71c7de59f100448c29cdb7f29fbd171b