Outils pour utilisateurs

Outils du site


les_sondes_de_temperature_thermistances_ctn

Les sondes de temperature (Thermistances CTN)


Introduction

Une des choses les plus communes et faciles a mesurer est sans conteste une temperature. Cependant, les capteurs de temperatures ne manquent pas. De la simple thermistance à la sonde de temperature haut-de-gamme PT-100, en passant par les sondes a base de semi-conducteur le choix est multiple, sans oublier les thermocouples !!!

Les sondes PT-1001) sont, à ma connaissances, les plus precises. Elles ont l'avantage d'etre lineaires. c'est a dire que leur loi de variation est de la forme d'une droite R=a*t+100. En effet, ces thermistances utilisent la resistance du platine, qui vrie en fonction de la temperature. Elles ont la caracteristique de faire 100Ohms à 0°C. Un autre avantage est que ce sont des capteurs normalisés : d'une PT-100 à l'autre, elles presentent les memes caracteristiques. Ceci est bien joli, mais leur prix en est du coup trés élevé. D'autres sondes on vu le jour et presentent les memes avantages seule differe la valeur de la resistance à 0°C (PT-500, PT-1000).

Les capteurs de temperatures a base de semi-conducteurs utilisent le fait que la tension de la jonction est inversément proportionelle à la T° absolue. En choisissant un courant tel que la tension à 20°C soit de 540mV, le coéfficient sera d'environ 2mV/°C; c'est approximatif, ça dépend la fabrication de la diode et ce n'est pas parfaitement linéaire, mais cela reste exploitable. Il semble que les diodes au germanium donnent de meilleurs resultats que les diodes au silicium. De meme nombre de precautions sont a prendre, le courant traversant la diode doit etre faible, afin de ne pas la faire chauffer par effet joule (passage du courant), ce qui aurait pour effet de perturber la mesure.

Les thermistance CTN2) ou CTP3) ont l'avantage d'etre bon marché. Leur loi R=f(T) n'est pas lineaire sur toute la plage de mesure ce qui présente un léger desavantage. Cependant leur sensibilité est interressante. Les CTP presente une loi avec des points de dérivé nulles (changement de pente), ce qui restreint leur utilisation a la partie lineaire de la courbe. Les CTN4) ont une loi un peu plus compliquée mais les contructeurs donnent pas mal d'info, le tout est de bien choisir.


CTNs EPCOS série B57164K

Des CTNs, j'en ai quelques une dans mes tiroirs. Le problème etait de connaitre leur comportement. J'avais donc regardé pour trouver les caracteristiques. C'etait pas pratique, sans connaitre precisement la reference de la CTN, il aurait fallu la mettre dans une eceinte regulée, et faire des relevé de R en fonction de la Temperature. Pas tres pratique. En regardant sur farnell, je suis tombé sur les CTNs EPCOS série B57164K5) aux caracteristques tout a fait honorables ([-55°C;155°C]). J'en ai acheté quelques unes.

De la datasheet6), j'ai pu extraire les données et les importer dans une feuille de calcul. De là, un bete graphique permet de visualiser l'allure des courbes. Il devient evident que la loi R=f(T) n'est pas lineaire. Il est egalement remarquable que les Coefficients B (beta) sont plutôt importants au moment du choix, surtout en limite de plage.

Ok. D'accord. Tout ca s'est bien joli, mais “Comment transformer cette variation de resistance en une tension qui pourra etre acquise par l'ADC de notre microcontroleur 7) ?”.

Tout simplement en utilisant le montage “Diviseur de Tension”.

Ce montage se veut un des plus simple en electronique. Il sert a des tas de choses, notamment a polariser les transistors bipolaires (de memoire, à confirmer). Sur le principe, deux resistances (une fixe, une variable) seront connectées en serie entre VCC (5V) et GND (0V). La tension est ensuite mesurée entre les deux resistances.

=⇒ Schéma.

