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.
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.
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); }
Comentarios
Publicar un comentario