Arranque automatizado de generador

Hola como va, este programa esta diseñado para abasteser un sistema fotovoltaico cuando las baterias se descargan, ademas de ello el generado se puede encender mediante un interruptor y usarlo para soldar, me gustaria saber sus opiniones! Saludos.

//////////////////
/*Esteban Werner*/
//////////////////

// Libraries
#include <Servo.h>
#include <ZMPT101B.h>

// Declaration of global control variables for each case
bool generator_control = false;          // Generator Control
bool welder_control = false;             // Welder Control
bool battery_charging_control = false;   // Charge Of Batteries
bool automatic_load_control = false;     // Automatic Load Batteries
bool blink_light_control = false;        // Blink

//Bye bye Magic Numbers
const int success_start_voltaje = 180;   
const int overload_start_voltaje = 280;  
const int max_time_for_5_starts = 300000;
const int low_batery_voltaje = 22.5;
const int high_batery_voltaje = 24;
const int minimun_welder_voltaje = 20;   
const int max_starts_trys = 5;          
const int max_shotdowns_trys = 5;        

// Sensors and Switches
const int SVB = A0; // 24VDC Voltage Sensor
const int I1 = A2;  // Switch to turn on the generator
const int I2 = A3;  // Switch to turn on the welder
const int I3 = A4;  // Switch to restart

// Voltage threshold
const int high_state = 4;

// Sensor 220V and Servos
ZMPT101B zmpt(A1);  // 220V Sensor
Servo myServo1;     // Gasoil
Servo myServo2;     // Decompressor

// Relays
const int relay1 = 23;
const int relay2 = 25;
const int relay3 = 27;
const int relay4 = 29;
const int relay5 = 31;
const int relay6 = 33;
const int relay7 = 35;
const int relay8 = 37;
const int relay16 = 41;

// Define variables
unsigned long timeStart;    // Variable to store the start time
int execution_counter = 0;  // ON counter
int shutdown_counter = 0;   // OFF counter

void setup() {
  Serial.begin(9600);  // Serial Communication
  myServo1.attach(8);  // Gasoil Pin 
  myServo2.attach(2);  // Decompressor Pin 
  // Initialization of analog pins
  pinMode(I1, INPUT);   // Start Switch
  pinMode(I2, INPUT);   // Welder Switch
  pinMode(I3, INPUT);   // Restart Switch     
  pinMode(SVB, INPUT);  // DC 24V Voltage Sensor
  // Initialization of digital pins
  pinMode(relay1, OUTPUT);    // Dead Pin
  pinMode(relay2, OUTPUT);    // Generator Start
  pinMode(relay3, OUTPUT);    // Generator Start
  pinMode(relay4, OUTPUT);    // Generator Start
  pinMode(relay5, OUTPUT);    // Welding Light 
  pinMode(relay6, OUTPUT);    // Battery Light
  pinMode(relay7, OUTPUT);    // Reset Light  
  pinMode(relay8, OUTPUT);    // Battery Contactor
  pinMode(relay16, OUTPUT);   // Generator Light
  // Relays Off
  digitalWrite(relay1, HIGH);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, HIGH);
  digitalWrite(relay4, HIGH);
  digitalWrite(relay5, HIGH);
  digitalWrite(relay6, HIGH);
  digitalWrite(relay7, HIGH);
  digitalWrite(relay8, HIGH);
  digitalWrite(relay16, HIGH);
  // Servo
  digitalWrite(8, LOW);
  digitalWrite(2, LOW);
  // Counter
  timeStart = millis();  // Save the start time
}

void loop() {
  unsigned long tiempoActual = millis();  // Get the current time
  // Check if 5 minutes have passed (300,000 milliseconds)
  if (tiempoActual - timeStart >= max_time_for_5_starts) {
    // Reset the counter and update the start time
    execution_counter = 0;
    shutdown_counter = 0;
    timeStart = tiempoActual;
  }

  if (execution_counter < max_starts_trys && shutdown_counter < max_shotdowns_trys) {
    
  // Sensor 220V
  float voltage = zmpt.getRmsVoltage(); // Library for countries with 110V, so multiply by 2
  float realvoltage = voltage * 2.182333490788852;

  // Storage of analog data in variable
  int valueI1 = analogRead(I1);
  int valueI2 = analogRead(I2);
  int valueI3 = analogRead(I3);
  int value24vdc= analogRead(SVB);
  // Calculation of voltage and/or switch state
  int estadoI1 = (valueI1/1023)*5;
  int estadoI2 = (valueI2/1023)*5;
  int estadoI3 = (valueI3/1023)*5;
  int estado24vdc = (value24vdc/1023.0)*25.0;
  
  // Standby State
  if(automatic_load_control == false && battery_charging_control == false && welder_control == false && generator_control == false){
    Serial.println("Standby State ""info for +");
  }else{
        char info = 'info'; 
    if (Serial.available() > 0) {
    char received = Serial.read(); 
    if (received == info) {
        data();
    }
  }
  }
      /*PANIC BUTTON*/

      if(estadoI3 > high_state){
          deadstate();
          while(true){
            digitalWrite(relay7, LOW);         // Reset Light // Emergency
            Serial.println("Panic Button");
             int valueI3 = analogRead(I3);
             int estadoI3 = (valueI3/1023)*5;
             if(estadoI3 < high_state){
                 digitalWrite(relay7, HIGH);  // Reset Light OFF
                 delay(100);
                  asm volatile ("  jmp 0");    // Jump to the beginning of the program
             }
          }
      }

      /*Control to start the generator*/

   if(generator_control == false &&  automatic_load_control == false){
     if(estadoI1 > high_state){
                   generatorstart();
       }
     }else{
        if(generator_control == true && automatic_load_control == false){
           if((estadoI1 < high_state && welder_control == false)){
                  Serial.println("Error: Braked by switch");
                   generatorbrake();
                }else{ 
                  if(welder_control == false && generator_control == true){
                    if (realvoltage < success_start_voltaje){
                    Serial.println("Error: Braked by 220v Sensor");
                    generatorbrake();
                  }    
                }         
              }
           }
     }

      /*CONTROL WHEN WELDING IS USED*/
  
   if(welder_control == false){
    if (generator_control == true && estadoI2 > high_state){
            digitalWrite(relay8, HIGH);    // Disconnect Battery Power
            digitalWrite(relay6, HIGH);    // Battery Charging Light OFF
            digitalWrite(relay5, HIGH);    // Welding Light OFF (To be able to use it)
            battery_charging_control = false;  // Control Variable
            welder_control = true;       // Control Variable
            Serial.println("Using Welder");
    }}else{
      if(estadoI2 < high_state && welder_control == true){
         welder_control = false; 
          digitalWrite(relay8, LOW);    // Connect Battery Power
          digitalWrite(relay6, LOW);    // Battery Charging Light ON
          digitalWrite(relay5, LOW);    // Welding Light ON (To NOT use it)
          Serial.println("Leaving Welder Switch");
          battery_charging_control = true;
      } else{
        if(realvoltage < minimun_welder_voltaje){
          digitalWrite(relay8, HIGH);   // Disconnect Battery Power
          battery_charging_control = false; // Control Variable
          welder_control = false;     // Control Variable
          Serial.println("Leaving Welder 220v Sensor");
          generatorbrake();
        }
      }
    }

       /*CONTROL WHEN STARTING AUTOMATICALLY*/

  if(generator_control == false && battery_charging_control == false  && welder_control == false && automatic_load_control == false){
    if (estado24vdc < low_batery_voltaje && welder_control == false && generator_control == false && automatic_load_control == false && welder_control == false){  
        generatorstart();
        if(generator_control == true){
                automatic_load_control = true;
                Serial.println("The generator was off and turned on to charge the batteries");
        }else{
                Serial.println("Error: The generator was off and attempted to turn on to charge the batteries");
        }
     }
   }else{
    if(estado24vdc > high_batery_voltaje && estadoI1 < high_state && automatic_load_control == true && generator_control == true && welder_control == false){
        generatorbrake(); 
        automatic_load_control = false; 
    }
   }
}else {
        limitExceeded();
       }
}
  
