Conocer porcentaje bateria de 12V

Buenos dias a todos!
Estoy trabajando en un proyecto en el que estoy utilizando una bateria de 12V.
Para el proyecto debo conocer el porcentaje de bateria que me queda, para ello he realizado un divisor de tension con resistencias de 4.7 y 6.8k omhios, y del punto medio extraigo una entrada analogica a mi Arduino micro, pero tengo varias dudas con la parte de programación porque quiero saber el porcentaje real.
Este es el codigo que tengo hecho hasta ahora.

float voltios;
int bateria;
void setup() {
long espera=10000;
long previousMillis = 0;

}
void leer_voltios()
{

voltios= (analogRead(A4))*0.004887585533*1.446808511;
bateria= map (voltios,0,7.23,0,100);
}
void loop() {
  // put your main code here, to run repeatedly:

}

Cualquier ayuda me vendria muy bien, muchas gracias de antemano!

No entiendo por qué tomas como nivel máximo de batería 7.23V si la que usas es de 12V...

Yo haria lo siguiente

float voltios;
int bateria;
void setup() {
long espera=10000;
long previousMillis = 0;

}
void leer_voltios()
{
int lectura= analogRead(A4);
voltios= lectura * 12.0 / 1024;
bateria= map (lectura,0,1023,0,100);
}
void loop() {
  // put your main code here, to run repeatedly:

}

Te explico el cálculo de voltios porque parece que faltaran cosas

0.00488... viene de 5Vref / 1024
La constante para llevar la lectura de 5V a 12V es 12V/5V
Entonces
voltios= lectura * (5/1024) * (12/5)
Simplificando
voltios= lectura * 12 / 1024

O visto de otro modo, sería la lectura por el coeficiente de un hipotético Vref de 12V.

Edito: En el código multiplico por 12.0 para que el resultado sea float, sino sería una operación entre enteros y no te daría los decimales.

Saludos

Hola gatul, muchas gracias por responder.
Entonces por lo que he entendido en tu respuesta, el porcentaje de la bateria lo puedo obtener directamente mapeando la señal de entrada del divisor de tension de 0-100?
Lo veo demasiado simple no? O es asi de sencillo?

Es así de sencillo y te explico.
Vos el valor que podés leer y trabajar es el del ADC, de 0 a 1023. Ok?

No importa que es lo que conectaste a la entrada, un divisor de tensión, una banana con 2 electrodos, una pila o nada, el ADC siempre te va a dar un valor entre 0 y 1023.

En el caso de de querer conocer el voltaje es lógico hacer la conversión, pero siempre se hace en base a ese valor entre 0 y 1023.

Pero en el caso del porcentaje, no tiene sentido hacer la conversión porque no va a variar, porque en realidad trabajas con el valor del ADC, cualquier otro cálculo es sobrecarga sin sentido.

Lo que haces con map() es decirle al arduino: "agarra la lectura, que va de 0 a 1023, y pasala a un valor que esté entre 0 y 100". O sea, porcentaje.

La función map() es una ventaja para simplificar las cosas

Supongamos que tenes una lectura de 512

bateria= map(512,0,1023,0,100)

bateria toma el valor 50

Pero si la lectura la pasas a voltaje, como hiciste vos, el 512 te daria 6V (calculando para 12V, obvio)
Entonces

bateria= map(6,0,12,0,100)

Y otra vez bateria tiene el valor 50!
Se entendió?

Saludos

Hola gatul, si entiendo lo que quieres decir, pero en mi caso yo esos 12V los necesito para que esten alimentando constantemente dos motores y sus respectivos controladores.
Entonces si la tension de entrada baja de 12V a 6V por ejemplo no funcionaria el motor porque no la alimentacion no es suficiente no?
Por eso lo que necesitaria es saber el porcentaje de bateria para el funcionamiento del motor, que supongo que deberá ser cuando el voltaje disminuye de 12V a 11V o algo por ese estilo...
Muchas gracias por toda tu atencion! Un saludo :smiley:

Entonces lo que necesitas es definir los valores para que estén acordes con la batería que vas a usar.

Por ejemplo, una batería de plomo/ácido de 12V nominales está al 100% cuando mide 12.6V o más, al 75% con 12.4V, al 50% con 12.1V, al 25% con 11.9V y por debajo ya está descargada y "para tirar" (fuente: Varta)

Nota: Tené presente que, en el caso de las baterías de plomo/ácido, si bien podes medir 11V y suponer que sirve, lo que no va a tener es corriente suficiente y en cuanto pongas una carga rápidamente va a caer la tensión.

Sigamos, verás que la curva de descarga no es lineal pero vamos a suponer que lo es y que cada 25% de caida baja 0.2V
Entonces, 100% =12.6V; 0% = 11.8V (lo que es mas o menos cierto)

Ahora voy a suponer que ponés la batería completamente cargada.
En estas condiciones el ADC te daría
1023 para el equivalente a 12.6V que te genere el divisor (deberias calcularlo para que de 5V) y 958 para 11.8V
Entonces

