Cette page présente un dispositif d'étude de la décharge d'une pile ou d'un accumulateur au moyen d'un Arduino Yun. Une pile de 1,5 V est déchargée dans une résistance de 10 Ω. La force électromotrice et le courant sont enregistrés pendant plusieurs heures, dans le but de tracer la force électromotrice en fonction de la charge débitée. Les mesures sont enregistrées sur la carte SD.
La pile a une force électromotrice maximale d'environ 1,5 V (typiquement une pile de format AA ou AAA). Lorsque la sortie D7 de l'arduino est au niveau haut (5 V), le transistor est saturé et la pile débite dans la résistance R2=10 Ω. Le potentiel du collecteur est à environ 0,1 V, ce qui fait un courant d'environ 140 mA lorsque la pile est chargée. Le courant de base du transistor est (5-0.7)/1000=4,3 mA. Le gain en courant est donc au plus de 32, ce qui est réalisable avec le transistor 2N2222.
Lorsque la pile débite, les potentiels aux bornes de la résistance sont relevés sur les entrées analogiques A0 et A1. La tension aux bornes de la pile est V0. L'intensité du courant est (V0-V1)/R2. La tension de référence du convertisseur analogique-numérique est fixée à environ 1,8 V par le pont diviseur et le suiveur. La valeur précise est relevée au voltmètre. Cette valeur de référence basse permet de minimiser le bruit de quantification.
Les mesures de tension sont faites toutes les secondes, ce qui permet d'intégrer le courant pour obtenir la charge débitée. Toutes les minutes, la sortie D7 passe au niveau bas afin de bloquer le transistor et de relever la force électromotrice sur l'entrée A0. La décharge s'arrête en principe lorsque la force électromotrice atteint le potentiel du collecteur, environ 0,1 V.
#include "Arduino.h" #include <FileIO.h> #define OUT 7 #define VREF 1.82 uint16_t diviseur[6] = {0,1,8,64,256,1024}; float resistance = 10.6; volatile float x[2]; float courant; float charge,tension,fem; float u0,u1; volatile int compteur = 0; float te; String data; volatile int flag;
La fonction suivante permet de programmer le Timer3 pour qu'il déclenche des interruptions périodiques.
void timer3_init(uint32_t period) { TCCR3A = (1 << COM3A1) | (1 << COM3A0); TCCR3B = (1 << WGM33); uint32_t top = (F_CPU/1000000*period/2); int clock = 1; while ((top>0xFFFF)&&(clock<5)) { clock++; top = (F_CPU/1000000*period/2/diviseur[clock]); } ICR3 = top; TIMSK3 = 1 << TOIE3; TCCR3B |= clock; }
La fonction suivante est appelée lors de l'interruption (toutes les secondes). La tension aux bornes de la pile et le courant sont obtenues à partir des entrées A0 et A1. La charge est calculée par intégration du courant. Toutes le 60 secondes, la sortie D7 est mise à zéro afin de faire la lecture de la force-électromotrice sur la voie A0. Les mesures sont alors enregistrées sous forme d'une chaine de caractères.
ISR(TIMER3_OVF_vect) { temps += te; compteur++; if (compteur==60) { compteur = 0; digitalWrite(OUT,LOW); // transistor bloqué delay(100); fem = analogRead(0)*VREF/1024; digitalWrite(OUT,HIGH); // transistor saturé data = String(temps)+"\t"+String(fem)+"\t"+String(tension)+"\t"+String(courant)+"\t"+String(charge); courant = 0; flag = 1; } else { u0 = analogRead(0)*VREF/1024; u1 = analogRead(1)*VREF/1024; tension = u0; courant = (u0-u1)/resistance; } // intégration du courant x[1] = x[0]; x[0] = courant; charge += te*0.5*(x[0]+x[1]); }
Voici la fonction d'initialisation. Le fichier texte de sauvegarde (sur la carte SD) est effacé s'il existe déjà. La référence de tension du convertisseur A/N est choisie EXTERNE. Il ne faut surtout pas oublier cette configuration lorsqu'une tension est imposée à l'entrée AREF, sous peine de détruire le convertisseur. Il faut donc téleverser le programmer avant de brancher l'entrée AREF (au cas où le programme déjà présent utiliserait l'ADC).
void setup() { pinMode(OUT,OUTPUT); digitalWrite(OUT,HIGH); analogReference(EXTERNAL); Bridge.begin(); FileSystem.begin(); FileSystem.remove("/mnt/sd/alcaline.txt"); te = 1.0; # une seconde charge = 0.0; x[0] = x[1] = 0; flag = 0; timer3_init(te*1000000); }
La fonction loop se charge d'écrire la chaine data dans le fichier lorsque une nouvelle donnée est disponible.
void loop() { if (flag) { File dataFile = FileSystem.open("/mnt/sd/alcaline.txt", FILE_APPEND); if (dataFile) { dataFile.println(data); dataFile.close(); flag = 0; } } }
Voici la courbe de décharge, force électromotrice en fonction de la charge débitée, pour une pile alcaline AA (ayant déjà un peu servi) :
import numpy from matplotlib.pyplot import * data = numpy.loadtxt("alcaline-2.txt",unpack=True) t = data[0] fem = data[1] u = data[2] i = data[3] q = data[4]/3.6 figure() plot(q,fem) xlabel("Q (mAh)") ylabel("e (V)") axis([0,q.max(),0,2.0]) grid()figA.pdf
Voici la fem en fonction du temps :
figure() plot(t/3600,fem) xlabel("t (h)") ylabel("e (V)") grid()figB.pdf
Après cette expérience, on laisse la pile reposer 24 heures puis on refait des mesures :
data = numpy.loadtxt("alcaline-3.txt",unpack=True) t = data[0] fem = data[1] u = data[2] i = data[3] q = data[4]/3.6 figure() plot(q,fem) xlabel("Q (mAh)") ylabel("e (V)") axis([0,q.max(),0,2.0]) grid()figC.pdf
La force électromotrice est faible, de l'ordre de 1 V, mais on arrive tout de même à extraire une charge non négligeable.
Voici la courbe de décharge d'un accumulateur Ni-MH venant juste d'être rechargé :
data = numpy.loadtxt("Ni-MH-1.txt",unpack=True) t = data[0] fem = data[1] u = data[2] i = data[3] q = data[4]/3.6 figure() plot(q,fem) xlabel("Q (mAh)") ylabel("e (V)") axis([0,q.max(),0,2.0]) grid()figD.pdf
L'accumulateur est marqué 2600 mAh, mais il a déjà beaucoup servi, ce qui explique sa capacité réduite. On remarque que la fem se stabilise à environ 1,2 V et reste constante pendant presque toute la décharge. La valeur 1,2 V est marquée sur la pile. Par comparaison, la pile alcaline a une décroissance beaucoup plus marquée se sa fem.