Reiniciar ordenadores/maquinas si no hay consumo suficiente.

Buenas, estoy probando de hacer un sistema de reinicio de ordenadores automático.

He comprado medidores de consumo ACS712 y un placa de relés a 5v todo comprado en una pagina china.

He echo funcionar sin problemas la primera parte con solo un sensor y un relé(quiero 4 o mas).

La idea es que si el pc deja de consumir es que no esta trabajando (cuando se cuelga consume la mitad aproximadamente) por desgracia cada x días por "X" causas no reinicia correctamente y tengo que reiniciarlos manualmente.

Necesitaría que cuando detecte que un valor esta por debajo de lo deseado (Amperios en este caso) lo comprobara durante "X" segundos para asegurar que si esta colgado y no es un reinicio del pc ya que sino cada vez que yo apagara/reiniciara el equipo un momento el relé empezaría a actuar.

Así que tendría que dejarlo comprobando que no hay consumo por ejemplo 8 minutos y si durante 8 minutos esta apagado entonces si activar el relé para que apague totalmente la electricidad durante un minuto y volver a encenderlo después de ese minuto.

Y para hacer el proyecto lo mas económico posible, interesa que no sea con delays porque si uso 5 medidores con 5 equipos distintos estaría muy bien que pudiera hacerlo simultáneamente a esos 5 medidores y relés.

Adjunto codigo cutre que encontre y he usado de base y le he echo pocas modificaciones:

#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)

//Aqui empiezo a darle ordenes al relé//
//*********************************************************************************************************//
    if (Irms > 0.35)    //Si el consumo es superior a 0.35A dejo el rele en HIGH
    {
      digitalWrite(RELAY1, HIGH);
      r1 = 0;
    }
    if (Irms < 0.35) //Si el consumo es inferior a 0.35A dejo el rele en LOW si durante 8 minutos no tiene ese consumo.
      {
      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;

  }
}

Si un experto puede echarme una mano en esto se agradecería mucho, quizás también le sirva a alguien para algún proyecto.

Un saludo y gracias!!

El código esta aparentemiente bien pero existe una librería que lo hace de modo mas eficiente y rápido.

EmonLib

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

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

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

void loop()
{
  double Irms = emon1.calcIrms(1480);  // Calculate Irms only
  
  Serial.print(Irms*230.0);	       // Apparent power
  Serial.print(" ");
  Serial.println(Irms);		       // Irms
}

Que te parece un poco mas simple no?
BUeno siempre hay alguna librería que hace las cosas mejor que uno.

De todos modos ser mas rápido con 8min no te cambiará nada

Esto crea la instancia

EnergyMonitor emon1;                   // Create an instance

puedes por ejemplo crear un array y manejar las 4 pero hay que ver si lo tolera.

EnergyMonitor emon[4];                   // Create an instance

el resto es manejarse con el vector respectivo.

Anda gracias, pues si simplifica cosas la librería esta jejeje.

Me pierdo mucho con c++ y no entiendo a que te refieres con crear la instancia y manejarse con el vector.

Voy a mirar en youtube/google un tuto de c++ que hable de la instancias, haber si así entiendo lo que me as comentado jejejej

He modificado el código y encontré como poder hacer el calculo para que el consumo se muestre correctamente con mi versión de acs712 de 30A que usa 66mv por A.

Copio el código por si le es útil a alguien, luego intento ponerme a hacer que el relé funcione para luego conseguir hacer el contador de tiempo para que cuente x minutos cuanto tiempo tiene que estar con poco consumo para actuar.

en el código comente las lineas de los otros sensores porque aun no los he conectado y primero empezare con uno.

#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
// }

que tal asi?
Si las calibraciones fueran diferentes puedes usar un vector de este modo

#include "EmonLib.h"                   // Include Emon Library
EnergyMonitor emon[5];                   // Create an instance for pin A0

float calibra[5] = {15.1515, 14.2345, 13.4578, 16.5687, 15.4544}; // puse valores inventados

