ESP32 ve Arduino

WiFiNINA ile Arduino Nano 33 IoT MQTT: IMU Verisini SSL Üzerinden Gönderin

Arduino Nano 33 IoT'deki ivmeölçer ve jiroskop okumalarını WiFiNINA, WiFiSSLClient ve ArduinoMqttClient ile bir MQTT broker'a yayınlayın, ardından kimlik bilgileri ve bir Last Will ile sağlamlaştırın.

SSL üzerinden bir Arduino Nano 33 IoT MQTT kurulumunda hareket sensörü verisi gönderen Arduino Nano 33 IoT kartı
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

Nano 33 IoT; Wi-Fi'yi, 6 eksenli bir IMU'yu ve bir güvenli elemanı (secure element) küçücük bir karta sığdırır; bu da Arduino Nano 33 IoT MQTT projelerini hareket izleme için ideal kılar. Bu rehberde WiFiNINA ve ArduinoMqttClient kullanarak ivmeölçer ve jiroskop verilerini şifreli bir SSL bağlantısı üzerinden göndereceksiniz. Ayrıca bir Last Will ekleyecek, mesaj hızını broker limitleri içinde tutacak ve insanların en sık karşılaştığı sertifika hatalarını çözeceksiniz.

Bir Dakikada Nano 33 IoT Mimarisi

Kart, bu proje için önemli olan üç çipi bir araya getirir:

Bileşen MQTT projesindeki rolü
SAMD21 (Arm Cortex-M0+) Sketch'inizi çalıştırır
u-blox NINA-W102 Wi-Fi yardımcı işlemcisi; TCP'yi ve SSL/TLS el sıkışmasını yürütür
LSM6DS3 3 eksenli ivmeölçer ve 3 eksenli jiroskop
ATECC608A Kripto elemanı; gelişmiş sertifika tabanlı kimlik doğrulama için kullanışlı

Sketch'iniz NINA modülüyle WiFiNINA kütüphanesi üzerinden konuşur. NINA firmware'i bir kök sertifika listesi saklar; böylece WiFiSSLClient, kod değişikliği yapmadan iyi bilinen sertifika otoritelerinin çoğunu doğrulayabilir. Bu kartın SSL bağlantılarını bir ESP8266'dan daha kolay yönetmesinin ana nedeni budur: ağır iş yardımcı işlemcide yapılır.

Ön Koşullar

  1. Boards Manager'dan Arduino SAMD Boards (32-bits ARM Cortex-M0+) kurulu Arduino IDE 2.x.
  2. Library Manager'dan kütüphaneler: WiFiNINA, ArduinoMqttClient ve Arduino_LSM6DS3.
  3. 2,4 GHz bir Wi-Fi ağı.
  4. Test için bilgisayarınızda Mosquitto komut satırı araçları.
  5. Güncel NINA firmware'i. File → Examples → WiFiNINA → Tools → CheckWiFiNINAFirmware örneğini yükleyin ve gerekirse Tools → WiFi101 / WiFiNINA Firmware Updater ile güncelleyin. Eski firmware, SSL hatalarının bir numaralı nedenidir.

Adım 1: IMU'yu Okuyun

Ağ özelliklerini eklemeden önce sensörün çalıştığını doğrulayın:

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

Masada düz dururken z değeri 1,0'a (bir g) yakın olmalıdır. Kartı eğin ve değerlerin değişmesini izleyin.

Adım 2: SSL Üzerinden Arduino Nano 33 IoT MQTT

broker.connectmq.com adresine 8883 portundan bağlanacaksınız. Broker sertifikası, kökü güncel NINA firmware'inde bulunan Let's Encrypt tarafından verilir; bu yüzden sketch'e herhangi bir sertifika yapıştırmanız gerekmez. İlk test için ücretsiz herkese açık MQTT broker'ı anonim olarak kullanabilirsiniz; yalnızca benzersiz ve boş olmayan bir client ID gerektirir. Herkese açık topic'lerin herkes tarafından okunabildiğini unutmayın.

arduino_secrets.h dosyasını oluşturun:

#define SECRET_SSID "YOUR_WIFI"
#define SECRET_PASS "YOUR_WIFI_PASSWORD"
// Herkese açık broker için boş bırakın, özel ConnectMQ broker'ınız için doldurun
#define SECRET_MQTT_CLIENT_ID "nano33-c7e2a4"
#define SECRET_MQTT_USER ""
#define SECRET_MQTT_PASS ""

Ana sketch, ivme ve dönüş bilgilerini içeren kompakt bir JSON mesajını saniyede beş kez yayınlar; bu, herkese açık broker'ın client başına saniyede 10 mesaj limitinin rahatça altında kalır:

#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;   // saniyede 5 mesaj
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) {          // asla saniyede 10 mesajdan hızlı değil
    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);      // derece/saniye

    // JSON'u doğrudan akıtın; print(float, digits) printf float desteği sorunlarını önler
    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();
  }
}

Akışı izleyin ve bilgisayarınızdan yavaşlatın:

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

Dizüstü bilgisayarınızın düz 1883 portunu, kartın ise 8883'te SSL'i kullandığına dikkat edin. Her ikisi de aynı broker'daki aynı topic'lere ulaşır.

Payload, snprintf yerine print(value, digits) ile akıtılır. printf tarzı fonksiyonlardaki float desteği Arduino core'ları arasında farklılık gösterirken print() float'ları her yerde aynı şekilde biçimlendirir; akış halinde göndermek de mesajın tamamını RAM'de tutma ihtiyacını ortadan kaldırır.

Adım 3: Özel Kimlik Bilgilerine Geçin

Herkese açık alan bir demo için uygundur, ancak gerçek makinelerden veya insanlardan gelen hareket verileri herkese açık olmamalıdır. ConnectMQ gibi yönetilen bir MQTT broker'da portalda bir broker oluşturur ve otomatik üretilmiş bir kullanıcı adı, parola ve client ID alırsınız. Bunları arduino_secrets.h içine koyun, bağlantıyı 8883'te tutun ve connectmq/demo/ önekini kaldırarak kendi topic yapınızı kullanın. Client ID'ler verilen kimlik bilgilerine bağlıdır, bu yüzden client ID birebir eşleşmelidir.

Topic tasarımı, kimlik bilgisi rotasyonu ve en az yetki ilkesi hakkında rehberlik için MQTT güvenliği en iyi uygulamaları yazısını okuyun.

IMU Verisi İçin QoS ve Hız Seçimi

Yüksek hızlı sensör verileri ile komut mesajlarının ihtiyaçları farklıdır:

  • 5 Hz veya üzeri telemetri: QoS 0. Yüzlerce örnekten birini kaybetmek önemli değildir ve QoS 0, NINA bağlantısı üzerinden ek onay trafiğini önler.
  • Hız değişiklikleri ve diğer komutlar: broker'ın teslimatı yeniden denemesi için QoS 1 ile abone olun.
  • Durum: eşleşen bir Last Will ile retained QoS 1; böylece dashboard'lar kartın çevrimiçi olup olmadığını her zaman bilir.

Titreşim analizi gibi özelliklere ihtiyacınız varsa, ham örnekler yerine cihazda özet değerler (örneğin bir saniyelik RMS ivme) hesaplayıp bunları yayınlamayı düşünün. Bu bant genişliğini azaltır ve her planın mesaj limitlerinin rahatça içinde kalır. MQTT QoS seviyeleri açıklamalı yazısı bu ödünleşimleri daha ayrıntılı ele alır.

Kart Üzerinde Titreşim Özetleri Hesaplamak

Ham IMU örnekleri deneyler için kullanışlıdır, ancak bir fanı, pompayı veya çamaşır makinesini izlerken genellikle cihazın zaman içinde ne kadar sarsıldığıyla ilgilenirsiniz. İvme büyüklüğünün bir saniye boyunca karekök ortalama karesini (RMS) hesaplamak, onlarca örneği tek ve anlamlı bir sayıya dönüştürür. Önce 1 g'lik yerçekimi bileşenini çıkarmak, makine dururken değeri sıfıra yaklaştırır.

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;   // yerçekimini çıkar
    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();
  }
}

sampleVibration() fonksiyonunu loop() içinden mqttClient.poll() ile birlikte çağırın. Sonuç, bir akış yerine saniyede bir mesajdır ve n alanı değerin kaç örneğe dayandığını söyler. Alıcı tarafta rms_g üzerinde bir eşik, anormal sarsıntıyı işaretlemenin basit ve etkili bir yoludur. Her makine ve montaj konumu farklı davrandığından, eşiği önce birkaç dakikalık normal çalışmayı kaydederek kalibre edin.

Bağlantıyı Sağlıklı Tutmak

Bir hareket kaydedici genellikle günlerce gözetimsiz çalışır, bu yüzden ağ aksaklıklarına hazırlıklı olun. Sketch'teki yeniden bağlanma mantığı birkaç saniyede bir yeniden dener, ancak bir router yeniden başlatması daha uzun sürebilir; bu nedenle ağı yormamak için tekrarlanan başarısızlıklardan sonra bekleme süresini artırmayı düşünün. Her başarılı yeniden bağlanmada retained durum topic'ini yayınlayın ve verilerinizle birlikte WiFi.RSSI() değerini de kaydedin: zayıf sinyal, metal bir kutu içindeki kartın sürekli bağlantıyı kaybetmesinin en yaygın nedenidir. Durum hâlâ çevrimiçi derken okumalar duruyorsa, poll() fonksiyonunun loop() içindeki her geçişte çağrıldığını kontrol edin.

Sorun Giderme Kontrol Listesi

  1. connect() 8883'te başarısız ama WiFiClient ile 1883'te çalışıyor: NINA firmware'ini güncelleyin. Alışılmadık bir CA kullanan bir broker kullanıyorsanız, kök sertifikasını firmware güncelleyicinin sertifika aracıyla yükleyin.
  2. "WiFi module not found": yanlış kart seçilmiş veya WiFiNINA kütüphanesi eski.
  3. Hata 2 (identifier rejected): boş client ID.
  4. Hata 4 veya 5: kimlik bilgileri veya client ID portalın verdikleriyle eşleşmiyor.
  5. Dakikalar sonra bağlantı kopuyor: loop() içindeki bir şey poll() çağrısını engelliyor ya da iki kart aynı client ID'yi paylaşıyor.
  6. IMU değerleri donmuş: IMU.begin() çağrısının başarılı olduğunu ve yalnızca accelerationAvailable() true olduğunda okuduğunuzu kontrol edin.

İlgili Rehberler

ArduinoMqttClient kütüphane rehberi burada kullanılan API'yi daha derinlemesine ele alır; Arduino UNO R4 WiFi MQTT eğitimi ise aynı deseni WiFiS3 yığınında gösterir. Gömülü MQTT projelerine daha geniş bir bakış için ESP32 IoT eğitimine göz atın.

Nano 33 IoT Verilerinizi ConnectMQ'ya Gönderin

ConnectMQ; 8883 portunda SSL, NINA modülünün kutudan çıktığı haliyle güvendiği bir Let's Encrypt sertifikası ve canlı topic gezgini ile eşik uyarı kuralları içeren bir portal sunan bir bulut MQTT broker'dır; bu da hareket ve titreşim uyarılarına çok iyi uyar. app.connectmq.com adresinde ücretsiz bir Serverless broker oluşturun, kredi kartı gerekmez.

Sık Sorulan Sorular

Arduino Nano 33 IoT, SSL üzerinden MQTT'yi destekler mi?

Evet. NINA-W102 Wi-Fi modülü SSL/TLS el sıkışmasını gerçekleştirir ve ArduinoMqttClient ile birleştirilen WiFiSSLClient, çok az kodla 8883 portuna bağlanır.

ConnectMQ için bir kök sertifika eklemem gerekir mi?

Normalde hayır. ConnectMQ bir Let's Encrypt sertifikası kullanır ve kökü güncel NINA firmware'inin bir parçasıdır. Doğrulama başarısız olursa firmware'i güncelleyin.

IMU verisini ne kadar hızlı yayınlayabilirim?

Cihazı broker'ınızın limitleri içinde tutun. Herkese açık broker'da bu, client başına saniyede 10 mesajdır; daha yüksek örnekleme hızları için birkaç okumayı tek bir mesajda toplayın veya hesaplanmış özetleri yayınlayın.

MQTT kimlik doğrulaması için ATECC608A'yı kullanabilir miyim?

Kripto elemanı, client sertifikalarını destekleyen broker'larla sertifika tabanlı kimlik doğrulama için anahtar saklayabilir. Bu rehberdeki kurulumda ise portalda verilen kullanıcı adı, parola ve client ID ile kimlik doğrularsınız.

İlgili yazılar

ESP32 NTP MQTT Zaman Damgası: Her Mesaja Doğru Zaman Ekleyin

ESP32 saatini NTP ile eşitleyin, ISO 8601 ve epoch milisaniye zaman damgalarını biçimlendirin ve bunları MQTT payload'larına ekleyin; böylece ölçümler geç yayınlansa bile gerçek alınma zamanlarını korur.

6 dk okuma

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.