void generatorstart(){
    execution_counter++;        // Increment the execution counter
    Serial.println("Starting is being executed");
    blink_light_control = true;
    while(blink_light_control == true){
          digitalWrite(relay5, LOW);    // Light 
          digitalWrite(relay6, LOW);    // Light 
          digitalWrite(relay7, LOW);    // Light 
          digitalWrite(relay16, LOW);   // Light 
          delay(1000);
          digitalWrite(relay5, HIGH);    // Light 
          digitalWrite(relay6, HIGH);    // Light 
          digitalWrite(relay7, HIGH);    // Light 
          digitalWrite(relay16, HIGH);   // Light 
          delay(1000);
    }
    digitalWrite(relay2, LOW);  // Key Contact
    digitalWrite(relay3, LOW);  // Key Contact
    // Diesel
    myServo1.write(50);          // Move the servo 50 degrees for startup
    delay(1000);
    //Start
    digitalWrite(relay4, LOW);   // Stick relays to start the generator
    delay(500);                  // Time to start the generator
    digitalWrite(relay4, HIGH);  // Unstick relays to start the generator
    delay(500);
    // Decompressor
    myServo2.write(180);        // Decompressor
    delay(1000);                // Time to decompress
    myServo2.write(70);         // Go back to its place
    delay(10000);                // Delay for it to reach 180V
    // Various
    float voltage = zmpt.getRmsVoltage();  // Library for countries with 110V, so multiply by 2
    float realvoltage = voltage * 2;
   
   // If the generator throws voltage, update control variable to TRUE
   if(realvoltage > success_start_voltaje){
      Serial.println("El voltaje es mayor a 180");
       if(realvoltage < overload_start_voltaje){
          Serial.println("El voltaje es menor a 280, por lo tanto se da como exitoso");
          blink_light_control = false;
          generator_control = true;           // Update Control Variable since the generator is ON
          digitalWrite(relay16, LOW);         // Generator Light on
          Serial.println("Successful Startup");
       }else{
            blink_light_control = false;
            generatorbrake(); 
            Serial.println("Error: Startup Failed, voltage greater than 280V");
       }
   }else{
       blink_light_control = false;
       generatorbrake(); 
       Serial.println("Error: Startup Failed, voltage less than 180V");
  }

   if(generator_control == true){
          digitalWrite(relay8, LOW);    // Connect Battery Power
          digitalWrite(relay6, LOW);    // Battery Charging Light
          digitalWrite(relay5, LOW);    // Light DO NOT USE WELDER (On)
          battery_charging_control = true;
  }
     delay(1000);
}

void generatorbrake(){
    if (shutdown_counter < max_shotdowns_trys){
    Serial.println("Shutdown is being executed");

    digitalWrite(relay8, HIGH);            // Disconnect Battery Power
    battery_charging_control = false;       // Update Control Variable
    digitalWrite(relay6, HIGH);            // Battery Charging Light OFF
    digitalWrite(relay5, HIGH);            // Welding Light OFF
    delay(1000);

    myServo1.write(90);                    // Disconnect diesel
    delay(11000);                          // Delay for the Generator to stop, and then update, or not, the control variable  

    float voltage = zmpt.getRmsVoltage();  // Library for countries with 110V, so multiply by 2
    float realvoltage = voltage * 2;       // "         "     "     "      "     "   "          "   
    
    shutdown_counter++;         // Increment the Shutdown counter        

    if(realvoltage < success_start_voltaje){
      generator_control = false;
      digitalWrite(relay16, HIGH);          // Generator Light Off
      Serial.println("Generator Off");
    }else{
      Serial.println("Error: Tried to Turn Off, did not turn off, so it tries again");
      generatorbrake();
    }

    digitalWrite(relay2, HIGH);            // Release Contact
    digitalWrite(relay3, HIGH);            // Release Contact
    digitalWrite(relay5, HIGH);            // Welding Light Off
    }else{
      limitExceeded();
    }
    
  }

  void limitExceeded(){
    Serial.println("The limit of executions has been exceeded. Blocking...");
     while (true) {
      Serial.println("Reset");
      digitalWrite(relay7, LOW);   // Reset Light ON
      digitalWrite(relay5, HIGH);  // Welding Light OFF
      digitalWrite(relay6, HIGH);  // Battery Light OFF
      digitalWrite(relay16, HIGH);  // Generator Light OFF
      int valueI3 = analogRead(I3);
      int estadoI3 = (valueI3/1023)*5;
       if(estadoI3 > high_state){
         digitalWrite(relay7, HIGH);  // Reset Light OFF
         delay(100);
         asm volatile ("  jmp 0");    // Jump to the beginning of the program
       }
    }
  }