Les resistances que j'ai commandé ont un B25/B100 de 4300K et une valeur a 25°C de 10KOhm. J'ai choisi la resistance en serie R=10KOhm ; je n'ai pas choisi cette valeur par hasard. Avec ces parametres, il est remarquable que la courbe V=f(T) presente une partie lineaire avec la pente la plus forte ayant pour “centre” [55°C;2.5V] et s'etendant quasiement sur la plage [0°C ; 50°C].

La loie R=f(T) etant decroissante : une augmentation de la temperature fait decroitre la resistance. Le fait que la resistance variable constitue le “bas” du pont, la loie V=f(T) est elle aussi decroissante. Il suffit d'intervertir les deux resistances et la loi devient croissante ; ce qui peut etre plus pratique. Pour que ce soit encore plus pratique, consideront que Vcc vaut 1023, soit la valeur de 5V acquise par l'ADC de notre microcontroleur.

Il est ensuite utile d'essayer d'approcher la loi par une droite. Pour ce faire on calcule les parametres des droites (y=a*x+b) entre chaque point. On obtient un coefficient maximal pour 25°C. La droite qui en découle reste proche de la courbe avec une erreur inferieure à 1% sur la plage [10°C;35°C].

Toute cette démarche reste applicable a l'ensemble des CTNs pour peu de disposer de la datasheet. Il est aussi possible de travailler sur des plages de temperatures différentes en adaptant la resistance du pont diviseur a la valeur de la CTN pour la valeur centrale de la plage choisie ; pour travailler autour de 100°C, par exemple, avec la CTN précédemment utilisée, il faudrait mettre une resistance de 5494Ohm ; on prendra la valeur la plus proche.

Il m'apparait possible d'utiliser une CTN sur toute sa plage de fonctionnement en utilisant un potentiometre electronique pour faire varier la resistance du pont diviseur, afin de “reguler” la tension acquise autour de 2,5V. On aurait R=Rt, ce qui permetterai de connaitre la valeur de la CTN, et donc la temperature.

Ci dessous les quelques “extract” des datasheet des CTNs EPCOS serie B57164K, TEWA TT2-100KCH3, et EPCOS G560 100K :
ctn-epcos_b57164k.ods tt2-100kc3h-7.ods ctn-epcos_g560_100k.xlsx


Calculer la température - Approximation Linéaire

Une fois le montage diviseur de tension fait, il convient d’acquérir le signal a l'aide de l'ADC de notre microcontrôleur ; pour ce faire, je vous renvoie au tutoriel sur ce sujet8).

L'acquisition du signal donne un résultat suivant la règle [0V;5V] ⇒ [0;1023] ; 1023, car notre ADC fait 10-bit : 2<sup>10</<sup>-1 = 1023. Cependant le résultat est stocké dans un registre 16-bits.

Partant de là, nous avons plusieurs solutions. La plus simple est d'utiliser la droite y = a*x + b que nous avons vu tout a l'heure, avec le coefficient a le plus fort. L'erreur est grande pour les températures les plus éloignées de 25°C, Cependant la précision du signal électrique sera bonne sur la plage [10°C;35°C].

Dans le cadre d'un thermostat d'ambiance, cela est suffisant. Pour des applications ayant besoin de plus de précision, il faudra peut-être considérer une autre approche.

L'autre approche consiste a utiliser ce qui s'appelle dans le jargon une “lookup table” : on va mettre en memoire la totalité de la table de valeur de resitance de la CTN et calculer la pente et l'ordonnée a l'origine pour chaque segment. On aura ainsi une valeur de T calculée pas trop eloignée de la réalité. Cependant, dans les extremités de la plage, la pente est faible et finie “quasi” horizontale, ce qui risque de resulter sur des erreurs non négligeables.

