Automatic reboot for computers with current sensor

Hi, i try to make an automatic rebooter for my computers.

I have 5 ACS712 current sensors and relay modules with 5 relays.

I have the current sensor with relay working good but i need help for make it works better.

I want to make Arduino if see low current in sensor put on high the relay and wait one minute, and i f current is high (500W for example) the relay don’t make nothing.

The problem is if i stop the software of computer for make something the computer stop consumption and i need to make a counter or something for see if the low consumption duration is 10 minutes for example.

Because if i stop software or i reboot the computer the relay switch and stop the computer and i need to make a counter.

I’m new in this world of arduino and c++ and i don’t know how to make this part.

Here i post my code:

#define RELAY1    7
#define C_SENSOR1 A0

//For analog read
int r1 = LOW;
int r1_received = LOW;
int incomingByte = 0;   // for incoming serial data
int c_min = 0;
int c_max = 3000;

//For analog read
double value;

//Constants to convert ADC divisions into mains current values.
double ADCvoltsperdiv = 0.0048;
double VDoffset = 2.4476; //Initial value (corrected as program runs)

//Equation of the line calibration values
double factorA = 15.35; //factorA = CT reduction factor / rsens
double Ioffset = 0;

//Constants set voltage waveform amplitude.
double SetV = 219.0;

//Counter
int i=0;

int samplenumber = 4000;

//Used for calculating real, apparent power, Irms and Vrms.
double sumI=0.0;

int sum1i=0;
double sumVadc=0.0;

double Vadc,Vsens,Isens,Imains,sqI,Irms;
double apparentPower;

void setup()
{
  Serial.begin(9600);
   //Prevent relay trigger on bootup
  pinMode(RELAY1, INPUT_PULLUP);
  pinMode(RELAY1, OUTPUT);
}

void loop()
{
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();

    // say what you got:
    //Serial.print("I received: ");
    //Serial.println(incomingByte, DEC);
    if (incomingByte == 48) {
      r1_received = HIGH;
      digitalWrite(RELAY1, HIGH);
      r1 = 0;
    } else if (incomingByte == 49) {
      r1_received = LOW;
      digitalWrite(RELAY1, LOW);
      r1 = 1;
    } else if (incomingByte >= 101 && incomingByte <= 130) {
      // its max current (30 max), prevent carry jump \r (char(13)) readed,
      // so added 100 to current value
      c_max = incomingByte-100;
    }
  }

  value = analogRead(C_SENSOR1);

  //Summing counter
  i++;

  //Voltage at ADC
  Vadc = value * ADCvoltsperdiv;

  //Remove voltage divider offset
  Vsens = Vadc-VDoffset;

  //Current transformer scale to find Imains
  Imains = Vsens;

  //Calculates Voltage divider offset.
  sum1i++; sumVadc = sumVadc + Vadc;
  if (sum1i>=1000) {VDoffset = sumVadc/sum1i; sum1i = 0; sumVadc=0.0;}

  //Root-mean-square method current
  //1) square current values
  sqI = Imains*Imains;
  //2) sum
  sumI=sumI+sqI;

  if (i>=samplenumber)
  {
    i=0;
    //Calculation of the root of the mean of the current squared (rms)
    Irms = factorA*sqrt(sumI/samplenumber)+Ioffset;
    if (Irms<0.05) {Irms=0;}

    //Calculation of the root of the mean of the voltage squared (rms)

//Here start the relay options//
//*********************************************************************************************************//
    if (Irms > 0.35)    //IF consumption is more than 0.35 Amp relay state HIGH
    {
      digitalWrite(RELAY1, HIGH);
      r1 = 0;
    }
    if (Irms < 0.35) //IF consumption is more than 0.35 Amp relay state LOW if the consumption continues in < 0.35, but if consumption another time is more than 0.35A don't make nothing and continue monitoring.
      {
      digitalWrite(RELAY1, LOW);
      r1 = 0;
    }
   
    apparentPower = Irms * SetV;
    Serial.print(" Watios: ");
    Serial.print(apparentPower);
    Serial.print(" Amperios: ");
    Serial.print(Irms);
    Serial.print(" status: ");
    Serial.print(r1);
    Serial.println();

    //Reset values ready for next sample.
    sumI=0.0;

  }
}

