🛠 Publier en MQTT sur le réseau GPRS
Objetivos
Conectar la MKR GSM 1400 a un broker MQTT apilando PubSubClient sobre GSMClient: la clase cliente de MKRGSM imita la clase Client de Arduino, por lo que PubSubClient funciona sin modificaciones. Patrón típico de un sensor de campo (riego Irriduo, vigilancia del agua): lectura periódica, publicación con QoS 1, reconexión robusta tras cortes de radio.
Material
- Placa Arduino MKR GSM 1400 + antena U.FL + LiPo ≥ 1500 mAh
- micro-SIM de datos (código PIN desactivado), APN conocido
- Un broker MQTT accesible por TCP 1883 (servidor propio o broker de prueba)
- Librerías: MKRGSM, PubSubClient
Código completo
#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);
}
Verificación esperada
mosquitto_sub -t 'maison/mkr1400/a1' (o el cliente de su broker) recibe una trama JSON cada minuto, incluso después de mover la placa a una zona sin red: el bucle de reconexión se reanuda solo. mqtt.loop debe llamarse con frecuencia; su ausencia provoca desconexiones por keepalive y mensajes entrantes no procesados.
Errores frecuentes
- Buffer de PubSubClient demasiado pequeño:
MQTT_PACKET_SIZE_EXCEEDEDal publicar; usesetBufferSizey, si es necesario, recompile conMQTT_MAX_PACKET_SIZE. - Olvidar
mqtt.loopenloop: el broker expulsa al cliente al finalizar el keepalive. - TLS: el puerto 8883 con
GSMClienten claro no funcionará; useGSMSSLClientoBearSSLClient(ECC508), y una librería MQTT compatible con Client TLS. - Publicar durante un corte: los mensajes se pierden sin cola de espera; almacene en búfer en RAM (solo 32 KB) o acepte la pérdida.
- Contraseña MQTT en el sketch: la memoria flash de la placa es legible mediante bossac incluso con el bit de seguridad activado (ArduinoCore-samd #570); use la pestaña Secret y credenciales con alcance limitado.
- Velocidad 2G: mantenga tramas pequeñas y una frecuencia baja (minutos, no segundos).
Otros tutoriales para esta placa
Ejemplos de código para esta placa
gsm-connexion.inoArduinoenvoi-sms.inoArduinohttp-get.inoArduinohttp-post-capteur.inoArduinoheure-gsm.inoArduinoappels.inoArduino