Protección baterías

Hola compañeros!
mejorando el proyecto y refrescando la memoria con millis, me puse a arreglar un problema que me a surgido con mi sistema de placas solares y baterías para mi huerto hidropónico

refresco un poco:
el Arduino me sirve para decir que batería trabaja y cuanto tiempo estar funcionando con chequeos de tensión, cogiendo de A o B según tensión leída o tiempo pasado mediante millis.

Tengo dos placas solares, dos mppt y dos baterías, así me ahorro conectar baterías en paralelo ya que son de diferentes amperios y se acabarían estropeando.

Bien me encuentro que los mppt ( controladores de carga de las baterías) cuando la batería tiene poca carga, solo que se cargue un poco va haciendo intermitencias on/off continuadas lo cual perjudica las baterías hasta que se quedan sin carga, lo cual estresa a todo el sistema y perjudica la vida de la baterías.

Entonces ahora he intentado que cuando detecte que los mppts cortan corriente el arduino bloquee con un relé la salida a "field", y así proteger todo el sistema del on/off continuado por el mppt

Mi idea es solida y le he metido cabeza al tema, pero la programación la llevo floja y es fácil poner algo mal y que no funcione como quieres(aunque la compilación sea exitosa), así que creo que he metido algo mal y no acaba de funcionar correctamente el tema.
adjunto programación:

const int sensorPinA = A0; // seleccionar la entrada para el sensor
const int sensorPinB = A2; // seleccionar la entrada para el sensor
const int LED = 13; //contador?
int sensorValueA;          // variable que almacena el valor raw (0 a 1023)
int sensorValueB;          // variable que almacena el valor raw (0 a 1023)

float valueA;              // variable que almacena el voltaje (0.0 a 25.0)
int releA = 8;             //salida 8
float valueB;              // variable que almacena el voltaje (0.0 a 25.0)
int releB = 7;             //salida 7
int releC = 4;             //salida 4
int contar=0; //contador
int cont= contar;// imprimir

unsigned long timbat1off = 0;
unsigned long timeStart;
bool disparado = false;     // flag en NO disparo

