Capteur de température avec le TMP36

08/05/2012: MCHobby vend maintenant des capteurs de température TMP36 (voir fiche produit du TMP36). Mais aussi des afficheur LCD + boutons de contrôles pilotable depuis un Arduino avec seulement 2 fils (voir fiche produit du Shield LCD RGB - 2 pins - AFFICHAGE NEGATIF ).

Description
Le TMP36 est un senseur qui se présente sous la forme d'un petit transistor.
Source: LadyAda

Une fois alimenté (entre 3 et 5v), ce petit module sort une tension analogique directement proportionnelle à la température... c'est bien pratique.
Source: Datasheet du TMP36

Les avantages principaux du TMP36 sont:
  • La couverture d'une large plage de température (de -50 à +150 °C).
  • Que la tension de sortie est totalement indépendante de l'alimentation du TMP36.
Caractéristique du TMP36:
  • Taille: boitier TO-92 à 3 broches (similaire à un transistor)
  • Gamme de température: -40°C a 150°C / -40°F a 302°F
  • Tension de sortie: 0.1V (-40°C) to 2.0V (150°C) mais la précision diminue après 125°C
  • Tension d'alimentation: 2.7V a 5.5V
  • Courant de charge: 0.05 mA
    Comment calculer la température
    Il faut donc convertir la tension analogique en degré.
    Comme le TMP36 permet de mesurer des température négatives, le 0 degré Celsius est placé à une offset de 500 milliVolts.
    Ainsi, toute mesure inférieur à 500 mv correspondra à une température négative.
     
    La formule est la suivante pour le TMP36:
    Temp en °C = ( Tension_de_sortie_en_milliVolts - 500) / 10

    Donc, si la tension de sortie est de 1 Volts, la température correspondante est de
       (1000 - 500)/10
    Soit 50 degrés Celcius.

    Equivalents
    Il existes quelques modèles équivalents au TMP36.

    • LM35/TMP35 (mesure de température Celsius)
    • LM34/TMP34 (mesure de température Farenheit).
    Attention, dans le cas du LM35, la formule de conversion est différente (ligne "a" sur le graphique température/tension):
    Temp en °C = Tension_de_sortie_en_milliVolts / 10

    Ou acheter
    Le TMP36 est disponible:
    Le LM35 est disponible:
    • Chez Cotubex (BE): en variante +/- 6 EUR.
    • Elitek (BE): en variante, de 4 à 15 EUR.
    Montage
    Je vais utiliser un TMP36 et un l'afficheur LCD pour afficher la température.
    Le montage est constitué des deux éléments suivants:

    Source: LadyAda

    Pour le montage de l'afficheur LCD, vous pouvez vous référer à l'article "(voir article "Commande d'un afficheur LCD MOP-AL162A-BBTW: LCD 2x16" de ce même blog.

    Code Source
    source: temperature.pde
    /*
      Mesure de la température à l'aide d'un TMP36
      Affichage sur LCD: MOP-AL162A-BBTW: LCD 2x16
     
     Le montage:
     Afficheur LCD
     * LCD RS     - pin 12
     * LCD Enable - pin 11
     * LCD D4     - pin 5
     * LCD D5     - pin 4
     * LCD D6     - pin 3
     * LCD D7     - pin 2
     * LCD R/W    - GND
     * LCD Vo contrast- potentiomètre 10K (entre Gnd et +5V)
     
     Senseur de température:
     * TMP36 Analog Output - Pin A0 (analogique)
     
     This example code is in the public domain.
     
    */
    
    // include the library code:
    #include <LiquidCrystal.h>
    
    
    int tempSensorPin = 0; // Pin analogique pour lecture de la tension de sortie du TMP36 (Vout).
                           // Resolution: 10 mV / degree celsius avec une offset de 500 mv.
    
    // Definition du caractere °
    byte degrees[8] = {
      B00000,
      B01000,
      B10100,
      B01000,
      B00000,
      B00000,
      B00000,
      B00000,
    };
    
    // initialize the library with the numbers of the interface pins
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    
    void setup(){
      // set up the LCD's number of columns and rows: 
      lcd.begin(16, 2);
      lcd.clear();
      
      // initialiser le caractère ° dans le LCD
      lcd.createChar( 0, degrees );
    }
    
    // mémorise la dernière température affichée
    int lastTemp = -100;
    
    void loop(){
      float temp = lectureTemp();
      
      // rafraichit le LCD que si la 
      // température a varié sensiblement
      if( abs(temp-lastTemp)<0.20 )
        return;
      lastTemp = temp;
      
      // Afficher la valeur en evitant le
      //   lcd.clear(), pour éviter l'effet de
      //   scintillement.
      lcd.setCursor(0,0);
      lcd.print( temp );
      lcd.write( 0 );  // affiche le signe degré 
      lcd.print( "c" );
    
      // Efface les derniers caractères si
      //   la température chute subitement
      lcd.print( "      " );
      
      // ne pas rafraichir trop souvent
      delay(800);
      
    }
    
    //Description:
    //  Lecture de la température sur la pin A0
    //
    //Returns:
    //  La température en degré Celcius.
    //
    float lectureTemp(){
     // Lecture de la valeur sur l'entrée analogique
     // Retourne une valeur entre 0->1024 pour 0->5v
     int valeur = analogRead(tempSensorPin);  
    
     // Converti la lecture en tension
     float tension = valeur * 5.0;
     tension /= 1024.0; 
     
     // Convertir la tension (mv) en temperature
     float temperature = ((tension * 1000) - 500) / 10;
     
     return temperature;
    }
    
    Résultats

    Le résultat sont en fin de compte assez corrects... pourtant j'étais loin de m'imaginer une telle température dans la pièce (il faisait mauvais dehors et le chauffage central n'est plus branché depuis des mois).
    Par ailleurs, la température indiquée au thermostat était de 23.0°c !?!?
    J'ai donc essayé de faire preuve d'esprit critique et cherché à vérifier les résultats produit par Arduino.

    Cette démarche ne fut pas aussi simple que je le pensais.

    Utiliser un glaçon sorti du congélateur indique une température négative... en effet, le congélateur fonctionne à -24°C et il faut attendre que la glaçon fonde (si possible dans l'eau) pour avoir une température de 0°c... difficile à mesurer en évitant les court-circuits.

    A contrario, la température du corps est de 36.6°c.
    J'ai pincé le senseur entre deux doigts et après 2 minutes, l'afficheur se stabilise autour de de 32.5°C. Cela semble erroné à première vue. pourtant, l'utilisation d'un thermomètre médical indique une température toute voisine (33.2°c).

    Finalement, j'ai sorti un bon vieux thermomètre à mercure.
    Les températures indiquées par Arduino sont visiblement correctes.


    Concernant, le thermostat indiquant 23°C (vs Arduino 25.6), l'usage du thermomètre à mercure démontra que le thermostat n'affichait pas une valeur correcte :-) .

    Bref, pour résumer, c'est Arduino qui donne la bonne température (à +/- 0.5°C). 

    Considérations sur la précision
    L'entrée analogique prend une valeur entre 0 et 1024 pour une tension variant entre 0 et 5v.
    La précision de la mesure est donc de 5 / 1024, soit 0.0048 v (~4.8 milliVolts).

    Hors, le TMP36 à un rapport de 10 mv par degré.

    La mesure via l'entré analogique est donc précise à +/- 0.5 °c.

    Augmenter la précision de l'entrée analogique
    En alimentant le TMP36 en 3.3 volts (disponible sur le board Arduino).
    Et en utilisant cette tension de  3.3v comme référence (pin ARef) pour les lectures analogiques, on améliore la précision de lecture.

    En effet, la valeur lue sur l'entrée analogique évoluera de 0 à 1024 pour une tension évoluant entre 0 et ARef (3.3 volts).
    Soit une précision de 3.3 / 1024 = 0.0032 v, soit 3.2 milliVolts.
    L'erreur est ici réduite à 0.33°C (1/3 de °C).

    Note technique:
    Initialiser le tension de référence pour l'acquisition analogique à l'aide de l'instruction analogReference(EXTERNAL) dans la fonction setup().

    Ne pas oublier de modifier la ligne de code calculant la conversion de analogRead en tension.
    La ligne de code passe de
       float tension = valeur * 5.0;
    à
       float tension = valeur * 3.3;

    Ressources