void setup() { 
  Serial.begin(9600);
  
  for (byte i=0; i<5; i++)
    emon0.current[i](i, calibra[i]);             // Current: input pin, calibration.
 

void loop(){

  for (byte i=0; i<5; i++)
       calculateirms(i); // Calculo Irms del sensor del pin A0 -- Calculation of sensor in pin A0
}
 
void calculateirms(byte sensor) {    // irms sensor 1 calculation and print to serial monitor
  double Irms = emon[sensor].calcIrms(1480);  // Calculate Irms only
  Serial.print("Ampers");
  Serial.print("--");
  Serial.println(Irms);          // Irms
}

Buenas Surbyte y muchas gracias por tu tiempo :wink:

El código que me pones entiendo que es para resumirlo en menos lineas, no?

Si es así, como podrás ver con mi pregunta es que no entiendo nada de lo que pone y me es mas fácil hacerlo en el modo simplón con mas lineas pero por lo menos de ese modo lo entiendo bien jejejeje.

La única parte que me preocupa es la del contador para cuando baje el consume lo mire "x" millis.

Imagino que una de las formas (que desconozco como aplicarla) es hacer que cada vez que encuentre un valor de consumo (Irms) inferior a "x" sume un 1 a una variable (si se llama así), y si llega ese numero a por ejemplo 1000 que apague el relé y si en algún momento ese numero esta por encima del valor "X" que le hemos asignado que se vuelva a poner a 0.

Un problema que quizás hay es que ese contador con lo rápido que va arduino y dependiendo del código que se meta ira mas rápido o lento a sumar y tendría que controlarse de alguna forma por tiempo el contador para que si se quiere hacer cada 8 minutos o 10 o 13 sea fácil de controlar.

Una vez mas agradezco tu ayuda.

Olvida el tiempo que insume. Si mal recuerdo, usa TIMERS o sea.. con consume tiempo de CPU.

El código que te mostré solo es estéticamente mas simple y nada mas que eso respecto de la opción que tu usaste.
Usa un vector... que es como si tuvieras las mismas variables que tu definiste llamadas del mismo modo pero identificadas por su índice.

emon0 sera emon[0]
emon1 será emon[1]
y asi.. con todas

No he probado con 5 sensores de corriente o tensión asi que no se como se comporte. Pero funciona con 3 (pq se usas con alimentaciones y cargas trifásicas) asi que debería andar con 4 o 5.

Ahora el disparo lo haces como lo venias haciendo.

millis() no afectará nada de esto.

NO USES DELAY en ningún momento!!

Buenas de nuevo, he enfocado el código de los timers y comprobación, me equivoco en muchas cosas que poco a poco voy entendiendo que no hacen falta, poco a poco va mejorando aun sin funcionar pero poco a poco creo que voy aprendiendo las cosillas y alguien me iluminara con los errores que hago con los if, else, millis :grin:

Un saludete y haber si podéis echarme una mano en la parte que estoy haciendo algo mal y no consigo entender que es.

#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
#define RELAY0 7


unsigned long tactual=0;
unsigned long tanterior=0;
unsigned long tiempo=0;

void setup()
{ 
  Serial.begin(9600);
 
  emon0.current(0, 15.1515);             // Current: input pin, calibration.
 // emon1.current(1, 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



}
 
void calculateirms0() {    // irms sensor 1 calculation and print to serial monitor
  double Irms0 = emon0.calcIrms(1480);  // Calculate Irms only
  
if (Irms0 > 4) { // si el consumo es mayor a 4A imprimo y no hago nada
      Serial.print("Watts");
      Serial.print("--");
      Serial.print(Irms0*230.0);         // Apparent power
      Serial.print("    ");
      Serial.print("Ampers");
      Serial.print("--");
      Serial.println(Irms0);          // Irms
      tactual=0; //reinicio millis ya que todo va bien
      tanterior=0; //reinicio millis ya que todo va bien
 //cierro este if ya que no debe hacer nada de nada despues de esto al estar bien el consumo

}
else (Irms0 < 4); { // pero si el consumo es menor a 4A abro corchete sin cerrarlo para englobar
            Serial.print("CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA   Ampers -- "); // imprimo solo amperios y error
            Serial.println(Irms0);
            Serial.print("--");
            Serial.print(tiempo/1000);          // Irms imprimo el tiempo transcurrido para ver como va
  
      if (Irms0 < 4 && tiempo > 600000); {  //si sigue despues de 600 segundos con consumo bajo (osea error) tendremos que actual con el relé
            Serial.print("10minutos FALLANDO EL SISTEMA   Ampers -- "); // imprimo solo amperios y error
            Serial.println(Irms0);
            Serial.print("--");
            Serial.print(tiempo/1000);          // Irms imprimo el tiempo transcurrido para ver como va
            digitalWrite(RELAY0, HIGH); //ACTIVO/desactivo el rele 50 segundos
            if (tiempo - tanterior > 50){ //si el tiempo menos el ultimo tiempo actuado es mayor a 50 vuelve a encender el rele (creo que asi activaria el rele de nuevo pasados 50 segundos)
            digitalWrite(RELAY0, LOW); //ACTIVO/desactivo el rele 50 segundos
             tactual=0; //reinicio millis ya que acabo de reiniciar el equipo y tarda unos minutos en volver a consumir
             tanterior=0; //reinicio millis ya que acabo de reiniciar el equipo y tarda unos minutos en volver a consumir
   
      }}}}

Si pones esto

else (Irms0 < 4); {

eliminas todo lo que sigue. Tu error es el ;
debes quitarlo para que la llave queden dentro de esa condición.

Por favor, no lo tomes a mal pero se prolijo al postear.
Indenta tu código ordenadamente para que pueda leerse.
si tu pones }}}}} yo debo imaginar que es cada cosa en lugar de que cada una cierre con su if, switch o lo que sea.