Il est a noter les microcontroleurs 8-bit tels que les ATmega328P montés sur les platines Arduino n'embarquent pas de FPU 9). Un micrprocesseur 8-bit saurait faire facilement des operations sur des données faisant 8-bit, il lui faudra un petit peu plus de temps pour faire des operations sur 16-bit, encore plus de temps sur 32-bit ; mais cela reste raisonable tant que le calcul se fait sur des entiers. Par contre puisque le microcontroleur ne possede pas de FPU, tout calcul fait avec des flotants sera fait de manière logicielle (au lieu de materielle avec une FPU) ; ceci a un cout en terme de temps processeur a faire ces calculs, mais ce n'est rien a coté du coût pour la mémoire ou plusieurs kOctets sont nécessaire au stockage des fonctions pour effectuer ces calculs. En somme, les flotants, c'est mal ! ^_^

Pour palier a ça, il y a l'arithmétique en virgule fixe, c'est un vrai bonheur et une vrai solution pour nos petits problèmes de calculs. Dans le cas présent, notre ADC nous convertit un signal electrique en une valeur codée sur 10-bit. Cette valeur sur 10-bits est mise dans deux registres consécutif mappés en mémoire, chacun de 8-bit soit un registre de 16-bit. Il nous est possible “d'aligner” le resultat de la conversion à gauche. Nos 10 bits de résultats seront donc alignés sur les bits [15 à 6]. En considerant que la loi est une droite, ou une segment de droite de la forme V = a * T + b, V est connu, c'est le resultat de notre conversion, a est connu, d'apres la dataheet, et b est connu d'apres la datasheet aussi. Il est donc possible de resoudre T = (V - b) / a.

D’après ma feuille de calcul, a vaut 12.1, b vaut 208.99, soit 209. Les opérations de calcul qu'il y a à faire, sont une soustraction suivit d'une division.

Auparavant, il faut transcrire nos deux paramètres de l’équation en nombre a virgule fixe.

Il y a plusieurs méthodes pour calculer en virgule fixe. Soit on multiplie par une puissance de 10, soit par une puissance de 2 ; on peut même faire les deux. Notre ADC nous permet d'aligner le résultat a gauche, les bits [15:6] sont les bits de puissances positives de 2, les bits [5:0] sont les bits de puissances négatives de 2. Par contre, avant toute opération il faudra tout décaler de 6 bits vers la gauche. Pour le cas de 12.1, on va l'encoder de la manière suivante : 121/10 ou 11/10*11. Dans la mesure on l'utilisera pour une multiplication/division, il n'est pas necessaire de decaler les vers la gauche. Pour 208.99, l'arrondit le plus proche est 209, compte-tenu que l'on procedera a une addition/soustraction, il faut decaler la valeur vers la gauche.


Calculer la température - Methode de la Lookup-Table

Un autre solution consiste a mettre toutes les couples {Temperature;Valeur} dans une table ; puis en fonction de la valeur acquise proceder a une interpolation lineaire sur le segment correspondant a la valeur acquise.

A partir des données contructeur, à l'aide d'un tableur, il est facile d'en extraire le couple {Temperature;Valeur}((ctn-epcos_b57164k.ods et d'en faire un tableau de structure de données.

typedef struct
{
	uint16_t uiTemp ;
	uint16_t uiADC_Value ;
} Temp_vs_ADC_Value_t ;
Temp_vs_ADC_Value_t Temp_vs_ADC_Value_LookupTable[] =
{
	{ -55,	   8},
	{ -50,	  12},
	{ -45,	  17},
	{ -40,	  24},
	{ -35,	  33},
	{ -30,	  45},
	{ -25,	  61},
	{ -20,	  82},
	{ -15,	 108},
	{ -10,	 140},
	{  -5,	 179},
	{   0,	 225},
	{   5,	 276},
	{  10,	 331},
	{  15,	 390},
	{  20,	 451},
	{  25,	 512},
	{  30,	 570},
	{  35,	 627},
	{  40,	 679},
	{  45,	 725},
	{  50,	 767},
	{  55,	 804},
	{  60,	 836},
	{  65,	 864},
	{  70,	 887},
	{  75,	 907},
	{  80,	 924},
	{  85,	 939},
	{  90,	 951},
	{  95,	 961},
	{ 100,	 970},
	{ 105,	 977},
	{ 110,	 983},
	{ 115,	 989},
	{ 120,	 993},
	{ 125,	 997},
	{ 130,	1000},
	{ 135,	1003},
	{ 140,	1006},
	{ 145,	1008},
	{ 150,	1010},
	{ 155,	1011},
} ;

L'algorythme de selection du segment et calcul de la temperature est ensuite assez simple. Il convient de faire appel a nos souvenirs de mathematiques de 4eme.

	double dA, dB, dB1, dB2, dY1, dY2, dX1, dX2 ;
 
	if( uiADCvalue < Temp_vs_ADC_Value_LookupTable[0].uiADC_Value )
	{	// Acquired ADC Value is lower than lower bound
		// Takes the two first points
		dX1 = Temp_vs_ADC_Value_LookupTable[0].uiTemp ;
		dY1 = Temp_vs_ADC_Value_LookupTable[0].uiADC_Value ;
		dX2 = Temp_vs_ADC_Value_LookupTable[1].uiTemp ;
		dY2 = Temp_vs_ADC_Value_LookupTable[1].uiADC_Value ;
	}
	else if( uiADCvalue >= Temp_vs_ADC_Value_LookupTable[sizeof(Temp_vs_ADC_Value_LookupTable)/sizeof(Temp_vs_ADC_Value_t)-1].uiADC_Value )
	{	// Acquired ADC Value is greater than upper bound
		// Takes the two last points
		dX1 = Temp_vs_ADC_Value_LookupTable[sizeof(Temp_vs_ADC_Value_LookupTable)/sizeof(Temp_vs_ADC_Value_t)-2].uiTemp ;
		dY1 = Temp_vs_ADC_Value_LookupTable[sizeof(Temp_vs_ADC_Value_LookupTable)/sizeof(Temp_vs_ADC_Value_t)-2].uiADC_Value ;
		dX2 = Temp_vs_ADC_Value_LookupTable[sizeof(Temp_vs_ADC_Value_LookupTable)/sizeof(Temp_vs_ADC_Value_t)-1].uiTemp ;
		dY2 = Temp_vs_ADC_Value_LookupTable[sizeof(Temp_vs_ADC_Value_LookupTable)/sizeof(Temp_vs_ADC_Value_t)-1].uiADC_Value ;
	}
	else
	{	// Find the interval where to perfom the computing of temperature
		uint16_t ui ;
		for(
			ui = 0 ;
			ui < sizeof(Temp_vs_ADC_Value_LookupTable)/sizeof(uint16_t) &&
			uiADCvalue >= Temp_vs_ADC_Value_LookupTable[ui].uiADC_Value ;
			ui++ ) ;
 
		// Computes the X1, Y1, X2, Y2 points
		dX1 = (ui*5.0-55.0) ;
		dY1 = Temp_vs_ADC_Value_LookupTable[ui].uiADC_Value ;
		dX2 = ((ui+1)*5.0-55.0) ;
		dY2 = Temp_vs_ADC_Value_LookupTable[ui+1].uiADC_Value ;
	}
 
	// Computes the slope and offset fir the Lookup-segment
	dA = ( dY2 - dY1)/( dX2 - dX1 ) ;
	dB2 = dY2 - dA*dX2 ;
	dB1 = dY1 - dA*dX1 ;
	dB  = (dB1+dB2)/2.0 ;
 
	// Computes the Temperature
	double dTemp = (uiADCvalue - dB) / dA ;
 
	//Removes 1.0 Celsius Degree Offset
	dTemp -= 1.0 ;
 
	PDEBUG( "CTN-Float\t%f\n", dTemp ) ;

Ce code est un extrait du projet Thermostat dont le bac à sable est situé ici : https://github.com/spelle/AVR_ADC.git.


Remarques, Propositions d'améliorations, Questions

Vous pouvez poster vos remarques, propositions d’amélioration, et questions sur le forum, dans la discussion prévue a cet effet : http://fablab-robert-houdin.org/fablab/phpBB-3.0.11-fr/phpBB3/viewtopic.php?f=3&t=17


les_sondes_de_temperature_thermistances_ctn.txt · Dernière modification: 2013/12/15 21:05 par spelle