Medidor de Cargas Baterías LI-PO

Esquema proto board

El funcionamiento es muy sencillo . Arduino lee por la entrada analógica A0 el voltaje que tiene la batería, y lo compara con la referencia de 5V , que es a la que él trabaja , mostrando dicho voltaje por el display LDC.

Así mismo , hace un cálculo del porcentaje de carga de dicha batería , en base a que plena carga (4..2V) nos dará el 100% y a 3.2V la carga será del 0%.

Estos valores vienen porqueestas baterías a plena carga arrojan un valor de 4.2V y durante su uso , el voltaje de las mismas no debe caer por debajo de 3.2V pues se pueden ir dañando y mermar sus capacidades. Se puede modificar el valor de carga mínima con tan solo modificarlo en el sketch.

Para un control a simple vista, se utilizan tres LEDs de colores verde , amarillo  y rojo. El primero estará encendido hasta una carga del 40% . A partir de ahí se encenderá el amarillo hasta que carga sea del 10% en el que se enciende el rojo , indicándonos que pronto habrá que recargar la batería.

Igualmente , estos porcentajes se pueden modificar en el sketch y darles otros rangos.

El potenciómetro lo utilizamos como offset (ajuste de voltaje) . El proyecto está ideado para alimentarlo con una fuente externa de 5V, como puede ser un cargador de móvil y un cable modificado para alimentar la protoboard con esos 5V. De esta manera , alimentamos a Arduino y al display LCD.
Muestra la medida de voltaje

Como los cargadores o fuentes no siempre entregan 5v exactos , y pueden oscilar entre 4.85V y 4.90V (tambien 5.3V). Arduino estará alimentado por ese voltaje , y su ADC (conversor analógico digital) también , y hará la conversión en base a ese voltaje, no a 5v. Pero en el sketch haceos el cálculo en base a 5v y debemos corregir esa diferencia.

Para eso usamos el potenciometro  y seleccionando entre un rango de valores predeterminado podemos ajustar esa diferencia, con la ayuda de un multímetro. Una vez ajustado , ya no es necesario mientras usemos la misma fuente de alimentación.

El condensador de 100uF le he colocado para estabilizar un poco la tensión de alimentación , y evitar demasiadas fluctuaciones.

En esta foto se muestra la precisión comparado con un multímetro. Se puede observar que para la fuente de alimentación utilizada, el offset se estableció en 42.

COnfirmando con la medida del voltimetro

El programa de Control

/* Sensor de voltaje para baterías Li-Po de una celda (1S).
   * Se toma el voltaje de la batería a través de la entrada A0.
   * Se muestra el voltaje y el porcentaje de carga por un display LCD I2C 1602
   * Además, tenemos tres LEDs que se van encendiendo dependiendo de la carga.
   * verde = hasta 40%
   * amarillo = hasta
   *   4.2 = 100% (máximo voltaje, máxima carga)
   *   3.2 = 0%   (mínimo voltaje de seguridad)
   *  
   * IMPORTANTE: La tensión que entra por USB o por el pin de 5V (Nano),
   * afecta a la precisión, ya que ésta puede ser difente de 5.0V en algunos mV.
   * El ADC utiliza el voltaje de alimentación como voltaje de referencia.
   * Utilizamos un potenciómetro para regular el voltaje de offset, y regular
   * la precisión, con la ayuda de un multímetro.
   *
   *
   * Por Suso. 19/04/2016
   */

  #include <LiquidCrystal_I2C.h>
  #include <Wire.h>
    /* Funcion de configuracion de pines del modulo 
       LCD/I2C (Direccion,en,rw,rs,d4,d5,d6,d7,backlight,polaridad)
    */

  LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
  byte pinV=A0; // Para leer el voltaje
  byte ledR=12; // LED rojo
  byte ledA=11; // LED amarillo
  byte ledV=10; // LED verde  

  float voltaje=0.0;
  int medida=0;
  int porcent=0;
  int pinOffset=A1;
  float offset=0.0;
  int valorPot = 0;

  unsigned long tAntes =0; // para el refresco de pantalla
  unsigned long tAhora =0;
  unsigned long tEjec =10000;

  void setup() 
     { lcd.begin(16,2); // inicializamos el LCD.
       lcd.backlight(); // encendemos la retroiluminación.
       pinMode(ledR, OUTPUT);
       pinMode(ledA, OUTPUT);
       pinMode(ledV, OUTPUT);
       Serial.begin(9600);
       digitalWrite(ledR, LOW);
       digitalWrite(ledA, LOW);
       digitalWrite(ledV, HIGH);
     }

void loop() 
    { tAhora = millis();              // Comprobamos para refrescar el LCD
      if( tAhora - tAntes >= tEjec)
        {  // cada 10 segundos
           tAntes = tAhora; // actualizamos variables
           lcd.clear();     // Refrescamos
        }

    medida = analogRead(pinV); // Leemos voltaje de la batería
    valorPot = analogRead(pinOffset); //Leemos ajuste de offset
    int ajuste = map (valorPot, 0,1023,60,5); // Mapeamos a un rango más corto

/* Podemos jugar con los dos últimos valores de la función map. Cuanta más diferencia
   haya entre ellos, menos precisión tendremos con el potenciómetro.
   El valor más grande es para voltajes más lejanos de 5V. El más pequeño para
   las fuentes muy cercanas a 5V. Así, con una fuente de 4.90V el valor de offset será
   de 9 ó 10.
*/

offset = (ajuste/100.0);
lcd.setCursor(12,1);
lcd.print (offset);
voltaje= ((((medida*5.0)/1023.0))- offset); // Convertimos a valor con decimales
if (voltaje<=0)
   { // Si es menor o igual a cero
     voltaje=0.0;  // Le damos valor 0, para evitar negativos
   }

porcent=((voltaje*100)-320); // Fórmula para mostrar el porcentaje de carga
if(porcent<=0)
   { // Evitamos valores negativos
     porcent=0;
   }

// Condicionales para encender los LEDs
if(porcent>=41)
  {  digitalWrite(ledR, LOW);
     digitalWrite(ledA, LOW);
     digitalWrite(ledV, HIGH);
  }

if(porcent<41 && porcent>10)
  {  digitalWrite(ledR, LOW);
     digitalWrite(ledA, HIGH);
     digitalWrite(ledV, LOW);
  }

if(porcent<=10)
  {  digitalWrite(ledR, HIGH);
     digitalWrite(ledA, LOW);
     digitalWrite(ledV, LOW);
  }

lcd.setCursor(0,0);
lcd.print("Voltaje: ");
lcd.print(voltaje);
lcd.print("V");
lcd.setCursor(0,1);
lcd.print("Carga: ");
lcd.print(porcent);
lcd.print("%    ");

//Descomentar para mostrar por monitor serial.
//Serial.print(medida); Serial.print("   ");
//Serial.print(voltaje);Serial.print("   ");
//Serial.print(porcent); Serial.println("%");

delay(1000);
}

Prototipo de medidor


Comentarios