Projet

Général

Profil

Mesure de La charge de la batterie

Informations supplémentaires sur le tableau de bord de Loris GALLAND

Présentation

Ce circuit permet de mesurer la tension de la batterie.
Il diminue la tension de celle-ci pour ensuite l'injecter dans un pin ADC de l'ESP32.

Conception du pcb

Source sur laquelle nous nous sommes basés : https://en.ovcharov.me/2020/02/29/how-to-measure-battery-level-with-esp32-microcontroller/
Nous avons utilisé Kicad afin de concevoir notre PCB. Avant de commencer son PCB, il faut faire attention à bien placer celui-ci au niveau de l'origine (coordonnées 0,0). Cela sera important pour la suite.

Lorsque nous lançons Kicad, nous arrivons sur cette page:

Normalement, aucun élèment n'est présent dans l'encadré à gauche lorsque vous lancez pour la 1e fois le logiciel. Nous allons donc créer un nouveau projet. On appuie sur ce bouton, situé en haut à gauche:

Une fenêtre apparait et nous pouvons éditer le nom de notre projet et son emplacement sur notre PC. Nous nommerons notre projet "Cablage Mesure Batterie" et le placerons dans le dossier "Stage FABLAB THERMO-BIBLI". Une fois validé, nous avons 2 fichiers qui vont se créer :
  • un fichier .kicad_pcb qui correspond au PCB
  • un fichier .sch qui correspond au schéma

Nous allons d'abord commencer par travailler sur notre fichier schéma. Ce fichier sera ensuite "transféré" sur le fichier PCB. Nous allons accéder à ce fichier. Pour cela, il suffit de cliquer dessus. Nous arrivons sur une page vierge telle quelle :

image schéma vierge

Afin d'ajouter des composants à notre schéma, il suffit de cliquer sur le bouton :

Une fois ce bouton selectionné, nous cliquons sur l'endroit où nous voulons placer le composant. Le logiciel va alors chargé les librairies de composants. Normalement, elles sont installées avec le logiciel mais vous pouvez aussi en rajouter plus tard. Une fenêtre s'ouvre alors:

Cette fenêtre permet d'afficher les composants dont nous avons besoin avec leur nom, leur description et leur représentation schématique. Dans notre cas, nous devons ajouter des résistances et des Mosfets.
Pour accéder aux résistances, nous pouvons taper dans la barre de recherche "R". Comme vous pouvez le constatez, le composant "résistance" apparait en premier avec le nom "R" et la description "résistor". Nous faisons la même chose avec nos mosfets. On écrit donc dans la barre de recherche DMG2302U qui correspond à la référence de nos mosfets. Attention, si aucun élèment ne correspond, cela signifie que Kicad ne possède pas les librairies comprenant ces composants. Pour cela, il vous suffit de chercher sur internet la librairie et de l'installer manuellement.

Après avoir placé tous nos composants, il faut les relier. Nous utiliserons donc le bouton situé dans la barre verticale à droite. Une fois, cela effectué, nous allons ajouter une Masse à notre circuit. Pour cela il faut appuyer, toujours dans la barre verticale à droite, sur le bouton .
Ensuite il faut cliquer sur l'endroit où nous voulons placer notre Masse. Une fenêtre va alors s'ouvrir. Elle permet de choisir le type de source. 2 catégories sont disponibles : "power" et "pspice". Nous pouvons rechercher dans la barre en haut notre Masse en écrivant "GND":

Une fois selectionnée, nous pouvons donc placer notre Masse. Cela étant fait, nous avons fini de tracer notre schéma :

Maintenant il faut "paramétrer" ce schéma. En effet, afin de pouvoir obtenir un fichier PCB, il nous faut d'abord définir les empreintes des différents composants. Ces empreintes permettent de représenter ceux-ci de manière "réaliste". Pour ce faire, nous allons donc appuyer sur le bouton , situé dans la barre d'outils horizontale, en haut. Une fenêtre s'ouvre donc :

On peut observer que cette fenêtre est divisée en 3 parties :
- La liste d'empreintes à gauche
- la liste de nos composants au milieu
- La liste des empreintes filtrées à droite

Normalement, lorsqu'aucune empreinte n'est assignée, seuls les noms des composants sont présents dans la sous-fenêtre au milieu.

Nous allons donc commencer par notre support de pin. Nous allons donc rechercher "Connector_PinHeader_2.54mm" (nos pins étant de dimension 2.54 mm) dans la liste d'empreintes.

Nous cliquons ensuite sur notre composant, dans la sous fenêtre au milieu. Une liste d'empreintes apparait donc à droite. Nous allons donc chercher dans cette liste l'empreinte qui nous intéresse. Nous allons donc choisir cette empreinte :

Après avoir associé les empreintes correspondantes à notre composant, nous pouvons donc créer la netliste de notre schéma. Cette netliste correspond à l'ensemble des paramètres de notre schéma que le PCB va prendre en compte.

Réalisation du pcb

Gerber sur le logiciel FlatCAM

Le logiciel FlatCAM permet de créer des fichiers de découpe à partir de nos fichiers GERBER. Nous pouvons donc régler la profondeur de découpe par exemple. Il faut aussi prévoir de laisser des petits espaces au niveau du contours afin de faciliter plus tard la récupération de notre PCB créé.

Découpe du PCB avec une fraiseuse

Nous avons utilisé le logiciel BCNC, permettant de se connecter à la fraiseuse. Dans ce logiciel, nous pouvons contrôler manuellement la fraiseuse ou lui "injecter" un fichier de découpe.
Afin

Brasure et pose des composants

<pre><code class="cpp">
<pre><code class="cpp">
h2. Code Informatique
</code></pre>

<pre><code class="cpp">
h3. Définitions des différents élèments
</code></pre>

#include "Arduino.h" 
#include "Pangodream_18650_CL.h" 

Pangodream_18650_CL::Pangodream_18650_CL(int addressPin, double convFactor, int reads)
{
    _reads = reads;
    _convFactor = convFactor;
    _addressPin = addressPin;
    _initVoltsArray();
}

Pangodream_18650_CL::Pangodream_18650_CL(int addressPin, double convFactor)
{
    _reads = DEF_READS;
    _convFactor = convFactor;
    _addressPin = addressPin;
    _initVoltsArray();
}

Pangodream_18650_CL::Pangodream_18650_CL(int addressPin)
{
    _reads = DEF_READS;
    _convFactor = DEF_CONV_FACTOR;
    _addressPin = addressPin;
    _initVoltsArray();
}

Pangodream_18650_CL::Pangodream_18650_CL()
{
    _reads = DEF_READS;
    _convFactor = DEF_CONV_FACTOR;
    _addressPin = DEF_PIN;
    _initVoltsArray();
}

int Pangodream_18650_CL::getAnalogPin()
{
    return _addressPin;
}
double Pangodream_18650_CL::getConvFactor()
{
    return _convFactor;
}

/**
 * Loads each voltage value in its matching charge element (index)
 */
void Pangodream_18650_CL::_initVoltsArray(){
    _vs[0] = 7.800; 
    _vs[1] = 7.848; _vs[2] = 7.896; _vs[3] = 7.944; _vs[4] = 7.992; _vs[5] = 8.040;
    _vs[6] = 8.088; _vs[7] = 8.136; _vs[8] = 8.184; _vs[9] = 8.232; _vs[10] = 8.280;
    _vs[11] = 8.328; _vs[12] = 8.376; _vs[13] = 8.424; _vs[14] = 8.472; _vs[15] = 8.520;
    _vs[16] = 8.568; _vs[17] = 8.616; _vs[18] = 8.664; _vs[19] = 8.712; _vs[20] = 8.760;
    _vs[21] = 8.808; _vs[22] = 8.856; _vs[23] = 8.904; _vs[24] = 8.952; _vs[25] = 9.000;
    _vs[26] = 9.048; _vs[27] = 9.096; _vs[28] = 9.144; _vs[29] = 9.192; _vs[30] = 9.240;
    _vs[31] = 9.288; _vs[32] = 9.336; _vs[33] = 9.384; _vs[34] = 9.432; _vs[35] = 9.480;
    _vs[36] = 9.528; _vs[37] = 9.576; _vs[38] = 9.624; _vs[39] = 9.672; _vs[40] = 9.720;
    _vs[41] = 9.768; _vs[42] = 9.816; _vs[43] = 9.864; _vs[44] = 9.912; _vs[45] = 9.960;
    _vs[46] = 10.008; _vs[47] = 10.056; _vs[48] = 10.104; _vs[49] = 10.152; _vs[50] = 10.200;
    _vs[51] = 10.248; _vs[52] = 310.296; _vs[53] = 10.344; _vs[54] = 10.392; _vs[55] = 10.440;
    _vs[56] = 10.488; _vs[57] = 10.536; _vs[58] = 10.584; _vs[59] = 10.632; _vs[60] = 10.680;
    _vs[61] = 10.728; _vs[62] = 10.776; _vs[63] = 10.824; _vs[64] = 10.872; _vs[65] = 10.920;
    _vs[66] = 10.968; _vs[67] = 11.016; _vs[68] = 11.064; _vs[69] = 11.112; _vs[70] = 11.160;
    _vs[71] = 11.208; _vs[72] = 11.256; _vs[73] = 11.304; _vs[74] = 11.352; _vs[75] = 11.400;
    _vs[76] = 11.448; _vs[77] = 11.496; _vs[78] = 11.544; _vs[79] = 11.592; _vs[80] = 11.640;
    _vs[81] = 11.688; _vs[82] = 11.736; _vs[83] = 11.784; _vs[84] = 11.832; _vs[85] = 11.880;
    _vs[86] = 11.928; _vs[87] = 11.976; _vs[88] = 12.024; _vs[89] = 12.072; _vs[90] = 12.120;
    _vs[91] = 12.168; _vs[92] = 12.216; _vs[93] = 12.264; _vs[94] = 12.312; _vs[95] = 12.360;
    _vs[96] = 12.408; _vs[97] = 12.456; _vs[98] = 12.504; _vs[99] = 12.552; _vs[100] = 12.600;
}

