Indicador de nivel bajo de batería LiPo 2s con Arduino

Hola, estoy haciendo un indicador basado en arduino para no dañar una batería LiPo de dos celdas, cada una de 3.7V, cuando alguna de estas celdas disminuye por debajo de 3.3 V la batería puede dañarse. Para ello utilizo el conector de tres pines que trae la batería:
Uno de los pines va directamente a una celda, otro es la suma de las dos, y el último es GND. Para medir la tensión en la primera celda es sencillo y se hace directamente, para medir la tensión en la segunda celda utilizo un divisor de tensión, puesto que arduino no admite 7.4 V en sus entradas analógicas (es la suma de ambas celdas) y luego mediante el código calculo la tensión en esa celda, multiplicando por dos (el divisor de tensión tiene ambas resistencias iguales por tanto divide la tensión entre dos) y restándole la tensión de la otra celda.
Un pequeño esquema para entenderlo mejor:
Indicador_esquemático.png

El potenciómetro que está conectado a la entrada analógica A2 sirve para ajustar el offset que puede haber debido a que el arduino no proporciona 5V fijos, puede ser 4.98 V o 5.20 V por ejemplo, con este potenciómetro ajustariamos esa diferencia (más adelante en el código se explica).

Los LEDs se encienden en función de la tensión que quede en las celdas, cuando la tensión de una de las celdas baja por debajo de los 3.3 V (zona de peligro) se enciende el LED rojo, también le pondré un zumbador y además el Arduino desactivará el circuito para que no siga conduciendo, por esta razón quiero que sea arduino el que controle la tensión en la batería, ya sé que hay otros circuitos que lo hacen pero a mi me interesa hacerlo con arduino.

Aquí dejo el código comentado:
C++:
#define PinCelda1 A0 //La celda sola, conector de 3.7 V
#define PinCelda2 A1 //Conector 7.4 V pasado por el divisor de tensión.
#define PinOffset A2 //Potenciómetro de 10K mínimo

float VoltiosCelda1=0.0;
float VoltiosCelda2=0.0;

float offset = 0.0;

int LEDR = 12; //Led rojo
int LEDA = 11; //Led amarillo
int LEDV = 10; //Led verde

void setup()
{
  Serial.begin(9600);
  pinMode(LEDR, OUTPUT); //Declaramos como salidas los pines de los leds
  pinMode(LEDA, OUTPUT);
  pinMode(LEDV, OUTPUT);
}


void loop()
{
/*Potenciómetro de 10K para ajustar el offset debido a que el arduino
* no proporciona los 5V perfectos, será un poco más o un poco menos
*/
  float ajuste = map(analogRead(PinOffset),0,1023,-50,50); //Offset negativo o positivo
  offset = (ajuste/100.0);

//Conversión a voltios de las lecturas realizadas en los pines analógicos con la corrección del offset
  VoltiosCelda1 = (analogRead(PinCelda1)*5.0/1023.0-offset);
  VoltiosCelda2 = (analogRead(PinCelda2)*5.0/1023.0-offset);
 
// Calculo del valor de la celda 2
  VoltiosCelda2=(VoltiosCelda2*2)-VoltiosCelda1;

//Mostramos los resultados
  Serial.print("S1 = ");
  Serial.print(VoltiosCelda1);
  Serial.print("V --- S2 = ");
  Serial.print(VoltiosCelda2);
  Serial.print("V ------ ");
  Serial.print("Offset = ");
  Serial.println(offset);

//Encendemos los LEDs en función de la carga de las celdas

  if ((VoltiosCelda1 <= 3.30) || (VoltiosCelda2 <= 3.30)){ //Si alguna de las celdas está por debajo de los 3.3V
      digitalWrite(LEDR, HIGH); //Encender LED rojo
      digitalWrite(LEDA, LOW);
      digitalWrite(LEDV, LOW);

// Si alguna de las celdas está entre 3.3 V y 3.6 V encender el LED amarillo
  }else if (((VoltiosCelda1 > 3.30) && (VoltiosCelda1 <= 3.60)) || ((VoltiosCelda2 > 3.30) && (VoltiosCelda2 <= 3.60))){
      digitalWrite(LEDR, LOW);
      digitalWrite(LEDA, HIGH);
      digitalWrite(LEDV, LOW);

//Si no se da nigún caso de los anteriores, encender luz verde
  }else  {
      digitalWrite(LEDR, LOW);
      digitalWrite(LEDA, LOW);
      digitalWrite(LEDV, HIGH);    
  }
  delay(500);
}

Mi problema es que los valores de la tensión que obtengo varían demasiado, los mido con el voltímetro y dan valores fijos así que no es problema de la batería (en mi caso estoy usando una fuente de alimentación para probar el circuito) además he probado a poner dos seguidores de tensión con el amplificador operacional LM358 por si la impedancia de entrada de los pines analógicos de Arduino no era lo suficientemente elevada, pero aún así obtengo valores demasiado variables:
monitorserial.jpg

Esto no me permite determinar con la exactitud suficiente si la batería está en peligro o no.
En teoría, la precisión de Arduino en las entradas analógicas sería de 5/1023=4.89 mV lo que me debe permitir una precisión de dos cifras decimales en las lecturas de tensión, pero en la realidad no obtengo de forma precisa ni la primera cifra decimal.

¿Alguna idea de cuál puede ser el problema? o ¿Alguna sugerencia de cambio en el circuito u otro circuito simple para conseguir el mismo resultado?

Un saludo.
 
Hola, que longitud de cable hay entre la batería y la entrada al ADC?
La conexión de GND, es correcta? Puede que haya una conexión GND analógica y otra digital!
Usas cables apantallados?
Coloca un filtro RC (resistencia de 1K y un condensador de 10uF) en cada entrada del ADC.
Una prueba antes de realizar cualquier cambio, chequea el funcionamiento del ADC, colocando un divisor resistivo de la propia alimentación, y verifica la estabilidad de las lecturas.
 
Hola, muchas gracias a los dos, ya lo he solucionado, el fallo era de dos cosas:
La alimentación: estaba alimentándolo desde el ordenador y se ve que la conexión entre ambas tierras no era demasiado buena, he optado por alimentarlo todo desde la misma fuente.
Filtro paso bajas: he añadido el filtro paso baja que comentaba Gudino Roberto duberlin con una red RC.
Con estas dos modificaciones los valores que obtengo son estables y fieles a lo que mido con el voltímetro, ni siquiera voy a necesitar ajustar el offset del que hablaba.

Muchas gracias a los dos, un saludo.
Mensaje automáticamente combinado:

Hola de nuevo.
Tengo una nueva duda, ¿Este circuito consume demasiado? ¿Habría alguna forma de activarlo sólo cada x tiempo para evitar este consumo o no merece la pena?
 
Última edición:
Buenas, debido a que no sé exactamente cual es la impedancia de entrada de las entradas analógicas de arduino no puedo hacer el cálculo exacto, no he encontrado por ningún lado el valor, algunos dicen que 100K otros que 100M... además posee una capacidad en paralelo con esta resistencia, pero que en mi caso no importa porque al tratarse de corriente continua el condensador actúa como circuito abierto.
Para estimar el consumo he supuesto el peor de los casos, en el que la resistencia de entrada de los pines de arduino es 100k, tendriamos el siguiente circuito:
cirequivalentye.jpg
La resistencia de 10M y el condensador de 100nF forman el filtro paso baja para eliminar las fluctuaciones en las medidas de las que hablaba al principio.
Para el pin A0 nos quedaría una resistencia de 10M en serie con una de 100k, I = 3.7/(10M+100k)=0.37 uA
Para el pin A1 nos queda abajo en el divisor de tensión la resistencia de 105k en paralelo con 10M+100k, podemos despreciar el efecto de la resistencia más grande, quedándonos con la de 105k, por tanto nos queda el divisor de tensión de dos resistencias de 105k, la corriente sería: I = 7.4/(2*105k)=35.4 uA

Al simular el ciruito comprobamos:
cirequivalentye.jpg
Tenemos los resultados esperados, en total el consumo de corriente sería de 35.77uA, que es poco importante para este caso, la batería es de 5A.
 
Pues yo tampoco sé cuál es la impedancia de entrada. Habrá que leer el datasheet del AT.

Sin leerlo 100k me parecen demasiados 1M absurdo y 10M muy absurdo.
A lo mejor me equivoco pero me suena que andarán por los 30k como mucho.
Si los cables son largos menos.
 
ya sé que hay otros circuitos que lo hacen pero a mi me interesa hacerlo con arduino.
Hola, se trata de un bus teledirigido controlado por Arduino, éste está alimentado por una batería LiPo así que ya aprovecho el mismo para medir el nivel de la batería.
Aunque si podrías decir la forma de hacerlo con un amplificador operacional y así ya sé el circuito por si me hace falta para otra ocasión.
Un saludo.
 
Hay unos cargadores balanceadores de LiPo que además las protegen de sobrecarga , sobreconsumo y desconectan por baja batería , son muy compactos y muy baratos.
 
Hola, se trata de un bus teledirigido controlado por Arduino, éste está alimentado por una batería LiPo así que ya aprovecho el mismo para medir el nivel de la batería.
Aunque si podrías decir la forma de hacerlo con un amplificador operacional y así ya sé el circuito por si me hace falta para otra ocasión.
Un saludo.

usas el operacional en comparador y el voltaje de referencia lo haces con un zener y resistencia y divisores resistivos
 
Última edición:
Atrás
Arriba