bateria = map(lectura, 958,1023,0,100);

Y listo, así vas a obtener el % de carga adaptado a la batería de plomo/ácido.

Como ves hay que hacer un poco de investigación para que las cosas salgan. :wink:

Saludos

Edito: en realidad para que la cosa funcione habría que hacer algunas modificaciones (fijate que la batería al 100% tiene 12.6V o más) la intención es darte una idea de como podes usar map() de acuerdo a tus necesidades.

Hola
Hay otras 2 cosas a tener en cuenta con las baterias de plomo si se carga durante la medición:
La carga se realiza a 14.2 o 14.3. Por tanto hay que tener en cuenta ese voltaje en el arduino. Normalmente yo lo programo para 15V.
El mantenimiento de carga de un cargador "normalito" es a 13.7 o 13.8. Ídem en lo del voltaje.

Yo suelo poner como limite de voltaje los 11.99V.

Saludos

Excelente observación @bosoft
Me di cuenta que como ese detalle lo tenía en mente pero decidí omitirlo para no complicarla, probablemente no fui claro en la explicación.
¡Gracias!

Hola Bosoft y Gatul, muchas gracias por vuestra atencion y siento mucho responder tan tarde.
Entonces por lo que he leido, tengo que realizar el mapeo desde 13.8V (lo pongo como maximo porque al estar cargando mientras funciona no se va a poder descargar) una vez cargada de forma completa como limite de 100% de porcentaje (adaptado a 5V) y de 11.99 como descarga completa (0 %).

Entonces quedaria:
100%-----13.8 V
75%------13.3475 V
50%------12.895 V
25%------12.4425 V
0%-------11.99 V

Para 1023 seria 13.8 de voltaje y cargada completamente o cargando.
Para 888 seria 11.99 de voltaje y descarga completa de la bateria.

Faltaria sacar la relacion para 5V.
En el divisor de tension con dos resistencias, una de 6800 y otra de 4700, tendria Vin 13.8 que corresponderian a 5.64 V
Para Vin 11.9 seria 4.9 V.
No se si estoy en lo cierto, pero lo he entendido asi

NO.
El mapeo es hasta 14.2 (o mejor 15V para proteger el arduino).
Y el % seria algo como esto
100%-----12,8 V
0%-------11.99 V
En cuanto dejes de cargar y sin tener consumo, el nivel baja hasta 12.8 - 12.6. El nivel de 0% podría ser hasta 11.50, pero puede fastidiar la batería.
Todo lo que supere 12.8 sería 100% cargando.

Para mi es mejor saber el voltaje. El rango del % no le veo sentido en las baterías de plomo

Saludos

Te respondo en orden de importancia.

NO! No puedes poner más de 5V a una entrada ADC. Tienes que calcular el divisor para que como máximo tenga 5V. De otro modo vas a arruinar la placa.

Una batería no está al 100% cuando mides 13.8V, cuando mides 13.8V es porque está en carga y mides lo que entrega el cargador. Jamás en una batería pb-acido de 12V puedes medir 13.8V
El 100% es 12.6V.
Haz un divisor con 8.2k y 4.7k (calculado para 15V como aconseja @bosoft).
Para 12.6V vas a tener unos 4.6V, el ADC te dará alrededor de 940.
Para 11.9V tendrás unos 4.3V, 855 de lectura.
Entonces

if(lectura > 940) lectura = 940; // fija el tope 100%
bateria = map(lectura, 855, 940, 0, 100);

Se entiende la idea?

Ah vale!
De acuerdo, creo que ya lo he entendido, el valor de 15 V es por prevención y cuando desarrolla un voltaje de 12.6 es que esta cargado al 100% y por encima de ese valor significa que esta cargando.

El porcentaje necesito saberlo porque el proyecto debe ser autónomo y las baterias van dentro de su infraestructura y por eso necesito saber la capacidad de carga que le quedan a las baterías, ya que cuando este funcionando no pueden estar cargándose.

Lo he programado como tu me has comentado gatul, cuando lleguen los diseños de los PCB que he pedido lo probaré y espero que funcione! Muchisimas gracias por vuestra ayuda y vuestra pronta atención y respuesta!
Un saludo :smiley:

No he hecho comentario porque opino lo mismo que @bosof y @gatul, el % no tiene sentido.
Seria conveniente para ti y para tu comprensión futura que muestres ambas cosas, % ya que es importante en esta etapa y tensión para que vayas asociando los valores con el % que te resulta cómodo en este momento.
Con el tiempo veras con cual te quedas.

A pesar de que después fuimos desarrollando el asunto, mi comentario inicial fue para que notara que, aunque calculase y usase el voltaje para otra cosa, no tenía sentido enredarse usando map() con voltajes para calcular el % cuando en realidad siempre está trabajando con los valores devueltos por el ADC, además evita arrastrar errores por redondeo o por precisión.
Después se puso más interesante. :wink: