Edge Impulse MQTT entegrasyonu, Edge Impulse Studio'da eğittiğiniz bir modeli sisteminizin geri kalanının kullanabileceği bir şeye dönüştüren son adımdır. Bu eğitimde bir impulse'u Arduino kütüphanesi olarak dışa aktaracak, bir ESP32 üzerinde çalıştıracak ve her tahmini JSON olarak broker.connectmq.com'a yayınlayacak, ardından aynısını Linux runner ve Python ile bir Raspberry Pi üzerinde yapacaksınız. Sonunda gösterge panelleri ve uyarı sistemleri, modelinizin çıktısına diğer herhangi bir sensör gibi abone olabilecek.
Parçalar Nasıl Bir Araya Gelir
Edge Impulse; veri toplama, sinyal işleme blokları, eğitim ve optimizasyonu üstlenir. Ürettiği şey dağıtılabilir bir çıktıdır: mikrodenetleyiciler için bir C++ kütüphanesi (Arduino kütüphanesi olarak da paketlenir) veya Linux hedefleri için bir .eim çalıştırılabilir dosyası. Bunların hiçbiri ağınız hakkında bir şey bilmez. Sınıflandırıcının etrafına sonuçları bir MQTT broker'a yayınlayan az miktarda kod eklersiniz ve oradan itibaren istediğiniz sayıda tüketici tepki verebilir.
| Hedef | Dışa aktarma seçeneği | Çıkarım çağrısı | MQTT istemcisi |
|---|---|---|---|
| ESP32 / ESP32-S3 | Arduino kütüphanesi (.zip) | C++'ta run_classifier() |
PubSubClient |
| Raspberry Pi / Linux | Linux runner ile .eim |
Python'da ImpulseRunner.classify() |
paho-mqtt 2.x |
Adım 1: Modeli Edge Impulse Studio'dan Dışa Aktarın
- Projenizi açın ve impulse'un eğitildiğinden ve Model testing sonuçlarının kabul edilebilir olduğundan emin olun.
- Deployment bölümüne gidin, Arduino library seçin ve EON Compiler ile nicemlenmiş seçenekler sunuluyorsa nicemlenmiş (int8) modeli seçin. Nicemlenmiş modeller daha az RAM kullanır ve mikrodenetleyicilerde daha hızlı çalışır.
- Build düğmesine tıklayın ve
.zipdosyasını indirin. Kütüphane adı proje adınızı izler, örneğinvibration_monitor_inferencing. - Arduino IDE'de yüklemek için Sketch > Include Library > Add .ZIP Library yolunu kullanın.
- Library Manager'dan Nick O'Leary'nin PubSubClient kütüphanesini de kurun ve Espressif'in ESP32 kart paketinin kurulu olduğundan emin olun.
Bir sensör bağlamadan test etmek için Studio'da Live classification veya bir test örneğini açın ve ham özniteliklerin yanındaki Copy to clipboard düğmesine tıklayın. Bu diziyi sketch'e yapıştıracaksınız.
Adım 2: Tahminleri Yayınlayan ESP32 Sketch'i
Aşağıdaki sketch, sınıflandırıcıyı her iki saniyede bir statik bir öznitelik tamponu üzerinde çalıştırır ve sonucu yayınlar. include satırını kütüphanenizin başlık dosyası adıyla değiştirin ve ham özniteliklerinizi yapıştırın. Sensörle çalışan bir sürüm ardından gösteriliyor.
#include <WiFi.h>
#include <PubSubClient.h>
#include <vibration_monitor_inferencing.h> // dışa aktardığınız kütüphane
const char *WIFI_SSID = "your-ssid";
const char *WIFI_PASS = "your-password";
const char *MQTT_HOST = "broker.connectmq.com";
const uint16_t MQTT_PORT = 1883;
const char *CLIENT_ID = "ei-esp32-4b7e19"; // benzersiz yapın
const char *TOPIC_BASE = "connectmq/demo/4b7e19/line1/fan3"; // benzersiz yapın
// Edge Impulse Studio'dan kopyalanan ham öznitelikleri yapıştırın
static const float features[] = {
0.0
};
WiFiClient net;
PubSubClient mqtt(net);
int raw_feature_get_data(size_t offset, size_t length, float *out_ptr) {
memcpy(out_ptr, features + offset, length * sizeof(float));
return 0;
}
void connectWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
Serial.printf("\nWi-Fi OK, IP %s\n", WiFi.localIP().toString().c_str());
}
void connectMqtt() {
String statusTopic = String(TOPIC_BASE) + "/status";
while (!mqtt.connected()) {
Serial.print("MQTT connecting... ");
if (mqtt.connect(CLIENT_ID, statusTopic.c_str(), 1, true, "offline")) {
mqtt.publish(statusTopic.c_str(), "online", true);
Serial.println("connected");
} else {
Serial.printf("failed rc=%d, retry in 3 s\n", mqtt.state());
delay(3000);
}
}
}
void publishResult(const ei_impulse_result_t &result) {
// En yüksek sınıfı bul ve tüm skorlarla bir JSON nesnesi oluştur
size_t best = 0;
String scores = "{";
for (size_t i = 0; i < EI_CLASSIFIER_LABEL_COUNT; i++) {
if (result.classification[i].value > result.classification[best].value) best = i;
scores += "\"" + String(result.classification[i].label) + "\":" +
String(result.classification[i].value, 3);
if (i < EI_CLASSIFIER_LABEL_COUNT - 1) scores += ",";
}
scores += "}";
String payload = "{\"label\":\"" + String(result.classification[best].label) + "\"" +
",\"p\":" + String(result.classification[best].value, 3) +
",\"scores\":" + scores +
",\"dsp_ms\":" + String(result.timing.dsp) +
",\"nn_ms\":" + String(result.timing.classification);
#if EI_CLASSIFIER_HAS_ANOMALY == 1
payload += ",\"anomaly\":" + String(result.anomaly, 3);
#endif
payload += "}";
String topic = String(TOPIC_BASE) + "/inference";
bool ok = mqtt.publish(topic.c_str(), payload.c_str());
Serial.printf("%s %s\n", ok ? "sent" : "FAILED", payload.c_str());
}
void setup() {
Serial.begin(115200);
delay(500);
if (sizeof(features) / sizeof(float) != EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
Serial.printf("Feature count mismatch: got %u, expected %u\n",
(unsigned)(sizeof(features) / sizeof(float)),
(unsigned)EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE);
}
connectWiFi();
mqtt.setServer(MQTT_HOST, MQTT_PORT);
mqtt.setBufferSize(512); // varsayılan 256 bayt tüm skorlar için çok küçük
connectMqtt();
}
void loop() {
if (!mqtt.connected()) connectMqtt();
mqtt.loop();
signal_t signal;
signal.total_length = EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE;
signal.get_data = &raw_feature_get_data;
ei_impulse_result_t result = { 0 };
EI_IMPULSE_ERROR err = run_classifier(&signal, &result, false);
if (err != EI_IMPULSE_OK) {
Serial.printf("run_classifier failed (%d)\n", err);
} else {
publishResult(result);
}
delay(2000);
}
Yükleyin, Serial Monitor'ü 115200 baud hızında açın; yapıştırdığınız örneğin sınıflandırması her iki saniyede bir görünür. Skorlar, Studio'nun aynı örnek için gösterdikleriyle eşleşmelidir. Eşleşmiyorsa öznitelikler farklı bir örnekten veya yanlış işleme bloğundan kopyalanmıştır.
Canlı Sensör Verisi Kullanmak
Gerçek bir dağıtım için, impulse'un eğitildiği örnekleme aralığında sensörden bir tampon doldurun ve ardından onu bir sinyale sarın. EI_CLASSIFIER_INTERVAL_MS ve EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME dışa aktarılan kütüphaneden gelir:
static float buffer[EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE];
void readAccel(float &x, float &y, float &z); // sensörünüz için uygulayın
bool classifyLive(ei_impulse_result_t &result) {
for (size_t i = 0; i < EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE; i += EI_CLASSIFIER_RAW_SAMPLES_PER_FRAME) {
uint64_t next = micros() + (uint64_t)(EI_CLASSIFIER_INTERVAL_MS * 1000);
readAccel(buffer[i], buffer[i + 1], buffer[i + 2]); // 3 eksenli bir impulse varsayar
while (micros() < next) { }
}
signal_t signal;
if (numpy::signal_from_buffer(buffer, EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, &signal) != 0) return false;
return run_classifier(&signal, &result, false) == EI_IMPULSE_OK;
}
Pencereler arasında mqtt.loop() çağırın. Uzun pencerelerde meşgul bekleyen bir örnekleme döngüsü MQTT keepalive'ını aksatabilir; bu yüzden ya pencereleri kısa tutun ya da bir zamanlayıcı kesmesinden veya FreeRTOS görevinden örnekleyin.
Adım 3: Python ile Raspberry Pi'de Edge Impulse
Linux hedeflerinde Edge Impulse, kart için optimize edilmiş bir .eim modeli indiren bir runner sağlar. CLI'yi cihazınıza yönelik Edge Impulse Linux belgelerini izleyerek kurun, ardından:
edge-impulse-linux-runner --download model.eim
pip install edge_impulse_linux "paho-mqtt>=2.0"
Bu betik modeli yükler, bir öznitelik vektörünü sınıflandırır ve sonucu yayınlar. get_features() fonksiyonunu kendi veri kaynağınızla, örneğin I2C üzerinden bir sensörden okunan değerlerle değiştirin.
import json
import time
import uuid
import paho.mqtt.client as mqtt
from edge_impulse_linux.runner import ImpulseRunner
MODEL = "model.eim"
RUN = uuid.uuid4().hex[:8]
BASE = f"connectmq/demo/{RUN}/line1/fan3"
def get_features(count):
"""Yer tutucu: Studio'nun ham öznitelikleriyle aynı formatta `count` adet float döndürür."""
return [0.0] * count
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"ei-pi-{RUN}")
client.will_set(f"{BASE}/status", "offline", qos=1, retain=True)
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
client.publish(f"{BASE}/status", "online", qos=1, retain=True)
runner = ImpulseRunner(MODEL)
try:
info = runner.init()
params = info["model_parameters"]
print("loaded", info["project"]["name"], "expects", params["input_features_count"], "features")
while True:
res = runner.classify(get_features(params["input_features_count"]))
scores = res["result"]["classification"]
label = max(scores, key=scores.get)
msg = {"label": label, "p": round(scores[label], 3),
"scores": {k: round(v, 3) for k, v in scores.items()},
"ms": res.get("timing", {}).get("classification")}
if "anomaly" in res["result"]:
msg["anomaly"] = round(res["result"]["anomaly"], 3)
client.publish(f"{BASE}/inference", json.dumps(msg), qos=1)
print(msg)
time.sleep(2)
finally:
runner.stop()
client.loop_stop()
Kamera ve mikrofon projeleri için aynı SDK, tek adımda yakalayıp sınıflandıran görüntü ve ses runner'ları sağlar; onların sonuçlarını da aynı şekilde yayınlayın.
Adım 4: Abone Olun ve Doğrulayın
mosquitto_sub -h broker.connectmq.com -p 1883 -i ei-viewer-77 -t 'connectmq/demo/+/line1/fan3/#' -v
Retained durumu ve bir çıkarım mesajları akışını görmelisiniz. Herkese açık MQTT test broker'ı herkese açıktır; bu yüzden rastgele bir önek kullanın ve asla özel veri göndermeyin. Üretim için özel bir broker oluşturun ve portaldaki kullanıcı adı, parola ve client ID ile ESP32'de WiFiClientSecure veya Python'da client.tls_set() kullanarak 8883 portunda TLS'e geçin.
Tahminleri Eylemlere Dönüştürmek
Tahminler bir broker'a ulaştığında cihazın işi biter ve geri kalanı sıradan MQTT entegrasyonudur. Birkaç desen çoğu projeyi kapsar.
Gösterge panelleri. Bir tarayıcı gösterge paneli, /mqtt yoluyla 8084 portunda güvenli WebSocket üzerinden abone olabilir ve her cihaz için scores nesnesini grafiğe dökebilir. Durum topic'i retained olduğundan, gösterge paneli yüklendiğinde hangi cihazların çevrimiçi olduğunu hemen bilir.
Uyarılar. Impulse'unuz bir anomali bloğu içeriyorsa, uyarı için en faydalı alan anomali skorudur; çünkü kaydetmediğiniz arıza modları da dahil olmak üzere modelin daha önce hiç görmediği girdilerde yükselir. ConnectMQ eşik uyarı kuralları sayısal bir değeri izleyebilir ve uyarıları uyarı günlüğüne kaydedebilir; bu, bir pilot sırasında çoğu zaman yeterlidir. Telefonlara veya sohbet araçlarına bildirimler için, çıkarım topic'lerini dinleyen ve zaten kullandığınız bildirim hizmetini çağıran bir Node-RED akışı veya küçük bir Python abonesi çalıştırın.
Historian'lar. Telegraf, Node-RED veya bir Python abonesi her tahmini bir zaman serisi veritabanına yazabilir; bu da size bakım kayıtlarıyla karşılaştırabileceğiniz bir makine durumları geçmişi sunar. Bu geçmiş aynı zamanda yeniden eğitim için en iyi aday kaynağıdır.
Kapalı döngü. Bir tahminin bir fanı durdurmak veya bir vanayı açmak gibi fiziksel bir şeyi değiştirmesi gerekiyorsa, bu mantığı cihazda veya yerel bir kontrolcüde tutun ve gerçekleştirilen eylemi ayrı bir mesaj olarak yayınlayın. Böylece broker kritik yolda yer almak yerine olanları kaydeder.
Edge Impulse MQTT En İyi Uygulamaları
- Değişiklikte veya eşikte yayınlayın; test aşamasını geçtikten sonra her çıkarımda değil. Sessizliğin asla belirsiz olmaması için bir kalp atışı ekleyin.
- Model sürümünü ekleyin. Edge Impulse projeleri sık sık yeniden eğitilir; her mesaja bir dağıtım sürümü dizesi ekleyin.
- Anomali skorunu kullanın; impulse'unuzda bir anomali bloğu varsa. Eğitimdeki hiçbir şeye benzemeyen girdileri yakalar; bunu tek başına sınıflandırma yapamaz.
- Güven eşiğini abone tarafında tutun; birden çok sistem aynı topic'i yanlış alarmlara farklı toleranslarla tükettiğinde.
- Mesaj sınırlarına uyun. Tüm sınıf skorlarını yayınlamak sorun değildir; yeniden eğitim verisi toplamak için seyrek örnekleme yapmıyorsanız ham pencereleri yayınlamak ise sorundur.
Arka planda çalışan şeye framework düzeyinde bir bakış için TensorFlow Lite Micro'ya başlangıç yazısını okuyun. Aynı işlem hattını bir platform olmadan kurmak için ESP32 üzerinde TinyML yazısını izleyin. Yapay zeka ve IoT rehberi her ikisini de bağlamına oturtuyor.
Edge Impulse Tahminlerinizi ConnectMQ'ya Gönderin
Model çalıştığında ona üretim düzeyinde bir hedef verin. ConnectMQ, TLS, MQTT 5, eşik uyarı kuralları ve canlı bir topic gezgini sunan barındırılan bir MQTT broker hizmetidir; böylece kendiniz bir broker çalıştırmadan tahminleri izleyebilir ve anomali skorlarında uyarı alabilirsiniz. app.connectmq.com adresinde ücretsiz Serverless planıyla kredi kartı gerektirmeden başlayın.
Sık Sorulan Sorular
Edge Impulse MQTT'yi doğrudan destekliyor mu?
Dışa aktarılan model kütüphanesi yalnızca çıkarım yapar. Bu eğitimde gösterildiği gibi, MQTT yayınını mikrodenetleyicilerde PubSubClient veya Linux'ta paho-mqtt gibi standart bir istemciyle siz eklersiniz.
ESP32'm Edge Impulse sonuçlarını yayınlarken neden başarısız oluyor?
En yaygın neden PubSubClient'ın varsayılan 256 baytlık tamponudur. setBufferSize() fonksiyonunu daha büyük bir değerle çağırın veya daha az alan yayınlayın.
Edge Impulse modellerini Arduino IDE olmadan bir ESP32'de çalıştırabilir miyim?
Evet. Edge Impulse, ESP-IDF ile derleyebileceğiniz genel bir C++ kütüphanesi de dışa aktarır ve PubSubClient yerine ESP-IDF MQTT istemcisiyle yayın yapabilirsiniz.
Dağıtılmış cihazlardan yeni eğitim verisini nasıl toplarım?
Ara sıra ham pencereleri veya düşük güvenli örnekleri ayrı bir topic'e yayınlayın, bir aboneyle saklayın ve etiketleme ile yeniden eğitim için Edge Impulse projenize yükleyin.