int Pangodream_18650_CL::getBatteryChargeLevel()
{
    int readValue = _analogRead(_addressPin);
    double volts = _analogReadToVolts(readValue);
    int chargeLevel = _getChargeLevel(volts);
    return chargeLevel;
}

int Pangodream_18650_CL::pinRead(){
    return _analogRead(_addressPin); 
}

int Pangodream_18650_CL::_analogRead(int pinNumber){
    int totalValue = 0;
    int averageValue = 0;
    for(int i = 0; i < _reads; i++){
       totalValue += analogRead(pinNumber);
    }
    averageValue = totalValue / _reads;
    return averageValue; 
}
/**
 * Performs a binary search to find the index corresponding to a voltage.
 * The index of the array is the charge %
*/
int Pangodream_18650_CL::_getChargeLevel(double volts){
  int idx = 50;
  int prev = 0;
  int half = 0;
  if (volts >= 12.6){
    return 100;
  }
  if (volts <= 7.8){
    return 0;
  }
  while(true){
    half = abs(idx - prev) / 2;
    prev = idx;
    if(volts >= _vs[idx]){
      idx = idx + half;
    }else{
      idx = idx - half;
    }
    if (prev == idx){
      break;
    }
  }
  return idx;
}

double Pangodream_18650_CL::_analogReadToVolts(int readValue){
  double volts; 
  volts = readValue * _convFactor / 1000;
  return volts;
}

double Pangodream_18650_CL::getBatteryVolts(){
    int readValue = analogRead(_addressPin);
    return _analogReadToVolts(readValue);
}
</code></pre>

Test

Ajustements

Dans notre cas, l'ESP32 utilise une batterie NCR18650B. Les pins de ce micro_contrôleur ne peuvent accueillir que du 3.3V. Afin d'ajuster la tension de la batterie, on utilise des résistances avec un diviseur de tension. Il faut bien vérifier que les résistances utilisées diminuent la tension correctement, c'est-à-dire à un niveau de tension admissible par les ports du micro-contrôleur. Leurs valeurs dépendra du composant et de la batterie utilisés.

Vbat _rapport R1/R2 _R1 _R2
4.2 0.28 10 35.7
8.4 1.56 10 6.41
12.6 2.81 10 3.56
Vbat _R1 _R2
4.2 100 10 0.42
4.2 100 22 0.924
4.2 100 33 1.386
4.2 100 47 1.974
4.2 100 56 2.352
4.2 100 68 2.856
4.2 100 82 3.444
8.4 100 10 0.84
8.4 100 22 1.848
8.4 100 33 2.772
8.4 100 47 1.974
8.4 100 56 3.948
12.6 100 10 0.42
12.6 100 22 0.924
12.6 100 33 1.386
100 47 1.974
4.2 100 56 2.352
4.2 100 68 2.856
4.2 100 82 3.444

Problème : Le pourcentage de batterie affiché est différent en fonction de la méthode d'alimentation :
- en mode usb, on obtient la bonne valeur
- en mode batterie, on obtient une valeur plus faible

Plusieurs hypothèses :
- Température supérieure à 25°C
- Tension envoyée à l'ESP32 différente

Test Mesure Multimètre : 3.23V sur USB et 3.22V sur batterie VALEUR IDENTIQUE

- Courant envoyée en alimentation à l'ESP32 différent

Test Mesure Multimètre : en mode batterie, valeur qui varie entre 7.51mA et 11mA

- Tension BAT_ADC_EN (référence) différente

Expérimentations :
Je teste d'abord différentes tensions de la batterie (simulées par un générateur de tension réglable, 0.5A). ESP32 branché en usb
rapport 3 3.2
Pourcentage Théorique
0 0 0
10 0 3
20 0 15
30 15 27
40 23 35
50 35 47
60 47 61
70 65
80 79
90 95
100 95

Je teste ensuite avec l'alimentation batterie

rapport 3.2 3.3 3.4
Pourcentage Théorique
0 0 0 0
10 0 3 5
15 3
20 9 15 17
25 15
30 21 23 27
35 23
40 29 35 41
45 35
50 39 47 53
55 47
60 53 61 65
65 59
70 67 77 79
75 73
80 83 91 97
85 91
90 100 100 100
95 100
100 100 100 100

J'ai effectué différents tests : la batterie en alimentation de l'ESP32 et un générateur de tension sur le pin. On observe un décalage entre les valeurs qui peut être réglé avec le rapport. Or lorsque la batterie est en alimentation et en entrée de pin, le décalage est beaucoup trop important 95 au lieu de 83 -> PROBLEME

Autre hyptohèse : Tension de référence récupéré d'un pin de l'ESP un peu trop grande (3.3 au lieu de 3.25V)