IF statmenet for a certain time

Hi
I used EmonLibrary code as below with CT sensor to monitor AC load current
how can I put a condition with time for IF statement once the current Irms > 19 for 2 seconds(or mili sconds) then OUTPUT 13 goes HIGH and if Irms < 15.5 for 2 seconds then OUTPUT 13 goes to LOW

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3

#include "EmonLib.h"                   // Include Emon Library
EnergyMonitor emon1;                   // Create an instance


void setup()
{  
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  emon1.current(1, 48);             // Current: input pin, calibration.
}

void loop()
{
  double Irms = emon1.calcIrms(1480);  // Calculate Irms only
  if (Irms > 19)
  
  {
    
    digitalWrite(13,HIGH);
  
  }

  if (Irms < 15.5)
  
  {
     
     digitalWrite(13,LOW);
  }  
    //Serial.print(Irms*230.0);	       // Apparent power
  Serial.print(" ");
  //delay(5000);
  Serial.println(Irms);		       // Irms
}

I put a delay but it is not work
any advice please

Use millis() for timing.

1 Like

Using millis() for timing tutorials:
Several things at a time.
Beginner's guide to millis().
Blink without delay().

1 Like

Appreciate if edit the code since I'm new with Arduino coding

If you want someone to write the code for you, request that a moderator move your thread to Gigs and Collaborations. Expect to pay.

Otherwise, give writing the code a try. If you get stuck, post the code, tell us what the code actually does and how that differs from what you want.

unsigned long LastTimeBelowUpperLimit = 0;
unsigned long LastTimeAboveLowerLimit = 0;

void loop()
{
  unsigned long currentMillis = millis();

  double Irms = emon1.calcIrms(1480);  // Calculate Irms only

  if (Irms <= 19.0)
    LastTimeBelowUpperLimit = currentMillis;

  if (currentMillis - LastTimeBelowUpperLimit >= 2000)
  {
    // Has been above upper limit for two seconds or more
    digitalWrite(13, HIGH);
  }

  if (Irms >= 15.5)
    LastTimeAboveLowerLimit = currentMillis;

  if (currentMillis - LastTimeAboveLowerLimit >= 2000)
  {
    // Has been below lower limit for two seconds or more
    digitalWrite(13, LOW);
  }
  
  // Serial.print(Irms*230.0);         // Apparent power
  Serial.print(" ");
  // delay(5000);
  Serial.println(Irms);          // Irms
}
1 Like

Thank you very much ,this is really helpful and will put me on the right way for such a difficult function like Millis
I will test it and comeback to you
by the way in my code the condition was if Irms > 19 but in your is <=19 and same for the lower value of Irms is that a print mistake or it must be like this ??

It is not a print mistake but it doesn't have to be written that way. You can write it other ways if you wish:

  if (!(Irms > 19.0))
    LastTimeBelowUpperLimit = currentMillis;

or

  if (Irms > 19.0)
    { /* Do Nothing */ }
  else
    LastTimeBelowUpperLimit = currentMillis;

They all mean the same thing. If you study the sketch, particularly the variable names, you may come to understand what is happening.

1 Like

Hi Johnwasser
I did as what you described and just modified the upper and lower current values to fit my current injection device but no response from digital output
I started with 3 Amper more than 2 seconds then jumped to 10 A and wait more than 2 seconds and nothing happens
please see the code if may has some mistakes
I tried to put {} for if statement <=9 and same for second if but nothing changed

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3

#include "EmonLib.h"                   // Include Emon Library
EnergyMonitor emon1;                   // Create an instance
unsigned long LastTimeBelowUpperLimit = 0;
unsigned long LastTimeAboveLowerLimit  = 0;

void setup()
{  
  Serial.begin(9600);
  
  emon1.current(1, 48);             // Current: input pin, calibration.
  pinMode(13, OUTPUT);

}

void loop()
{
  unsigned long currentMillis = millis();
  
  double Irms = emon1.calcIrms(1480);  // Calculate Irms only
  if( Irms <= 9.0)
   LastTimeBelowUpperLimit = currentMillis;
  
   if (currentMillis - LastTimeBelowUpperLimit >= 2000 )
   {
    digitalWrite (13,HIGH);
    
   }


  if (Irms >= 5.0)
  LastTimeAboveLowerLimit  = currentMillis;
  
  if (currentMillis - LastTimeAboveLowerLimit >= 2000);

  {
    digitalWrite(13,LOW);
  }
  
  //Serial.print(Irms*230.0);	       // Apparent power
  //Serial.print(" ");
  Serial.println(Irms);		       // Irms
}

appreciate your support 

The sketch looks correct. What was showing up on Serial Monitor?

For current sketch the serial monitor is showing the Irms value in Amper
Do you have a specific thing to review on serial monitor?? please tell me

Does it repeatedly show a value near 3.00 when you set the current injection device to 3A and repeatedly show a value near 10.00 when you set the current injection device to 10A?

1 Like

Do you have a device on pin 1? On some boards, that is reserved for serial communications.

Yes ,serial monitor shows the injected current

No I don't have

Then I see no reason for the sketch to not set Pin 13 to HIGH when the current has been above 9A continuously for more than 2 seconds. Sorry.

  emon1.current(1, 48);             // Current: input pin, calibration.

Sorry, yes it is for current sensor measurements

Pin 1 on the UNO is serial TX. Do you think that might interfere with the current sensor, when you perform serial prints?

Frankly I have no experience in Arduino,I will change it to 0 and re-check