ESP32 und Arduino

SIM7600 MQTT: Vom ESP32 über 4G LTE mit TinyGSM veröffentlichen

Verbinden Sie einen ESP32 mit einem SIM7600-Modem, TinyGSM und PubSubClient über 4G LTE mit einem MQTT Broker, erholen Sie sich sauber von Netzabbrüchen und halten Sie Mobilfunk-Datenvolumen und Kosten im Griff.

ESP32-Board mit SIM7600-4G-Modem und Antenne, das SIM7600-MQTT-Nachrichten sendet
Probieren Sie es auf Ihrem eigenen MQTT-Broker ausHolen Sie sich im Free-Tarif einen privaten, verwalteten MQTT-Broker und starten Sie mit fertigen Codebeispielen.
Kostenlos testen Codebeispiele Keine Kreditkarte erforderlich

Mit SIM7600 MQTT kann ein ESP32 Daten dort veröffentlichen, wo es überhaupt kein WLAN gibt: an Pumpstationen, auf Baustellen, in Fahrzeugen, auf landwirtschaftlichen Flächen und in abgelegenen Schaltschränken. In diesem Tutorial schalten Sie ein SIM7600-4G-LTE-Modem ein, buchen es mit TinyGSM ins Mobilfunknetz ein, verbinden PubSubClient über das Modem mit broker.connectmq.com und erholen sich sauber von Netzabbrüchen. Außerdem erfahren Sie, wohin das Mobilfunk-Datenvolumen tatsächlich fließt und wie Sie den monatlichen Verbrauch klein halten.

Wie die Teile zusammenspielen

Der SIM7600 ist ein vollständiges Mobilfunkmodem mit eigenem TCP/IP-Stack. Der ESP32 spricht über einen UART per AT-Befehlen mit ihm. TinyGSM kapselt diese Befehle in einer Arduino-Client-Klasse, TinyGsmClient, und weil PubSubClient jeden Client akzeptiert, ist der MQTT-Code fast identisch mit einem WLAN-Sketch.

Ebene Komponente Aufgabe
Anwendung Ihr Sketch Sensoren lesen, entscheiden, was veröffentlicht wird
MQTT PubSubClient CONNECT, PUBLISH, SUBSCRIBE, Keep-Alive
Transport TinyGsmClient Öffnet per AT-Befehl TCP-Sockets im Modem
Modem SIM7600 Netzregistrierung, PDP-Kontext, TCP/IP
Funk LTE-Netz und SIM Netzabdeckung, APN, Datentarif

Die meisten Probleme mit MQTT über Mobilfunk sind keine MQTT-Probleme. Es sind Probleme mit Stromversorgung, Antenne, SIM oder APN, die sich als „MQTT verbindet sich nicht" zeigen. Der Sketch prüft deshalb jede Ebene einzeln und protokolliert, wo es scheitert.

Hardware

  • Ein ESP32-Board mit SIM7600-Modul. Integrierte Boards wie die LilyGO-T-SIM7600-Serie sind der einfachste Einstieg; ein separates SIM7600-Breakout plus ESP32-DevKit funktioniert ebenfalls.
  • Eine Micro- oder Nano-SIM mit aktivem Datentarif. IoT-Daten-SIMs sind ideal; eine Handy-SIM genügt zum Testen.
  • Eine LTE-Antenne am Hauptantennenanschluss. Betreiben Sie das Modem niemals ohne Antenne.
  • Ein Netzteil, das die Stromspitzen des Modems beim Senden liefern kann. Eine gute 18650-Zelle oder ein 5-V-Netzteil mit mindestens 2 A ist eine sinnvolle Basis.

Die Stromversorgung ist die häufigste Fehlerursache. LTE-Modems ziehen beim Senden kurze, hohe Stromstöße. Ein schwacher USB-Port oder dünne Leitungen verursachen Spannungseinbrüche, die das Modem mitten in der Verbindung zurücksetzen, und die Symptome wirken zufällig: Mal bucht es sich ein, mal nicht, mal trennt es sich nach ein paar Nachrichten.

Signal Typischer Pin auf dem LilyGO T-SIM7600 Zweck
Modem-TX zu ESP32-RX GPIO 26 UART-Daten vom Modem
Modem-RX von ESP32-TX GPIO 27 UART-Daten zum Modem
PWRKEY GPIO 4 Impuls zum Einschalten des Modems
Power Enable GPIO 12 Aktiviert bei manchen Board-Revisionen die Modemversorgung

Die Pinbelegung unterscheidet sich zwischen Boards und Revisionen. Prüfen Sie die Dokumentation Ihres Boards und passen Sie die Defines im Sketch an.

Bibliotheken

Installieren Sie über den Arduino-Bibliotheksverwalter:

  • TinyGSM von Volodymyr Shymanskyy.
  • PubSubClient von Nick O'Leary.

TinyGSM muss das Modemmodell zur Kompilierzeit kennen, deshalb muss #define TINY_GSM_MODEM_SIM7600 vor dem Include stehen.

Der vollständige SIM7600-MQTT-Sketch

#define TINY_GSM_MODEM_SIM7600
#define TINY_GSM_RX_BUFFER 1024          // größerer Puffer für eingehende MQTT-Daten

#include <TinyGsmClient.h>
#include <PubSubClient.h>

// ---- Board-Pins (Standardwerte LilyGO T-SIM7600, an Ihr Board anpassen) ----
#define MODEM_TX      27
#define MODEM_RX      26
#define MODEM_PWRKEY  4
#define MODEM_POWER   12

// ---- Mobilfunkeinstellungen ----
const char APN[]       = "internet";       // vom SIM-Anbieter
const char APN_USER[]  = "";
const char APN_PASS[]  = "";
const char SIM_PIN[]   = "";               // leer lassen, wenn die SIM keine PIN hat

// ---- MQTT-Einstellungen ----
const char* MQTT_HOST = "broker.connectmq.com";
const uint16_t MQTT_PORT = 1883;
const char* CLIENT_ID = "lte-81c3e5";      // eindeutig
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;  // ein Messwert pro 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);              // Impuls zum Einschalten
  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);                        // weniger Pings, weniger Daten
  mqtt.setSocketTimeout(15);                     // Mobilfunk-Roundtrips sind langsamer
}

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);
  }
}

Worauf Sie im seriellen Monitor achten sollten

Ein gesunder Start gibt die Modemkennung aus, dann Registered, signal quality N, die lokale IP und MQTT connected over LTE. Die Signalqualität ist der CSQ-Wert von 0 bis 31, wobei 99 „unbekannt" bedeutet. Werte unter etwa 10 sind grenzwertig; richten Sie die Antenne neu aus, bevor Sie die Software verdächtigen. Bleibt der Sketch bei der Registrierung hängen, liegt das Problem bei SIM, Netzabdeckung oder Antenne. Bucht er sich ein, aber die Datenverbindung scheitert, ist der APN falsch oder der Tarif enthält keine Daten. Gelingt beides, aber MQTT scheitert mit Status -2, wird die TCP-Verbindung blockiert; manche restriktive SIMs erlauben nur freigegebene Ziele.

Von Ihrem Rechner aus testen

mosquitto_sub -h broker.connectmq.com -p 1883 -i watch-81c3e5 -v -t "connectmq/demo/lte-81c3e5/#"

Sie sollten status online sehen, gefolgt von einer Telemetrie-Nachricht pro Minute. Senden Sie einen Befehl, um den Downlink-Pfad zu prüfen; das beweist zugleich, dass das NAT des Netzbetreibers die Verbindung offen hält:

mosquitto_pub -h broker.connectmq.com -p 1883 -i cmd-81c3e5 -t "connectmq/demo/lte-81c3e5/cmd" -m "ping"

Der kostenlose öffentliche MQTT-Broker eignet sich für die Inbetriebnahme und Prototypen, aber alles, was Sie dort veröffentlichen, ist für jeden lesbar, und Produktionsdaten gehören nicht dorthin. Wechseln Sie daher zu eigenen Zugangsdaten, bevor das Gerät die Werkbank verlässt.

Das Datenvolumen bei SIM7600 MQTT niedrig halten

