ESP32 ve Arduino

MQTT Üzerinden ESP32 SCT-013 Akım Sensörü ile Enerji İzleme

Bir SCT-013 akım trafosunu şebeke kablosuna takın, ESP32 ADC ile RMS akımı ölçün, güç ve enerjiyi tahmin edin ve sonuçları enerji dashboard'ları için broker.connectmq.com'a yayınlayın.

Esp32 sct-013 akım sensörü projesini gösteren, bir kabloya takılı ve ESP32 enerji izleyicisine bağlı SCT-013 akım pensi
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

Bir ESP32 SCT-013 akım sensörü düzeneği, bir devrenin ne kadar güç kullandığını görmenin en ucuz ve temassız yoludur; çünkü pens hiçbir şeyi kesmeden kablonun etrafına takılır. Bu eğitimde bias devresini kuracak, ESP32 ADC ile RMS akımı hesaplayacak, güç ve kWh tahmini yapacak ve sonuçları bir enerji dashboard'u için MQTT üzerinden broker.connectmq.com'a yayınlayacaksınız.

Önce Güvenlik

SCT-013'ün kendisi, gerilim altındaki iletkenlere asla dokunmayan, açılabilir çekirdekli bir penstir; bu da projeyi erişilebilir kılan şeydir. Takıldığı pano ise başka bir konudur. Bir sigorta kutusunu veya dağıtım panosunu açmak ölümcül gerilimleri açığa çıkarır. Yetkin değilseniz, pensi yalnızca zaten erişilebilir olan bir kabloya takın; örneğin bu amaçla üretilmiş bir adaptörde iletkenlerine ayrılmış tek bir cihaz kablosu gibi. Ya da pensi bir elektrikçiye taktırın. Bir SCT-013-000'ın pensini, burden direnci takılı değilken akım akarken asla açmayın; çünkü yüksüz bir akım trafosu uçlarında tehlikeli bir gerilim oluşturabilir.

Doğru SCT-013 Varyantını Seçmek

Model Çıkış Burden gerekli mi Aralık Dönüşüm
SCT-013-000 Akım, 100 A'de 50 mA Evet, harici 100 A'e kadar Burden direncinize bağlıdır
SCT-013-030 Gerilim, 30 A'de 1 V RMS Hayır, dahili 30 A'e kadar Volt başına 30 A
SCT-013-020 Gerilim, 20 A'de 1 V RMS Hayır, dahili 20 A'e kadar Volt başına 20 A
SCT-013-005 Gerilim, 5 A'de 1 V RMS Hayır, dahili 5 A'e kadar Volt başına 5 A

İlk düzenek için devreye uygun boyutta gerilim çıkışlı bir sürüm seçin. Düşük akımlarda daha yüksek çözünürlük, maksimum yükünüzü karşılayan en küçük aralığı seçmekten gelir: bir buzdolabı devresinde 5 A'lik bir pens, 100 A'lik bir pensten çok daha iyi ölçümler verir.

SCT-013-000 kullanıyorsanız çıkışına paralel bir burden direnci ekleyin. 22 Ohm'luk bir burden, 100 A RMS'de tepe gerilimini yaklaşık 1,6 V'un altında tutar; bu da aşağıdaki bias devresine uyar ve 2000 / 22, yani volt başına yaklaşık 90,9 A'lik bir dönüşüm sağlar.

Bias Devresi

Pens, sıfır etrafında pozitif ve negatif salınan bir AC sinyal üretir. ESP32 ADC yalnızca 0 ile yaklaşık 3,1 V arasını okuyabilir; bu yüzden sinyalin bir DC orta noktası üzerine bindirilmesi gerekir.

  1. İki eşit direnci (her biri 10 kOhm) 3V3 ile GND arasına seri bağlayın. Birleşim noktaları yaklaşık 1,65 V'ta durur.
  2. Orta noktayı sabitlemek için birleşim noktasından GND'ye 10 uF'lık bir elektrolitik kondansatör bağlayın.
  3. Pensin bir ucunu (3,5 mm jakın uç kısmı) birleşim noktasına bağlayın.
  4. Diğer ucunu (gövde kısmı) ADC girişine, GPIO 34'e bağlayın.

1 V RMS çıkışla sinyal yaklaşık 1,41 V tepe değerine ulaşır; bu yüzden ADC kabaca 0,24 V ile 3,06 V arasını görür. Bu, varsayılan zayıflatma (attenuation) aralığının içinde kalır. ADC1 üzerindeki bir pini kullanın (klasik bir ESP32'de GPIO 32 ila 39); ADC2 pinleri Wi-Fi etkinken okunamaz.

RMS Akımı Ölçmek

Kod, 50 Hz'de 10, 60 Hz'de 12 tam periyodu kapsayan 200 ms boyunca ADC'yi olabildiğince hızlı örnekler. Ortalamayı (varsayılmak yerine ölçülen DC orta noktası) ve onun etrafındaki standart sapmayı hesaplar; bu da AC bileşeninin tam olarak RMS değeridir. Pensin dönüşüm katsayısıyla çarpmak amper değerini verir.

Orta noktayı her geçişte ölçmek, direnç toleransından ve besleme kaymasından kaynaklanan hataları ortadan kaldırır; analogReadMilliVolts() ise fabrika ADC kalibrasyonunu uygular, bu da ESP32 ADC'nin bilinen doğrusal olmama sorununa yardımcı olur.

ESP32 SCT-013 Akım Sensörü Sketch'i

#include <WiFi.h>
#include <PubSubClient.h>
#include <Preferences.h>
#include <math.h>

const char* WIFI_SSID     = "YOUR_WIFI_SSID";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";
const char* MQTT_HOST     = "broker.connectmq.com";
const uint16_t MQTT_PORT  = 1883;
const char* PREFIX        = "connectmq/demo/sct3m8w";   // kendi rastgele kimliğinizi kullanın

const uint8_t CT_PIN          = 34;      // ADC1 pini
const float   AMPS_PER_VOLT   = 30.0f;   // SCT-013-030; 22 Ohm burden ile -000 için 90.9
const float   MAINS_VOLTAGE   = 230.0f;  // Kuzey Amerika'da 120.0 yapın
const float   CALIBRATION     = 1.00f;   // bir pens ampermetreyle karşılaştırdıktan sonra ayarlayın
const float   NOISE_FLOOR_A   = 0.08f;   // bunun altındaki ölçümler 0 olarak bildirilir
const uint32_t WINDOW_MS      = 200;
const uint32_t PUBLISH_MS     = 10000;
const uint32_t SAVE_MS        = 600000;  // enerjiyi her 10 dakikada bir kalıcı kaydet

WiFiClient   net;
PubSubClient mqtt(net);
Preferences  prefs;
String clientId, tPower, tStatus;

double energyKwh = 0;
uint32_t lastSample = 0, lastPublish = 0, lastSave = 0;
float lastIrms = 0, sumIrms = 0;
uint32_t samplesInPeriod = 0;

float readIrms() {
  uint32_t n = 0;
  double sum = 0, sumSq = 0;
  uint32_t start = millis();
  while (millis() - start < WINDOW_MS) {
    double mv = analogReadMilliVolts(CT_PIN);
    sum += mv;
    sumSq += mv * mv;
    n++;
  }
  double mean = sum / n;
  double variance = sumSq / n - mean * mean;
  if (variance < 0) variance = 0;
  double vrms = sqrt(variance) / 1000.0;          // AC kısmın volt RMS değeri
  float irms = vrms * AMPS_PER_VOLT * CALIBRATION;
  return irms < NOISE_FLOOR_A ? 0.0f : irms;
}

void connectWifi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) delay(300);
  Serial.printf("Wi-Fi OK, IP %s\n", WiFi.localIP().toString().c_str());
}

void connectMqtt() {
  while (!mqtt.connected()) {
    if (mqtt.connect(clientId.c_str(), tStatus.c_str(), 1, true, "offline")) {
      mqtt.publish(tStatus.c_str(), "online", true);
      Serial.println("MQTT connected");
    } else {
      Serial.printf("MQTT failed, state %d\n", mqtt.state());
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  analogReadResolution(12);
  prefs.begin("energy", false);
  energyKwh = prefs.getDouble("kwh", 0.0);

  clientId = "esp32-sct013-" + String((uint32_t)ESP.getEfuseMac(), HEX);
  tPower   = String(PREFIX) + "/power";
  tStatus  = String(PREFIX) + "/status";

  connectWifi();
  mqtt.setServer(MQTT_HOST, MQTT_PORT);
  mqtt.setBufferSize(512);
  connectMqtt();
  lastSample = lastPublish = lastSave = millis();
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) connectWifi();
  if (!mqtt.connected()) connectMqtt();
  mqtt.loop();

  // Yaklaşık saniyede bir örnekle ve enerjiyi entegre et
  uint32_t now = millis();
  if (now - lastSample >= 1000) {
    float irms = readIrms();
    float dtHours = (millis() - lastSample) / 3600000.0f;
    lastSample = millis();
    energyKwh += (irms * MAINS_VOLTAGE) * dtHours / 1000.0;
    lastIrms = irms;
    sumIrms += irms;
    samplesInPeriod++;
    mqtt.loop();
  }

  if (now - lastPublish >= PUBLISH_MS && samplesInPeriod > 0) {
    lastPublish = now;
    float avgIrms = sumIrms / samplesInPeriod;
    sumIrms = 0;
    samplesInPeriod = 0;

    char payload[200];
    snprintf(payload, sizeof(payload),
             "{\"irms\":%.2f,\"irmsAvg\":%.2f,\"apparentPowerVA\":%.0f,"
             "\"energyKwh\":%.4f,\"voltageAssumed\":%.0f}",
             lastIrms, avgIrms, avgIrms * MAINS_VOLTAGE, energyKwh, MAINS_VOLTAGE);
    mqtt.publish(tPower.c_str(), payload);
    Serial.println(payload);
  }

  if (now - lastSave >= SAVE_MS) {
    lastSave = now;
    prefs.putDouble("kwh", energyKwh);   // sınırlı yazma flash'ı korur
  }
}

Her ölçüm penceresi döngüyü 200 ms bloklar; sketch örneklemeden hemen sonra mqtt.loop() çağırdığı için bu MQTT keep-alive'ları açısından zararsızdır. Daha fazla pens eklerseniz, onları aynı geçişte arka arkaya okuyun veya ağ kodunun asla uzun bir pencere dizisinin arkasında beklememesi için örneklemeyi ESP32 FreeRTOS MQTT rehberinde gösterildiği gibi kendi FreeRTOS görevine taşıyın.

Test ve Kalibrasyon

Topic'e subscribe olun:

mosquitto_sub -h broker.connectmq.com -p 1883 -i sct-view-3m8w -t "connectmq/demo/sct3m8w/#" -v

Hiçbir şey çalışmıyorken irms 0 okumalıdır. Su ısıtıcısı veya ısıtıcı gibi bilinen bir rezistif yükü açın ve irms değerini aynı iletkene takılı bir pens ampermetreyle karşılaştırın. CALIBRATION değerini iki ölçüm arasındaki orana göre ayarlayın; örneğin ESP32 yüzde 4 düşük okuyorsa 1.04. En iyi genel doğruluk için pensin aralığının ortasına yakın bir değerde kalibre edin.

Broker'ın herkese açık alanı herkes tarafından okunabilir ve güç tüketimi desenleri bir evin ne zaman dolu olduğunu açığa çıkarabilir; bu yüzden onu yalnızca tezgah testleri için kullanın. Sınırları ücretsiz herkese açık MQTT broker sayfasında listelenmiştir.

Sayılar Ne Anlama Gelir

Sketch, ölçülen akım ve varsayılan şebeke geriliminden hesaplanan görünür gücü volt-amper cinsinden yayınlar. Su ısıtıcıları ve ısıtıcılar gibi rezistif yüklerde görünür güç, watt cinsinden gerçek güce yakındır. Motorlar, kompresörler, güç kaynakları ve LED sürücülerde güç faktörü 1'in altındadır; bu yüzden gerçek güç VA değerinden düşüktür. Şebeke gerilimi de gün içinde değişir.

Gerçek güç için bir gerilim ölçümü de gerekir; tipik olarak ikinci bir ADC pinini besleyen izole bir AC-AC trafodan, artı örnek bazında çarpma işlemi. Bu değerli bir sonraki adımdır, ancak yalnızca akım ölçen sürüm bile hangi cihazın ne zaman çalıştığını görmek, bekleme yüklerini fark etmek ve günleri karşılaştırmak için yeterlidir.

Doğruluk Kontrol Listesi

  1. Pensi yalnızca tek bir iletkenin etrafına takın. Tüm kablonun etrafında faz ve nötr akımları birbirini götürür ve sıfıra yakın okursunuz.
  2. Maksimum akımınızı karşılayan en küçük pens aralığını seçin.
  3. Analog kabloları kısa ve Wi-Fi antenlerinden ve anahtarlamalı güç kaynaklarından uzak tutun.
  4. 1,65 V varsaymak yerine orta noktayı her pencerede ölçün.
  5. Boştaki bir devrenin birkaç yüz miliamper değil 0 okuması için bir gürültü tabanı uygulayın.
  6. Rezistif bir yükle güvenilir bir ölçüm aletine göre kalibre edin.

Bir Enerji Dashboard'u Oluşturmak

Alıcı tarafta bir subscriber mesajları grafiklere dönüştürür. Telegraf'ın MQTT consumer'ı JSON'u ayrıştırıp Grafana için InfluxDB'ye yazabilir, Node-RED günlük toplamları ve maliyetleri hesaplayabilir, Home Assistant ise bir MQTT sensor tanımıyla energyKwh değerini bir enerji sensörü olarak ele alabilir. Hepsi broker'a normal MQTT istemcileri olarak bağlanır. Birden fazla devreyi veya sıcaklığı aynı anda izliyorsanız bu düğümü DS18B20 çoklu prob projesiyle birleştirin veya mevcut sayaçları ESP32 Modbus RS485 gateway'i ile okuyun.

Production için app.connectmq.com adresinde bir broker oluşturun, ISRG Root X1 sertifikasıyla 8883 portunda WiFiClientSecure kullanmaya geçin ve YOUR_CLIENT_ID, YOUR_USERNAME ve YOUR_PASSWORD ile bağlanın. ConnectMQ portalının eşik uyarı kuralları, örneğin bir devre sigorta değerine yaklaştığında olduğu gibi, akım bir sınırı aştığında sizi uyarabilir.

ConnectMQ ile Başlayın

Enerji verileri en çok kesintisiz toplandığında ve gizli tutulduğunda değerlidir. ConnectMQ; TLS, MQTT 3.1.1 ve 5.0, canlı topic gezgini ve uyarı özellikleri sunan bir yönetilen MQTT broker hizmetidir ve ücretsiz Serverless plan kredi kartı gerektirmez. Bu sketch'i broker'ınıza yönlendirin ve daha fazla ölçüm projesi için ESP32 IoT eğitimi merkezine göz atın.

Sık Sorulan Sorular

ESP32 SCT-013 akım sensörü watt cinsinden gerçek gücü ölçebilir mi?

Yalnızca akımla VA cinsinden görünür gücü tahmin eder. Gerçek güç için bir gerilim ölçümü de gerekir; böylece kod güç faktörünü hesaba katabilir.

Hiçbir şey açık değilken ölçümüm neden akım gösteriyor?

Bu ADC gürültüsü ve parazittir. Bir gürültü tabanı uygulayın, kabloları kısa tutun ve orta nokta kondansatörünün takılı olduğunu kontrol edin.

SCT-013 için hangi ESP32 pinlerini kullanabilirim?

ADC1 pinlerini kullanın (klasik bir ESP32'de GPIO 32 ila 39). ADC2 pinleri Wi-Fi etkinken çalışmaz.

Bir burden direncine ihtiyacım var mı?

Yalnızca akım çıkışlı SCT-013-000 için. SCT-013-030 gibi gerilim çıkışlı sürümlerde dahili bir burden bulunur.

İ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.