Arranque eléctrico de un generador

Hola.
Soy nuevo en el foro. A principios de año entré buscando información para poder hacer mi propio arrancador automático para un generador eléctrico y que posteriormente arrancase una bomba para sacar agua, y encontré una entrada con el mismo título que a día de hoy está cerrada.
La cosa es que me sirvió de poco lo que se comentaba, pero con es fuerzo y ayuda he conseguido desarrollar mi arrancador automático con un arduino UNO y una placa de 4 relés mas un relé conectado a la salida eléctrica de 220v del generador.

La alimentación a la placa de arduino la hago a través un cargador de móvil que está conectado un enchufe programable conectado a la red (placas solares)

La placa de arduino manda una señal al relé 1 que cierra el contacto para que giré el motor de arranque del generador (2,3s) y vuelve abrirse

Una vez que el generador ha arrancado el relé de 220V se cierra y manda una señal a la placa de arduino

Cuando el arduino recibe esta señal hay una espera de 10s para que el motor gire libremente antes de conectar la bomba.

Pasados estos 10s se cierra el relé 2 y pone la bomba en marcha

En el conducto por donde va el agua hay instalado un sensor de flujo el cual manda un señal al arduino para indicar que efectivamente está saliendo agua. En caso de no recibir señal, el arduino inicia la secuencia de apagado (BOMBA - espera - MOTOR)

Transcurrida una hora desde el inicio del loop el arduino inicia la secuencia de apagado: primero abre el relé 2 para desconectar la bomba, después hay un espera de 15s para que el motor y la alternadora giren libremente y finalmente cierra el relé 3 durante 8s para parar el motor del generador.

Luego el enchufe programable se desconecta y se vuelve a conectar al día siguiente.

Como protecciones he puesto un máximo de 3 intentos de arranque y el sensor de flujo.

Espero que esto pueda ayudar a alguien.

Aquí dejo el código:

#define TIEMPO_BUCLE  25000         // queremos 100ms 0,1s x 16000000Hz/64 = 25000 cuentas
#define PIN_SENSOR_FLUJO    2
#define PIN_GENERADOR       3
#define PIN_ON_OFF_BOMBA    4
#define PIN_ARRANQUE_MOTOR  5
#define PIN_PARO_MOTOR      6
#define PIN_LED             13

#define ESTADO_INICIAL            0
#define COMPROBAR_ARRANQUE        1
#define ESPERAR_TENSION_GENERADOR 2
#define ESPERAR_CALENTAMIENTO     3
#define ESPERAR_FLUJO             4
#define FUNCIONAMIENTO_BOMBA      5
#define ESPERAR_ENFRIAMIENTO      6
#define ESPERAR_PARO              8
#define FIN_PROGRAMA              9
#define ERROR_GENERADOR           100
#define ERROR_ARRANQUE            101
#define ERROR_FLUJO               102

#define TIEMPO_ARRANQUE       23    // 2,3s /0,1s 
#define TIEMPO_ESPERA_TENSION 50    // 5/0,1
#define TIEMPO_CALENTAMIENTO  100   // 10/0,1
#define TIEMPO_FLUJO          1800 //1800  // 180/0,1
#define TIEMPO_FUNCIONAMIENTO 36000 // 1800/0,1 = 30min \\ 3600/0,1 = 1h \\ 7200/0,1 = 2h
#define TIEMPO_ENFRIAMIENTO   150   // 15/0,1
#define TIEMPO_PARO           80    // 8S/0,1

#define MAXIMO_NUMERO_ARRANQUE 3
#define MINIMO_PULSOS_FLUJO    50

#define ON_BOMBA            5
#define OFF_BOMBA           6

#define ACTIVAR_PARE        7
#define DESACTIVAR_PARE     8

#define ACTIVAR_RELE        LOW
#define DESACTIVAR_RELE     HIGH