Nos lleva tiempo a los que respondemos entender algo que esta todo pegado a la izquierda sin orden.
Sigo mirando pero tenlo presente y disculpa, fui profesor y no se me quitan las mañas!!

Esta es la versión indentada, ahora dime si donde creo yo que van las llaves coincide con tu criterio
Veo un posible error en los 50 segundos finales porque no vi o no entendí donde cargas millis() para comenzar esa cuenta.
Bueno como he visto, no actualizas nunca tactual ni tanterior, asi que creo que los tiempos no estarán trabajando.

#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
#define RELAY0 7


unsigned long tactual=0;
unsigned long tanterior=0;
unsigned long tiempo=0;

void setup()
{ 
  Serial.begin(9600);
 
  emon0.current(0, 15.1515);             // Current: input pin, calibration.
 // emon1.current(1, 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



}
 
void calculateirms0() {    // irms sensor 1 calculation and print to serial monitor
    double Irms0 = emon0.calcIrms(1480);  // Calculate Irms only
  
    if (Irms0 > 4) { // si el consumo es mayor a 4A imprimo y no hago nada
          Serial.print("Watts");
          Serial.print("--");
          Serial.print(Irms0*230.0);         // Apparent power
          Serial.print("    ");
          Serial.print("Ampers");
          Serial.print("--");
          Serial.println(Irms0);          // Irms
          tactual=0; //reinicio millis ya que todo va bien
          tanterior=0; //reinicio millis ya que todo va bien
        //cierro este if ya que no debe hacer nada de nada despues de esto al estar bien el consumo

    else (Irms0 < 4) { // pero si el consumo es menor a 4A abro corchete sin cerrarlo para englobar
          Serial.print("CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA   Ampers -- "); // imprimo solo amperios y error
          Serial.println(Irms0);
          Serial.print("--");
          Serial.print(tiempo/1000);          // Irms imprimo el tiempo transcurrido para ver como va
 
          if (tiempo > 600000) {  //si sigue despues de 600 segundos con consumo bajo (osea error) tendremos que actual con el relé
              Serial.print("10minutos FALLANDO EL SISTEMA   Ampers -- "); // imprimo solo amperios y error
              Serial.println(Irms0);
              Serial.print("--");
              Serial.print(tiempo/1000);          // Irms imprimo el tiempo transcurrido para ver como va
              digitalWrite(RELAY0, HIGH); //ACTIVO/desactivo el rele 50 segundos
              if (tiempo - tanterior > 50){ //si el tiempo menos el ultimo tiempo actuado es mayor a 50 vuelve a encender el rele (creo que asi activaria el rele de nuevo pasados 50 segundos)
                  digitalWrite(RELAY0, LOW); //ACTIVO/desactivo el rele 50 segundos
                  tactual=0; //reinicio millis ya que acabo de reiniciar el equipo y tarda unos minutos en volver a consumir
                  tanterior=0; //reinicio millis ya que acabo de reiniciar el equipo y tarda unos minutos en volver a consumir
              }
         }
    } 
}

Disculpa por mi desorden, hago tantos cambios a lo loco para intentar aclararme que al final esta echo un desastre.

Me basare en tu modificación y la dejare ordenada lo mejor posible.

Te entiendo perfectamente que es un lio para ti entender mi código (si se le puede llamar así aun).

Me encuentro con que me pide que ponga un "}" antes del else que cierre el if anterior no entiendo porque.

Si cierro el IF que creo que seria lo correcto tengo que poner un else if para que lo acepte tal cual.

Gracias por tu tiempo.

He ordenado y añadido

  • un else if en lugar de else porque no me aceptaba el else sin ;
  • he cerrado el primer if
    -he añadido pinmode, output y que este en high al iniciar para que no me parpadee (me parpadea el relé al irse la luz o apagar y encender arduino.

Tiene fallos por todos lados :frowning: veo que el monitor serie marca bien los Watt y amperios, pero cuando le bajo el consumo empieza a mostrar el tiempo desde que se encendió el arduino, no aplico bien los millis.

Y el relé no se enciende al encontrarse en la ultima parte donde debería encender el relé y apagar-lo a los 50 segundos (será un relé normalmente cerrado para solo hacerlo trabajar cuando toque).

De nuevo mis disculpas y agradecimiento.

#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
#define RELAY0 7


unsigned long tactual=0;
unsigned long tanterior=0;
unsigned long tiempo=0;

void setup()
{
  Serial.begin(9600);
  pinMode(RELAY0, OUTPUT);
  digitalWrite(RELAY0, HIGH); //si no defino esto al reiniciar el arduino o apagar la luz un momento o se va un momento la electricidad el rele salta un momento
  emon0.current(0, 15.1515);             // Current: input pin, calibration.
 // emon1.current(1, 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



}
 
void calculateirms0() {    // irms sensor 1 calculation and print to serial monitor
    double Irms0 = emon0.calcIrms(1480);  // Calculate Irms only
 
    if (Irms0 > 3.3) // si el consumo es mayor a 4A imprimo y no hago nada
    { 
          Serial.print("Watts");
          Serial.print("--");
          Serial.print(Irms0*230.0);         // Apparent power
          Serial.print("    ");
          Serial.print("Ampers");
          Serial.print("--");
          Serial.println(Irms0);          // Irms
          tactual=0; //reinicio millis ya que todo va bien
          tanterior=0; //reinicio millis ya que todo va bien
        
    } //cierro este if ya que no debe hacer nada de nada despues de esto al estar bien el consumo
    
    else if (Irms0 < 3.3)  // pero si el consumo es menor a 4A abro corchete sin cerrarlo para englobar
          {
         tactual=millis();
         tanterior=0;
         tiempo= tactual-tanterior; 
          Serial.print("CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA   Ampers -- "); // imprimo solo amperios y error
          Serial.println(Irms0);
          Serial.print("--");
          Serial.println(tiempo/1000);          // Irms imprimo el tiempo transcurrido para ver como va

          if (tiempo > 20000)  //si sigue despues de 20 segundos (20 para pruebas mientras se hace funcionar) con consumo bajo (osea error) tendremos que actual con el relé
                            { 
              tactual=millis();
              tanterior=0;
              tiempo= tactual-tanterior;
              Serial.print("10minutos FALLANDO EL SISTEMA   Ampers -- "); // imprimo solo amperios y error
              Serial.println(Irms0);
              Serial.print("--");
              Serial.println(tiempo/1000);          // Irms imprimo el tiempo transcurrido para ver como va
              digitalWrite(RELAY0, LOW); //ACTIVO/desactivo el rele 50 segundos
              if (tiempo - tanterior > 50)   //si el tiempo menos el ultimo tiempo actuado es mayor a 50 vuelve a encender el rele (creo que asi activaria el rele de nuevo pasados 50 segundos)
                                           {
                  digitalWrite(RELAY0, HIGH); //ACTIVO/desactivo el rele 50 segundos
                  tactual=0; //reinicio millis ya que acabo de reiniciar el equipo y tarda unos minutos en volver a consumir
                  tanterior=0; //reinicio millis ya que acabo de reiniciar el equipo y tarda unos minutos en volver a consumir
                                          }
                            }
           }
}

Bueno veo que agregaste algo a los 20 segundos
Mira a ver que tal esto

#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
#define RELAY0 7


unsigned long tstart        = 0;
unsigned long tstart50      = 0;
unsigned long tiempo        = 0;
bool firstTime = false, firtTime50 = false;

void setup() { 
  Serial.begin(9600);
  emon0.current(0, 15.1515);             // Current: input pin, calibration.
 // emon1.current(1, 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

}
 
void calculateirms0() {    // irms sensor 1 calculation and print to serial monitor
    double Irms0 = emon0.calcIrms(1480);  // Calculate Irms only
  
    if (Irms0 > 4) { // si el consumo es mayor a 4A imprimo y no hago nada
          Serial.print("Watts");
          Serial.print("--");
          Serial.print(Irms0*230.0);         // Apparent power
          Serial.print("    ");
          Serial.print("Ampers");
          Serial.print("--");
          Serial.println(Irms0);          // Irms
          tstart    = 0; //reinicio millis ya que todo va bien
          firstTime = true; // la preparo para cuando estemos x debajo de 4A
          firtTime50 = true;
        //cierro este if ya que no debe hacer nada de nada despues de esto al estar bien el consumo
    }
    else 
    
    if (Irms0 < 4) { // pero si el consumo es menor a 4A abro corchete sin cerrarlo para englobar
          
          if (firstTime) {
              tstart = millis(); 
              firstTime = false;
          }
          tiempo = (millis()-tstart)/1000;
          Serial.print("CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA   Ampers -- "); // imprimo solo amperios y error
          Serial.println(Irms0);
          Serial.print("--");
          Serial.print(tiempo);          // Irms imprimo el tiempo transcurrido para ver como va
 
          if (tiempo > 600) {  //si sigue despues de 600 segundos con consumo bajo (osea error) tendremos que actual con el relé
              if (firtTime50)
                 tstart50 = tiempo;
              Serial.print("10minutos FALLANDO EL SISTEMA   Ampers -- "); // imprimo solo amperios y error
              Serial.println(Irms0);
              Serial.print("--");
              Serial.print(tiempo);             // Irms imprimo el tiempo transcurrido para ver como va
              digitalWrite(RELAY0, HIGH);       // ACTIVO/desactivo el rele 50 segundos

              if (tiempo - tstart50 > 50){      // si el tiempo menos el ultimo tiempo actuado es mayor a 50 vuelve a encender el rele (creo que asi activaria el rele de nuevo pasados 50 segundos)
                  digitalWrite(RELAY0, LOW);    // ACTIVO/desactivo el rele 50 segundos
                  tstart    = 0;                // reinicio millis ya que acabo de reiniciar el equipo y tarda unos minutos en volver a consumir
                  tstart50  = 0;
              }
         }
    } 
}

No tiene las modificaciones de tu último post!!

Ostras, tendre que estudiar el codigo este jejeje

Ahora ya cada vez que le bajo el consumo empieza a contar desde 0, le baje el valor a 60 en lugar de 600 para hacer las pruebas.

Mientras llega a 60 muestra
CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA Ampers -- 3.19--56
CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA Ampers -- 3.11--57
CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA Ampers -- 3.11--58
CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA Ampers -- 3.11--59

Cuando llega a esos 60 muestra

10minutos FALLANDO EL SISTEMA Ampers -- 3.16--61
CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA Ampers -- 3.08--61
10minutos FALLANDO EL SISTEMA Ampers -- 3.08--62
CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA Ampers -- 3.12--62
10minutos FALLANDO EL SISTEMA Ampers -- 3.12--63
CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA Ampers -- 3.16--63
10minutos FALLANDO EL SISTEMA Ampers -- 3.16--64
CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA Ampers -- 3.12--64

Y el relé no salta, ni hace nada. Por si las moscas postearé el código pero lo he repasado todo para copiar el tuyo y la única diferencia que veo es que en el void setup tengo puesto:

pinMode(RELAY0, OUTPUT);
digitalWrite(RELAY0, HIGH);

Porque sino al marchar la luz o cualquier reinicio el relé se apaga y enciende medio segundo o así, eso me pararía las maquinas.

Ese HIGH en el setup hace que se quede fijo en HIGH y no se estimule la bobina? (Mi relé se activa con LOW, con HIGH no esta estimulada la bobina).

Otra de las muchas veces mil gracias por tu dedicación y tiempo.

Codigo actual por si prefieres mirar este pero la dif es la que comente al principio:

#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
#define RELAY0 7


unsigned long tstart =0;
unsigned long tstart50 =0;
unsigned long tiempo =0;
bool firstTime = false, firtTime50 = false;

void setup()
{
  Serial.begin(9600);
  pinMode(RELAY0, OUTPUT);
  digitalWrite(RELAY0, HIGH); //si no defino esto al reiniciar el arduino o apagar la luz un momento o se va un momento la electricidad el rele salta un momento
  emon0.current(0, 15.1515);             // Current: input pin, calibration.
 // emon1.current(1, 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



}
 
void calculateirms0() {    // irms sensor 1 calculation and print to serial monitor
    double Irms0 = emon0.calcIrms(1480);  // Calculate Irms only
 
    if (Irms0 > 3.3) // si el consumo es mayor a 4A imprimo y no hago nada
    { 
          Serial.print("Watts");
          Serial.print("--");
          Serial.print(Irms0*230.0);         // Apparent power
          Serial.print("    ");
          Serial.print("Ampers");
          Serial.print("--");
          Serial.println(Irms0);          // Irms
          tstart = 0; //reinicio millis ya que todo va bien
          firstTime = true; //reinicio millis ya que todo va bien
          firtTime50 = true;
    } //cierro este if ya que no debe hacer nada de nada despues de esto al estar bien el consumo
    else
   
    if (Irms0 < 3.3)  // pero si el consumo es menor a 4A abro corchete sin cerrarlo para englobar
          {
              if (firstTime) {
              tstart = millis();
              firstTime = false;
             }
                 tiempo = (millis()-tstart)/1000;    
                 Serial.print("CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA   Ampers -- "); // imprimo solo amperios y error
                 Serial.print(Irms0);
                 Serial.print("--");
                 Serial.println(tiempo);          // Irms imprimo el tiempo transcurrido para ver como va

          if (tiempo > 60)  //si sigue despues de 20 segundos (20 para pruebas mientras se hace funcionar) con consumo bajo (osea error) tendremos que actual con el relé
                            { 
              if (firtTime50)
                  tstart50 = tiempo;
              Serial.print("10minutos FALLANDO EL SISTEMA   Ampers -- "); // imprimo solo amperios y error
              Serial.print(Irms0);
              Serial.print("--");
              Serial.println(tiempo);          // Irms imprimo el tiempo transcurrido para ver como va
              digitalWrite(RELAY0, HIGH); //ACTIVO/desactivo el rele 50 segundos
              
               if (tiempo - tstart50 > 50) {   //si el tiempo menos el ultimo tiempo actuado es mayor a 50 vuelve a encender el rele (creo que asi activaria el rele de nuevo pasados 50 segundos)
               
                  digitalWrite(RELAY0, LOW); //ACTIVO/desactivo el rele 50 segundos
                  tstart =0; //reinicio millis ya que acabo de reiniciar el equipo y tarda unos minutos en volver a consumir
                  tstart50 =0; //reinicio millis ya que acabo de reiniciar el equipo y tarda unos minutos en volver a consumir
                                          }
                            }
           }
}

He avanzado un poco gracias a tu ayuda :slight_smile:

Ya funciona con alguna cosa que pulir.

Lo he puesto para que cuanto falla el consumo 20 segundos se pare el relé 10 segundos.

He modificado:

{ que tenia que ir después de else

Y los millis a partir de if tstart50 he cambiado:

tstart50 = (tiempo - 20); porque entienda que si dejaba tstart50 = tiempo se quedaba igual el valor seria el mismo en tiempo y tstart y no podía ser el mismo sino la función de debajo no actuaria correctamente. Entonces le pues un - 20 que es el tiempo que puse actualmente. De esta forma cada vez que cambie el tiempo tendré que modificar los dos 20 del código.

También en la paste final he puesto una función que reinicia el tiempo de "tiempo" para que empiece de 0 de nuevo ya que ya ha echo su trabajo de reiniciar el equipo y debe volver a esperar "X" segundos para volver a actuar.

Falla una cosa que estoy intentado encontrar el problema, si le doy al reset del arduino o lo apago y enciendo mientras no hay consumo, es decir que el arduino empieza directamente con la detección de error en el consumo no hace nada y es un problema porque si se a la luz y el equipo no reinicia correctamente no me lo reiniciara y tengo que solucionarlo si o si.

El problema es que las funciones de bool que pusiste con sus trues o falses no las entiendo ni de coña :o

Otra vez te agradezco mucho tu ayuda, QUE ES MUCHA.

#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
#define RELAY0 7


unsigned long tstart =0;
unsigned long tstart50 =0;
unsigned long tiempo =0;
bool firstTime = false, firtTime50 = false;

void setup()
{
  Serial.begin(9600);
  pinMode(RELAY0, OUTPUT);
  digitalWrite(RELAY0, HIGH);
   //si no defino esto al reiniciar el arduino o apagar la luz un momento o se va un momento la electricidad el rele salta un momento
  emon0.current(0, 15.1515);             // Current: input pin, calibration.
 // emon1.current(1, 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
}
 
void calculateirms0() {    // irms sensor 1 calculation and print to serial monitor
    double Irms0 = emon0.calcIrms(1480);  // Calculate Irms only
 
    if (Irms0 > 3.3) // si el consumo es mayor a 4A imprimo y no hago nada
    { 
          Serial.print("Watts");
          Serial.print("--");
          Serial.print(Irms0*230.0);         // Apparent power
          Serial.print("    ");
          Serial.print("Ampers");
          Serial.print("--");
          Serial.println(Irms0);          // Irms
          digitalWrite(RELAY0, HIGH);
          tstart = 0; //reinicio millis ya que todo va bien
          firstTime = true; //reinicio millis ya que todo va bien
          firtTime50 = true;
    } //cierro este if ya que no debe hacer nada de nada despues de esto al estar bien el consumo
    else 
{
   
    if (Irms0 < 3.3)  // pero si el consumo es menor a 4A abro corchete sin cerrarlo para englobar
        {
              if (firstTime) {
              tstart = millis();
              firstTime = false;
              }
                 tiempo = (millis()-tstart)/1000;    
                 Serial.print("CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA   Ampers -- "); // imprimo solo amperios y error
                 Serial.print(Irms0);
                 Serial.print("--");
                 Serial.println(tiempo);          // Irms imprimo el tiempo transcurrido para ver como va

          if (tiempo >= 20)  //si sigue despues de 20 segundos (20 para pruebas mientras se hace funcionar) con consumo bajo (osea error) tendremos que actual con el relé
             { 
              if (firtTime50)
                          {
                  tstart50 = (tiempo - 20); //-20 pk tengo puestos 20 arriva asi se diferencia el tiempo del firsttime al de firttime50 y cuenta de 0
            
              digitalWrite(RELAY0, LOW); //ACTIVO/desactivo el rele 50 segundos
              Serial.print("10minutos FALLANDO EL SISTEMA   Ampers -- "); // imprimo solo amperios y error
              Serial.print(Irms0);
              Serial.print("--");
              Serial.println(tstart50);          // Irms imprimo el tiempo transcurrido para ver como va
              
              if (tstart50 > 10) 
                                            {   //si el tiempo menos el ultimo tiempo actuado es mayor a 50 vuelve a encender el rele (creo que asi activaria el rele de nuevo pasados 50 segundos)
 
                  digitalWrite(RELAY0, HIGH); //ACTIVO/desactivo el rele 50 segundos
                  tstart = millis();
                  tiempo = (millis()-tstart)/1000;

                                            }                         
                           }
               } //cierro el if que engloba el contador de tiempo de error "X"
        } //cierro todo el if global
 }  //cierro el else
}

O sea que si reinicias deberías forzar a que no haga nada por X tiempo, asi que agrega un delay en el setup para que arranque la PC. Dale 5 min?
Si la PC arranca bien, necesita menos pero si esta actualizando ya estará consumiendo.
De lo contrario tendrias que sabes que si tienes energía (220VAC) sea con un rele o una fuente que te dijera. Podrias conectarte a una salida USB y leer que hay 5V, una forma simple consumiendo un enchufe USB.

Anda un delay en setup, no sabia que se puede hacer eso en el setup creia que setup solo era para eso para hacer setup jajajajaja.

Imagino que solo se ejecutaría una vez al arrancar y ya esta no?

Con eso tendría que ser suficiente, un delay de 5 o 10 segundos y a correr como lo demás funciona perfectamente y el tiempo que le daré al programa es suficiente para que arranque y consuma no hay problema.

Sabes porque puede ser que los dos if se ejecuten siempre en el loop?

Ya funciona correctamente pero ya para dejarlo redondo y perfecto no tendria que salir el mensaje de:

CONSUMO BAJO POSIBLE FALLO EN EL SISTEMA Ampers -- 0.73--26
10minutos FALLANDO EL SISTEMA Ampers -- 0.73--6

En lugar de salir solo el que toca, no se si me explico bien.

Otra vez muchas gracias.

Si observas en ambos if hay dos firsTime que sirven para inicializar los timers, asi que coloca los mensajes ahi dentro, no necesitas que se ejecuten a cada momento.
O bien crea nuevos flags y si estas en la sección mas interna o sea cuando realmente activas el relay, prohibe que se imprima el primer mensaje.

Los flags son bool como estos

bool firstTime = false, firtTime50 = false;

crea nuevos y si estas en un lugar no puedes estar en el otro. o Muestra el serial de un if en un estado del flag pero si pasas al otro no se verá el primero y viceverza..
Son sugerencias.

Ya esta!

Gracias por llevarme por buen camino jeje

Los mensajes serie solo hay una diferencia entre el firsttime y el firttime50 en el segundo el mensaje en pantalla va mostrando el contador de tiempo y en el primero no, sale un mensaje solo del error sin mostrar el tiempo que va transcurriendo (es para integrar una pantalla cuando este funcionando y poder ponerle un lcd).

Imagino que es por el firsttime false que se aplica justo despues de ese propio evento, mirare de mover-lo haber si funciona (La lastima es que es por descarte o intuición la mayoría de lo que hago, no porque lo entienda bien).

El delay no servia de nada en el setup, pero con lo que me as dicho ahora de los flags se me ilumino, son ellos los que deben ir en el void setup así que copie las lineas del true de los dos bools en el setup y listo ahora ya va siempre, se haya apagado encendido o lo que sea siempre funciona :slight_smile:

Eres una maquina jejejeje

intento hacer que muestre bien los contadores y empezare a duplicarlo todo para mas sensores.

No se si se puede usar el firsttme,tiempo,tstart50... y tal en varios sitios pero por si las moscas creare unos firsttime/fisttime50 con un numero delante identificando cada sensor (2firsttime,3firsttime...) todo lo duplicare pero para ahorrar posibles dolores de cabeza con los tiempo y todo lo que se a puesto a todo le pondré el numero del sensor delante así seguro que ninguno se solapa con otro si llega a pasar que fallen 2 o mas maquinas a la vez.

Otra vez gracias, cuando este funcionando copiare el código por si le es útil a alguien.

Yo por ahora tengo dos proyectos en mente el actual y la puerta del garaje/local de mis bajos que creo que no tiene freno automático electrónico (creo que va por finales de carrera, tengo que mirarlo que hasta ahora lo tenia alquilado y la puerta automática la puso el cliente) si algo/alguien se engancha debajo, imagino que si algo se engancha el consumo subirá considerablemente así que seria una forma de hacerlo y de paso poner alguna "fotocelula" que tampoco hay y ya que estoy con eso añadir mando a distancia (que solo tengo uno y se pasan dos pueblos cuando pides otro de recambio) y lector RFID para los llaveros que abro la puerta del piso que tengo echo ya de hace unos años.