void data(){
  // Voltage Sensor 220V
  float voltage = zmpt.getRmsVoltage(); // Library for 110V countries, so multiply by 2
  float realvoltage = voltage * 2.182333490788852;
  // Analog data storage in variables
  int valueI1 = analogRead(I1);
  int valueI2 = analogRead(I2);
  int valueI3 = analogRead(I3);
  int value24vdc = analogRead(SVB);
  // Voltage and/or Switch state calculation
  float estadoI1 = (valueI1 / 1023.0) * 5.0;
  float estadoI2 = (valueI2 / 1023.0) * 5.0;
  float estadoI3 = (valueI3 / 1023.0) * 5.0;
  float estado24vdc = (value24vdc / 1023.0) * 25.0;

  Serial.println("/////////////////////////");
  Serial.print("Generator: ");
  if (generator_control > 0){
    Serial.println("On");
  } else {
    Serial.println("Off");
  }
  Serial.print("AutomaticLoad: ");
  if (automatic_load_control > 0){
    Serial.println("On");
  } else {
    Serial.println("Off");
  }
  Serial.print("Batteries: ");
  if (battery_charging_control > 0){
    Serial.println("On");
  } else {
    Serial.println("Off");
  }
  Serial.print("Welder: ");
  if (welder_control > 0){
    Serial.println("On");
  } else {
    Serial.println("Off");
  }
  Serial.println("/////////////////////////");
  Serial.print("Switch 1: ");
  Serial.print(estadoI1);
  Serial.println("V");
  Serial.print("Switch 2: ");
  Serial.print(estadoI2);
  Serial.println("V");
  Serial.print("Switch 3: ");
  Serial.print(estadoI3);
  Serial.println("V");
  Serial.print("Sensor 24VDC: ");
  Serial.print(estado24vdc);
  Serial.println("V");
  Serial.print("Sensor 220VAC: ");
  Serial.print(realvoltage);
  Serial.println("V");
}

void deadstate(){
  digitalWrite(relay8, HIGH); // Battery charging contactor
  delay(500);
  // Various
  myServo1.write(90);    // Diesel unplug
  myServo2.write(70);    // Decompressor
  // Relay Off
  digitalWrite(relay1, HIGH);  // Dead
  digitalWrite(relay2, HIGH);  // Contact
  digitalWrite(relay3, HIGH);  // Contact
  digitalWrite(relay4, HIGH);  // Start
  digitalWrite(relay5, HIGH);  // Light
  digitalWrite(relay6, HIGH);  // Light
  digitalWrite(relay7, HIGH);  // Light
  // Relay 8 does not turn off as it is later turned on to indicate an error
  digitalWrite(relay16, HIGH); // Light
  // Global control variables set to FALSE
  bool ControlDeGenerador = false;
  bool ControlSoldadora = false;
  bool ControlCargaBaterias = false;
  bool ControlCargaAUTOMATICA = false;
}


Su publicacion se MUEVE a su ubicacion actual ya que es mas adecuada.

1 Like

Tu programa da errores de compilación. Además de corregirlos, te recomiendo que habilites en la configuración del IDE la opción de ver los avisos del compilador. Hay algunos a los que hay que poner atención.

Los corriges y luego le seguimos.

1 Like

Gracias por avisar! ya lo volvi a subir corregido

Cada vez que modifiques tu código debes postearlo de nuevo. Si lo modificas in situ los comentarios que quedan en este track pierden sentido. Para la próxima...


Esto es incorrecto. El compilador te lo avisa. El programa se compila porque técnicamente no es un error, pero el caso es que una variable tipo char solamente puede almacenar un carácter, no 4 como en este caso.


Aquí hay otro caso. Tampoco es un error desde el punto de vista del compilador, pero una variable tipo int no puede almacenar un valor tan grande.

Ejecuta este pequeño programa para comprobarlo:

const int max_time_for_5_starts = 300000;
void setup() {
	Serial.begin(115200);
	Serial.print("El valor de max_time_for_5_starts es ");
	Serial.println(max_time_for_5_starts);
}

void loop () {
	// aqui no hacemos nada
}

Tu variable debe ser tipo long (de preferencia, unsigned long)


Estos son avisos que da el compilador cuando configuras tu IDE para verlos al momento de compilar, tal como te sugerí en mi primer post...

La division dará como resultado cero, en el mundo de los enteros. Usa 1023.0 como divisor.

Tu programa requiere de un replanteamiento general, sobre todo para hacerlo más simple. Lo simple es más fácil de entender y de modificar. Un enfoque de máquinas de estado (finite state machine) te sería útil.

Por ejemplo, este trozo de código es un loop infinito:

  blink_light_control = true;
  while (blink_light_control == true) {
    digitalWrite(relay5, LOW);    // Light
    digitalWrite(relay6, LOW);    // Light
    digitalWrite(relay7, LOW);    // Light
    digitalWrite(relay16, LOW);   // Light
    delay(1000);
    digitalWrite(relay5, HIGH);    // Light
    digitalWrite(relay6, HIGH);    // Light
    digitalWrite(relay7, HIGH);    // Light
    digitalWrite(relay16, HIGH);   // Light
    delay(1000);
  }

Si no te queda claro entonces debes empezar por hacer programas más simples.

Otro ejemplo:

    if (generator_control == false && battery_charging_control == false  && welder_control == false && automatic_load_control == false) {
      if (estado24vdc < low_batery_voltaje && welder_control == false && generator_control == false && automatic_load_control == false && welder_control == false) {

El segundo if tiene una condición innecesariamente compleja. Ambos if pueden quedar así:

    if (!generator_control && !battery_charging_control  && !welder_control && !automatic_load_control) {
      if (estado24vdc < low_batery_voltaje) {

Lo cual todavía me parece demasiado complejo.

Y esto rompe todos los paradigmas de la programación estructurada y facilita la aparición de errores inesperados:

      asm volatile ("  jmp 0");    // Jump to the beginning of the program

Muchas gracias por tomarte el tiempo de corregirme todos estos errores, soy novato en esto, pero voy aprendiendo de a poco, ya subire el codigo mejorado ni bien lo tenga!

Aqui va el codigo con unas cuantas mejoras implementadas. Que compilador usas? ya que en el arduini IDE no puedo encontrar esa configuracion sobre advertencuas de compilador. Desde ya que muchas gracias

#include <Servo.h>
#include <ZMPT101B.h>
ZMPT101B zmpt(A1);      // 220V Sensor
Servo myServo1;         // Gasoil
Servo myServo2;         // Decompressor
int execution_counter = 0;               // Execution Counter
int shutdown_counter = 0;                // ShutDowns Counter
bool generator_control = false;          // Generator Control
bool welder_control = false;             // Welder Control
bool battery_charging_control = false;   // Charge Of Batteries
bool automatic_load_control = false;     // Automatic Load Batteries
char data_order = '+';                   // Letter to request information
char received = Serial.read();           // Data received in serial port
const int success_start_voltaje = 180;   
const int overload_start_voltaje = 280;  
const int low_batery_voltaje = 22.5;
const int high_batery_voltaje = 24;
const int minimun_welder_voltaje = 20;   
const int max_starts_trys = 5;          
const int max_shotdowns_trys = 5;   
const int high_state = 4; //Swich ON State   
const int SVB = A0;       // 24VDC Voltage Sensor
const int I1 = A2;        // Switch to turn on the generator
const int I2 = A3;        // Switch to turn on the welder
const int I3 = A4;        // Switch to restart
const int relay2 = 25;    //Relay2
const int relay3 = 27;    //Relay3
const int relay4 = 29;    //Relay4
const int relay5 = 31;    //Relay5
const int relay6 = 33;    //Relay6
const int relay7 = 35;    //Relay7
const int relay8 = 37;    //Relay8
const int relay16 = 41;   //Relay16
unsigned long max_time_for_5_starts = 300000; 
unsigned long timeStart;    

void setup() {
  Serial.begin(9600);   // Serial Communication
  myServo1.attach(8);   // Gasoil Pin 
  myServo2.attach(2);   // Decompressor Pin 
  digitalWrite(8, LOW);
  digitalWrite(2, LOW);
  pinMode(I1, INPUT);   // Start Switch
  pinMode(I2, INPUT);   // Welder Switch
  pinMode(I3, INPUT);   // Restart Switch     
  pinMode(SVB, INPUT);  // DC 24V Voltage Sensor
  pinMode(relay2, OUTPUT);    // Generator Start
  pinMode(relay3, OUTPUT);    // Generator Start
  pinMode(relay4, OUTPUT);    // Generator Start
  pinMode(relay5, OUTPUT);    // Welding Light 
  pinMode(relay6, OUTPUT);    // Battery Light
  pinMode(relay7, OUTPUT);    // Reset Light  
  pinMode(relay8, OUTPUT);    // Battery Contactor
  pinMode(relay16, OUTPUT);   // Generator Light
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, HIGH);
  digitalWrite(relay4, HIGH);
  digitalWrite(relay5, HIGH);
  digitalWrite(relay6, HIGH);
  digitalWrite(relay7, HIGH);
  digitalWrite(relay8, HIGH);
  digitalWrite(relay16, HIGH);
  timeStart = millis();  // Save the start time
}

void loop() {
  unsigned long tiempoActual = millis();  // Get the current time
  // Check if 5 minutes have passed (300,000 milliseconds)
  if (tiempoActual - timeStart >= max_time_for_5_starts) {
    execution_counter = 0;
    shutdown_counter = 0;
    timeStart = tiempoActual;
  }

  if (execution_counter < max_starts_trys && shutdown_counter < max_shotdowns_trys) {
  float voltage = zmpt.getRmsVoltage(); // Library for countries with 110V, so multiply by 2
  float realvoltage = voltage * 2.182333490788852;
  int valueI1 = analogRead(I1);
  int valueI2 = analogRead(I2);
  int valueI3 = analogRead(I3);
  int value24vdc= analogRead(SVB);
  int estadoI1 = (valueI1/1023.0)*5.0;
  int estadoI2 = (valueI2/1023.0)*5.0;
  int estadoI3 = (valueI3/1023.0)*5.0;
  int estado24vdc = (value24vdc/1023.0)*25.0;
  
  /*Standby State*/
  if(automatic_load_control == false && battery_charging_control == false && welder_control == false && generator_control == false){
    Serial.println("Standby State ""+ for info");
  }else{
    if (Serial.available() > 0) {
    if (received == data_order) {
        data();
    }
  }
  }
  /*Emergency BUTTON*/
  if(estadoI3 > high_state){
      limitExceeded_Emergency();
  }

  /*Control to start the generator*/

   if(generator_control == false &&  automatic_load_control == false){
     if(estadoI1 > high_state){
                   generatorstart();
       }
     }else{
        if(generator_control == true && automatic_load_control == false){
           if((estadoI1 < high_state && welder_control == false)){
                  Serial.println("Error: Braked by switch");
                   generatorbrake();
                }else{ 
                  if(welder_control == false && generator_control == true){
                    if (realvoltage < success_start_voltaje){
                    Serial.println("Error: Braked by 220v Sensor");
                    generatorbrake();
                  }    
                }         
              }
           }
     }

  /*CONTROL WHEN WELDING IS USED*/
  
   if(welder_control == false){
    if (generator_control == true && estadoI2 > high_state){
            digitalWrite(relay8, HIGH);    // Disconnect Battery Power
            digitalWrite(relay6, HIGH);    // Battery Charging Light OFF
            digitalWrite(relay5, HIGH);    // Welding Light OFF (To be able to use it)
            battery_charging_control = false;  // Control Variable
            welder_control = true;             // Control Variable
            Serial.println("Using Welder");
    }}else{
      if(estadoI2 < high_state && welder_control == true){
          welder_control = false; 
          digitalWrite(relay8, LOW);    // Connect Battery Power
          digitalWrite(relay6, LOW);    // Battery Charging Light ON
          digitalWrite(relay5, LOW);    // Welding Light ON (To NOT use it)
          Serial.println("Leaving Welder Switch");
          battery_charging_control = true;
      } else{
        if(realvoltage < minimun_welder_voltaje){
          digitalWrite(relay8, HIGH);   // Disconnect Battery Power
          battery_charging_control = false; // Control Variable
          welder_control = false;     // Control Variable
          Serial.println("Leaving Welder 220v Sensor");
          generatorbrake();
        }
      }
    }

  /*CONTROL WHEN STARTING AUTOMATICALLY*/

  if(generator_control == false && battery_charging_control == false  && welder_control == false && automatic_load_control == false){
    if (estado24vdc < low_batery_voltaje){  
        generatorstart();
        if(generator_control == true){
                automatic_load_control = true;
                Serial.println("The generator was off and turned on to charge the batteries");
        }else{
                Serial.println("Error: The generator was off and attempted to turn on to charge the batteries");
        }
     }
   }else{
    if(estado24vdc > high_batery_voltaje && estadoI1 < high_state && automatic_load_control == true && generator_control == true && welder_control == false){
        generatorbrake(); 
        automatic_load_control = false; 
    }
   }

}else {
        limitExceeded_Emergency();
       }
}
  
void generatorstart(){
    execution_counter++;        // Increment the execution counter
    Serial.println("Starting is being executed");
    digitalWrite(relay2, LOW);  // Key Contact
    digitalWrite(relay3, LOW);  // Key Contact
    // Diesel
    myServo1.write(50);          // Move the servo 50 degrees for startup
    delay(1000);
    //Start
    digitalWrite(relay4, LOW);   // Stick relays to start the generator
    delay(500);                  // Time to start the generator
    digitalWrite(relay4, HIGH);  // Unstick relays to start the generator
    delay(500);    
    // Decompressor
    myServo2.write(180);        // Decompressor
    delay(1000);                // Time to decompress
    myServo2.write(70);         // Go back to its place
    delay(10000);               // Delay for it to reach 180V
    // Various
    float voltage = zmpt.getRmsVoltage();  // Library for countries with 110V, so multiply by 2
    float realvoltage = voltage * 2;
   // If the generator throws voltage, update control variable to TRUE
   if(realvoltage > success_start_voltaje){
      Serial.println("El voltaje es mayor a 180");
       if(realvoltage < overload_start_voltaje){
          Serial.println("El voltaje es menor a 280, por lo tanto se da como exitoso");
          generator_control = true;           // Update Control Variable since the generator is ON
          digitalWrite(relay16, LOW);         // Generator Light on
          Serial.println("Successful Startup");
       }else{
            generatorbrake(); 
            Serial.println("Error: Startup Failed, voltage greater than 280V");
       }
   }else{
       generatorbrake(); 
       Serial.println("Error: Startup Failed, voltage less than 180V");
  }
   if(generator_control == true){
          digitalWrite(relay8, LOW);    // Connect Battery Power
          digitalWrite(relay6, LOW);    // Battery Charging Light
          digitalWrite(relay5, LOW);    // Light DO NOT USE WELDER (On)
          battery_charging_control = true;
  }
}

void generatorbrake(){
    if (shutdown_counter < max_shotdowns_trys){
    Serial.println("Shutdown is being executed");
    digitalWrite(relay8, HIGH);            // Disconnect Battery Power
    battery_charging_control = false;      // Update Control Variable
    digitalWrite(relay6, HIGH);            // Battery Charging Light OFF
    digitalWrite(relay5, HIGH);            // Welding Light OFF
    delay(1000);
    myServo1.write(90);                    // Disconnect diesel
    delay(11000);                          // Delay for the Generator to stop, and then update, or not, the control variable 
    float voltage = zmpt.getRmsVoltage();  // Library for countries with 110V, so multiply by 2
    float realvoltage = voltage * 2;       // "         "     "     "      "     "   "          "   
    shutdown_counter++;                    // Increment the Shutdown counter        
    if(realvoltage < success_start_voltaje){
      generator_control = false;
      digitalWrite(relay16, HIGH);          // Generator Light Off
      Serial.println("Generator Off");
    }else{
      Serial.println("Error: Tried to Turn Off, did not turn off, so it tries again");
      generatorbrake();
    }
    digitalWrite(relay2, HIGH);            // Contact
    digitalWrite(relay3, HIGH);            // Contact
    digitalWrite(relay5, HIGH);            // Welding Light Off
    }else{
      limitExceeded_Emergency();
    }
  }

  void limitExceeded_Emergency(){
    Serial.println("The limit of executions has been exceeded or the emergency swich was used. Blocking...");
    digitalWrite(relay8, HIGH); // Battery charging contactor
    delay(500);
    myServo1.write(90);    // Diesel unplug
    myServo2.write(70);    // Decompressor
    digitalWrite(relay2, HIGH);  // Contact
    digitalWrite(relay3, HIGH);  // Contact
    digitalWrite(relay4, HIGH);  // Start
    digitalWrite(relay5, HIGH);  // Light
    digitalWrite(relay6, HIGH);  // Light
    digitalWrite(relay16, HIGH); // Light
    bool ControlDeGenerador = false;
    bool ControlSoldadora = false;
    bool ControlCargaBaterias = false;
    bool ControlCargaAUTOMATICA = false;
     while (true) {
      Serial.println("Reset // Emergency");
      digitalWrite(relay7, LOW);   // Reset Light ON
      int valueI3 = analogRead(I3);
      int estadoI3 = (valueI3/1023)*5;
       if(estadoI3 > high_state){
         digitalWrite(relay7, HIGH);  // Reset Light OFF
         delay(100);
         break; 
       }
    }
  }

  void data(){
  // Voltage Sensor 220V
  float voltage = zmpt.getRmsVoltage(); // Library for 110V countries, so multiply by 2
  float realvoltage = voltage * 2.182333490788852;
  // Analog data storage in variables
  int valueI1 = analogRead(I1);
  int valueI2 = analogRead(I2);
  int valueI3 = analogRead(I3);
  int value24vdc = analogRead(SVB);
  // Voltage and/or Switch state calculation
  float estadoI1 = (valueI1 / 1023.0) * 5.0;
  float estadoI2 = (valueI2 / 1023.0) * 5.0;
  float estadoI3 = (valueI3 / 1023.0) * 5.0;
  float estado24vdc = (value24vdc / 1023.0) * 25.0;

  Serial.println("/////////////////////////");
  Serial.print("Generator: ");
  if (generator_control > 0){
    Serial.println("On");
  } else {
    Serial.println("Off");
  }
  Serial.print("AutomaticLoad: ");
  if (automatic_load_control > 0){
    Serial.println("On");
  } else {
    Serial.println("Off");
  }
  Serial.print("Batteries: ");
  if (battery_charging_control > 0){
    Serial.println("On");
  } else {
    Serial.println("Off");
  }
  Serial.print("Welder: ");
  if (welder_control > 0){
    Serial.println("On");
  } else {
    Serial.println("Off");
  }
  Serial.println("/////////////////////////");
  Serial.print("Switch 1: ");
  Serial.print(estadoI1);
  Serial.println("V");
  Serial.print("Switch 2: ");
  Serial.print(estadoI2);
  Serial.println("V");
  Serial.print("Switch 3: ");
  Serial.print(estadoI3);
  Serial.println("V");
  Serial.print("Sensor 24VDC: ");
  Serial.print(estado24vdc);
  Serial.println("V");
  Serial.print("Sensor 220VAC: ");
  Serial.print(realvoltage);
  Serial.println("V");
}

En cualquier versión de IDE
Menú Archivo/Preferencias

1 Like

Esta es una función recursiva. En términos generales las funciones recursivas deben manejarse con técnicas especiales y controlarse cuidadosamente, y no se recomienda su uso en un programa Arduino por cuestiones de manejo de memoria. Esta función no tiene los controles adecuados y puede generar recursión infinita. Debes reescribir tu programa para que no use funciones recursivas.


Estas líneas no cumplen ninguna función y pueden eliminarse por completo. Lo que me indican es que este programa ha sido víctima de varios intentos de modificación/traducción que se quedaron a medias.

Mi último comentario es que el programa es innecesariamente complejo y difícil de leer. Te recomiendo plantearte el escribirlo desde cero para eliminarte futuros dolores de cabeza.

Si usas el enfoque de FSM (Finite State Machine) tendrás un programa muy sencillo, fácil de leer y de modificar.

Muchisimas gracias, voy a reestructurar el codigo a un enfoque FSM!!, Como ultima consulta quisiera saber que tan peligrosas son las funciones recursivas, ya que en este caso el programa intenta ejecutar el encendido de el generador 5 veces, si las 5 veces fue un intento fallido simplemente el programa se bloquea en un while infinito que la unica manera de salir es usando un interruptor y deverdad que muchas gracias por la paciencia, soy novato en esto!

Por ejemplo esto podria ser peligroso si el timestart se convierte en un valor muy grande?

unsigned long max_time_for_5_starts = 300000; 
unsigned long timeStart;   unsigned long max_time_for_5_starts = 300000; 
unsigned long timeStart;   
timeStart = millis();  // Save the start time
if (tiempoActual - timeStart >= max_time_for_5_starts) {
  execution_counter = 0;
  shutdown_counter = 0;
  timeStart = tiempoActual;
}

Para hacer eso no necesitas recursividad, lo resuelves con un simple for() que ejecute 5 intentos de arranque y del que sales cuando el arranque es exitoso.
Si ninguno es exitoso entonces ejecutas el lazo while ().

La recursividad se usa en otros casos, el mas típico es la serie Fibonacci por citar una, traducido se usa mucho en algoritmos.

Hola como va, le di un enfoque FSM a el codigo, espero tus opiniones acerca de el codigo!(disculpen que el codigo tenga comentarios en español y ingles)

//////////////////
/*Esteban Werner*/
/*Copyright 2024*/
//////////////////
#include <Servo.h>
#include <ZMPT101B.h>
ZMPT101B zmpt(A1);      // 220V Sensor
Servo myServo1;         // Gasoil
Servo myServo2;         // Decompressor
int succes_execution_counter = 0;               // Execution Counter
int succes_shutdown_counter = 0;                // ShutDowns Counter
char data_order = '+';                   // Letter to request information
char received = Serial.read();           // Data received in serial port
float voltage = zmpt.getRmsVoltage();            // Library for countries with 110V, so multiply by 2
float realvoltage = voltage * 2.182333490788852; // Library for countries with 110V, so multiply by 2
const int success_start_voltaje = 180;   
const int overload_start_voltaje = 280;   
const int max_starts_trys = 5;          
const int max_shotdowns_trys = 5;   
const int high_state = 4; //Swich ON State   
const int SVB = A0;       // 24VDC Voltage Sensor
const int I1 = A2;        // Switch to turn on the generator
const int I2 = A3;        // Switch to turn on the welder
const int I3 = A4;        // Switch to restart
int valueI1 = analogRead(I1);
int valueI2 = analogRead(I2);
int valueI3 = analogRead(I3);
int value24vdc= analogRead(SVB);
int estadoI1 = (valueI1/1023.0)*5.0;
int estadoI2 = (valueI2/1023.0)*5.0;
int estadoI3 = (valueI3/1023.0)*5.0;
int estado24vdc = (value24vdc/1023.0)*25.0;
const int relay2 = 25;    //Relay2
const int relay3 = 27;    //Relay3
const int relay4 = 29;    //Relay4
const int relay5 = 31;    //Relay5
const int relay6 = 33;    //Relay6
const int relay7 = 35;    //Relay7
const int relay8 = 37;    //Relay8
const int relay16 = 41;   //Relay16
unsigned long max_time_for_5_starts = 300000; 
unsigned long timeStart;

typedef void (*STATE_HANDLER_T)();    // Defined type to store pointer to a state handler function
//States
void waiting();                //redy                     
void starting();               //redy
void running();                //
void welding();                //
void starting_to_charge();     // 
void emergency_limitexceed();  //redy
//Extra(Instruccions)
void instructions_for_start(); //redy
void instructions_for_stop();  //redy
void data();                   //redy

STATE_HANDLER_T prior_state, state;   // Global variables to store the prior and current states

void setup() {
  Serial.begin(9600);   // Serial Communication
  myServo1.attach(8);   // Gasoil Pin 
  myServo2.attach(2);   // Decompressor Pin 
  digitalWrite(8, LOW); // Initializing Servos in low
  digitalWrite(2, LOW); // Initializing Servos in low
  pinMode(I1, INPUT);   // Start Switch
  pinMode(I2, INPUT);   // Welder Switch
  pinMode(I3, INPUT);   // Restart Switch     
  pinMode(SVB, INPUT);  // DC 24V Voltage Sensor
  pinMode(relay2, OUTPUT);    // Generator Start Relay
  pinMode(relay3, OUTPUT);    // Generator Start Relay
  pinMode(relay4, OUTPUT);    // Generator Start Relay
  pinMode(relay5, OUTPUT);    // Welding Light Relay
  pinMode(relay6, OUTPUT);    // Battery Light Relay
  pinMode(relay7, OUTPUT);    // Reset Light Relay
  pinMode(relay8, OUTPUT);    // Battery Contactor Relay
  pinMode(relay16, OUTPUT);   // Generator Light Relay
  digitalWrite(relay2, HIGH); // Initializing Relays in low
  digitalWrite(relay3, HIGH); // Initializing Relays in low
  digitalWrite(relay4, HIGH); // Initializing Relays in low
  digitalWrite(relay5, HIGH); // Initializing Relays in low
  digitalWrite(relay6, HIGH); // Initializing Relays in low
  digitalWrite(relay7, HIGH); // Initializing Relays in low
  digitalWrite(relay8, HIGH); // Initializing Relays in low
  digitalWrite(relay16, HIGH);// Initializing Relays in low
  timeStart = millis();       // Save the start time
  prior_state = NULL;
  state = waiting;
}
 
void loop() {
  state();
}

void waiting() {
  succes_shutdown_counter = 0;
  //Starting
  if (state != prior_state) {         
    prior_state = state;
  }
  // Perform state tasks
  Serial.println("Waiting State");


  // Check for state transitions
  if (estadoI1 > high_state) { //Starting by switch
    state = starting;
  }
  if (estadoI3 > high_state){  //Emergency switch
    state = emergency_limitexceed;  
  }
  if (estado24vdc < 22.5 ){    //Starting by sensor to charge te batteries
    state = starting_to_charge;
  }

  
  if (state != prior_state) {         // If we are leaving the state, do clean up stuff
    Serial.println("Leaving waiting state now the state is:  ");
  }
}

void starting() {
    // Intentar encender el generador 5 veces
    for (int i = 0; i < 5; ++i) {
      instructions_for_start();
        if (realvoltage > success_start_voltaje) {
            Serial.println( "El generador se ha encendido exitosamente.");
            succes_execution_counter++;
            break; // Salir del bucle for si el intento es exitoso
        }else{
            Serial.println("El generador NO se ha encendido exitosamente, por lo tanto se ejecutara el apagado y se vovlera a intentar encederlo");
            // Before try again, shutdown generator to avoid any problem.
            // It is likely that the sensor that detects that it is on is broken
            // therefore it does not send the signal causing the generator to try 
            // to start again when it is actually already running, which would be a big problem.
            instructions_for_stop(); 
        }
    }
   
   if(succes_execution_counter >= 1){
       state = running;
   }else{
    if (succes_execution_counter == 0) { // Si no hay intentos exitosos, ejecutar el bucle while
        while (true) {
                Serial.println("The limit of startups trys was exceed");
                emergency_limitexceed();
                 if(estadoI3 > high_state){
                   digitalWrite(relay7, HIGH); //Apagar Luz de Error
                   state = waiting;
                 } 
         } 
    }
  }
}

void running(){
  succes_execution_counter = 0;
  if(estadoI1 < high_state ){
    // Intentar apagar el generador 5 veces
    for (int i = 0; i < 5; ++i) {
      instructions_for_stop();
        if (realvoltage < success_start_voltaje) {
            Serial.println("El generador se ha apagado exitosamente.");
            succes_shutdown_counter++;
            break; // Salir del bucle for si el intento es exitoso
        }
    }
  }
   if(succes_shutdown_counter >= 1){
       state = waiting;
   }else{
    if (succes_shutdown_counter == 0) { // Si no hay intentos exitosos, ejecutar el bucle while
        while (true) {
                Serial.println("The limit of shutdowns trys was exceed");
                emergency_limitexceed();
                 if(estadoI3 > high_state){
                   digitalWrite(relay7, HIGH); //Apagar Luz de Error
                   state = waiting;
                 } 
         } 
    }
  }
  
  if(estadoI2 > high_state){
     digitalWrite(relay8, HIGH); //Shutdown contactor
     digitalWrite(relay5, HIGH); //Shutdown welding advisor light
     digitalWrite(relay6, HIGH); //Shutdown chargin baterry light
     state = welding;
  }
}    

void welding(){
  if(estadoI2 < high_state){
     digitalWrite(relay8, LOW); //Start contactor
     digitalWrite(relay5, LOW); //Start welding advisor light
     digitalWrite(relay6, LOW); //Start chargin baterry light
     state = running;
}
}

void emergency_limitexceed(){
    Serial.println("The limit of executions has been exceeded or the emergency swich was used. Blocking...");
    digitalWrite(relay8, HIGH); // Battery charging contactor
    delay(500);
    myServo1.write(90);    // Diesel unplug
    myServo2.write(70);    // Decompressor
    digitalWrite(relay2, HIGH);  // Contact
    digitalWrite(relay3, HIGH);  // Contact
    digitalWrite(relay4, HIGH);  // Start
    digitalWrite(relay5, HIGH);  // Light
    digitalWrite(relay6, HIGH);  // Light
    digitalWrite(relay16, HIGH); // Light
    digitalWrite(relay7, LOW);   // Reset Light ON
}

void starting_to_charge(){
   starting();
   if(state == running && estado24vdc > 24){
    // Intentar apagar el generador 5 veces
    for (int i = 0; i < 5; ++i) {
      instructions_for_stop();
        if (realvoltage < success_start_voltaje) {
            Serial.println("El generador se ha apagado exitosamente.");
            succes_shutdown_counter++;
            break; // Salir del bucle for si el intento es exitoso
        }
    }
  
   if(succes_shutdown_counter >= 1){
       state = waiting;
   }else{
    if (succes_shutdown_counter == 0) { // Si no hay intentos exitosos, ejecutar el bucle while
        while (true) {
                Serial.println("The limit of shutdowns trys was exceed");
                emergency_limitexceed();
                 if(estadoI3 > high_state){
                   digitalWrite(relay7, HIGH); //Apagar Luz de Error
                   state = waiting;
                 } 
         } 
    }
  }
     
   }
}

void instructions_for_start(){
    Serial.println("Starting is being executed");
    digitalWrite(relay2, LOW);   // Key Contact
    digitalWrite(relay3, LOW);   // Key Contact
    myServo1.write(50);          // Move the servo 50 degrees for startup
    delay(1000);
    digitalWrite(relay4, LOW);   // Stick relays to start the generator
    delay(500);                  // Time to start the generator
    digitalWrite(relay4, HIGH);  // Unstick relays to start the generator
    delay(500);    
    myServo2.write(180);         // Decompressor
    delay(1000);                 // Time to decompress
    myServo2.write(70);          // Go back to its place
    delay(10000);                // Delay for it to reach 180V
}

void instructions_for_stop(){
    Serial.println("Shutdown is being executed");
    digitalWrite(relay8, HIGH);            // Disconnect Battery Power
    digitalWrite(relay6, HIGH);            // Battery Charging Light OFF
    digitalWrite(relay5, HIGH);            // Welding Light OFF
    delay(1000);                           
    myServo1.write(90);                    // Disconnect diesel
    delay(11000);                          // Delay for the Generator to stop
}

void data(){
  Serial.println("/////////////////////////");

  Serial.print("Generator: ");
  if (state == running){
    Serial.println("On");
  } else {
    Serial.println("Off");
  }

  Serial.print("AutomaticLoad: ");
  if (state == starting_to_charge){
    Serial.println("On");
  } else {
    Serial.println("Off");
  }

  Serial.print("Batteries: ");
  if (state == starting_to_charge || state == running){
    Serial.println("On");
  } else {
    Serial.println("Off");
  }

  Serial.print("Welder: ");
  if (state == welding){
    Serial.println("On");
  } else {
    Serial.println("Off");
  }

  Serial.println("/////////////////////////");
  Serial.print("Switch 1: ");
  Serial.print(estadoI1);
  Serial.println("V");
  Serial.print("Switch 2: ");
  Serial.print(estadoI2);
  Serial.println("V");
  Serial.print("Switch 3: ");
  Serial.print(estadoI3);
  Serial.println("V");
  Serial.print("Sensor 24VDC: ");
  Serial.print(estado24vdc);
  Serial.println("V");
  Serial.print("Sensor 220VAC: ");
  Serial.print(realvoltage);
  Serial.println("V");
}

Tu programa ha mejorado mucho con ese nuevo enfoque y es más fácil de leer y de modificar.

Tengo algunos comentarios:

  1. Estas instrucciones deben ejecutarse dentro de loop() para que sus valores estén actualizados:

  1. Estas instrucciones me preocupan de manera especial:

...

...

El único caso en que estadoI1 (que es un tipo int) tiene un valor superior a high_state es cuando valueI1 es exactamente igual a 1023, ya que a pesar de que la aritmética se hace con decimales, éstos se pierden al almacenar el resultado en la variable. Desconozco los detalles de tu aplicación, pero creo que conviene revisar a detalle esta situación.


  1. La construcción de este while implica que es un ciclo infinito. Viendo las instrucciones que se ejecutan dentro del ciclo tengo al duda de si realmente esa es tu intención:

Y el segundo if está de más, ya que si no se cumplió la condición del primero siempre se cumplirá la del segundo, considerando que la variable succes_execution_counter nunca se hace negativa.


  1. En esta versión suprimiste la lógica que determina si hay una sobrecarga (voltaje>280). Es solamente una observación, considerando que no hay más detalles sobre tu proyecto.

Hay otra áreas de oportunidad en el programa, pero creo que hay que considerar primero las que señalo aquí.

Observacion 1:

Cito de float Arduino.cc
The float data type has only 6-7 decimal digits of precision. That means the total number of digits, not the number to the right of the decimal point. Unlike other platforms, where you can get more precision by using a double (e.g. up to 15 digits), on the Arduino, double is the same size as float.
6 o 7 digitos de precisioón.
Si quieres como en tu caso 15 digitos usa double no float.
Corrige no solo eso sino todas las operaciones involucradas o redondea a 7.
2.18233349
luego sigue el 0 asi que no cambia mucho, vamos un paso mas, 2.1823334907 lo que seria un redondeo en 2.182333491 tampoco cambia mucho.

Observación 2 (al margen):
Se supone que esto corresponde a un generador que no tiene arranque eléctrico o si lo tiene? En las instrucciones para start pareciera que tienes un arranque electrico.

void instructions_for_start() {
  Serial.println("Starting is being executed");
  digitalWrite(relay2, LOW);  // Key Contact
  digitalWrite(relay3, LOW);  // Key Contact
  myServo1.write(50);         // Move the servo 50 degrees for startup
  delay(1000);
  digitalWrite(relay4, LOW);   // Stick relays to start the generator
  delay(500);                  // Time to start the generator
  digitalWrite(relay4, HIGH);  // Unstick relays to start the generator
  delay(500);
  myServo2.write(180);  // Decompressor
  delay(1000);          // Time to decompress
  myServo2.write(70);   // Go back to its place
  delay(10000);         // Delay for it to reach 180V
}

Esto podria ser acción de cebado

myServo1.write(50);         // Move the servo 50 degrees for startup

Esto si que no me gusta.

  delay(10000);         // Delay for it to reach 180V

Porque no poner algo que mida la tensión y al alcanzar 180V durante X tiempo entonces si lo das por conseguido.
Por lo que veo viene del código base en inglés.

Moderador:
He movido el tema a Proyectos por considerarlo interesante y que tiene buen seguimiento de la comunidad.
Por favor mejora la información con los esquemas electricos/electrónicos que dispongas.
No necesitan ser profesionales. Mano alzada bien prolijo es suficiente.

Gracias por la observacion de el float!, lo redondeare mas. Efectivamente el generador tiene arranque electrico y esta el la problematica que me llevo a este proyecto:




Problemática :
La problemática es la siguiente, el cliente se encuentra en una localización remota, donde no tiene acceso a él tendido el eléctrico, por lo tanto cuenta con un equipo fotovoltaico el cual no es capaz de mantener los electrodomésticos de la casa en continuo funcionamiento(Esto debido al mal cálculo de las baterías de el que realizó dicha instalación).
Por otro lado debido a su trabajo cuenta con una soldadora la cual siempre ha usado con un generador eléctrico el cual obtuvo desde antes de la instalación del sistema fotovoltaico.
Por lo tanto debido a la problemática planteada y el alto costo de la instalación de nuevas baterías para tener un sistema fotovoltaico que cumpla los requisitos, y teniendo a disposición el generador, el cliente desea desarrollar un sistema de carga automático para las baterías del sistema fotovoltaico, además de poder continuar usando el generador para sus trabajos de soldadura sin afectar a las baterías del sistema fotovoltaico.
Dada la problematica:
Se llego a la conclusion de que se desarrollaria un sistema el cual detecte el voltaje constantemente de las baterias de el sistema fotovoltaico, y que cuando este sea bajo, el generador se encederia solo automaticamente para cargar dichas baterias hasta que lleguen a un voltaje aceptable, a el mismo tiempo cuando este sistema automatico no este funcionando, mediante un interruptor podria encenderce el generador, al encenderse mediante el interrutor automaticamente cargaria las baterias para no desperdiciar combustible y en caso de querer soldar se presionaria un interruptor que frenaria la carga de las baterias (ya que las soldadoras generan armonicos entre otras cosas) por eso opte por separar dichas funciones.
Hardware:
-Sensor 25vdc para las baterias
-Sensor 220V para saber si el generador encendio correctamente
-Arduino atmega
-Contactor para controlar la carga de las baterias
-x2 Servos de 12kg de torque

Entre otras cosas no tan importantes.

Debo agregar que el codigo que subi inicialmente funciona perfectamente, pero es verdad que era muy desprolijo y que podria traerme problemas con la memoria de el arduino, por lo tanto ahora me encuentro desarrollando este codigo con enfoque FSM, asique aprecio mucho sus consejos! Estare trabajando en el codigo y lo volvere a subir mediante este hilo.

Me faltan agregar medidas de control a el codigo anteriormente proporcionado, parece sencillo pero verdaderamente es mas complejo de lo que parece, tanto en software como hardware(por la vibracion y temperatura de el generador), y con lo que respecta a software no soy ni mucho menos una persona experimentada, pero hacer un sistema de deteccion en timpo real con la baja calidad de los sensores lo vi algo complejo, prefiero darle un enfoque mas sencillo, si el voltaje es major a 180, esta encendio, si es menor algo malo esta ocurriendo y debes apagarlo y volver a intentar prenderlo. Pero como e dicho falta derrollo aun! muchas gracias por tomarse el tiempo de leer esto