Indiquer charge batterie

Bonjour je suis actuellement en Terminale STI2D et j'ai pour projet une serre automatique.
Je suis totalement perdu pour le code sur arduino pour indiquer le % de charge de la batterie ( 7.2V / 3000 mAh NiMH) et si elle se recharge ou pas.
J'aimerais de l'aide car j'ai vu plusieurs topic pour des batteries Lipo mais pas pour des batteries NiMH.

Salut

La tension de la batterie 7.2V (6 éléments de 1.2V) peut être de 8.4V à pleine charge.

Il faut d'abord monter un pont diviseur pour ramener cette tension en dessous de 5V (si tu utilises la référence externe 5V) ou 1.1V (si tu utilises la référence interne 1.1V) , ensuite brancher le point milieu sur un entrée analogique.

Ensuite il faut chercher la courbe de décharge d'une batterie NI-MH, celle du fabricant de préférence s'il la publie.
C'est une courbe qui donne en fonction de la tension le pourcentage de capacité restante.
Il faut relever entre 20 et 40 points sur cette courbe et renseigner une table de structures tension / capacité.

Un exemple pour une LITHIUM-ION de 3.7V :

struct batteryCapacity
{
  float voltage;
  int capacity;
};

const batteryCapacity remainingCapacity[] = {
  4.20,   100,
  4.10,   96,
  4.00,   92,
  3.96,   89,
  3.92,   85,
  3.89,   81,
  3.86,   77,
  3.83,   73,
  3.80,   69,
  3.77,   65,
  3.75,   62,
  3.72,   58,
  3.70,   55,
  3.66,   51,
  3.62,   47,
  3.58,   43,
  3.55,   40,
  3.51,   35,
  3.48,   32,
  3.44,   26,
  3.40,   24,
  3.37,   20,
  3.35,   17,
  3.27,   13,
  3.20,   9,
  3.1,    6,
  3.00,   3,
};

const int ncell = sizeof(remainingCapacity) / sizeof(struct batteryCapacity);

Ensuite une petite fonction pour récupérer la capacité :

#define VREF                  1.099

unsigned int getBatteryCapacity(void)
{
  analogReference(INTERNAL);
  analogRead(0);
  unsigned int adc = analogRead(0);
  Serial.print("ADC: ");
  Serial.println(adc);
  float voltage = adc * VREF / 1023 / 0.248;
  Serial.print("VCC: ");
  Serial.println(voltage, 3);
  for (int i ; i < ncell ; i++){
    Serial.print(i);
    Serial.print(" : ");
    Serial.print(remainingCapacity[i].voltage);
    Serial.print(" | ");
    Serial.println(remainingCapacity[i].capacity);
    if (voltage > remainingCapacity[i].voltage) {
      return remainingCapacity[i].capacity;
    }
  }
  return 0;
}

Cet exemple utilise l'entrée A0 et la référence interne 1.1V.
La valeur de 0.248 dans le code représente le rapport du pont diviseur de tension.
Mon application travaille avec une batterie de 4.2V à pleine charge.

Comme tu utilises une batterie 8.4V, tu dois diviser par 8 cette tension. Cela donnera 1.05V à pleine charge sur l'entrée analogique.
La valeur de 0.248 devra être remplacée par 1/8 c'est à dire 0.125.

La valeur de VREF est 1.099 car je l'ai étalonnée avec un multimètre.

@+

Bonjour il nous faudrait un peu plus d'aide. Nous devons faire un programme qui communique sur le port série le pourcentage de batterie et un message pour 3 pallier (100%<50%) (50%<20%) et (20%<0%) pour une batterie de 7.2V / 3000 mAh NiMH.

Merci bonne journée

Bonjour
hbachetti a détaillé la méthode permettant d'évaluer la charge restante dans une batterie.

il nous faudrait un peu plus d'aide.

La voiçi :
-étudier les tutoriels mentionnés dans les messages épinglés en tête de forum (Règles de Fonctionnement du Forum)
-étudier en particulier les parties qui traitent de la mesure d'une tension
-bâtir un programme et , au besoin revenir içi avec votre programme pour une aide sur un ou plusieurs points particuliers

Le problème c'est que même en forçant on comprends rien

Le code que j'ai posté au #1 te semble t'il incompréhensible ?

@+

Le problème c'est que même en forçant on comprends rien

Sérieux ? Si ce 'rien' couvre le contenu des tutoriels recommandés (celui çi par exemple) je ne vois pas ce que le forum peut faire !!

Commencer par comprendre ce tutoriel , puis, dans un second temps intégrér les idées développée çi-dessus par hbachetti.

regles.jpg

Même en étudiant le programme proposé par hbachetti nous n'y arrivons pas, il faut changer les valeur pour que ça corresponde à une batterie 7.2V c'est bien ça ? Mais ensuite pour afficher les messages par tranches de pourcentage avez vous un exemple, et non le rien signifie que nous avons des bases mais elles sont très pauvres. Merci si vous prenez le temps de répondre

il faut changer les valeur pour que ça corresponde à une batterie 7.2V c'est bien ça ?

Bien entendu. Tu multiplies toutes les valeurs de tension (4.20 à 3.0) par deux.

@+

Merci ! Et du coup aurai tu une solution pour l'affichage par tranche?

  float voltage = adc * VREF / 1023 / 0.248;

Comment calcule t'on la valeur 0.248 dans le code du #1 ?

Le pont diviseur que j'ai utilisé pour mesurer la tension batterie 3.7V (4.2V à pleine charge) est bâti avec deux résistance : 1M et 330K.
Le rapport de division = 1 / ((1000000 + 330000) / 330000) = 0.248

La tension sur la pin analogique sera au maximum de 4.2 * 0.248 = 1,04V
ça passe pile poil sous la barre des 1.1V (tension de référence interne), un peu trop près, je dirais.

Pour mesurer une tension de 7.4V (8.4V à pleine charge), tu peux utiliser un pont de 1M / 150K.
Le rapport de division = 1 / ((1000000 + 130000) / 130000) = 0.115

La tension sur la pin analogique sera au maximum de 8.4 * 0.115 = 0.966V
ça passe bien sous la barre des 1.1V (tension de référence interne)

Il faut que la tension sur la pin analogique soit au moins à 10% en dessous de la tension de référence interne 1.1V.
Avec 0.966V c'est OK.

La référence interne 1.1V se sélectionne comme ceci :

  analogReference(INTERNAL)

Voir code du post #1

J'ai sélectionné la référence dans la fonction getBatteryCapacity(), mais tu peux la déplacer dans la fonction setup().

Dans mon code tu peux remarquer ceci :

#define VREF                  1.099

La valeur de tension de la référence interne 1.1V n'est pas précise (10%). Sa valeur est ajustée dans le code par comparaison entre le résultat mesuré par l'ARDUINO et celui affiché par un multimètre précis.

La valeur de tension de la référence interne 1.1V varie en fonction de la température. Si la température est constante, cela ne pose pas de problème. Sinon, il faudra compenser par une mesure de la température.

On peut aussi utiliser aussi un régulateur de bonne qualité pour alimenter l'ARDUINO. Selon le régulateur, la dérive en température peut être largement inférieure.

Dans ce cas, il faut utiliser la référence par défaut 5V.

  analogReference(DEFAULT)

Et dans ce cas, il faut recalculer le pont diviseur selon le même principe.

Voilà, j'espère avoir tout dit ?

@+

faut se réveiller là... vous êtes en Terminale, vous devenez adulte...

à mon avis il faut

  • mettre de côté Deezer, les jeux vidéo, facebook, snapchat, instagram et autres ainsi que les séries TV
  • mettre de côté votre projet scolaire pour le moment car vous manquez de bases
  • lire un petit cours de C et C++ sur open Classroom pour la base
  • relire votre cours de base sur l'électricité, la loi d'Ohm et autres théories de base.
  • pour bien débuter avec l'arduino, lire quelques tutos d'eskimon

Une fois cela effectué, vous verrez que votre projet scolaire sera super facile.

Les principales causes d'un échec, blocage d'un projet de BAC.

  • Projet beaucoup trop ambitieux.
  • Manque de créativité.
  • Esprit de vulgarisation pas encore développé.
  • Manque d'intégration de vos acquis.
  • Base technique trop faible.

Merci ! Et du coup aurai tu une solution pour l'affichage par tranche ?

Toutes la base est dans mon premier post.

Je suis conscient que les bases nécessaires à l'acquisition de la connaissance ADC soient au dessus du niveau débutant.

Je vous ai fourni la partie la plus dure à réaliser, parce que je la possédais déjà.

Mais afficher un message quand la capacité passe au dessous ou au dessus de quelques valeurs (100%, 50%, 20%, 0%), cela revient à faire 4 comparaisons.
Si vous ne savez pas faire une comparaison de valeurs en C, c'est que vous ne connaissez même pas ce qu'est une condition if ou else ou un opérateur logique.

Revoyez vos cours, essayez de mettre en oeuvre ce qui manque et revenez ensuite poster votre code.

Mon fils attaque un master en informatique cette année. Sur un projet de 7 personnes il y en a deux qui bossent, dont lui.
Au boulot.

@+

@ hbachetti si un jour cela te tente je suis disponible pour l'adoption .

Oui mais qui adopte qui ? :slight_smile:

adoptez moi svp

Hey du coup si vous êtes chaud pour l'adoption j'ai toujours un deuxième projet coef 12 qui va arriver, mais merci pour tout on a fini tout grâce à vous en grosse partie. Bye

float charge ;  // 100% : 4V ; 8V / 50% : 3.275V ; 6.55V / 20% : 2.84V ; 5.68V / 0% : 2.55V ; 5.1V
int valeur ;

void setup()
{
Serial.begin(9600);
}


void loop()
{
valeur = analogRead(A3);
charge = (4*valeur)/818.50 ;
Serial.println(charge);
if(charge <= 4 && charge > 3.275 ) 
{
 delay(300);
 Serial.println( "Charge bonne" );
}

else if (charge <= 3.275 && charge > 2.84 )
{
 delay(300);
 Serial.println("Penser a recharger la batterie");
}

else 
{
 delay(300);
 Serial.println("Recharger la batterie !");
}

}

virez les delay(300); ils ne servent à rien (ou gardez en un juste pour toute la boucle si vous voulez vérifier la charge toutes les x ms)


Avec 7 posts au compteur, vous n'êtes plus novice, merci d'utiliser les balises de code...

corrigez vos posts ci dessus et rajoutez les code tags autour du code:
[code]`` [color=blue]// votre code ici[/color] ``[/code].

ça doit ressembler à cela:// votre code ici
(faites aussi ctrl-T (PC) or cmd-T (Mac) dans l'IDE avant de copier le code pour qu'il soit indenté correctement)

Salut

  charge = (4*valeur)/818.50 ;
  
  // pas très clair ce calcul
  // je pense que mathématiquement, pour la compréhension, il vaudrait mieux décomposer
  // en général on procède plutôt comme ceci :
  // valeur ADC * tension de référence / 1023 / rapport du pont diviseur

  charge = valeur * VREF / 1023 / 0.248;

@+