Energy Monitor Library Problem - SCT013

Guys,
I’ve just try to build Current Readout using SCT013 and Energy Monitoring Library, during runtime somehow causing “Hearbeat Timeout” on Blynk,

1384, room 16 
tail 8
chksum y⸮[20742] Connecting to Camar-24
[24743] Connected to WiFi
[24743] IP: 192.168.0.16
[24743] 
    ___  __          __
   / _ )/ /_ _____  / /__
  / _  / / // / _ \/  '_/
 /____/_/\_, /_//_/_/\_\
        /___/ v0.4.8 on NodeMCU

[24816] Connecting to 192.168.0.23
[24866] Ready (ping: 8ms).
310.74
-10.73
-7.35
-7.89
-5.81
-5.27
-11.98
-11.09
-3.74
-9.54
1.43
1.15
-8.42
-6.30
-18.85
-13.24
[51155] Heartbeat timeout
-13.26
-10.33
-11.85
[54519] Connecting to 192.168.0.23
-13.66
[56679] Login timeout
-2.97
-0.75
[59599] Connecting to 192.168.0.23
-16.79
-10.24
-7.07
[64669] Connecting to 192.168.0.23
-8.32
-3.22
-18.05
-9.45
[69741] Connecting to 192.168.0.23
-11.73
-1.71

Here are my NodeMCU sketch:

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include "EmonLib.h"                   // Include Emon Library


char auth[] = "blabla";

char ssid[] = "xxx";
char pass[] = "xxx";

SimpleTimer timer;

EnergyMonitor emon1;                   // Create an instance
float Vrms = 220.0;

double Irms2 = 0;
int ReadCurrentCounter = 0;
void Timer_ReadCurrent()
{
  double Irms = 0;
  ReadCurrentCounter++;
  if (ReadCurrentCounter <= 10) {
    Irms2 = Irms2  + (emon1.calcIrms(1480) - 0.140);  // Calculate Irms only;
 }
  else {
    ReadCurrentCounter = 0;
    Irms = Irms2 / 10; 
    Irms2 = 0;
    Serial.println(Irms*Vrms);    
    Blynk.virtualWrite(V100, Irms*Vrms);
  }
}


void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass, IPAddress(192,168,0,23)); // Local Server

  emon1.current(A0, 111.1);             // Current: input pin, calibration.

  timer.setInterval(100L, Timer_ReadCurrent);

  
}


void loop()
{
  timer.run();
  Blynk.run();
}

I’m using Blynk local server and currently working fine for other NodeMCU (not using Emon Lib
Any idea what went wrong?

Thanks

1 Like

It could be a Wifi connection issue, It could also be you are reading the sensor too often, though I doubt it with a local server. Can you try setting the timer to a longer interval, say 5 seconds and see what happens than?

Also, what hardware are you running the local server on? Is there enough CPU to process all the Blynk stuff? E.g. does it spike CPU usage?

1 Like

Thanks Lichtsignaal,

I’ve just reduce the timing to just 500 mili second without 10x looping each time the function called and it seems working fine… so it means the problem was caused by to many readout on the sensors, it seems the library is taken quite big resource …

br
Noer

no, your 100ms loop was taking all the resources.

Even at 500ms it’s probably overkill for most projects. We use 3000ms with our Smart Meter’s and feel this could be increased further.

1 Like

Hi noersaleh. Would it be possible to publish or send your final code? Thank you.

Very sorry took a long time to reply … FYI: recently I’ve just added an OTA Updates as well …

// #define BLYNKCLOUD
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include "EmonLib.h"
#include <WidgetRTC.h>
// ************** OTA *****************
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
// ************** OTA *****************



const char ssid[] = "wifi-name";
const char pass[] = "wifi-password";
const char OTA_Hostname[] = "myesp-E-Mon";

#ifdef BLYNKCLOUD
  const char auth[] = "my-cloud-auth"; 
  const char bsvr[] = "blynk-cloud.com";
#else
  const char auth[] = "my-local-auth"; 
  const char bsvr[] = "xx.xx.x.xx";
#endif

SimpleTimer timer;
EnergyMonitor emon1; 
WidgetLED VLED_SystemBlink(V23); 
WidgetRTC rtc;

int Vrms = 210;
boolean SystemBlink_Active = true;
boolean LED_On = true;
int Seconds_Counter = 0;
double AccKWH = 0;
double TotalKWH = 0;
int kWhStart = 0;

String MyPrintDigits(int digits) { // -- Utility function for digital clock display: prints preceding colon and leading 0
  String new_digits = ":";
  if (digits < 10) new_digits += "0";
  new_digits += String(digits);
  return new_digits;
}


String ClockFormat(int InputClock) { // --- Utility function to convert seconds to clock format  
  int my_h = InputClock / 3600; // Hour ==>> total_seconds div 3600
  int my_d = my_h / 24;
  my_h = my_h%24;
  String MyClock = String(my_d) + " - " +String(my_h);
  int my_m = InputClock%3600/60; // Minute ==>> total_seconds mod 3600 div 60
  MyClock += MyPrintDigits(my_m);
  return MyClock;
} // End: ClockFormat()

void ConnectWifi() {
  Serial.println("Booting");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(60000);
    ESP.restart();
  }  
}

void Init_ArduinoOTA() {
  // Port defaults to 8266
  // ArduinoOTA.setPort(8266);

  // Hostname defaults to esp8266-[ChipID]
  ArduinoOTA.setHostname(OTA_Hostname);

  // No authentication by default
  // ArduinoOTA.setPassword(upload_pwd);

  // Password can be set with it's md5 value as well
  // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH)
      type = "sketch";
    else // U_SPIFFS
      type = "filesystem";

    // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}


void Timer_ReadCurrent()
{
    // unsigned long timethen = millis();
    double Irms = emon1.calcIrms(4385);  // Calculate Irms only Sampling 1480;
    // Serial.print("Time: ");Serial.print(millis() - timethen);Serial.println(" ");
    
    // Serial.println(Irms*Vrms);    
    Blynk.virtualWrite(V100, Irms);
    Blynk.virtualWrite(V101, Vrms);
    Blynk.virtualWrite(V102, Irms*Vrms);

    Seconds_Counter = Seconds_Counter + 2;
    if (Seconds_Counter >= 1800) { 
      Seconds_Counter = 0;
      TotalKWH = TotalKWH + AccKWH;
      AccKWH = 0;
    }
    else {
       AccKWH = AccKWH + ((Irms*Vrms) / 1800000);
    }
    Blynk.virtualWrite(V103, TotalKWH+AccKWH);
  
    
}

void Timer_LEDNetConnect() {
  if (Blynk.connected()) { // -- Blink the LED when connected to Blynk Server
    if (SystemBlink_Active) {
       LED_On = !LED_On;
       if (LED_On) { digitalWrite(D4, LOW); VLED_SystemBlink.on(); }
       else { digitalWrite(D4, HIGH); VLED_SystemBlink.off(); }
    }
    else { digitalWrite(D4, HIGH); VLED_SystemBlink.off(); }
  }
}


void Timer_kWhStartTime() {
  kWhStart++;
  Blynk.setProperty(V103, "label", "kWh: " + ClockFormat(kWhStart*60));
}

BLYNK_WRITE(V47) { //-- Button Widget for Activate/Deactivate VLED_SystemBlink
  SystemBlink_Active = (param.asInt() == 1);
  if (!SystemBlink_Active) {
    digitalWrite(D4, HIGH); // Switch off the hardware LED
  }
}

BLYNK_WRITE(V50) { //-- Button Widget for reset KWH counter
  if (param.asInt() == 1) { 
      TotalKWH = 0;
      kWhStart = 0;
      AccKWH = 0;
      Seconds_Counter = 0;
      Blynk.setProperty(V103, "label", "kWh: " + ClockFormat(int(0)));
  }
}

BLYNK_WRITE(V40) { // --- Slider Voltage
  Vrms = param[0].asInt() ;  // -- Slider - Step H (don't send step)
}



void setup()
{
  Serial.begin(115200);
  
  pinMode(D4, OUTPUT); // Internal LED (Blink network)
  emon1.current(A0, 111.1);             // Current: input pin, calibration. -- CAMAR 
//  emon1.current(A0, 15);             // Current: input pin, calibration. -- DK KUPANG

  // Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 8442);
  Blynk.begin(auth, ssid, pass, bsvr, 8080);
  
  rtc.begin();
  timer.setInterval(2000L,Timer_ReadCurrent);
  timer.setInterval(1000L,Timer_LEDNetConnect);
  timer.setInterval(60000L,Timer_kWhStartTime);
  Blynk.setProperty(V103, "label", "kWh: " + ClockFormat(int(0)));

  Init_ArduinoOTA(); 
}


void loop()
{
  timer.run();
  Blynk.run();
  ArduinoOTA.handle();
}

1 Like

Hello, thanks for the code !!! Could you maybe also share schematic ? Thanks and kind regards,

Tony

thanks for the code . i got some question, on idle without clamping thing, the Vrms would be the value of what set ?

Plz share connection diagram…

Oi… sera que voce poderia me ajudar com meu codigo… pra voce seria uma coisa muito simples comparado ao seu codigo!!
Tenho este codigo que funciona perfeitamente fora do blynk , mas nao estou conseguindo fazer ele funcionar dentro do blynk, utilizo o blynk atraves da USB… ESTE É O CODIGO:

//Programa : Medidor de corrente com Arduino e SCT-013 100A

//Baseado no programa exemplo da biblioteca EmonLib
 
//Carrega as bibliotecas


#include "EmonLib.h"

 
EnergyMonitor emon1;
EnergyMonitor emon2;
EnergyMonitor emon3;
EnergyMonitor emon4;


//Tensao da rede eletrica
int rede1 = 127;
int rede2 = 127;
int rede3 = 127;
int rede4 = 127;
 
//Pino do sensor SCT
int pino_sct1 = A8;
int pino_sct2 = A9;
int pino_sct3 = A10;
int pino_sct4 = A11;
 
void setup()
{
  Serial.begin(9600);
  //Pino, calibracao - Cur Const= Ratio/BurdenR. 2000/33 = 60
  emon1.current(pino_sct1, 60);
  emon2.current(pino_sct2, 60);
  emon3.current(pino_sct3, 60);
  emon4.current(pino_sct4, 60);
  
 
 
}
 
void loop()
{
  //Calcula a corrente
  double Irms1 = emon1.calcIrms(1480)- 0.16;
  double Irms2 = emon2.calcIrms(1480)- 0.16;
  double Irms3 = emon3.calcIrms(1480)- 0.16;
  double Irms4 = emon4.calcIrms(1480)- 0.16;
  //CALCULA KLW
  int CONSUMO1 = Irms1 * 127.0;
  int CONSUMO2 = Irms2 * 127.0;
  int CONSUMO3 = Irms3 * 127.0;
  int CONSUMO4 = Irms4 * 127.0;
  //Mostra o valor da corrente no serial monitor e display
  Serial.println ("Corrente1 : ");
  Serial.println(Irms1); // Irms
  Serial.println ("Corrente2 : ");
  Serial.println(Irms2); // Irms
  Serial.println ("Corrente3 : ");
  Serial.println(Irms3); // Irms
  Serial.println ("Corrente4 : ");
  Serial.println(Irms4); // Irms
  Serial.println ("CONSUMO1 : ");
  Serial.println(CONSUMO1); // CONSUMO
  Serial.println ("CONSUMO2 : ");
  Serial.println(CONSUMO2); // CONSUMO
  Serial.println ("CONSUMO3 : ");
  Serial.println(CONSUMO3); // CONSUMO
  Serial.println ("CONSUMO4 : ");
  Serial.println(CONSUMO4); // CONSUMO

  
  delay(3000);
}

E este é oque eu estou tentando criar… os dht estao funcionais…


#define BLYNK_PRINT Serial1


#include <BlynkSimpleStream.h>
#include <DHT.h>
#include "EmonLib.h"

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

#define DHTPIN  2          // What digital pin we're connected to
#define DHTPIN1 3          // What digital pin we're connected to


// Uncomment whatever type you're using!
#define DHTTYPE  DHT11     // DHT 11
#define DHTTYPE1 DHT11     // DHT 11
//#define DHTTYPE DHT22   // DHT 22, AM2302, AM2321
//#define DHTTYPE DHT21   // DHT 21, AM2301



DHT dht (DHTPIN , DHTTYPE );
DHT dht1(DHTPIN1, DHTTYPE1);
BlynkTimer timer;

// This function sends Arduino's up time every second to Virtual Pin (5).
// In the app, Widget's reading frequency should be set to PUSH. This means
// that you define how often to send data to Blynk App.
void sendSensor()
{
  float h = dht.readHumidity();
  float t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit

  if (isnan(h) || isnan(t)) {
    Serial1.println("Failed to read from DHT sensor!");
    return;
  }
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V5, h);
  Blynk.virtualWrite(V6, t);
}

void sendSensor1()
{
  float h1 = dht1.readHumidity();
  float t1 = dht1.readTemperature(); // or dht.readTemperature(true) for Fahrenheit

  if (isnan(h1) || isnan(t1)) {
    Serial1.println("Failed to read from DHT sensor!");
    return;
  }
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V0, h1);
  Blynk.virtualWrite(V1, t1);
}
  EnergyMonitor emon1;
  EnergyMonitor emon2;
  EnergyMonitor emon3;
  EnergyMonitor emon4;

  //Tensao da rede eletrica
int rede1 = 127;
int rede2 = 127;
int rede3 = 127;
int rede4 = 127;
 
//Pino do sensor SCT
int pino_sct1 = A8;
int pino_sct2 = A9;
int pino_sct3 = A10;
int pino_sct4 = A11;

void MEDIDOR_ENERGIA()
{
  //Calcula a corrente
  double Irms1 = emon1.calcIrms(1480)- 0.16;
  double Irms2 = emon2.calcIrms(1480)- 0.16;
  double Irms3 = emon3.calcIrms(1480)- 0.16;
  double Irms4 = emon4.calcIrms(1480)- 0.16;
  //CALCULA KLW
  int CONSUMO1 = Irms1 * 127.0;
  int CONSUMO2 = Irms2 * 127.0;
  int CONSUMO3 = Irms3 * 127.0;
  int CONSUMO4 = Irms4 * 127.0;
  //Mostra o valor da corrente no serial monitor e display
  Serial.println ("Corrente1 : ");
  Serial.println(Irms1); // Irms
  Serial.println ("Corrente2 : ");
  Serial.println(Irms2); // Irms
  Serial.println ("Corrente3 : ");
  Serial.println(Irms3); // Irms
  Serial.println ("Corrente4 : ");
  Serial.println(Irms4); // Irms
  Serial.println ("CONSUMO1 : ");
  Serial.println(CONSUMO1); // CONSUMO
  Serial.println ("CONSUMO2 : ");
  Serial.println(CONSUMO2); // CONSUMO
  Serial.println ("CONSUMO3 : ");
  Serial.println(CONSUMO3); // CONSUMO
  Serial.println ("CONSUMO4 : ");
  Serial.println(CONSUMO4); // CONSUMO

  Blynk.virtualWrite(V50, Irms1);
  Blynk.virtualWrite(V51, CONSUMO1);

  Blynk.virtualWrite(V52, Irms2);
  Blynk.virtualWrite(V53, CONSUMO2);

  Blynk.virtualWrite(V54, Irms3);
  Blynk.virtualWrite(V55, CONSUMO3);

  Blynk.virtualWrite(V56, Irms4);
  Blynk.virtualWrite(V58, CONSUMO4);
  

}
  

void setup()
{
  // Debug console
  Serial1.begin(9600);
  
    //Pino, calibracao - Cur Const= Ratio/BurdenR. 2000/33 = 60
  emon1.current(pino_sct1, 60);
  emon2.current(pino_sct2, 60);
  emon3.current(pino_sct3, 60);
  emon4.current(pino_sct4, 60);

  

 
 
  // Blynk will work through Serial
  // Do not read or write this serial manually in your sketch
  Serial.begin(9600);
  Blynk.begin(Serial, auth);

  dht.begin();
  dht1.begin();

  // Setup a function to be called every second
  timer.setInterval(1000L, MEDIDOR_ENERGIA );
  timer.setInterval(1000L, sendSensor );
  timer.setInterval(1000L, sendSensor1);
}


void loop()
{
  
  
  Blynk.run();
  timer.run();
}

Se puder me ajudar fico imensamente agradecido!!

Please edit your code to add triple backticks at the beginning and end, so that it displays correctly, otherwise your code will be deleted.
Triple backticks look like this:
```

Pete.

Obrigado!!