ESP32 und Arduino

Arduino Nano 33 IoT MQTT mit WiFiNINA: IMU-Daten über SSL streamen

Senden Sie Beschleunigungs- und Gyroskopwerte vom Arduino Nano 33 IoT mit WiFiNINA, WiFiSSLClient und ArduinoMqttClient an einen MQTT-Broker und härten Sie das Setup mit Zugangsdaten und einem Last Will.

Arduino Nano 33 IoT, das in einem Arduino-Nano-33-IoT-MQTT-Setup Bewegungssensordaten über SSL streamt
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

Der Nano 33 IoT vereint WLAN, eine 6-Achsen-IMU und ein Secure Element auf einem winzigen Board und macht Arduino-Nano-33-IoT-MQTT-Projekte damit ideal für die Bewegungsüberwachung. In diesem Leitfaden streamen Sie Beschleunigungs- und Gyroskopdaten mit WiFiNINA und ArduinoMqttClient über eine verschlüsselte SSL-Verbindung. Außerdem ergänzen Sie einen Last Will, halten die Nachrichtenrate innerhalb der Broker-Limits und beheben die häufigsten Zertifikatsfehler.

Die Architektur des Nano 33 IoT in einer Minute

Das Board kombiniert drei für dieses Projekt relevante Chips:

Komponente Rolle in einem MQTT-Projekt
SAMD21 (Arm Cortex-M0+) Führt Ihren Sketch aus
u-blox NINA-W102 WLAN-Coprozessor; übernimmt TCP und den SSL/TLS-Handshake
LSM6DS3 3-Achsen-Beschleunigungssensor und 3-Achsen-Gyroskop
ATECC608A Krypto-Element, nützlich für fortgeschrittene zertifikatsbasierte Authentifizierung

Ihr Sketch kommuniziert über die Bibliothek WiFiNINA mit dem NINA-Modul. Die NINA-Firmware speichert eine Liste von Root-Zertifikaten, sodass WiFiSSLClient die meisten bekannten Zertifizierungsstellen ohne Codeänderungen prüfen kann. Das ist der Hauptgrund, warum dieses Board SSL-Verbindungen leichter bewältigt als ein ESP8266: Die Schwerarbeit erledigt der Coprozessor.

Voraussetzungen

  1. Arduino IDE 2.x mit Arduino SAMD Boards (32-bits ARM Cortex-M0+), installiert über den Boardverwalter.
  2. Bibliotheken aus dem Bibliotheksverwalter: WiFiNINA, ArduinoMqttClient und Arduino_LSM6DS3.
  3. Ein 2,4-GHz-WLAN.
  4. Mosquitto-Kommandozeilentools auf Ihrem Computer zum Testen.
  5. Aktuelle NINA-Firmware. Laden Sie Datei → Beispiele → WiFiNINA → Tools → CheckWiFiNINAFirmware hoch und aktualisieren Sie bei Bedarf über Werkzeuge → WiFi101 / WiFiNINA Firmware Updater. Veraltete Firmware ist die häufigste Ursache für SSL-Fehler.

Schritt 1: Die IMU auslesen

Bevor Sie Netzwerkfunktionen ergänzen, prüfen Sie, ob der Sensor funktioniert:

#include <Arduino_LSM6DS3.h>

void setup() {
  Serial.begin(115200);
  while (!Serial) {}
  if (!IMU.begin()) {
    Serial.println("IMU not found");
    while (true) {}
  }
  Serial.print("Accelerometer sample rate: ");
  Serial.println(IMU.accelerationSampleRate());
}

void loop() {
  float x, y, z;
  if (IMU.accelerationAvailable()) {
    IMU.readAcceleration(x, y, z);
    Serial.print(x); Serial.print('\t');
    Serial.print(y); Serial.print('\t');
    Serial.println(z);
  }
  delay(200);
}

Liegt das Board flach auf dem Tisch, sollte z nahe 1,0 (ein g) liegen. Kippen Sie das Board und beobachten Sie, wie sich die Werte ändern.

Schritt 2: Arduino Nano 33 IoT MQTT über SSL

Sie verbinden sich auf Port 8883 mit broker.connectmq.com. Das Broker-Zertifikat stammt von Let's Encrypt, dessen Root in aktueller NINA-Firmware enthalten ist, sodass kein Zertifikat in den Sketch eingefügt werden muss. Für den allerersten Test können Sie den kostenlosen öffentlichen MQTT-Broker anonym nutzen; er verlangt nur eine eindeutige, nicht leere Client ID. Denken Sie daran, dass öffentliche Topics für jeden lesbar sind und der Broker für Tests und Prototypen gedacht ist, nicht für Produktionsdaten.

Legen Sie arduino_secrets.h an:

