BTS Mesure BTS Mesure
Présentation2014CapteursModulationTyponsArduinoDémodulationApp InventorCourbesVidéos

CTNPT1000PressionPhotodiodeAccéléro

La PT1000

Les sondes à résistance de platine  (PT) sont très utilisées dans l'industrie.
La PT100 est une résistance de 100 Ohms à 100°C, sa sensibilité est environ de 0,385 Ohms/°C.

Cette variation est faible aussi la résistance des fils n'est pas négligeable et peut perturber la mesure. La consultation du site technetea.com permet de comprendre l'intérêt des montages à 3 fils ou 4 fils.

Dans notre cas l'utilisation d'une Pt1000 permet d'augmenter la sensibilité d'un facteur 10 (3,85 Ohms/°C) et ainsi de rendre négligeable les résistances de contact.
Dans ces conditions un simple montage à deux fils sera suffisant.

RT = R0 · (1 + aT) avec a = 3.85·10-3 °C-1  et R0 = 1000 Ohms

Le conditionneur-transmetteur

Cahier des charges :

  • Un Arduino ne peut mesurer qu'une tension comprise entre 0 et 5 V.
  • Notre étendue de mesure souhaitée est de -50°C à 40°C
  • Par conséquent on souhaite obtenir -50°C -> 0,5 V  et 40°C -> 4,5V
  • Pour éviter l'autoéchauffement :  IPT1000 < 1,2 mA
  • Alimentation disponible 0V - 9V  (pas d'alimentation symétrique)
  • Choisir un AmpliOp supportant une alimentation non symétrique (Single Supply, éviter le classique TL081...)
    LM324, LM358 : Voutput = 0 à VCC- 1,5
    LMC662 :  Rail to Rail, Voutput = 0 - 0,2 à VCC- 0,2

Etage 1 : le générateur de courant

Point de repos : V+ = 10/(10+10) * 5 = 2,5 V

Il s'agit d'un montage linéaire donc Vd = 0 V
Loi des noeuds (I+ = I- = 0) : IR2B = IPT1000
D'après la loi d'ohm : I = IPT1000 = (5 - V-)/R2B = (5-2.5)/2200 =  1,136 mA
D'après la loi des mailles : VS1 + VPT1000 - V- = 0
<=> VS1 = V- - RPT1000*I = 2,5 - 1000(1+aT)*1,136 10-3 = 2,5 - 1,136 - 1.136*0.00385*T = 1,364 - 4,37 10-3 T

Si T = -50°C => VS1(-50°C) = 1,5825 V

Si T = 40 °C =>  VS1(40°C) = 1,1892 V

Sensibilité du montage : S1 = dV/dT = 4,37 mV/°C

Etage 2 : L'amplificateur inverseur

D'après le diviseur de tension : V+ = (2,2+2,2)/(10+2.2+2.2) * 5 = 1,5278 V

Il s'agit d'un montage linéaire donc V+ = V- , d'après le théorème de Millman :

V- = (R6B*VS1+R5B*VS2)/(R6B+R5B)

VS2 = ((R6B+R5B)*V- - R6BVS1 ) / R5B = -10 * VS1  + 16,8058

VS2 = -10 (1,364 - 4,37 10-3 T) + 16.8058

VS2 =  43,7 10-3 * T + 3,1658

Si T = - 50°C => VS2(-50°C) = 0,98 V

Si T = 40 °C =>  VS1(40°C) = 4,91 V

Sensibilité du montage : S2 = dV/dT = 43,7 mV/°C

Nous avons choisi de ne pas descendre trop bas  VS2(-50°C) = 0,98 V, car notre alimentation non symétrique nous permet pas d'atteindre 0 V

Le choix d'un Ampli Op "Rail to Rail" nous permet d'obtenir un Vsat proche de l'alimentation.
D'après le datasheet du LMC662 : Vsat- = V- + 0,2  = 0,2 V   et Vsat+ = V+ - 0,2 = 9, 3 V  (pour un AmpliOp classique : Vsat+ = V+ - 1 ,5)

Ce montage répond au cahier des charges.

Cette fonction de transfert est théorique :  la dispersion des composants et l'offset de l'ampliOp rendent cette formule approximative.

Il faut maintenant étalonner ce conditionneur.

Etalonnage final

Voici la courbe d'étalonnage obtenue avec la carte finale :

En abscisse : tension numérisée par le CAN de l'Arduino (1024 <-> 5 V)

La courbe verte est la courbe théorique établie ci-dessus.

Les points de mesure sont en rouge.

La courbe d'étalonnage a un excellent coefficient de corrélation r²=0,9996.

La différence entre la courbe théorique et la courbe expérimentale s'explique par :

  • la dispersion des composants (résistances à 1 % - Erreur de gain et d'offset)
  • l'offset des AmpliOp (Erreur d'offset)
  • l'exactitude de notre thermomètre étalon qui était un DHT22
  • les conditions de l'expérience : mesure à la volée dans une boite isotherme (pour limiter l'erreur de traînage) à l'intérieur d'un congélateur.

