はじめに
今回は「M5Stack Basic V2.7」と「CatM + GNSS」を使用して取得したGPS(位置情報)をMQTTでNode-REDに送る方法を紹介する
・M5StackをArduino IDEで動かす方法については過去の記事を参照


・M5Stack内部から取得した加速度データをMQTTでNode-REDに送る方法については過去の記事を参照

使用デバイス
M5Stack Basic V2.7

・M5Stackの2.7バージョン、CatM+GNSSモジュールとの通信を管理し、取得したGPSデータを処理・表示する中心的な役割を担う。
CatM + GNSSモジュール

・CatM+GNSSモジュールは、LTE Cat-M1通信とGNSS(GPS)機能を統合したモジュールであり、低消費電力で広域通信が可能なため、IoTデバイスに最適なモジュールとなっている。今回はGPS衛星から位置情報を取得し、そのデータをM5Stackに送信する役割を担う。
接続方法
全体構成

ハードウェア接続
1. PCとM5StackをTypeC-USBで接続
2. GROVEオス-メスケーブルを使用してM5StackとCatM+GNSSを接続

3. CatM+GNSSに9~24Vの電源・GPSアンテナ・LTEアンテナを繋げる
ライブラリマネジャーの設定
・ライブラリマネージャーで「PubSubClient」を検索&インストール

コード概要
#include <M5Stack.h>
#include <WiFi.h>
#include <PubSubClient.h>
// WiFi設定
const char* ssid = "****"; // WiFiのSSID
const char* password = "****"; // WiFiのパスワード
// MQTTブローカーの設定
const char* mqtt_server = "****"; // ホストマシンのIPアドレス
const char* mqtt_topic = "/m5stack/gps"; // MQTTトピック
WiFiClient espClient;
PubSubClient client(espClient);
// GPSモジュールとのシリアル接続を定義
#define SerialGPS Serial2
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
// 再接続ループ
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// 接続を試みる
if (client.connect("M5StackClient")) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// 再試行まで5秒待機
delay(5000);
}
}
}
void setup() {
M5.begin();
Serial.begin(115200); // デバッグ用シリアル通信
SerialGPS.begin(9600, SERIAL_8N1, 16, 17); // GPSモジュールとのシリアル接続設定
Serial.println("Initializing GPS module...");
// GPSモジュールの初期化
SerialGPS.println("AT+CGNSPWR=1"); // GNSS電源をオンにする
delay(1000);
while (SerialGPS.available()) {
char c = SerialGPS.read();
Serial.print(c);
}
Serial.println();
SerialGPS.println("AT+CGNSSEQ=\"RMC\""); // GNSS出力シーケンスを設定
delay(1000);
while (SerialGPS.available()) {
char c = SerialGPS.read();
Serial.print(c);
}
Serial.println();
Serial.println("GPS initialized");
setup_wifi();
client.setServer(mqtt_server, 1883);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
SerialGPS.println("AT+CGNSINF"); // GNSS情報を照会
delay(1000);
String gpsData = "";
while (SerialGPS.available()) {
char c = SerialGPS.read();
gpsData += c;
}
if (gpsData.length() > 0) {
Serial.println("Data received:");
Serial.println(gpsData);
// 受信データの解析
if (gpsData.startsWith("AT+CGNSINF")) {
int index = gpsData.indexOf(":");
if (index != -1) {
String gpsInfo = gpsData.substring(index + 1);
String jsonPayload = parseGPSData(gpsInfo);
// MQTTメッセージの送信
client.publish(mqtt_topic, jsonPayload.c_str());
// デバッグ用にシリアル出力
Serial.println("Published GPS data:");
Serial.println(jsonPayload);
}
} else {
Serial.println("No valid GPS data");
}
}
delay(5000); // 5秒待機後、再度照会
}
String parseGPSData(String gpsInfo) {
gpsInfo.trim();
String data[20];
int index = 0;
while (gpsInfo.length() > 0 && index < 20) {
int commaIndex = gpsInfo.indexOf(",");
if (commaIndex == -1) {
data[index++] = gpsInfo;
break;
} else {
data[index++] = gpsInfo.substring(0, commaIndex);
gpsInfo = gpsInfo.substring(commaIndex + 1);
}
}
String jsonPayload = "{";
jsonPayload += "\"latitude\": " + data
+ ",";
jsonPayload += "\"longitude\": " + data
+ ",";
jsonPayload += "\"altitude\": " + data[5] + ",";
jsonPayload += "\"speed\": " + data[6];
jsonPayload += "}";
return jsonPayload;
}
コードの説明
① WifiとMQTTブローカーの接続(以下の内容をコードに記入):
・WifiのSSID → 右下のインターネットアクセスで確認
・Wifiのパスワード
・ホストマシンのIPアドレス → CMDで”ipconfig”するなどして確認

➁ 初期設定:
・M5.begin()
でM5Stackを初期化。
・Serial.begin(115200)
データ転送速度
・SerialGPS.begin(9600, SERIAL_8N1, 16, 17)
UART通信で実装するため、16/17Pinに設定する
➂ MQTTメッセージの送信:
・client.publish(mqtt_topic, jsonPayload.c_str())
・PubSubClientライブラリを使用してMQTTメッセージを特定のTOPICに公開する
➃ データ取得ループ:
・SerialGPS.println("AT+CGNSINF")
でGNSS情報を要求
・取得したデータを解析し、緯度、経度、高度、速度などの情報を表示
ポートが開いているか確認
① 管理者権限でCMDを立ち上げ、mosquittoを起動する
net start mosquitto
➁ 1883ポートが開いているか(LISTENINGされているか確認)
netstat -an | find "1883"
Node-REDのフロー
全体像

MQTT INノードの設定

・画像の通り設定
実行結果
Arduino IDEの画面

-> Data received:
GPSモジュールからデータが受信されたことを示している
-> AT+CGNSINF
M5StackがGPSモジュールに送信したATコマンド
-> +CGNSINF:1,1,20240724030344.000,~
GPSモジュールから返ってきたデータ
-> OK
GPSモジュールからの応答
-> Published GPS data:
GPSデータがMQTTトピックに公開されたことを示す
-> {“latitude”: 35.678178,”longitude”: 139.687137,”altitude”: 51.589,”speed”: 0.00}
MQTTメッセージとして公開されたGPSデータ

緯度(Latitude):35.678227
経度(Longitude):139.687100
高度(Altitude):42.436
速度(Speed):0.00
→ 取得したGPS(位置)データをNode-RED上で確認することができた