🛠 Publier en MQTT sur le réseau GPRS
Objectifs
Relier la MKR GSM 1400 à un broker MQTT en empilant PubSubClient sur GSMClient : la classe client de MKRGSM imitant la classe Client d'Arduino, PubSubClient fonctionne sans modification. Patron typique d'un capteur terrain (irrigation Irriduo, surveillance d'eau) : lecture périodique, publication QoS 1, reconnexion robuste après coupure radio.
Matériel
- Carte Arduino MKR GSM 1400 + antenne U.FL + LiPo ≥ 1500 mAh
- micro-SIM data (code PIN désactivé), APN connu
- Un broker MQTT accessible en TCP 1883 (serveur perso ou broker d'essai)
- Bibliothèques : MKRGSM, PubSubClient
Code complet
#include <MKRGSM.h>
#include <PubSubClient.h>
#include "arduino_secrets.h"
const char PINNUMBER[] = SECRET_PINNUMBER;
const char GPRS_APN[] = SECRET_GPRS_APN;
const char GPRS_LOGIN[] = SECRET_GPRS_LOGIN;
const char GPRS_PASSWORD[] = SECRET_GPRS_PASSWORD;
const char MQTT_BROKER[] = "broker.example.org";
GSMClient netClient;
GPRS gprs;
GSM gsmAccess;
PubSubClient mqtt(netClient);
uint32_t dernierePub = 0;
void connexion {
while (gsmAccess.begin(PINNUMBER) != GSM_READY) delay(2000);
while (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) != GPRS_READY)
delay(2000);
mqtt.setServer(MQTT_BROKER, 1883);
mqtt.setBufferSize(256);
while (!mqtt.connect("mkr1400-capteur")) {
Serial.print("MQTT rc="); Serial.println(mqtt.state);
delay(5000);
}
Serial.println("MQTT connecte");
}
void setup {
Serial.begin(9600);
while (!Serial) {}
connexion;
}
void loop {
if (!mqtt.connected || !gprs) { // coupure radio ou broker
Serial.println("Reconnexion...");
gsmAccess.shutdown;
connexion;
}
mqtt.loop; // indispensable : trafic + keepalive
if (millis - dernierePub > 60000UL) {
dernierePub = millis;
int v = analogRead(A1); // exemple : capteur analogique
char trame[48];
snprintf(trame, sizeof trame, "{\"a1\":%d}", v);
mqtt.publish("maison/mkr1400/a1", trame, true); // retain
}
delay(100);
}
Vérification attendue
mosquitto_sub -t 'maison/mkr1400/a1' (ou le client de votre broker) reçoit une trame JSON chaque minute, même après avoir déplacé la carte dans une zone sans réseau : la boucle de reconnexion reprend seule. mqtt.loop doit être appelé souvent — son absence provoque des déconnexions keepalive et des messages entrants non traités.
Erreurs fréquentes
- Buffer PubSubClient trop petit :
MQTT_PACKET_SIZE_EXCEEDEDà la publication ;setBufferSizepuis recompilation avecMQTT_MAX_PACKET_SIZEsi nécessaire. - Oublier
mqtt.loopdansloop: le broker éjecte le client au bout du keepalive. - TLS : le port 8883 avec
GSMClienten clair ne fonctionnera pas ; utiliserGSMSSLClientouBearSSLClient(ECC508), et une bibliothèque MQTT compatible Client TLS. - Publier pendant une coupure : les messages sont perdus sans file d'attente — mettre en tampon en RAM (32 Ko seulement) ou accepter la perte.
- Mot de passe MQTT dans le sketch : le flash de la carte est lisible via bossac même avec le bit de sécurité activé (ArduinoCore-samd #570) ; utiliser l'onglet Secret et des identifiants à portée limitée.
- Débit 2G : garder des trames petites et une fréquence basse (minutes, pas secondes).
Autres tutoriels pour cette carte
Exemples de code pour cette carte
gsm-connexion.inoArduinoenvoi-sms.inoArduinohttp-get.inoArduinohttp-post-capteur.inoArduinoheure-gsm.inoArduinoappels.inoArduino