#define SECRET_SSID "YOUR_WIFI"
#define SECRET_PASS "YOUR_WIFI_PASSWORD"
// Für den öffentlichen MQTT-Broker leer lassen, für Ihren privaten ConnectMQ Broker ausfüllen
#define SECRET_MQTT_CLIENT_ID "nano33-c7e2a4"
#define SECRET_MQTT_USER ""
#define SECRET_MQTT_PASS ""

Der Haupt-Sketch veröffentlicht fünfmal pro Sekunde eine kompakte JSON-Nachricht mit Beschleunigung und Drehrate und bleibt damit deutlich unter dem Limit des öffentlichen MQTT-Brokers von 10 Nachrichten pro Sekunde und Client:

#include <WiFiNINA.h>
#include <ArduinoMqttClient.h>
#include <Arduino_LSM6DS3.h>
#include "arduino_secrets.h"

const char broker[] = "broker.connectmq.com";
const int  port     = 8883;

const char topicImu[]    = "connectmq/demo/nano33-c7e2a4/imu";
const char topicStatus[] = "connectmq/demo/nano33-c7e2a4/status";
const char topicRate[]   = "connectmq/demo/nano33-c7e2a4/rate/set";

WiFiSSLClient sslClient;
MqttClient mqttClient(sslClient);

unsigned long publishIntervalMs = 200;   // 5 Nachrichten pro Sekunde
unsigned long lastPublish = 0;

void connectWifi() {
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("WiFi module not found");
    while (true) {}
  }
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print("Connecting to ");
    Serial.println(SECRET_SSID);
    WiFi.begin(SECRET_SSID, SECRET_PASS);
    delay(5000);
  }
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());
}

void onMqttMessage(int size) {
  char buf[16];
  int i = 0;
  while (mqttClient.available() && i < (int)sizeof(buf) - 1) {
    buf[i++] = (char)mqttClient.read();
  }
  buf[i] = '\0';
  unsigned long ms = strtoul(buf, nullptr, 10);
  if (ms >= 100 && ms <= 60000) {          // nie schneller als 10 Nachr./s
    publishIntervalMs = ms;
    Serial.print("New interval: ");
    Serial.println(publishIntervalMs);
  }
}

bool connectMqtt() {
  mqttClient.setId(SECRET_MQTT_CLIENT_ID);
  if (strlen(SECRET_MQTT_USER) > 0) {
    mqttClient.setUsernamePassword(SECRET_MQTT_USER, SECRET_MQTT_PASS);
  }
  mqttClient.setKeepAliveInterval(30 * 1000L);
  mqttClient.setConnectionTimeout(10 * 1000L);

  mqttClient.beginWill(topicStatus, true, 1);
  mqttClient.print("offline");
  mqttClient.endWill();

  Serial.print("MQTT over SSL... ");
  if (!mqttClient.connect(broker, port)) {
    Serial.print("failed, error ");
    Serial.println(mqttClient.connectError());
    return false;
  }
  Serial.println("connected");

  mqttClient.onMessage(onMqttMessage);
  mqttClient.subscribe(topicRate, 1);

  mqttClient.beginMessage(topicStatus, true, 1);
  mqttClient.print("online");
  mqttClient.endMessage();
  return true;
}

void setup() {
  Serial.begin(115200);
  unsigned long start = millis();
  while (!Serial && millis() - start < 3000) {}

  if (!IMU.begin()) {
    Serial.println("IMU init failed");
    while (true) {}
  }
  connectWifi();
  while (!connectMqtt()) delay(5000);
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) connectWifi();
  if (!mqttClient.connected()) {
    delay(3000);
    connectMqtt();
    return;
  }
  mqttClient.poll();

  if (millis() - lastPublish >= publishIntervalMs &&
      IMU.accelerationAvailable() && IMU.gyroscopeAvailable()) {
    lastPublish = millis();
    float ax, ay, az, gx, gy, gz;
    IMU.readAcceleration(ax, ay, az);   // g
    IMU.readGyroscope(gx, gy, gz);      // Grad pro Sekunde

    // JSON direkt streamen; print(float, digits) umgeht Probleme mit Float-Unterstützung in printf
    mqttClient.beginMessage(topicImu);
    mqttClient.print("{\"ax\":"); mqttClient.print(ax, 3);
    mqttClient.print(",\"ay\":"); mqttClient.print(ay, 3);
    mqttClient.print(",\"az\":"); mqttClient.print(az, 3);
    mqttClient.print(",\"gx\":"); mqttClient.print(gx, 1);
    mqttClient.print(",\"gy\":"); mqttClient.print(gy, 1);
    mqttClient.print(",\"gz\":"); mqttClient.print(gz, 1);
    mqttClient.print("}");
    mqttClient.endMessage();
  }
}

Beobachten Sie den Datenstrom und verlangsamen Sie ihn von Ihrem Computer aus:

mosquitto_sub -h broker.connectmq.com -p 1883 -i pc-c7e2a4 -t "connectmq/demo/nano33-c7e2a4/#" -v
mosquitto_pub -h broker.connectmq.com -p 1883 -i ctl-c7e2a4 -t "connectmq/demo/nano33-c7e2a4/rate/set" -m 1000

Beachten Sie, dass Ihr Laptop den unverschlüsselten Port 1883 nutzt, während das Board SSL auf 8883 verwendet. Beide erreichen dieselben Topics auf demselben Broker.

Die Payload wird mit print(value, digits) statt mit snprintf gestreamt. Die Float-Unterstützung in Funktionen im printf-Stil unterscheidet sich zwischen Arduino-Cores, während print() Floats überall gleich formatiert, und das Streaming vermeidet, die ganze Nachricht im RAM zu halten.

Schritt 3: Auf private Zugangsdaten umstellen

Der öffentliche MQTT-Broker genügt für eine Demo, aber Bewegungsdaten von echten Maschinen oder Personen sollten nicht öffentlich sein. Bei einem verwalteten MQTT-Broker wie ConnectMQ legen Sie im Portal einen Broker an und erhalten generierte Werte für Benutzername, Passwort und Client ID. Tragen Sie sie in arduino_secrets.h ein, bleiben Sie bei der Verbindung über 8883 und ersetzen Sie das Präfix connectmq/demo/ durch Ihre eigene Topic-Struktur. In einer Fabrik bietet sich die ISA-95-Hierarchie an, wie sie ein Unified Namespace (UNS) nutzt, etwa acme/werk-augsburg/montage/linie-2/luefter-4/vibration. Client IDs sind an die ausgestellten Zugangsdaten gebunden, die Client ID muss also exakt übereinstimmen.

Hinweise zu Topic-Design, Rotation von Zugangsdaten und dem Prinzip der minimalen Rechte finden Sie in Best Practices für MQTT-Sicherheit.

QoS und Rate für IMU-Daten wählen

Hochfrequente Sensordaten und Befehlsnachrichten haben unterschiedliche Anforderungen:

  • Telemetrie mit 5 Hz oder mehr: QoS 0. Der Verlust eines Messwerts unter Hunderten spielt keine Rolle, und QoS 0 vermeidet zusätzlichen Bestätigungsverkehr über die NINA-Verbindung.
  • Ratenänderungen und andere Befehle: Mit QoS 1 abonnieren, damit der Broker die Zustellung wiederholt.
  • Status: retained mit QoS 1 und passendem Last Will, damit Dashboards immer wissen, ob das Board online ist.

Brauchen Sie Funktionen wie Schwingungsanalyse, berechnen Sie besser Kennwerte auf dem Gerät (zum Beispiel den RMS-Wert der Beschleunigung über eine Sekunde) und veröffentlichen diese statt Rohdaten. Das reduziert die Bandbreite und bleibt bequem innerhalb der Nachrichtenlimits jedes Plans. MQTT-QoS-Stufen erklärt behandelt diese Abwägungen ausführlicher.

Schwingungskennwerte auf dem Board berechnen

Rohe IMU-Messwerte sind für Experimente nützlich, aber bei der Überwachung eines Lüfters, einer Pumpe oder einer Waschmaschine interessiert meist, wie stark das Gerät über die Zeit vibriert. Der quadratische Mittelwert (RMS) des Beschleunigungsbetrags über eine Sekunde macht aus Dutzenden Messwerten eine einzige aussagekräftige Zahl. Zieht man zuvor die Erdbeschleunigung von 1 g ab, liegt der Wert bei stillstehender Maschine nahe null. Gerade im Mittelstand ist das ein günstiger Weg, Bestandsmaschinen ohne Eingriff in die SPS für ein erstes Condition Monitoring nachzurüsten.

float sumSq = 0;
int samples = 0;
unsigned long windowStart = 0;

void sampleVibration() {
  float x, y, z;
  if (IMU.accelerationAvailable()) {
    IMU.readAcceleration(x, y, z);
    float mag = sqrt(x * x + y * y + z * z) - 1.0;   // Erdbeschleunigung entfernen
    sumSq += mag * mag;
    samples++;
  }
  if (millis() - windowStart >= 1000 && samples > 0) {
    float rms = sqrt(sumSq / samples);
    mqttClient.beginMessage("connectmq/demo/nano33-c7e2a4/vibration");
    mqttClient.print("{\"rms_g\":");
    mqttClient.print(rms, 4);
    mqttClient.print(",\"n\":");
    mqttClient.print(samples);
    mqttClient.print("}");
    mqttClient.endMessage();
    sumSq = 0;
    samples = 0;
    windowStart = millis();
  }
}