uint8_t contadorTiempoArranque;     // para indicar el tiempo de arranque (2,3s)
uint8_t contadorDeArranque; 
uint8_t contadorTiempoTension;      //  para esperar tension generador
uint8_t contadorTiempoCalentamiento; // para calentamiento motor
uint16_t contadorTiempoFlujo;          // para espera la entrada de flujo de agua
uint32_t contadorTiempoFuncionando;  // para indicar el tiempo que lleva en marcha todo el sistema
uint8_t contadorTiempoEnfriamiento;  // para indicar el tiempo de enfriamiendot del motor desde que se para la bomba
uint8_t contadorTiempoParo;         // para indicar el tiempo de paro del motor (8s)
uint16_t contadorPulsosFlujo;

uint8_t estadoGeneral; 

// función a ejecutarse en cada interrupción
void pulso () 
{
  contadorPulsosFlujo++;
  //Serial.println("pluso flujo");
}

void inicializarVariables(void)
{
   estadoGeneral = ESTADO_INICIAL;
   contadorDeArranque = 0;
}

void configurarPines(void)
{
  pinMode(PIN_ARRANQUE_MOTOR,OUTPUT);   // a relé 1 arranque motor
  pinMode(PIN_GENERADOR,INPUT);        // entrada señal relé 2, para saber si hay corriente en el generador (motor en marcha)
  pinMode(PIN_ON_OFF_BOMBA,OUTPUT);   // a relé 3, para arrancar y parar la bomba
  pinMode(PIN_SENSOR_FLUJO,INPUT);     // señal del sensor de flujo de agua
  pinMode(PIN_PARO_MOTOR,OUTPUT);     // a rele 4, para parar el motor
  pinMode(PIN_LED,OUTPUT);            // led de prueba

  digitalWrite(PIN_ARRANQUE_MOTOR, DESACTIVAR_RELE);// desactivar rele arranque logica inversa
  digitalWrite(PIN_PARO_MOTOR, DESACTIVAR_RELE);    // desactivar rele paro arranque logica inversa
  digitalWrite(PIN_ON_OFF_BOMBA, DESACTIVAR_RELE);  // desactivar rele bomba logica inversa
}
void configurarTimer1(void)
{
  //https://exploreembedded.com/wiki/AVR_Timer_programming 
  
  TCCR1A = 0;
  TCCR1B = 0;
 
  TCCR1B |= (1 << WGM12); // modo CTC el contador pasa a cero automaticamente cada vez que llega al valor del registro de comparacion

  TCNT1  = 0;             //inicializar temporizador a 0
  
  OCR1A = TIEMPO_BUCLE;   //tiempo de bucle 
  
  //CS12 - CS10 = 000: ninguna fuente de reloj TC1 está APAGADA
  //CS12 - CS10 = 001: dividir por 1
  //CS12 - CS10 = 010: dividir por 8
  //CS12 - CS10 = 011: dividir por 64
  //CS12 - CS10 = 100: dividir por 256
  //CS12 - CS10 = 101: dividir por 1024
 
  TCCR1B |= ((1 << CS11) | (1 << CS10)) ;  // poner en marcha el temporizador con 64 prescaler f=16000000/64 = 250000Hz
 
}

void setup() 
{
  configurarPines();
  configurarTimer1();
  inicializarVariables();
  attachInterrupt(digitalPinToInterrupt(PIN_SENSOR_FLUJO),pulso,RISING);
  Serial.begin(115200); // poner en monitor con la misma bps 115200
  Serial.println("setup completo");
}

