SIM7600 MQTT permet à un ESP32 de publier des données là où il n'y a aucun Wi-Fi : stations de pompage, chantiers, véhicules, parcelles agricoles et armoires isolées. Dans ce tutoriel, vous allez mettre sous tension un modem 4G LTE SIM7600, l'enregistrer sur le réseau mobile avec TinyGSM, connecter PubSubClient à broker.connectmq.com via le modem et rétablir proprement la connexion après les coupures réseau. Vous verrez aussi où partent réellement les données cellulaires et comment limiter votre consommation mensuelle.
Comment les éléments s'articulent
Le SIM7600 est un modem cellulaire complet doté de sa propre pile TCP/IP. L'ESP32 dialogue avec lui sur un UART à l'aide de commandes AT. TinyGSM encapsule ces commandes dans une classe Client Arduino, TinyGsmClient, et comme PubSubClient accepte n'importe quel Client, le code MQTT est presque identique à celui d'un sketch Wi-Fi.
| Couche | Composant | Rôle |
|---|---|---|
| Application | Votre sketch | Lire les capteurs, décider quoi publier |
| MQTT | PubSubClient | CONNECT, PUBLISH, SUBSCRIBE, keep-alive |
| Transport | TinyGsmClient | Ouvre des sockets TCP dans le modem via des commandes AT |
| Modem | SIM7600 | Enregistrement réseau, contexte PDP, TCP/IP |
| Radio | Réseau LTE et carte SIM | Couverture, APN, forfait data |
La plupart des problèmes de MQTT cellulaire ne sont pas des problèmes MQTT. Ce sont des problèmes d'alimentation, d'antenne, de SIM ou d'APN qui se manifestent par un « MQTT ne se connecte pas ». Le sketch vérifie donc chaque couche séparément et journalise l'endroit où il échoue.
Matériel
- Une carte ESP32 avec un module SIM7600. Les cartes intégrées comme la série LilyGO T-SIM7600 sont le point de départ le plus simple ; une breakout SIM7600 séparée associée à un ESP32 DevKit fonctionne aussi.
- Une carte micro ou nano SIM avec un forfait data actif. Les SIM data IoT sont idéales ; une SIM de téléphone convient pour les tests.
- Une antenne LTE raccordée au port d'antenne principal. N'alimentez jamais le modem sans antenne.
- Une alimentation capable de fournir les pics de courant d'émission du modem. Une bonne cellule 18650 ou une alimentation 5 V d'au moins 2 A constitue une base raisonnable.
L'alimentation est la cause numéro un des pannes. Les modems LTE tirent de brèves et fortes pointes de courant pendant l'émission. Un port USB faible ou des fils trop fins provoquent des chutes de tension qui réinitialisent le modem en pleine connexion, et les symptômes semblent aléatoires : parfois il s'enregistre, parfois non, parfois il se déconnecte après quelques messages.
| Signal | Broche typique sur LilyGO T-SIM7600 | Rôle |
|---|---|---|
| TX du modem vers RX de l'ESP32 | GPIO 26 | Données UART venant du modem |
| RX du modem depuis TX de l'ESP32 | GPIO 27 | Données UART vers le modem |
| PWRKEY | GPIO 4 | Impulsion pour allumer le modem |
| Activation de l'alimentation | GPIO 12 | Active l'alimentation du modem sur certaines révisions de carte |
L'affectation des broches varie selon les cartes et les révisions. Consultez la documentation de votre carte et ajustez les defines du sketch.
Bibliothèques
Installez via le gestionnaire de bibliothèques Arduino :
- TinyGSM de Volodymyr Shymanskyy.
- PubSubClient de Nick O'Leary.
TinyGSM doit connaître le modèle de modem à la compilation : c'est pourquoi #define TINY_GSM_MODEM_SIM7600 doit apparaître avant l'include.
Le sketch SIM7600 MQTT complet
#define TINY_GSM_MODEM_SIM7600
#define TINY_GSM_RX_BUFFER 1024 // tampon plus grand pour les données MQTT entrantes
#include <TinyGsmClient.h>
#include <PubSubClient.h>
// ---- Broches de la carte (valeurs par défaut LilyGO T-SIM7600, à adapter) ----
#define MODEM_TX 27
#define MODEM_RX 26
#define MODEM_PWRKEY 4
#define MODEM_POWER 12
// ---- Paramètres cellulaires ----
const char APN[] = "internet"; // fourni par votre opérateur SIM
const char APN_USER[] = "";
const char APN_PASS[] = "";
const char SIM_PIN[] = ""; // laisser vide si la SIM n'a pas de code PIN
// ---- Paramètres MQTT ----
const char* MQTT_HOST = "broker.connectmq.com";
const uint16_t MQTT_PORT = 1883;
const char* CLIENT_ID = "lte-81c3e5"; // unique
const char* BASE = "connectmq/demo/lte-81c3e5";
HardwareSerial SerialAT(1);
TinyGsm modem(SerialAT);
TinyGsmClient gsmClient(modem);
PubSubClient mqtt(gsmClient);
unsigned long lastAttempt = 0, lastPublish = 0;
const unsigned long PUBLISH_INTERVAL = 60000; // une mesure par minute
void powerOnModem() {
pinMode(MODEM_POWER, OUTPUT);
digitalWrite(MODEM_POWER, HIGH);
pinMode(MODEM_PWRKEY, OUTPUT);
digitalWrite(MODEM_PWRKEY, LOW);
delay(100);
digitalWrite(MODEM_PWRKEY, HIGH); // impulsion d'allumage
delay(1000);
digitalWrite(MODEM_PWRKEY, LOW);
}
bool ensureNetwork() {
if (!modem.isNetworkConnected()) {
Serial.println("Waiting for network registration...");
if (!modem.waitForNetwork(60000L)) {
Serial.println("No network: check antenna, SIM and coverage");
return false;
}
Serial.printf("Registered, signal quality %d\n", modem.getSignalQuality());
}
if (!modem.isGprsConnected()) {
Serial.printf("Opening data connection with APN %s\n", APN);
if (!modem.gprsConnect(APN, APN_USER, APN_PASS)) {
Serial.println("Data connection failed: check APN and data plan");
return false;
}
Serial.print("Local IP: ");
Serial.println(modem.localIP());
}
return true;
}
void onMessage(char* topic, byte* payload, unsigned int length) {
Serial.printf("Command %s: %.*s\n", topic, (int)length, (const char*)payload);
}
bool connectMqtt() {
String status = String(BASE) + "/status";
if (!mqtt.connect(CLIENT_ID, nullptr, nullptr, status.c_str(), 1, true, "offline")) {
Serial.printf("MQTT failed, state=%d\n", mqtt.state());
return false;
}
mqtt.publish(status.c_str(), "online", true);
mqtt.subscribe((String(BASE) + "/cmd").c_str(), 1);
Serial.println("MQTT connected over LTE");
return true;
}
void setup() {
Serial.begin(115200);
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
powerOnModem();
Serial.println("Initializing modem...");
if (!modem.init()) {
Serial.println("init failed, trying restart");
modem.restart();
}
Serial.println("Modem: " + modem.getModemInfo());
if (strlen(SIM_PIN) && modem.getSimStatus() == SIM_LOCKED) modem.simUnlock(SIM_PIN);
mqtt.setServer(MQTT_HOST, MQTT_PORT);
mqtt.setCallback(onMessage);
mqtt.setKeepAlive(120); // moins de pings, moins de données
mqtt.setSocketTimeout(15); // les allers-retours cellulaires sont plus lents
}
void loop() {
if (!mqtt.connected()) {
if (millis() - lastAttempt > 15000) {
lastAttempt = millis();
if (ensureNetwork()) connectMqtt();
}
return;
}
mqtt.loop();
if (millis() - lastPublish > PUBLISH_INTERVAL) {
lastPublish = millis();
char json[64];
snprintf(json, sizeof(json), "{\"t\":%.1f,\"csq\":%d}",
20.0 + (esp_random() % 100) / 10.0, modem.getSignalQuality());
mqtt.publish((String(BASE) + "/telemetry").c_str(), json);
}
}
Ce qu'il faut surveiller sur le moniteur série
Un démarrage sain affiche l'identification du modem, Registered, signal quality N, l'IP locale et MQTT connected over LTE. La qualité du signal est la valeur CSQ de 0 à 31, 99 signifiant inconnue. En dessous d'environ 10, le signal est limite ; repositionnez l'antenne avant d'accuser le logiciel. Si le sketch s'arrête à l'enregistrement, le problème vient de la SIM, de la couverture ou de l'antenne. S'il s'enregistre mais que la connexion data échoue, l'APN est faux ou le forfait n'inclut pas de data. Si les deux réussissent mais que MQTT échoue avec l'état -2, la connexion TCP est bloquée ; certaines SIM restrictives n'autorisent que des destinations sur liste blanche.
Tester depuis votre ordinateur
mosquitto_sub -h broker.connectmq.com -p 1883 -i watch-81c3e5 -v -t "connectmq/demo/lte-81c3e5/#"
Vous devriez voir status online puis un message de télémétrie chaque minute. Envoyez une commande pour vérifier la voie descendante, ce qui prouve aussi que le NAT de l'opérateur maintient la connexion ouverte :
mosquitto_pub -h broker.connectmq.com -p 1883 -i cmd-81c3e5 -t "connectmq/demo/lte-81c3e5/cmd" -m "ping"
Le serveur MQTT public gratuit convient pour la mise au point, mais tout ce que vous y publiez est lisible par tous : passez donc à vos propres identifiants avant que l'appareil ne quitte l'établi.
Limiter la consommation de données SIM7600 MQTT
Les forfaits cellulaires facturent à l'octet, et MQTT n'est efficace que si vous l'utilisez efficacement. Voici les leviers qui comptent le plus, à peu près par ordre d'impact :
- Évitez les reconnexions. Chaque nouvelle connexion coûte une poignée de main TCP, le CONNECT et le CONNACK MQTT, les abonnements et, avec le TLS, un handshake complet incluant la chaîne de certificats. Un appareil qui se reconnecte toutes les quelques minutes peut dépenser plus de données à se connecter qu'en télémétrie. Corrigez la cause des coupures plutôt que de vous reconnecter sur minuterie.
- Réglez le keep-alive. À chaque période de keep-alive, le client envoie un petit PINGREQ et le broker répond. Un keep-alive plus long économise des données, mais les passerelles NAT des opérateurs coupent les connexions inactives au bout d'un moment, et si le keep-alive dépasse ce délai, la connexion meurt en silence. Commencez autour de deux minutes et ajustez selon vos observations.
- Raccourcissez les payloads. Utilisez des clés JSON courtes (
"t"au lieu de"temperature"), arrondissez les valeurs et omettez les champs qui changent rarement. - Regroupez les mesures. Envoyer dix mesures dans un seul message toutes les dix minutes coûte bien moins de surcharge que dix messages séparés.
- Publiez sur changement. Pour les valeurs qui évoluent lentement, publiez uniquement lorsque la valeur varie de plus d'un seuil, plus un heartbeat périodique.
- Utilisez des topics courts. Le topic est envoyé avec chaque message.
f/42/tcoûte moins cher qu'un long chemin descriptif, même si la lisibilité compte aussi ; trouvez un équilibre. - Surveillez les abonnements. Des abonnements avec wildcards sur des topics très actifs peuvent faire entrer bien plus de données que prévu.
N'oubliez pas que les opérateurs peuvent arrondir chaque session ou période de facturation à une unité minimale : mesurez donc la consommation réelle sur le portail de votre opérateur SIM pendant quelques jours plutôt que de vous fier aux calculs.
Sécurité sur les liaisons cellulaires
En production, utilisez le TLS sur le port 8883 ainsi que le nom d'utilisateur, le mot de passe et le client ID générés dans le portail ConnectMQ. Avec le SIM7600, vous avez deux options. Certaines versions et forks de TinyGSM exposent un client sécurisé qui utilise le moteur SSL intégré au modem, ce qui économise la mémoire de l'ESP32 ; vérifiez si votre version installée le prend en charge pour le SIM7600. Vous pouvez aussi exécuter le TLS sur l'ESP32 lui-même avec une bibliothèque d'encapsulation comme SSLClient placée au-dessus de TinyGsmClient. Dans les deux cas, vérifiez le certificat du broker par rapport à la racine ISRG Root X1 au lieu de désactiver la vérification. Le guide ESP32 MQTT SSL explique le choix du certificat et pourquoi l'heure NTP ou réseau est importante ; le SIM7600 peut d'ailleurs fournir l'heure réseau.
Dépannage
- Le modem ne répond jamais aux commandes AT. Mauvaises broches UART, mauvais débit, ou modem non alimenté. Vérifiez la broche d'activation de l'alimentation et l'impulsion PWRKEY pour votre carte.
- S'enregistre uniquement en 2G ou 3G, ou pas du tout. La bande n'est peut-être pas prise en charge par votre variante de SIM7600 (E, A, SA, G et d'autres couvrent des régions différentes).
- Se connecte, puis décroche après quelques minutes de silence. Keep-alive plus long que le timeout NAT de l'opérateur. Raccourcissez-le.
- Resets par brownout pendant l'émission. L'alimentation ne peut pas fournir le courant de crête. Ajoutez un gros condensateur près du modem et utilisez des fils plus épais.
- Messages retardés de plusieurs secondes. C'est normal sur les liaisons cellulaires ; la latence est plus élevée et plus variable qu'en Wi-Fi. Concevez en conséquence.
Pour une stratégie de reconnexion plus robuste avec backoff, adaptez la machine à états de la logique de reconnexion MQTT ESP32. Si l'appareil dispose d'une option filaire sur site, comparez avec ESP32 Ethernet MQTT avec W5500, et pour les biens mobiles, consultez le traceur GPS ESP32 via MQTT.
Exploiter une flotte cellulaire
Les appareils cellulaires coûtent cher à aller visiter : le côté broker devrait donc être le dernier de vos soucis. Un broker MQTT managé garde le point d'accès disponible pendant que les appareils passent d'une cellule à l'autre et se reconnectent. ConnectMQ attribue à chaque appareil ses propres identifiants, expose l'état de connexion via $SYS/broker/connection/{clientId}/state et vous permet de suivre le trafic en direct dans le portail, ce qui est utile pour comprendre où partent les données d'une SIM. Un broker MQTT cloud doté d'un nom d'hôte public évite aussi les configurations d'APN privé et de VPN que les brokers auto-hébergés exigent souvent pour les appareils cellulaires. S'il s'agit de votre premier projet ESP32, commencez par le tutoriel IoT ESP32.
Démarrez avec ConnectMQ
Créez gratuitement un broker Serverless sur app.connectmq.com, sans carte bancaire. Vos appareils SIM7600 peuvent y publier depuis n'importe quel endroit couvert, et vous pouvez voir chaque message arriver dans l'explorateur de topics en direct.
Questions fréquentes
PubSubClient fonctionne-t-il avec le SIM7600 ?
Oui. TinyGSM fournit TinyGsmClient, qui implémente l'interface Client d'Arduino : PubSubClient utilise donc les sockets TCP du modem exactement comme il utiliserait le Wi-Fi.
Combien de données consomme SIM7600 MQTT ?
Cela dépend surtout de la fréquence des reconnexions, de l'intervalle de keep-alive et de la taille des payloads. Un appareil qui reste connecté et envoie des messages compacts consomme très peu ; les reconnexions fréquentes, surtout en TLS, dominent la consommation. Mesurez-la sur le portail de votre opérateur SIM.
Quel APN dois-je utiliser ?
L'APN est fourni par votre opérateur SIM et figure généralement dans sa documentation ou son portail IoT. Un APN erroné laisse le modem s'enregistrer sur le réseau mais empêche la connexion data.
Peut-on utiliser MQTT sur TLS avec le SIM7600 ?
Oui, soit via le moteur SSL du modem si votre version de TinyGSM le prend en charge pour le SIM7600, soit en exécutant le TLS sur l'ESP32 avec une bibliothèque d'encapsulation au-dessus de TinyGsmClient. Vérifiez toujours le certificat du broker.



