Way over my head

Hi,
I have a 20 amp ACS712 current sensor hooked up and working per the recommended sketch as shown below. The serial monitors first displays 3.63 Amps RMS then stabilizes to 0.00 Amps RMS with no load. When I apply a load it displays an accurate reading (0.5 Amps RMS for my portable heater).

Thats all great. However, I can’t figure out how to obtain a digital output (to drive a relay) when a load is applied, and to have the relay stay on for an additional 10 seconds when the load is turned off.

Any help in this programing be much appreciated:

/*
Measuring AC Current Using ACS712
*/
const int sensorIn = A0;
int mVperAmp = 100; // use 100 for 20A Module and 66 for 30A Module

double Voltage = 0;
double VRMS = 0;
double AmpsRMS = 0;

void setup(){
Serial.begin(9600);
}

void loop(){

Voltage = getVPP();
VRMS = (Voltage/2.0) *0.707;
AmpsRMS = (VRMS * 1000)/mVperAmp;
Serial.print(AmpsRMS);
Serial.println(" Amps RMS");

}

float getVPP()
{
float result;

int readValue; //value read from the sensor
int maxValue = 0; // store max value here
int minValue = 1024; // store min value here

uint32_t start_time = millis();
while((millis()-start_time) < 1000) //sample for 1 Sec
{
readValue = analogRead(sensorIn);
// see if you have a new maxValue
if (readValue > maxValue)
{
/record the maximum sensor value/
maxValue = readValue;
}
if (readValue < minValue)
{
/record the maximum sensor value/
minValue = readValue;
}
}

// Subtract min from max
result = ((maxValue - minValue) * 5.0)/1024.0;

return result;
}

Please read the forum guide in the sticky post, then modify your post above and put the code between code tags. If you have not already done Auto-Format on your code, please do that also before you re-post it.

You can put the extra code needed just after the line that prints the current measurement to serial monitor.

Just use an if statement to compare the measurement with some threshold value. If it is above the threshold, and the relay is currently off, turn on the relay.

If the value is below the threshold, and the previous value was above, take a copy of the value of millis() into an unsigned long variable.

If the value is below the threshold and the relay is on, substract the unsigned long variable from millis() and if the difference is 10 second or more, switch off the relay.

PaulRB:
If it is above the threshold, turn on the relay and take a copy of the value of millis() into an unsigned long variable.

I think the OP needs to save the value of millis() when the value falls below the threshold - so he can calculate a further 10 seconds.

...R

Robin2:
I think the OP needs to...

Oops, thanks Robin, post updated. Looks ok now?

Thanks, but wow that’s a little advanced for me at this stage. While I’m not doing too bad for an untrained old geezer, I’m really struggling to figure out the proper formatting for these sketches. I get one problem corrected and then is causes a new error somewhere else?? I’ve pulled out all my available hair, and now the dog is hiding from me.

I understand the Millis() concept as being preferable to the delay command, and I found a Millis() led blink sketch to play with. Fun! But I couldn’t adapt it, or any other examples, to operate within my project sketch as experimental exercises.

Frankly, I can’t even figure out how to trigger pin 13 when the Amps RMS goes to 0.5 Amps. I’ve tried a number of different methods from this site, but they all create errors in the original sketch. I really need help getting the basic commands written so I can then play with the values and expand it to additional inputs.

Thanks again for the help, and here is the original sketch properly inserted:

/*
Measuring AC Current Using ACS712
*/
const int sensorIn = A0;
int mVperAmp = 100; // use 100 for 20A Module and 66 for 30A Module

double Voltage = 0;
double VRMS = 0;
double AmpsRMS = 0;

void setup(){ 
 Serial.begin(9600);
}

void loop(){


 Voltage = getVPP();
 VRMS = (Voltage/2.0) *0.707; 
 AmpsRMS = (VRMS * 1000)/mVperAmp;
 Serial.print(AmpsRMS);
 Serial.println(" Amps RMS");

}

float getVPP()
{
 float result;

 int readValue; //value read from the sensor
 int maxValue = 0; // store max value here
 int minValue = 1024; // store min value here

 uint32_t start_time = millis();
 while((millis()-start_time) < 1000) //sample for 1 Sec
 {
 readValue = analogRead(sensorIn);
 // see if you have a new maxValue
 if (readValue > maxValue) 
 {
 /*record the maximum sensor value*/
 maxValue = readValue;
 }
 if (readValue < minValue) 
 {
 /*record the maximum sensor value*/
 minValue = readValue;
 }
 }

 // Subtract min from max
 result = ((maxValue - minValue) * 5.0)/1024.0;

 return result;
 }

Frankly, I can't even figure out how to trigger pin 13 when the Amps RMS goes to 0.5 Amps. I've tried a number of different methods from this site, but they all create errors in the original sketch. I really need help getting the basic commands written so I can then play with the values and expand it to additional inputs.