void loop() 
{
 
  while((TIFR1 & (1<<OCF1A)) == 0); // comprobar si el contador llega al tiempo de bucle
  TIFR1 |= (1<<OCF1A);             //borrar flag del comparador, automáticamente el contador vuelve a 0

  // se ejecuta cada 100ms
  switch(estadoGeneral)
  {
    // TENER EN CUENTA los relés funcionan con lógia inversa
    
    case ESTADO_INICIAL:
    if(digitalRead(PIN_GENERADOR)== LOW) // no está arrancado
    {
      Serial.println("activar rele arranque");
      digitalWrite(PIN_ARRANQUE_MOTOR, ACTIVAR_RELE); // activa el relé de arranque
      contadorTiempoArranque = 0;
      estadoGeneral = COMPROBAR_ARRANQUE;
    }
    else // generador activo
    {
      Serial.println("error generador ya en marcha");
      estadoGeneral = ERROR_GENERADOR;
    }
    break;
    case COMPROBAR_ARRANQUE:
    contadorTiempoArranque ++;
    if(contadorTiempoArranque == TIEMPO_ARRANQUE)
    {
      Serial.println("parar rele arranque");
      digitalWrite(PIN_ARRANQUE_MOTOR, DESACTIVAR_RELE); // cierra el relé de arranque del motor
      contadorTiempoTension = 0;
      estadoGeneral = ESPERAR_TENSION_GENERADOR;    
    }
    break;
    case ESPERAR_TENSION_GENERADOR:
    contadorTiempoTension ++;
    if(contadorTiempoTension == TIEMPO_ESPERA_TENSION)
    { 
      if(digitalRead(PIN_GENERADOR)== HIGH) // hay tension
      {
        Serial.println("esperar calentamiento");
        contadorTiempoCalentamiento = 0;
        estadoGeneral = ESPERAR_CALENTAMIENTO;       
      }
      else // no hay tension
      {
        contadorDeArranque ++;
        if(contadorDeArranque == MAXIMO_NUMERO_ARRANQUE)  
        {
          Serial.println("error arranque");
          estadoGeneral = ERROR_ARRANQUE;       
        }
        else // volvemos a intentar arranque
        {
          Serial.println("arranque fallido");
          Serial.println("activar rele arranque");
          digitalWrite(PIN_ARRANQUE_MOTOR, ACTIVAR_RELE); // activa el relé de arranque
          contadorTiempoArranque = 0;
          estadoGeneral = COMPROBAR_ARRANQUE;          
        }
      }
    }
    break;
    case ESPERAR_CALENTAMIENTO:
    contadorTiempoCalentamiento ++;
    if(contadorTiempoCalentamiento == TIEMPO_CALENTAMIENTO) // encender bomba
    {
      Serial.println("activar bomba");
      digitalWrite(PIN_ON_OFF_BOMBA, ACTIVAR_RELE); // activa el relé de la bomba
      contadorTiempoFlujo = 0;
      
      contadorPulsosFlujo = 0;
      contadorTiempoFuncionando = 0;
      estadoGeneral = FUNCIONAMIENTO_BOMBA; 
    }
    break;
    case FUNCIONAMIENTO_BOMBA:
    contadorTiempoFuncionando ++; // comprobar que sigue habiendo flujo
    contadorTiempoFlujo ++;
    if(contadorTiempoFuncionando < TIEMPO_FUNCIONAMIENTO)
    {
      if(contadorTiempoFlujo > TIEMPO_FLUJO)  // 3 minutos
      {
          Serial.print("pulsos :");
          Serial.println(contadorPulsosFlujo);
          if(contadorPulsosFlujo < MINIMO_PULSOS_FLUJO)
          {
            Serial.println("error flujo bomba, parar bomba");
            digitalWrite(PIN_ON_OFF_BOMBA, DESACTIVAR_RELE);  // no hay flujo parar bomba y generador
            estadoGeneral = ERROR_FLUJO;
          }
          contadorPulsosFlujo = 0;
          contadorTiempoFlujo = 0;       
      }
    }
    else // tiempo funcionamiento superado
    {
      Serial.println("fin funcionamiento bomba");
      digitalWrite(PIN_ON_OFF_BOMBA, DESACTIVAR_RELE);
      contadorTiempoEnfriamiento = 0;
      estadoGeneral = ESPERAR_ENFRIAMIENTO;
    }
    break;
    break; 
    case ERROR_GENERADOR: // no hacer nada, mantener el PIN_ARRANQUE_MOTOR en LOW
    if(digitalRead(PIN_GENERADOR)== HIGH)
    {
        
    }
    break;    
    case ERROR_ARRANQUE: // apagar el sistema
    break;
    case ERROR_FLUJO:
      digitalWrite(PIN_ON_OFF_BOMBA, DESACTIVAR_RELE);
      contadorTiempoEnfriamiento = 0;
      estadoGeneral = ESPERAR_ENFRIAMIENTO;   
    break;
    case ESPERAR_ENFRIAMIENTO:
    contadorTiempoEnfriamiento ++;
    if(contadorTiempoEnfriamiento > TIEMPO_ENFRIAMIENTO)
    {
      digitalWrite(PIN_PARO_MOTOR, ACTIVAR_RELE);
      contadorTiempoParo = 0;
      estadoGeneral = ESPERAR_PARO;
      
    }
    break; 
  case ESPERAR_PARO:
    contadorTiempoParo ++;
    if(contadorTiempoParo > TIEMPO_PARO)
    {
      Serial.println("Fin del programa");
      digitalWrite(PIN_PARO_MOTOR, DESACTIVAR_RELE);
      estadoGeneral =  FIN_PROGRAMA;
      
    }
    break; 
  case  FIN_PROGRAMA:
  break;  
  }  

}