Rufen Sie sampleVibration() in loop() neben mqttClient.poll() auf. Das Ergebnis ist eine Nachricht pro Sekunde statt eines Datenstroms, und das Feld n gibt an, auf wie vielen Messwerten der Wert beruht. Auf der Empfängerseite ist ein Schwellenwert auf rms_g eine einfache und wirksame Methode, ungewöhnliche Vibrationen zu erkennen. Kalibrieren Sie ihn, indem Sie zuerst einige Minuten Normalbetrieb aufzeichnen, denn jede Maschine und jede Montageposition verhält sich anders.

Die Verbindung stabil halten

Ein Bewegungslogger läuft oft tagelang unbeaufsichtigt, planen Sie also Netzwerkaussetzer ein. Die Reconnect-Logik im Sketch versucht es alle paar Sekunden erneut, doch ein Router-Neustart kann länger dauern. Erhöhen Sie daher nach wiederholten Fehlschlägen die Wartezeit, um das Netzwerk nicht zu überlasten. Veröffentlichen Sie das retained Status-Topic bei jedem erfolgreichen Reconnect und protokollieren Sie WiFi.RSSI() zusammen mit Ihren Daten: Ein schwaches Signal ist der häufigste Grund, warum ein Board in einem Metallgehäuse immer wieder die Verbindung verliert. Bleiben die Messwerte aus, während der Status noch online meldet, prüfen Sie, ob poll() bei jedem Durchlauf von loop() aufgerufen wird.

Checkliste zur Fehlerbehebung

  1. connect() scheitert auf 8883, funktioniert aber auf 1883 mit WiFiClient: Aktualisieren Sie die NINA-Firmware. Nutzen Sie einen Broker mit ungewöhnlicher CA, laden Sie dessen Root-Zertifikat mit dem Zertifikatswerkzeug des Firmware-Updaters hoch.
  2. "WiFi module not found": falsches Board ausgewählt oder veraltete WiFiNINA-Bibliothek.
  3. Fehler 2 (Identifier abgelehnt): leere Client ID.
  4. Fehler 4 oder 5: Zugangsdaten oder Client ID stimmen nicht mit den im Portal ausgestellten überein.
  5. Verbindungsabbrüche nach einigen Minuten: Etwas in loop() blockiert poll(), oder zwei Boards teilen sich eine Client ID.
  6. IMU-Werte eingefroren: Prüfen Sie, ob IMU.begin() erfolgreich war und Sie nur lesen, wenn accelerationAvailable() true ist.

Verwandte Leitfäden

Der Leitfaden zur ArduinoMqttClient-Bibliothek geht tiefer auf die hier verwendete API ein, und das Arduino-UNO-R4-WiFi-MQTT-Tutorial zeigt dasselbe Muster mit dem WiFiS3-Stack. Einen breiteren Überblick über Embedded-MQTT-Projekte bietet das ESP32-IoT-Tutorial.

Streamen Sie Ihre Nano-33-IoT-Daten zu ConnectMQ

ConnectMQ ist ein Cloud-MQTT-Broker mit SSL auf Port 8883, einem Let's-Encrypt-Zertifikat, dem das NINA-Modul ab Werk vertraut, und einem Portal mit Live-Topic-Explorer und Schwellenwert-Alarmregeln, die sich gut für Bewegungs- und Vibrationsalarme eignen. Erstellen Sie einen kostenlosen Serverless Broker unter app.connectmq.com, ohne Kreditkarte.

Häufig gestellte Fragen

Unterstützt der Arduino Nano 33 IoT MQTT über SSL?

Ja. Das WLAN-Modul NINA-W102 führt den SSL/TLS-Handshake aus, und WiFiSSLClient verbindet sich zusammen mit ArduinoMqttClient mit sehr wenig Code auf Port 8883.

Muss ich für ConnectMQ ein Root-Zertifikat hinzufügen?

Normalerweise nicht. ConnectMQ verwendet ein Let's-Encrypt-Zertifikat, dessen Root Teil aktueller NINA-Firmware ist. Aktualisieren Sie die Firmware, falls die Prüfung fehlschlägt.

Wie schnell kann ich IMU-Daten veröffentlichen?

Bleiben Sie innerhalb der Limits Ihres Brokers. Auf dem öffentlichen MQTT-Broker sind das 10 Nachrichten pro Sekunde und Client; für höhere Abtastraten fassen Sie mehrere Messwerte in einer Nachricht zusammen oder veröffentlichen berechnete Kennwerte.

Kann ich den ATECC608A für die MQTT-Authentifizierung nutzen?

Das Krypto-Element kann Schlüssel für die zertifikatsbasierte Authentifizierung bei Brokern speichern, die Client-Zertifikate unterstützen. Beim Setup in diesem Leitfaden authentifizieren Sie sich mit Benutzername, Passwort und Client ID aus dem Portal.

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.