Mobilfunktarife rechnen nach Byte ab, und MQTT ist nur effizient, wenn Sie es effizient einsetzen. Dies sind die wichtigsten Stellschrauben, ungefähr nach Wirkung sortiert:

  1. Reconnects vermeiden. Jede neue Verbindung kostet einen TCP-Handshake, MQTT-CONNECT und CONNACK, die Abonnements und mit TLS einen vollständigen Handshake einschließlich Zertifikatskette. Ein Gerät, das sich alle paar Minuten neu verbindet, kann mehr Daten für das Verbinden aufwenden als für die Telemetrie. Beheben Sie die Ursache der Abbrüche, statt zeitgesteuert neu zu verbinden.
  2. Keep-Alive abstimmen. In jeder Keep-Alive-Periode sendet der Client ein kleines PINGREQ, und der Broker antwortet. Ein längeres Keep-Alive spart Daten, aber NAT-Gateways der Netzbetreiber verwerfen inaktive Verbindungen nach einer Weile, und ist das Keep-Alive länger als diese Zeit, stirbt die Verbindung lautlos. Beginnen Sie bei etwa zwei Minuten und passen Sie den Wert nach Ihren Beobachtungen an.
  3. Payloads kürzen. Verwenden Sie kurze JSON-Schlüssel ("t" statt "temperature"), runden Sie Werte und lassen Sie Felder weg, die sich selten ändern.
  4. Messwerte bündeln. Zehn Messwerte in einer Nachricht alle zehn Minuten verursachen weit weniger Overhead als zehn einzelne Nachrichten.
  5. Bei Änderung veröffentlichen. Bei sich langsam ändernden Werten veröffentlichen Sie nur, wenn sich der Wert um mehr als einen Schwellenwert bewegt, plus einen periodischen Heartbeat.
  6. Kurze Topics verwenden. Das Topic wird mit jeder Nachricht übertragen. f/42/t ist günstiger als ein langer, sprechender Pfad, allerdings zählt auch die Lesbarkeit; finden Sie ein Gleichgewicht. Soll das Gerät in einen Unified Namespace (UNS) mit ISA-95-Pfaden wie stadtwerke/wasserwerk-nord/pumpstation-3/pumpe-1/druck einfließen, kann ein Backend-Dienst die kurzen Mobilfunk-Topics auf diese sprechende Struktur abbilden, sodass das Datenvolumen klein bleibt und der UNS trotzdem lesbar ist.
  7. Abonnements im Blick behalten. Wildcard-Abonnements auf stark frequentierte Topics können weit mehr Daten hereinholen als erwartet.

Bedenken Sie, dass Netzbetreiber jede Sitzung oder jeden Abrechnungszeitraum auf eine Mindesteinheit aufrunden können. Messen Sie den tatsächlichen Verbrauch daher einige Tage lang im Portal Ihres SIM-Anbieters, statt sich auf Berechnungen zu verlassen.

Sicherheit auf Mobilfunkverbindungen

Für die Produktion verwenden Sie TLS auf Port 8883 sowie den im ConnectMQ-Portal generierten Benutzernamen, das Passwort und die Client ID. Beim SIM7600 haben Sie zwei Möglichkeiten. Manche TinyGSM-Versionen und Forks bieten einen sicheren Client, der die integrierte SSL-Engine des Modems nutzt und so ESP32-Speicher spart; prüfen Sie, ob Ihre installierte Version das für den SIM7600 unterstützt. Alternativ betreiben Sie TLS auf dem ESP32 selbst mit einer Wrapper-Bibliothek wie SSLClient, die auf TinyGsmClient aufsetzt. In beiden Fällen prüfen Sie das Broker-Zertifikat gegen das Root ISRG Root X1, statt die Prüfung abzuschalten. Der Leitfaden zu ESP32 MQTT SSL erklärt die Zertifikatswahl und warum NTP oder Netzzeit wichtig ist; der SIM7600 kann ebenfalls die Netzzeit liefern.

Fehlerbehebung

  • Modem antwortet nie auf AT. Falsche UART-Pins, falsche Baudrate oder das Modem wird nicht versorgt. Prüfen Sie Power-Enable-Pin und PWRKEY-Impuls für Ihr Board.
  • Bucht sich nur in 2G oder 3G ein oder gar nicht. Das Frequenzband wird von Ihrer SIM7600-Variante möglicherweise nicht unterstützt (E, A, SA, G und weitere decken unterschiedliche Regionen ab).
  • Verbindet sich und bricht nach einigen Minuten Stille ab. Das Keep-Alive ist länger als der NAT-Timeout des Netzbetreibers. Verkürzen Sie es.
  • Brownout-Resets beim Senden. Das Netzteil kann den Spitzenstrom nicht liefern. Setzen Sie einen großen Kondensator nahe am Modem ein und verwenden Sie dickere Leitungen.
  • Nachrichten um Sekunden verzögert. Bei Mobilfunkverbindungen normal; die Latenz ist höher und schwankender als im WLAN. Planen Sie das ein.