What have you tried?

https://www.arduino.cc/reference/en/language/structure/control-structure/if/

I’ve tried several variations of the “if” command. For example, the attempt below gets error code “getVPP was not declared in this scope”

void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  
}

void loop() {
  Voltage = getVPP();
  VRMS = (Voltage / 2.0) * 0.707;
  AmpsRMS = (VRMS * 1000) / mVperAmp;
  Serial.print(AmpsRMS);
  Serial.println(" Amps RMS");

  if(AmpsRMS > 1.0)
  digitalWrite(pin 13, high);
}

You seem to have launched yourself into a project which is too much for your skills at this stage. Start with some basic tutorials to help you learn the basics of programming in C, covering variables, control structures and so on.

Snack-chaser:
I've tried several variations of the "if" command. For example, the attempt below gets error code "getVPP was not declared in this scope"

Is that your entire sketch at this point? If not, please always post complete sketches, because the problem may not be in the part if the sketch you think it is. If that is your entire sketch, why did you cut out so much? This error will be the first of many, because the compiler is complaining about stuff you cut out, but your remaining sketch is still referring to.

Go back to the earlier version you posted. And please perform Auto Format before you post it again, as I asked you to before. If we ask you to do something you don't understand, please ask, don't ignore.

Okay, got it. I had formatted as requested, but only posted part of the sketch. This is the simplest version that I tried, all other were not saved. I tried calling OUTPUT, HIGH, and using the onboard LED Ect. The example sketches all worked on their own, I just can’t incorporate them, or figure out a suitable input parameter. I assume that using the AmpsRMS value from the SerialPrint would work.

/*
  Measuring AC Current Using ACS712
*/
const int sensorIn = A0;
int mVperAmp = 100; // use 100 for 20A Module and 66 for 30A Module


double Voltage = 0;
double VRMS = 0;
double AmpsRMS = 0;



void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop() {

  Voltage = getVPP();
  VRMS = (Voltage / 2.0) * 0.707;
  AmpsRMS = (VRMS * 1000) / mVperAmp;
  Serial.print(AmpsRMS);
  Serial.println(" Amps RMS");
  if (AmpsRMS > 1.0)
    digitalWrite(pin 13, high);
}

float getVPP(
{
  float result;

  int readValue; //value read from the sensor
  int maxValue = 0; // store max value here
  int minValue = 1024; // store min value here

  uint32_t start_time = millis();
  while ((millis() - start_time) < 1000) //sample for 1 Sec
  {
    readValue = analogRead(sensorIn);
    // see if you have a new maxValue
    if (readValue > maxValue)
    {
      /*record the maximum sensor value*/
      maxValue = readValue;
    }
    if (readValue < minValue)
    {
      /*record the maximum sensor value*/
      minValue = readValue;
    }
  }

  // Subtract min from max
  result = ((maxValue - minValue) * 5.0) / 1024.0;

  return result;
}
float getVPP(
{

Something missing between ( and {

  digitalWrite(pin 13, high);

What is that word pin doing there ?
high is not the same as HIGH

Oops, I messed the "pin" and "high" in an effort to quickly recreate an example. The other error you pointed out, the missing ")", really was the root problem. Having fixed all of that, the code was validated with no errors. Great!

However, in running the sketch, the LED turns on and stays on. My guess is that it's turned on by the initial startup spike to 3.63 Amps output before it stabilizes to 0.0 Amps no load. If I increase the "AmpsRMS > 0.0" value, the led does not come on, but the increase is greater than the loaded value of 0.5 amps. How can that be resolved?

Also, I still can't figure out how to turn off the led when amps goes back to 0.0, with a 10 second delay.

Thanks for the continuing help, it's the difference that stops me from giving up.

in running the sketch, the LED turns on and stays on

No surprise there as you have no code to turn it off. Start by adding an else if clause that sets a boolean to true and saves the value of millis() to a variable when the value of AmpsRMS falls below your desired trigger value.

Then in loop(), test whether the boolean is set to true and if so whether the value of millis() now minus the value previously saved is greater than 10 seconds. If so, turn off the LED and set the boolean to false. If not then do nothing.

Have you read Using millis() for timing. A beginners guide, Several things at the same time and looked at the BlinkWithoutDelay example in the IDE.

Okay, got it to turn off when amps fall below the load value. I will go back and study your references for doing the timing.
Thanks again and I will report back sometime soon.

Maybe start by simply turning it off when the current falls below the threshold. Add the timing after you know that works

Snack-chaser:
This is the simplest version that I tried, all other were not saved.

Get into the habit of saving versions as you move forward. You never know when you might like to start again with an earlier version.

...R

To go back to a version of the code you posted on the forum, just scroll back to that post and click the word "[select]" above the code box. Copy & paste into IDE.