Les erreurs d'offset et de gain sont corrigées par notre étalonnage. Le coefficient de corrrélation élevé nous permet d'avoir confiance dans notre équation :

   tPT= analogRead(PT1000);
   tPT=0.1029*tPT-67.808;   // Etalonnage par DHT22

Attention : ce montage est sensible aux perturbations électromagnétiques de l'émetteur Kiwi.
Il faut veiller à éloigner ce montage de l'émetteur !

Test et étalonnage

/* Objectif 
Lire la tension de sortie du montage 1 Pile    A0  -> M0
Lire la tension de sortie du montage 2 PT1000   A1  -> M1
Lire la tension de sortie du montage 3 CTN 10k  A2  -> M2
Lire la température indiquée par le dht22 

*/

#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SD.h>

#define DHTPIN 3     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)

LiquidCrystal_I2C lcd(0x27,20,4);
DHT dht(DHTPIN, DHTTYPE);

int mes,i,M0=0,M1,M2;
int chipSelect=10;
int indicatorLed = 13; 
boolean error=false;
char message[140];
float t,VPT1000,VCTN,Pile;



void setup()
{
  Serial.begin(9600);
  pinMode(indicatorLed, OUTPUT);
  lcd.init();                      // initialize the lcd  
  lcd.noBacklight();
  dht.begin();                    // Initialiser le capteur dht22 
  lcd.setCursor(15, 0);
  if (!SD.begin(chipSelect)) {error=true;lcd.print("SD Er");}  // Initialisation carte SD
    else {lcd.print("SD OK");iniSD();}
  lcd.setCursor(0, 0);
  lcd.print("M");
  lcd.setCursor(7, 0); 
  lcd.print("T=");
  lcd.setCursor(0, 1);
  lcd.print("Mes1 PT100  =");
  lcd.setCursor(0, 2);
  lcd.print("Mes2 PT1000 =");
  lcd.setCursor(0, 3);
  lcd.print("Mes3 CTN    =");
}

void loop()
{
    if(i%30==3) lcd.noBacklight();  
    t = dht.readTemperature();
    M0=analogRead(A0);
    M1=analogRead(A1);
    M2=analogRead(A2);
    VPT1000=5.0/1024.0*M1;
    VCTN=5.0/1024.0*M2;
    Pile=10.0/1024.0*M0;
    affiche();  
    if (i%30==0) ecrireSD();
    i++;
    delay(1000); // Show new results every second.
  }

  void affiche() {
    lcd.setCursor(9, 0);
    lcd.print(t,1);
    lcd.setCursor(14, 1);
    lcd.print(M0);
    lcd.print("  ");
    lcd.setCursor(14, 2);
    lcd.print(M1);
    lcd.print("  ");
    lcd.setCursor(14, 3);
    lcd.print(M2);
    lcd.print("  ");    
    Serial.print(t,1);Serial.print(" C\t Pile=");
    Serial.print(Pile,1);Serial.print(" V\t CTN="); 
    Serial.print(VCTN,3);Serial.print(" V\t PT1000=");
    Serial.print(VPT1000,3);Serial.println(" V");
    if (error) Serial.println ("Erreur SD");   
    }
    
  void iniSD() {
      File TEMPtab = SD.open("TEMPtab.csv", FILE_WRITE);
      if (TEMPtab) {
        error=false;
        TEMPtab.println("mes;t(dht);Pile;PT1000;CTN;VCTN;VPT1000");
        TEMPtab.close();
        }
      else  {
        error=true;
        lcd.setCursor(15,0);
        lcd.print("SD Er");}
  }  
    
    
  void ecrireSD(){
      mes++;
      lcd.backlight();
      lcd.setCursor(1, 0);
      lcd.print(mes);
      File TEMPtab = SD.open("TEMPtab.csv", FILE_WRITE);
      if (TEMPtab) {
        error=false;
        TEMPtab.print(mes);
        TEMPtab.print(";");
        TEMPtab.print(t,1);
        TEMPtab.print(";");
        TEMPtab.print(Pile,1); 
        TEMPtab.print(";");
        TEMPtab.print(M1); 
        TEMPtab.print(";");
        TEMPtab.print(M2);
        TEMPtab.print(";");
        TEMPtab.print(VCTN,3);
        TEMPtab.print(";");
        TEMPtab.println(VPT1000,3);
        TEMPtab.close();
        }
      else  {
        error=true;
        lcd.setCursor(15,0);
        lcd.print("SD Er");}

    }