Intéressé par des cours d'informatique en ligne ?
Visitez mon nouveau site https://www.yesik.it !

J'ai eu besoin récemment de suivre l'évolution de la charge d'une batterie de voiture sur une longue période. C'est une opération qui n'est pas très complexe, puisqu'au final il suffit de mesurer à peu près régulièrement la tension aux bornes de la batterie. Et c'est une tâche parfaite pour un micro-contrôleur équipé d'un circuit de conversion analogique/numérique comme l'ATmega328P. Le seul problème, c'est que la tension aux bornes de la batterie est nettement trop élevée pour pouvoir la connecter directement aux broches du micro-contrôleur…

Arduino?

Vous verrez que j'utilise ici la bibliothèque Arduino pour programmer l'ATmega328P. J'ai fait ce choix tant pour des raisons de rapidité de mise en œuvre que par motivations pédagogiques.

Par contre, pour des raisons économiques cette fois-ci, la réalisation électronique utilise directement un ATmega328P nu – mais rien ne vous empêche de refaire les manipulations décrites ici avec une carte Arduino. Faites juste attention: certaines cartes Arduino sont alimentées en 5V et d'autres en 3,3V. Si vous êtes dans le second cas, il vous faudra vérifier les calculs de résistances et modifier le code source en conséquence.

Montage électronique

12V battery monitor-ATmega328P.png

Mesure de tension — Ce montage utilise un diviseur de tension pour mesurer une tension supérieure à celle que peut accepter le convertisseur analogique/numérique de l'ATmega28P.

Les résistances ont été calculées pour minimiser l'influence du circuit de mesure, tout en protégeant le micro-contrôleur et en assurant une mesure convenable.

Les véhicules automobiles utilisent des batteries 12V. En réalité, sur une batterie moderne, la tension à pleine charge dépasse souvent 14V. Dans tous les cas, c'est largement plus que ce que peut accepter le convertisseur analogique/numérique de l'ATmega328P: en effet, celui-ci n'accepte pas une tension supérieure à la tension d'alimentation du micro-contrôleur qui, pour un ATmega328P, doit se situer entre 1,8V et 5,5V. Enfreindre cette règle reviendrait à condamner à coup sûr le circuit…

Il est donc nécessaire d'adapter la tension à mesurer à l'intervalle de tension acceptable par le convertisseur. Pour ce projet, un simple diviseur de tension basé sur deux résistances respectivement de 27kΩ et 10kΩ fera l'affaire. Ces valeurs n'ont pas été choisies au hasard: en effet, elles assurent qu'avec une batterie à la charge nominale de 12V, la tension sur la broche du micro-contrôleur n'atteindra que 3,25V. Ce qui me donne une marge confortable pour mesurer la charge réelle. Par ailleurs, elle me permettent de maintenir l'impédance d'entrée du convertisseur sous les 10kΩ recommandés par Atmel. Tout en rendant négligeable les pertes de courant dues au système de mesure et qui sont ici inférieures à 1mA. En prime, même en cas de grosse surtension (causée par exemple par un alternateur défectueux), la résistance de 27kΩ est assez largement dimensionnée pour protéger la broche d'entrée du convertisseur: en effet, en interne, chaque broche de l'ATmega328P est protégée par un clamp – c'est à dire une paire de diode entre la broche et d'un côté l'alimentation (Vcc) et de l'autre la masse (GND). Même avec 30V en entrée du diviseur, le courant traversé par la diode reliée à Vcc resterait sous sa limite de tolérance estimée à 1 mA. Ceci dit, je dois avouer ne pas avoir testé jusqu'à cette valeur…

Pour en terminer avec l'examen du circuit, vous remarquerez dans le schéma ci-dessus l'utilisation de la broche PD1 reliée à une ligne labellisée TX. En effet, dans cette version le micro-contrôleur sert uniquement de voltmètre. Le traitement est dévolu à un système externe, en l’occurrence un ordinateur portable raccordé au port série de l'ATmega328P par un adaptateur série TTL-USB 5V.

Arduino?

Pour les utilisateur de cartes Arduino:

  • la broche PD1 n'est pas à connecter, puisque vous avez déjà accès au port série;
  • la broche PC0 correspond à la broche Arduino analog input 0;
  • Vcc et AVcc sont déjà connectées sur votre carte;
  • la masse GND de la carte est bien entendu à raccorder à la masse (pôle −) de la batterie.

Code source

Une fois le montage fait, le programme est trivial dans cette version de base. C'est juste une mise en œuvre du port série et du convertisseur analogique/numérique.

Disponible sur GitHub:

L'ensemble des sources de cet article ainsi que les fichiers de données qui lui servent de support sont disponibles sur GitHub dans le projet s-leroux/ArduinoBatteryMonitor.

À votre convenance vous pouvez:
/*
ArduinoBatteryMonitor
by Sylvain Leroux <sylvain@chicoree.fr>
 
Based on Arduino example AnalogInOutSerial by Tom Igoe
 
This example code is in the public domain.
*/
 
#include <stdlib.h>
 
// Constants
const int analogInPin = A0; // Analog pin the voltage divider is attached to
const float Vcc = 5; // µC Vcc (V)
const float R1 = 27000; // Voltage divider R1 (Ohm)
const float R2 = 10000; // Voltage divider R2 (Ohm)
 
const int pause = 60*1000; // delay between samples (ms)
 
 
void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
}
 
void loop() {
  // read the analog in value:
  int sensorValue = analogRead(analogInPin);
 
  // Serial.println(sensorValue); // for debug / calibration
  float v_pin = Vcc*sensorValue/1023.;
  float v_bat = v_pin/(R2/(R1+R2));
 
  // Convert to string using the format ddd.dd
  char buffer[21];
  dtostrf(v_bat, 6, 2, buffer);
  buffer[6] = 0;
 
  // Display result
  Serial.println(buffer);
 
  // wait before the next loop
  delay(pause);
}

Mesures

Mesures batterie.png

La fiabilité du convertisseur analogique/numérique est très satisfaisante — Lors de tests avec une alimentation de laboratoire, et en comparant avec les mesures d'un multimètre, l'erreur est de moins de 2% à partir d'une tension de batterie de 2,5V environ – soit 0,68V sur la broche du convertisseur, après le diviseur de tension.

Pour m'assurer du fonctionnement du système, j'ai utilisé une alimentation de laboratoire à la place de la batterie, et j'ai comparé les résultats fournis par le système à ceux obtenus à l'aide d'un multimètre Metrix. et je dois avouer que j'ai été surpris de constater la qualité des mesures: avec des résistances 10kΩ±1% et 27kΩ±5% (en fait, ce que j'avais en stock…) j'obtiens sur la plage 3V~15V une erreur de ±2% à peine par rapport à mon multimètre. Pour être plus précis, le convertisseur sous-estime systématiquement la mesure de quelques dizaines de millivolts. C'est sans doute causé par le fait que, dans le programme, j'utilise les valeurs nominales des résistances pour effectuer les calcul. En ajustant les constantes du code avec les valeurs réelles de ces résistances, je pense que l'on pourrait faire encore mieux. Je reprends toutes ces mesures dans le fichier Mesures.xls disponible sur Github.

stabilité thermique

Je n'ai pas étudié la stabilité des mesures en fonction de la température, mais c'est un point qu'il serait intéressant d'évaluer.


Attention:

La fiabilité des mesures dépend de la qualité de l'alimentation sur la broche AVcc. Dans mon cas, j'utilisais le 5V à peu près propre du port USB de mon ordinateur portable. Dans d'autres configurations – alimentation bruitée, mal stabilisée ou variable (pile) – il faudrait sans doute se diriger vers une solutions plus sophistiquée pour assurer des mesures précises. Celle-ci passerait sans doute par un filtrage sur AVcc ou par l'utilisation d'une référence de voltage externe sur la broche AREF. Mais cela sort du cadre de cet article.

Traitements et évolution

Dans la version présentée ici, ce projet reste élémentaire. En effet, la partie embarquée se contente de faire des mesures, qui sont ensuite transmises sur le port série.

Cela peut sembler simpliste; mais a pour avantage de rendre le système modulaire. En effet, dans mon cas, j'ai placé un ordinateur portable pour collecter les données, puis les post-traiter avec un tableur. Mais on peut facilement envisager d'autres applications. Par exemple, il serait tout à fait possible de connecter le montage à un module RF ou ZigBee pour transmettre par onde radio les données en flux continu.

Une autre évolution possible (souhaitable?) serait d'ajouter un opto-coupleur pour assurer l'isolation galvanique entre le système de mesure connecté à la batterie et système de traitement.

Dans un ordre d'idée différent, on pourrait adjoindre au montage un dispositif de stockage permettant de mémoriser les mesures. Les spécialistes d'Arduino penseraient par exemple au microSD shield ou à un équivalent. Dans une version plus minimaliste, on pourrait aussi envisager de stocker les mesures dans l'EEPROM intégrée de l'ATmega328P. Celle-ci ne compte que 1KiB (1024 octets), mais à raison d'un échantillon toutes les minutes, et en se basant sur 2 octets par échantillons (la taille d'un float), on arrive tout de même à plus de 8h de mesures en continu. Ce qui n'est pas négligeable.