samedi 29 septembre 2012

Mesurer une température avec un Arduino

Le projet est simple:  construire un thermomètre au moyen d'un Arduino, d'un capteur de température et d'un afficheur à cristaux liquides.

Option 1:  le capteur numérique DS18B20

Je me suis procuré sur eBay une sonde constituée d'un capteur DS18B20 enfermé dans une capsule métallique hermétique et muni d'un câble d'environ 1 mètre de long (cherchez "Digital Temperature Sensor Probe DS18B20").

Les branchements du capteur à l'Arduino sont extrêmement simples:
  • fil rouge du capteur:  5 V de l'Arduino
  • fil noir du capteur: GND de l'Arduino
  • fil bleu du capteur:  entrée numérique 8 de l'Arduino
  • résistance de 4,7 K placée entre le fil rouge et le fil bleu
La sonde est précalibrée, les résultats sont extrêmement stables, et vous pouvez en principe mesurer n'importe quelle température entre -55°C et +125°C avec une résolution d'un demi degré.  En plus, puisque chaque DS18B20 dispose de sa propre adresse encodée en usine, vous pouvez relier plusieurs dizaines de capteurs de température à votre Arduino en n'utilisant qu'une seule entrée numérique!

Le seul inconvénient que je pourrais y voir, c'est que le décodage du message numérique reçu en provenance du DS18B20 est à mon avis un peu plus compliqué qu'un traditionnel signal analogique, mais la librairie "OneWire" fait le gros du travail.  Pour dire la vérité, je me suis contenté de modifier légèrement un sketch trouvé sur le site Hacktronics, sans me poser trop de questions sur la signification profonde du code.   Pour bien comprendre ce qui se passe, je vous conseille plutôt cet excellent tutoriel en français.

/************************************************************
*
* Thermometre Arduino avec ds18b20 (et un afficheur LCD)
*
* Basé sur un sketch trouvé sur www.hacktronics.com
* Branchements du LCD:
*
* LCD RS : Arduino 12
* LCD Enable : Arduino 11
* LCD D4 : Arduino 5
* LCD D5 : Arduino 4
* LCD D6 : Arduino 3
* LCD D7 : Arduino 2
* LCD R/W : Arduino GND
* Potentiometre 10K entre 5 V et GND, wiper sur LCD V0
*
* Branchements du ds18b20:
*
* GND du ds18b20 : Arduino GND
* Signal du ds18b20: Arduino digital 8
* Vs du ds18b20: Arduino 5 V
*
* https://electroniqueamateur.blogspot.com/2012/09/mesurer-une-temperature-avec-un-arduino.html
*
*****************************************************************/
#include <OneWire.h> // pour le ds18b20
#include <LiquidCrystal.h> // pour l'afficheur LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
OneWire ds(8); // l'entrée 8 de l'Arduino recevra
// les messages du ds18b20
byte i;
byte present = 0;
byte data[12];
byte addr[8];
int HighByte, LowByte, SignBit, Whole, Fract, TReading, Tc_100, FWhole;
void setup(void) {
// initialisation de l'afficheur:
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0,0);
// initialisation du ds18b20:
if ( !ds.search(addr)) {
lcd.clear();
lcd.print("Erreur addr");
delay(1000);
ds.reset_search();
return;
}
if ( OneWire::crc8( addr, 7) != addr[7]) {
lcd.clear();
lcd.print("Ereur CRC");
delay(1000);
return;
}
}
void getTemp() {
int bar;
ds.reset();
ds.select(addr);
ds.write(0x44,1);
present = ds.reset();
ds.select(addr);
ds.write(0xBE);
for ( i = 0; i < 9; i++) {
data[i] = ds.read();
}
LowByte = data[0];
HighByte = data[1];
TReading = (HighByte << 8) + LowByte;
SignBit = TReading & 0x8000; // test most sig bit
if (SignBit) {
TReading = -TReading;
}
Tc_100 = (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25
Whole = Tc_100 / 100; // separate off the whole and fractional portions
Fract = Tc_100 % 100;
if (Fract > 49) {
if (SignBit) {
--Whole;
} else {
++Whole;
}
}
if (SignBit) {
bar = -1;
} else {
bar = 1;
}
}
void printTemp(void) {
lcd.clear();
lcd.setCursor(0,0);
// lcd.print("Temperature: ");
//
if (SignBit) {
lcd.print("-");
}
lcd.print(Whole);
lcd.print(" C");
lcd.setCursor(0,1);
if (SignBit) {
lcd.print(273 - Whole);
}
else{
lcd.print(273 + Whole);
}
lcd.print(" K");
}
void loop(void) {
getTemp();
printTemp();
delay(1000);
}

En ce qui concerne les branchements de l'afficheur à cristaux liquides (LCD), vous pouvez vous référer au schéma publié ici.



Option 2:  le capteur analogique LM35DZ

J'ai aussi essayé le LM35, qui est un capteur de température analogique:  il émet une tension proportionnelle à la température en degrés Celsius (10,0 mV par degré).   Il permet de mesurer des températures similaires au DS18B20:  de -55°C à 150°C, avec une résolution de 0,5°C.  Toutefois, la mesure d'une température négative avec un Arduino entraîne quelques complications, car on ne veut pas acheminer une tension négative à une entrée analogique...

J'ai fabriqué ma propre sonde hermétique en enfermant un LM35DZ dans une gaine thermorétractable et en ajoutant un peu de silicone.

En principe, les branchements à l'Arduino sont ridiculement simples:
  • broche GND du LM35 : GND de l'Arduino
  • broche Vout du LM35:  Entrée analogique 0 de l'Arduino
  • broche Vs du LM35:  Sortie 5 V de l'Arduino
Mais avec environ 1 mètre de câblage entre l'Arduino et le capteur, les résultats étaient un brin décevants:  la température affichée oscillait constamment sur une gamme d'environ 3 degrés.  L'ajout d'une résistance de 68 Ω et d'un condensateur de 1 µF en série entre l'entrée analogique 0 et le GND a permis de stabiliser l'affichage de façon spectaculaire:  il est maintenant très stable et parfaitement en accord avec la mesure obtenue au moyen du DS18B20.

Autre précaution utile:  puisque la tension qui provient à l'entrée analogique de l'Arduino ne dépassera guère 1 V, aussi bien utiliser une valeur de référence de 1,1 V plutôt que la valeur habituelle de 5 V (auquel cas l'appareil n'utiliserait que 20% de la plage disponible).  C'est fait dans le sketch au moyen de l'instruction "analogReference(INTERNAL);".

/************************************************************
*
* Thermometre Arduino avec un LM35D (et un afficheur LCD)
*
* Branchements du LCD:
*
* LCD RS : Arduino 12
* LCD Enable : Arduino 11
* LCD D4 : Arduino 5
* LCD D5 : Arduino 4
* LCD D6 : Arduino 3
* LCD D7 : Arduino 2
* LCD R/W : Arduino GND
* Potentiometre 10K entre 5 V et GND, wiper sur LCD V0
*
* Branchements du LM35D (voir DataSheet):
*
* GND du LM35D : Arduino GND
* Vout du LM35D: Arduino analog 0
* Vs du LM35D: Arduino 5 V
*
* https://electroniqueamateur.blogspot.com/2012/09/mesurer-une-temperature-avec-un-arduino.html
*
*****************************************************************/
// La librairie pour l'afficheur LCD
#include <LiquidCrystal.h>
// Initialisation de la librairie en indiquant les pins que
// nous utiliserons
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int thermoPin = A0; // là où est branché le LM35
int tempC; // température en degrés celcius
int tempK; // conversion en Kelvin
int reading; // lecture brute de l'entrée analogique (0 à 1024)
void setup() {
// nombre de colonnes et de lignes du LCD
lcd.begin(16, 2);
// pour une meilleure resolution, on regle la reference a 1,1 V
analogReference(INTERNAL);
}
void loop() {
// mesure
reading = analogRead(thermoPin);
// conversion en celcius
tempC = round(reading / 9.31);
// conversion en Kelvin
tempK = tempC + 273;
// affichage
lcd.setCursor(0, 0);
lcd.print(tempC);
lcd.setCursor(4, 0);
lcd.print("Celsius");
lcd.setCursor(0, 1);
lcd.print(tempK);
lcd.setCursor(5, 1);
lcd.print("Kelvin");
delay(500);
lcd.clear();
}
view raw Termo_LM35D.ino hosted with ❤ by GitHub

En ce qui concerne les branchements de l'afficheur à cristaux liquides (LCD), vous pouvez vous référer au schéma publié ici.


D'autres options?

Le LM335 est un autre capteur analogique qui peut être utilisée à la place du LM35 (il s'agit d'une diode Zener dont la tension de rupture est proportionnelle à la température.

Un thermocouple pourrait aussi être utilisé si vous désirez mesurer des températures très élevées (dans un four, par exemple).  Et il y a la bonne vieille thermistance, dont la résistance varie avec la température.  Dans ces cas, le calcul d'une température exacte en degrés Celsius à partir du signal mesuré peut par contre se révéler assez complexe.

Yves Pelletier (Twitter: @ElectroAmateur)

3 commentaires:

  1. Bonjour,
    pouvez-vous me dire à quoi correspond l'affichage sur le LCD 296K ???
    Je suis un débutant. Merci

    RépondreSupprimer
  2. bin, en fait, il s'agit de la température en Kelvin, qui est une unité de température absolue.

    RépondreSupprimer
  3. Bonjour, l'afficheur LCD résiste t-il aux rayons uv ? merci d'avance.

    RépondreSupprimer