Anyone have idea how can i make it without delay option because this code need to be expanded for 5 relays or more in the future (with mega).

If anyone use this code for control ACS712 i don’t know if it’s exact because i don’t need an exact valor because i need to control only if consumption of 100/300w at 900/1200w.

Thanks for your time.

comeollas: I want to make Arduino if see low current in sensor put on high the relay and wait one minute, and i f current is high (500W for example) the relay don't make nothing.

I wonder if your problem might have anything to do with the fact that current is measured in Amps and not Watts?

...R

Robin2:
I wonder if your problem might have anything to do with the fact that current is measured in Amps and not Watts?

…R

It’s an example i use Amps.

But in Watts it’s possible too because this code have converter for watts “apparentPower” in code.

But in serial print i erased this part because i don’t need this data in serialprint.


apparentPower = Irms * SetV;
Serial.print(" Watios: “);
Serial.print(apparentPower);
Serial.print(” Amperios: “);
Serial.print(Irms);
Serial.print(” status: ");
Serial.print(r1);
Serial.println();

You know anything useful for make a counter or something in C++ for this project?

Hi,

I want to make Arduino if see low current in sensor put on high the relay and wait one minute, and i f current is high (500W for example) the relay don't make nothing.

What about when you set the high relay set a flag and a variable with the time =millis() saved. Then keep doing what ever you are doing and read the time and compare if it passed one minute then do what ever you need to do.

example:

high_relay_flag =1 and wait_minute = millis() //set flag and save time when enable the high relay on

then

if (high_relay_flag ==1 && wait_minute>= 1 minute && current is high (500W ){do nothing ; }

Just a suggestion.

tauro0221: Hi,

I want to make Arduino if see low current in sensor put on high the relay and wait one minute, and i f current is high (500W for example) the relay don't make nothing.

What about when you set the high relay set a flag and a variable with the time =millis() saved. Then keep doing what ever you are doing and read the time and compare if it passed one minute then do what ever you need to do.

example:

high_relay_flag =1 and wait_minute = millis() //set flag and save time when enable the high relay on

then

if (high_relay_flag ==1 && wait_minute>= 1 minute && current is high (500W ){do nothing ; }

Just a suggestion.

Thanks you i try this, i understand your explanation and have sense :) .

I'ts possible make this more times? (i never used flags and don't know if its possible to repeat the process for "x" times).

I very appreciate your help.

Hi, Do you have to do it for each of the 5 relays.

comeollas: The problem is if i stop the software of computer for make something the computer stop consumption and i need to make a counter or something for see if the low consumption duration is 10 minutes for example.

The way your program is written with all of the code in loop() rather than breaking it out into small single-purpose functions makes it difficult to understand and difficult to modify.

You seem to have code that read the sensor several times and comes up with an Irms value which then becomes the centre of your logic.

Move all the code that calculates the Irms value into a function.

If this was my project the code in loop() would be like this

void loop() {
  calculateIRMS();
  checkPowerLow();
  operateRelays();
}

See Planning and Implementing a Program

If you need to check that the value stays low for a period of time you need code something like this pseudo code

if (value is below threshold) {
  startLowMillis = millis();
}
if (millis() - startLowMillis >= interval) {
 // now it has been low continuously for the full interval
}

...R

tauro0221: Hi, Do you have to do it for each of the 5 relays.

Ok, repeat the same with dif relays and sensors, thnx :)

Robin2: The way your program is written with all of the code in loop() rather than breaking it out into small single-purpose functions makes it difficult to understand and difficult to modify.

You seem to have code that read the sensor several times and comes up with an Irms value which then becomes the centre of your logic.

Move all the code that calculates the Irms value into a function.

If this was my project the code in loop() would be like this

void loop() {
  calculateIRMS();
  checkPowerLow();
  operateRelays();
}

See Planning and Implementing a Program

If you need to check that the value stays low for a period of time you need code something like this pseudo code

if (value is below threshold) {
  startLowMillis = millis();
}
if (millis() - startLowMillis >= interval) {
 // now it has been low continuously for the full interval
}

...R

I see, i can make one void loop with all "processes" and after void loop define what can i do with him.

Tnx for the tips i start to try to make it functionally and undestand how works.

For the moment i changed the code for another with library from energymon.

#include "EmonLib.h"                   // Include Emon Library
EnergyMonitor emon0;                   // Create an instance for pin A0
EnergyMonitor emon1;                   // Create an instance for pin A1
EnergyMonitor emon2;                   // Create an instance for pin A2
EnergyMonitor emon3;                   // Create an instance for pin A3
EnergyMonitor emon4;                   // Create an instance for pin A4

void setup()
{
  Serial.begin(9600);
 
  emon0.current(0, 15.1515);             // Current: input pin, calibration.
 // emon1.current(1, 111.1);             // Current: input pin, calibration.
 // emon2.current(2, 111.1);             // Current: input pin, calibration.
 // emon3.current(3, 111.1);             // Current: input pin, calibration.
 // emon4.current(4, 111.1);             // Current: input pin, calibration.
}

void loop()
{

  calculateirms0(); // Calculo Irms del sensor del pin A0 -- Calculation of sensor in pin A0
 // calculateirms1(); // Calculo Irms del sensor del pin A1 -- Calculation of sensor in pin A1
 // calculateirms2(); // Calculo Irms del sensor del pin A2 -- Calculation of sensor in pin A2
 // calculateirms3(); // Calculo Irms del sensor del pin A3 -- Calculation of sensor in pin A3
 // calculateirms4(); // Calculo Irms del sensor del pin A4 -- Calculation of sensor in pin A4



}
 
void calculateirms0() {    // irms sensor 1 calculation and print to serial monitor
  double Irms0 = emon0.calcIrms(1480);  // Calculate Irms only
  Serial.print("Watts");
  Serial.print("--");
  Serial.print(Irms0*230.0);         // Apparent power
  Serial.print("    ");
  Serial.print("Ampers");
  Serial.print("--");
  Serial.println(Irms0);          // Irms
}

 
// void calculateirms1() {    // irms sensor 1 calculation and print to serial monitor
//  double Irms1 = emon1.calcIrms(1480);  // Calculate Irms only
//  Serial.print(Irms1*230.0);         // Apparent power
//  Serial.print(" ");
//  Serial.println(Irms1);          // Irms
// }
 
// void calculateirms2() {    // irms sensor 1 calculation and print to serial monitor
//  double Irms2 = emon2.calcIrms(1480);  // Calculate Irms only
//  Serial.print(Irms2*230.0);         // Apparent power
//  Serial.print(" ");
//  Serial.println(Irms2);          // Irms
// }
 
// void calculateirms3() {    // irms sensor 1 calculation and print to serial monitor
//  double Irms3 = emon3.calcIrms(1480);  // Calculate Irms only
//  Serial.print(Irms3*230.0);         // Apparent power
//  Serial.print(" ");
//  Serial.println(Irms3);          // Irms
// }
 
// void calculateirms4() {    // irms sensor 1 calculation and print to serial monitor
//  double Irms4 = emon4.calcIrms(1480);  // Calculate Irms only
//  Serial.print(Irms4*230.0);         // Apparent power
//  Serial.print(" ");
//  Serial.println(Irms4);          // Irms
// }

I commented all lines for the sensors 1,2,3 and 4 because in the table i use only one and first make it work alone.

Later i put the relays and try to make works with counters.

With this code what option make posible to compare for example 100 times?

if (Irms0 < 3) { // if value is lower than 3 Ampers
  startLowMillis = millis(); // Start to count "x" millis
}
if (millis() - startLowMillis >= interval) { // this line i don't understand what make
 // now it has been low continuously for the full interval
}

Thanks and i appreciate your help.