Moderador:
Bienvenido al Foro Arduino en Español.
Por favor, lee las Normas del foro y edita tu código usando etiquetas de código.
Ve a edición, luego selecciona todo el error que has publicado, lo cortas y click en </>


Bueno, el programa luce bien, y solo haría una sugerencia o dos si te parece.
No termino de entender bien la consulta que quieres hacer.
Voy a releer y en todo caso edito.

Pasados estos 10s se cierra el relé 2 y pone la bomba en marcha

Sugerencia 1: 10 segundos pueden ser suficientes o no.
Por que no poner este sensor de Voltaje Corriente Alterna Ac 250v Zmpt101b
image
Ver Sensor
Entonces aquí si te aseguras que el generador entró en régimen y pones en marcha la bomba.

Sugerencia 2. Sacas agua y lo haces por 1 hora. Tiense un flujostato lo que me parece excelente. Pero tal vez llenes el tanque y no necesites seguir bombeando, entonces porque no agregas un medidor de nivel de tanque para detener la acción de la bomba si se cumpliera esta condición? Solo es una sutileza pero tu sistema esta bien implementado y seguramente la recibirás bien, porque suma o no hace falta por una razón que ahora no visualizo.

Gracias por la acogida Surbyte.

Realmente no quiero hacer ninguna consulta, simplemente a portar el código, ya que en mi búsqueda detecté que había mas gente con la misma necesidad que yo, y ya que he podido resolverlo y el sistema funciona (llevo desde mayo usándolo sin problemas) si esas personas dan con este foro puedan usarlo igualmente.

En cuanto a tu primera sugerencia, desconocía totalmente que existía tal dispositivo, pero el que he instalado realiza bien su función.

En cuanto al medidor de nivel en mi caso no es necesario ya que el agua que extrae la bomba lo hace de un pozo natural y las canalizaciones están conectadas directamente al sistema de riego. Pero efectivamente se le podría añadir al sistema.

Son aportes a considerar.
Ejemplo : si todo funcionara con energía limpia (paneles solares) cada Wh es relevante.
El arranque y puesta en régimen si me parece importante, al menos estoy haciendo un control de generador trifásico y uso 3 de esos.

Si tu idea es que quede como aporte, deja algún esquema eléctrico que permita visualizar mejor las cosas. Yo te entiendo pero no todo el mundo lo hará.