🛠 Nœud MQTT : télémétrie IMU et commandes à distance
Objectives
Turn the M5StickC Plus2 into a complete IoT node: periodic publication of telemetry (acceleration, battery voltage via the G38 detection pin) to MQTT topics, and subscription to a command topic to trigger the buzzer remotely. Using the PubSubClient library on 2.4 GHz Wi-Fi.
Hardware
- 1× M5StickC Plus2 (v2)
- Accessible MQTT broker (e.g.,
test.mosquitto.orgfor testing, or a local broker) - A test client (Mosquitto CLI, MQTT Explorer) on the PC
- Arduino IDE / PlatformIO: M5Unified + PubSubClient
Complete code
// Noeud MQTT : publie accel + batterie, recoit des ordres de bip
#include <M5Unified.h>
#include <WiFi.h>
#include <PubSubClient.h>
const char* SSID = "VOTRE_WIFI_24GHZ";
const char* PASS = "motdepasse";
const char* BROKER = "test.mosquitto.org"; // port 1883
const char* BASE = "stickc2/atelier/";
WiFiClient wifiNet;
PubSubClient mqtt(wifiNet);
uint32_t dernierEnvoi = 0;
void callback(char* topic, byte* payload, unsigned int len) {
String msg((char*)payload, len);
M5.Display.setCursor(0, 90);
M5.Display.printf("<-%s", msg.c_str);
int freq = msg.toInt;
if (freq > 40 && freq < 8000) M5.Speaker.tone(freq, 400); // buzzer G2
}
void setup {
auto cfg = M5.config;
M5.begin(cfg);
M5.Display.setRotation(1);
M5.Display.setTextSize(1);
WiFi.mode(WIFI_STA);
WiFi.begin(SSID, PASS);
while (WiFi.waitForConnectResult != WL_CONNECTED) delay(2000);
mqtt.setServer(BROKER, 1883);
mqtt.setCallback(callback);
while (!mqtt.connect("stickc2plus2")) delay(1000);
String cmd = String(BASE) + "cmd";
mqtt.subscribe(cmd.c_str);
}
void loop {
M5.update;
mqtt.loop;
if (!mqtt.connected) { // reconnexion + re-abonnement
if (mqtt.connect("stickc2plus2")) {
String cmd = String(BASE) + "cmd";
mqtt.subscribe(cmd.c_str);
}
}
if (millis - dernierEnvoi > 2000) {
dernierEnvoi = millis;
float ax, ay, az;
M5.Imu.getAccel(&ax, &ay, &az);
String t = String(BASE) + "accel";
char json[96];
snprintf(json, sizeof json, "{\"ax\":%.2f,\"ay\":%.2f,\"az\":%.2f}", ax, ay, az);
mqtt.publish(t.c_str, json);
// Tension batterie : broche de detection G38 (ADC1) — la conversion
// brute -> pourcentage n'est pas documentee :
// >
uint32_t batt = mqtt.publish((String(BASE) + "batt").c_str,
String(analogRead(38)).c_str);
(void)batt;
M5.Display.setCursor(0, 20);
M5.Display.printf("pub accel OK RSSI %d\n", WiFi.RSSI);
}
vTaskDelay(20 / portTICK_PERIOD_MS);
}
Expected verification
With mosquitto_sub -h test.mosquitto.org -t 'stickc2/atelier/#', you will see the acceleration JSON and the raw battery value arrive every 2 seconds. Publishing 880 to stickc2/atelier/cmd makes the buzzer sound for 400 ms and displays the command on the screen.
Common errors
- Publishing without calling
mqtt.loopregularly: ACKs and command reception do not work. - Forgetting to resubscribe after a reconnection: telemetry resumes, but commands remain silent.
- Using a broker with
mqtts://(TLS, port 8883) with a simple WiFiClient: you need WiFiClientSecure. - Reading the battery on G25/G26: these ADC2 pins are unusable when Wi-Fi is active; official battery detection is on G38 (ADC1).
- Converting raw ADC values to percentage without a reference curve: the official documentation does not provide the discharge curve for the 200 mAh battery — display the raw value or calibrate it yourself.
- Flooding publications at 10 Hz on a public broker: throttle to 0.5–1 Hz and preserve battery margin.
Other tutorials for this board
Code examples for this board
hello-stick.inoArduinoboutons.inoArduinobuzzer.inoArduinoinclinometre.inoArduinohorloge.inoArduinoir-tv.inoArduino