Für eine robustere Reconnect-Strategie mit Backoff passen Sie die Zustandsmaschine aus ESP32-MQTT-Reconnect-Logik an. Gibt es am Standort eine kabelgebundene Option, vergleichen Sie mit ESP32-Ethernet-MQTT mit W5500, und für mobile Objekte lesen Sie den ESP32-GPS-Tracker über MQTT.

Eine Mobilfunkflotte betreiben

Mobilfunkgeräte vor Ort aufzusuchen ist teuer, ob Pumpstation eines Wasserversorgers oder beim Kunden installierte Maschine eines Maschinenbauers, daher sollte die Broker-Seite Ihre geringste Sorge sein. Ein verwalteter MQTT-Broker hält den Endpunkt verfügbar, während die Geräte zwischen Funkzellen wechseln und sich neu verbinden. ConnectMQ gibt jedem Gerät eigene Zugangsdaten, zeigt den Verbindungsstatus über $SYS/broker/connection/{clientId}/state und lässt Sie den Live-Datenverkehr im Portal beobachten, was hilft, wenn Sie verstehen wollen, wohin das Datenvolumen einer SIM fließt. Ein Cloud-MQTT-Broker mit öffentlichem Hostnamen erspart Ihnen außerdem die privaten APN- und VPN-Konstruktionen, die selbst gehostete Broker für Mobilfunkgeräte oft erfordern. Wenn dies Ihr erstes ESP32-Projekt ist, beginnen Sie mit dem ESP32-IoT-Tutorial.

Starten Sie mit ConnectMQ

Erstellen Sie einen kostenlosen Serverless Broker unter app.connectmq.com, ohne Kreditkarte. Ihre SIM7600-Geräte können von überall mit Netzabdeckung dorthin veröffentlichen, und Sie sehen jede eingehende Nachricht im Live-Topic-Explorer.

Häufig gestellte Fragen

Funktioniert PubSubClient mit dem SIM7600?

Ja. TinyGSM stellt TinyGsmClient bereit, der die Arduino-Client-Schnittstelle implementiert, sodass PubSubClient die TCP-Sockets des Modems genauso nutzt wie WLAN.

Wie viel Datenvolumen verbraucht SIM7600 MQTT?

Das hängt vor allem von der Häufigkeit der Reconnects, dem Keep-Alive-Intervall und der Payload-Größe ab. Ein Gerät, das verbunden bleibt und kompakte Nachrichten sendet, verbraucht sehr wenig; häufige Reconnects, besonders mit TLS, dominieren den Verbrauch. Messen Sie im Portal Ihres SIM-Anbieters.

Welchen APN sollte ich verwenden?

Der APN stammt von Ihrem SIM-Anbieter und steht meist in dessen Dokumentation oder IoT-Portal. Mit einem falschen APN bucht sich das Modem zwar ins Netz ein, kann aber keine Datenverbindung aufbauen.

Kann ich MQTT über TLS mit dem SIM7600 nutzen?

Ja, entweder über die SSL-Engine des Modems, sofern Ihre TinyGSM-Version das für den SIM7600 unterstützt, oder indem Sie TLS auf dem ESP32 mit einer Wrapper-Bibliothek über TinyGsmClient betreiben. Prüfen Sie immer das Broker-Zertifikat.

Verwandte Artikel

ESP32 NTP MQTT Zeitstempel: genaue Uhrzeit in jeder Nachricht

Synchronisieren Sie die ESP32-Uhr per NTP, formatieren Sie Zeitstempel in ISO 8601 und Epoch-Millisekunden und hängen Sie sie an MQTT-Payloads, damit Messwerte ihren echten Erfassungszeitpunkt behalten, auch wenn sie verspätet veröffentlicht werden.

8 Min. Lesezeit

Alle Artikel →

Ihr privater MQTT-Broker ist nur wenige Klicks entfernt

Konto anlegen, Broker-Zugangsdaten erhalten und das erste Gerät verbinden — ohne Server, die installiert, gepatcht oder skaliert werden müssen.