void setup()
{
  Serial.begin(9600);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(4, OUTPUT);
 
}
void loop()
{digitalWrite (releC, HIGH); // control salida corriente hay?¿
{
  sensorValueA = analogRead(sensorPinA);           // realizar la lectura
  valueA = fmap(sensorValueA, 0, 1023, 0.0, 25.0); // cambiar escala a 0.0 - 25.0
  Serial.print("ValueA: ");
  Serial.println(valueA); // mostrar el valor por serial
 
  sensorValueB = analogRead(sensorPinB);           // realizar la lectura
  valueB = fmap(sensorValueB, 0, 1023, 0.0, 25.0); // cambiar escala a 0.0 - 25.0
  Serial.print("ValueB: ");
  Serial.println(valueB); // mostrar el valor por serial
  }

  if (valueA >= 12.0)   {
      digitalWrite(releA, LOW); // salida NC relé
      digitalWrite(releB, LOW); // salida NC relé
      
      Serial.print ("BAT A ON-->");
      }
 
  if (valueA < 11.8)   {
      if (!disparado) {
          digitalWrite(releA, HIGH); // salida NO relé
          digitalWrite(releB, HIGH); // salida NO relé
          disparado = true;          // solo lo disparo 1 vez
          timbat1off = millis();     // comienzo a contar el tiempo
          Serial.print ("BAT B ON-->");
      } 
      if (millis()- timbat1off> 10000000UL) { // cuando se cumpla el tiempo habilito el flag para prepararlo de nuevo
        disparado = false;}  
if (valueB <8.00 && valueA < 8.00) { ///si hay interrupción
contar = contar+1 ; //contar +1
Serial.println(cont);}//imprimir cont para ver contaje
else if (contar= 5); { ///si se cumple contar= 5
digitalWrite (releC,LOW); //cambio rele off
digitalWrite(LED, HIGH); //testigo 13
Serial.print ("PROTECCION ACTIVADA BAT OFF-->");///aviso bat off
delay(6000); //144000000 ///tiempo de espera
contar = 0 ; ///poner contar a 0 reseteo contar
digitalWrite(LED, LOW);} // testigo 13 se apaga
}}
float fmap(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

no se si he colocado correctamente las sentencias o { corchetes, y acaba funcionando que cuando A me baja de tensión, el relé C me corta sin tener en cuenta el contaje o voltaje de B... la función es cuando los dos están bajos corta.

Aunque pongo que me imprima el contaje siempre lo veo a 0, no veo que sume en ningún momento, el Else tampoco se si esta bien puesto ya que es la opción que pasa si -->contaje llega a 5 se ejecuta esa sentencia...

  • hardware utilizado
  • un Arduino
  • 3 relés
  • 2 sensores de voltaje

Gracias por vuestro tiempo
saludos!

Un par de errores que paso a describir

Primero un código debidamente identado para que pueda leerse.

void loop()
{ digitalWrite (releC, HIGH); // control salida corriente hay?¿
  {
    sensorValueA = analogRead(sensorPinA);           // realizar la lectura
    valueA = fmap(sensorValueA, 0, 1023, 0.0, 25.0); // cambiar escala a 0.0 - 25.0
    Serial.print("ValueA: ");
    Serial.println(valueA); // mostrar el valor por serial

    sensorValueB = analogRead(sensorPinB);           // realizar la lectura
    valueB = fmap(sensorValueB, 0, 1023, 0.0, 25.0); // cambiar escala a 0.0 - 25.0
    Serial.print("ValueB: ");
    Serial.println(valueB); // mostrar el valor por serial
  }

  if (valueA >= 12.0)   {
    digitalWrite(releA, LOW); // salida NC relé
    digitalWrite(releB, LOW); // salida NC relé

    Serial.print ("BAT A ON-->");
  }

  if (valueA < 11.8)   {
    if (!disparado) {
      digitalWrite(releA, HIGH); // salida NO relé
      digitalWrite(releB, HIGH); // salida NO relé
      disparado = true;          // solo lo disparo 1 vez
      timbat1off = millis();     // comienzo a contar el tiempo
      Serial.print ("BAT B ON-->");
    }
    if (millis() - timbat1off > 10000000UL) { // cuando se cumpla el tiempo habilito el flag para prepararlo de nuevo
      disparado = false;
    }
    if (valueB < 8.00 && valueA < 8.00) { ///si hay interrupción
      contar = contar + 1 ; //contar +1
      Serial.println(cont);
    }//imprimir cont para ver contaje
    else if (contar = 5); { ///si se cumple contar= 5
      digitalWrite (releC, LOW); //cambio rele off
      digitalWrite(LED, HIGH); //testigo 13
      Serial.print ("PROTECCION ACTIVADA BAT OFF-->");///aviso bat off
      delay(6000); //144000000 ///tiempo de espera
      contar = 0 ; ///poner contar a 0 reseteo contar
      digitalWrite(LED, LOW);
    } // testigo 13 se apaga
  }
}

usa AutoFormato o CTRL+T
image
Detalle al margen.

Primera linea del loop

digitalWrite (releC, HIGH); // control salida corriente hay?¿

ya me hace ruido!!. En cada loop apagas ese rele. Tu sabras por qué pero ya lo veo mal

disparado tarda 10000 seg o sea 2:46:40 en reponerse, eso esta bien?

Esto si esta mal

if (contar = 5); {

debe ser

if (contar == 5) {

Otro detalle menor pero detalle al fina
Defines fmap como

float fmap(float x, float in_min, float in_max, float out_min, float out_max)

pero le envias dos enteros

valueA = fmap(sensorValueA, 0, 1023, 0.0, 25.0);

modifa a

float fmap(int x, int in_min, int in_max, float out_min, float out_max)
{
  return ((float) x -(float) in_min) * (out_max - out_min) / (float) (in_max - in_min) + out_min;
}

muchas gracias @Surbyte, ok arreglado con autoformat
primera linea, quizás no esta bien explicada

digitalWrite (releC, HIGH); // control salida corriente hay?¿ <- simplemente cierra para tener voltaje

bien ese relé lo necesito encendido, solo empezar(rele puedo utizar NC(normalmente cerrado) o NA( normalmente abierto), necesito que el NA se quede activo(cerrado), porque?¿ si se queda sin energía la batería , se quedara en NA, cortara corriente directamente, dejando en NC y sin salida (en si solo tendrá salida en NA) el contaje evitara los on/off continuos.

el disparo dejo alrededor de 2 horas para que la batería a o b cargue

el fmap, ya me daba a mi que le meto dos valores y quizás daba problemas, aun así los calcula por separado cada uno bien con sus cambios, no le di mas ojo a esto, quizás es el problema..

he probado y sigue igual si bajo voltaje de A me entra el ELSE IF <-
tampoco veo el contaje
PROTECCION ACTIVADA BAT OFF-->ValueA: 0.15
ValueB: 0.10
0
PROTECCION ACTIVADA BAT OFF-->ValueA: 0.12
ValueB: 0.00
0
PROTECCION ACTIVADA BAT OFF-->ValueA: 0.10
ValueB: 0.00
0
PROTECCION ACTIVADA BAT OFF-->ValueA: 0.10
ValueB: 0.00
0
Antes de entrar en el else if, no debería hacer el conteo?
copio programación arreglada

const int sensorPinA = A0; // seleccionar la entrada para el sensor
const int sensorPinB = A2; // seleccionar la entrada para el sensor
const int LED = 13; //contador?
int sensorValueA;          // variable que almacena el valor raw (0 a 1023)
int sensorValueB;          // variable que almacena el valor raw (0 a 1023)

float valueA;              // variable que almacena el voltaje (0.0 a 25.0)
int releA = 8;             //salida 8
float valueB;              // variable que almacena el voltaje (0.0 a 25.0)
int releB = 7;             //salida 7
int releC = 4;             //salida 4
int contar=0; //contador
int cont= contar;// imprimir

unsigned long timbat1off = 0;
unsigned long timeStart;
bool disparado = false;     // flag en NO disparo

void setup()
{
  Serial.begin(9600);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(4, OUTPUT);
 
}
void loop()
{ digitalWrite (releC, HIGH); // control salida corriente hay?¿
  {
    sensorValueA = analogRead(sensorPinA);           // realizar la lectura
    valueA = fmap(sensorValueA, 0, 1023, 0.0, 25.0); // cambiar escala a 0.0 - 25.0
    Serial.print("ValueA: ");
    Serial.println(valueA); // mostrar el valor por serial

    sensorValueB = analogRead(sensorPinB);           // realizar la lectura
    valueB = fmap(sensorValueB, 0, 1023, 0.0, 25.0); // cambiar escala a 0.0 - 25.0
    Serial.print("ValueB: ");
    Serial.println(valueB); // mostrar el valor por serial
  }

  if (valueA >= 12.0)   {
    digitalWrite(releA, LOW); // salida NC relé
    digitalWrite(releB, LOW); // salida NC relé

    Serial.print ("BAT A ON-->");
  }

  if (valueA < 11.8)   {
    if (!disparado) {
      digitalWrite(releA, HIGH); // salida NO relé
      digitalWrite(releB, HIGH); // salida NO relé
      disparado = true;          // solo lo disparo 1 vez
      timbat1off = millis();     // comienzo a contar el tiempo
      Serial.print ("BAT B ON-->");
    }
    if (millis() - timbat1off > 10000000UL) { // cuando se cumpla el tiempo habilito el flag para prepararlo de nuevo
      disparado = false;
    }
    if (valueB < 8.00 && valueA < 8.00) { ///si hay interrupción
      contar = contar + 1 ; //contar +1
      Serial.println(cont);
    }//imprimir cont para ver contaje
    else if (contar == 5); { ///si se cumple contar= 5
      digitalWrite (releC, LOW); //cambio rele off
      digitalWrite(LED, HIGH); //testigo 13
      Serial.print ("PROTECCION ACTIVADA BAT OFF-->");///aviso bat off
      delay(6000); //144000000 ///tiempo de espera
      contar = 0 ; ///poner contar a 0 reseteo contar
      digitalWrite(LED, LOW);
    } // testigo 13 se apaga
  }
}
float fmap(int x, int in_min, int in_max, float out_min, float out_max)
{
  return ((float) x -(float) in_min) * (out_max - out_min) / (float) (in_max - in_min) + out_min;
}

saludos y gracias por tu tiempo :slight_smile:

Hi,
Si yo entiendo tu problema es que cuando el voltaje de los mppt baja entonces la bateria se descargan. Si esto es el problema entonces puedes anadirle un diodo que conecte el mppt a la bateria. Esto evita que cuando el voltaje del mppt baje del voltaje de la bateria el diode desconecta la bateria y evita que se descarque. Puedes hacer una prueba para ver si te resuelve tu problema. Digo si yo entendi tu problem correctamente.

Hola @tauro0221 gracias por tu respuesta, ok explico el mppt
tiene entrada de placas solares, salida a baterías, donde carga y recoge y salida a field...
el diodo ya pensé en el.... pero, ojo como lo pones... si es dirección a batería cargaras pero no cogerás energía, además de que el mppt revisa carga constantemente, lo cual perdería esa lectura y podría estar cargando eternamente...quemamos batería... si va hacia el mppt, no cargara batería
gracias por tu idea, pero en este caso no me sirve.
lo suyo es cortar el field cuando empieza a generar esos cortes y eso es lo que quiero conseguir con el arduino :slight_smile:

Yo no he sugerido nada porque no entiendo el planteo.
Dos conjuntos Placa -MPPT-Bateria.
Lees valueA y valueB y decides con un rele sobre tu carga real, es así?
No entiendo nada de esto, porque haces un control sobre 11.8 y 12 de valueA y no lo haces con valueB del mismo modo?

Hi,
El diode se conecta con el catodo hacia la bateria. No entiendo cuando dices que no cogera energia. Porque dices eso ya que cuando el voltaje del anodo es mas arriba del catado vaz a cargar la bateria ya que una vez que conduce el diode la perdida atravez del diodo va a ser de .3 a .4 voltios. Como vez el diodo practicamente funciona como un switche o mejor dicho como un relay. El proposito del diodo es prevenir que la bateria se descarque hacia el MPPT.

¿Y cómo mide el mppt el nivel de batería si el diodo bloquea la corriente?

Saludos

Hi,
Segun yo entiendo el problema es que cuando el panel solar no suple suficiente voltaje la bateria se descarga atravez del MTTP. El quire resolver el problema usando un relay que el energize/de-gernize cuando el voltaje del MTTP es mas bajo.Esto es lo que yo entendi. Esto me esta raro que la bateria se descargue atravez del MTTP cuando no hay luz solar.

Si, a mi tampoco me termina de cerrar el problema que nos cuenta, se supone que el mttp no tendría que deteriorar las baterías, al margen de eso, el mttp tiene que sensar la batería y el diodo lo impediría.

Saludos

Hola!
@anon90500195, @tauro0221 @Surbyte
El tema del diodo no es posible, el mppt carga y recibe energía por la misma entrada, un diodo bloquea carga de la batería o alimentación de esta, los diodos me pueden servir en salida como protección alas baterías de cortocircuitos en field.

Son mppt sencillos de 20A máximo, el problema que la carga va rápida, lo cual detecta un voltaje correcto pero el amperaje cae.. cuando el field lo coge de golpe, por eso genera ese on/off repetido.

he estado dándole vueltas creo que lo mas sencillo es un relé en la salida de 12v a field, si abre o cierra me dará un contaje al arduino sin tener que hacer lectura de ninguna batería y modificando solo un poco la programación.
saludos!!!

Hola @Surbyte
son dos placas de 100v cada una de hay se reparten en dos mppt, los mppt solo demandan o dejan pasar según estado de baterías a field, mientras la placas dan energía suficiente carga batería y da energía a campo, cuando cae la energía de las placas el mppt coge de la batería para field.
realmente solo necesito controlar una batería ya que cuando A esta baja cogerá de B, y se ira intercalando hasta que A y B estén a poca energía, hay es cuando tengo que cortar para preservar que la batería no se descargue del todo por eso meto retardos largos, evito que entren en cambio constante sin que cargue lo suficiente.
como ves solo tengo que monitorear una la otra solo me da info adicional de estado.

O sea, que solo quieres hacer algo que le de energia a field (como tu dices) segun la tensión.
Si es asi porque tienes criterios diferentes para A y B?
El criterio deberia ser el mismo.
Si una bateria esta descargada pues que se cargue y eso lo hace el MPPT.
Tu solo decides de donde derivas energia a field.
Ahora bien... derivas de 1 o de otra hasta cuando? Acá es donde no entiendo, quieres volver a hacer lo mismo que hace el MPPT? Porque el MPPT carga la bateria pero tambien la protege, entonces cuantas veces vas a proteger la batería y con que criterio.
Resumiendo.
Para mi tienes dos fuentes de energia A y B
Si A es > B alimentas con A y si no con B hasta que no se pueda mas pero eso no lo decides tu, lo decide el MPPT que corresponde a esa batería. Si en el proceso A se recupera y quieres cambiar a A, bueno... y dejas que B se recupere. Asi puedes estar jugando todo el tiempo pero usando el mismo criterio en ambas.

Hi,
No dices el modelo del MTTP que usas pues creo que lo que esta ocuriendo puede ser que el MTTP esta programado para hacer lo que estas sucediendo en tu systema. El MTTP puede cargar la bateria y a la misma vez suplir voltaje a la carga. Ahora si la bateria baja el voltaje entonces el MTTP desconecta la carga y carga la bateria. Una vez la bateria esta cargada entonces vuelve y conecta la bateria.Mi sugerencia es de que incluya el modelo de MTTP que usa para ver la expecificaciones del MTTP .

Justamente por eso, porque quiere trangredir de algun modo lo que hace un MPPT (Maximum Power Point Tracker) es que le sugiero que solo mire tensiones y decida donde se carga usando los reles y mientras el segundo sistema se recupera, pero mas que eso no creo que pueda hacer.

Hola!
@Surbyte @tauro0221
El mppt es marca china , con programación muy sencilla, no puedo tocar mas parámetros que el tipo de batería y poco mas.

mppt

según programación coge A hasta que A baja, de hay coge de B , creo que esta en b dos horas y chequea A si esta bien coge de A otra vez (carga B) y así repetidamente, hasta que no carga A, si chequea A dejara otras horas en B y así hasta que A y B estén bajas.

de hecho cargas y tal lo hace el MPPT , yo solo controlo quien da energía a field mediante los relés, siempre que una batería este inactiva por relés se estará cargando por mppt

el problema del MPPT es ese "on/off" repetido en la salida de FIELD, ese paso no lo cumple, abre y cierra el field, de hecho el mppt cumple bien su función, pero no tiene carga suficiente para el field, y eso genera este percance, además que este estado me estresa baterías, bombas y otros elementos que controlan el Field y es lo que no quiero, ya que me genera averías.

estoy montando una caja con voltímetros y amperímetros y dos mppts nuevos como el del link para controlar cada batería y ver que pasa, el conteo seria algo fácil ya que si alimento un relé de 12v en cada salida de field y van haciendo clicks de A y B el arduino puede detectar "anomalía" y cerrar field, aun tengo que mirarlo bien.
Os voy informando :slight_smile:
muchas gracias por vuestro tiempo

Hi,
Los cotes que son causados por MPPT que problemas causan al el equipo conectado de la DC del MTTP. No Se si estoy pidiendo demaciado pero seria beneficioso que hagas un schematico de como tienes conectados los modulos que usas en el systema para asi tener una mejjor idea de como solucionar el problema que estas experimentando.

Hola @tauro0221 !
me causan daños en las bombas ya que al hacer un off/on continuo hasta que se queda sin energía, ya he tenido que cambiar 2 o 3 bombas de agua en un periodo de meses, ademas de un controlador de velocidad de la bomba se quemo :frowning:
hay va el circuito no todo es lo correcto pero se entiende, no tengo software para hacerlo mejor.


el problema esta en cuando la batería esta baja y el sol se esta yendo, solo que recoja un pico de energía abre field y genera este percance.
en la siguiente imagen veras que hace:
VID20220509203206 (1)
veras batería descargada, coge algo de energía abre field que es la bombilla, se descarga y vuelta a empezar...
también puede ser que no estén bien, los que he comprado nuevos son actualizados... a ver que hacen
gracias por tu tiempo

Ok. Al menos para mi empieza a tener mas color la comprensión del problema.

Por lo que se ve en el video, hace falta garantizar que la acción de uno u otro MPPT se corresponda con una bateria en condiciones.
El problema que yo veo es que pasas de un sistema que esta en vacío (12.6v) viniendo de otro que esta cargado y agotado digamos a 10.7 (aunque este dato no es el mismo).
El sistema en vacio claramente luce como que tiene una bateria que tomó carga (lease tensión de 12.6V como en el video) pero claramente es falso porque lo hizo en vacío. Al ponerlo a trabajar el sistema no puede soportarlo y se desploma.

hola @Surbyte
Durante el video solo esta en marcha la batería A sin arduino,(no habia control de nada mppt a bateria A) no tiene nada que ver el programa(no estaba funcionando), ese es el problema del mppt directo, eso es lo que hace, cuando lo controlo con el programa aguanta horas sin ese problema , hasta que cae la tarde/noche hay es donde debo cortar antes que empiece el problema.
de hecho el programa lo estoy mejorando para evitar que se desplome y pase eso en las dos :slight_smile: