Thermomètre USB à sonde de platine

Ce projet vise à réaliser un thermomètre capable d’enregistrer des points, de les envoyer à un PC via USB et de permettre son utilisation en autonomie. La température est acquise par une thermorésistance en platine ou par un LM35 monté sur le circuit imprimé. Les informations sont traitées par un classique PIC18F4550 et affichées par un afficheur LCD.

1 – Le conditionneur pour Pt500

Schéma du conditionneur

Les thermorésistances à fil de platine sont des capteurs de température de qualité offrant une bonne répétabilitée et une grande étendue de mesure (possibilité de mesurer des températures très faibles, de l’ordre de quelques kelvins). Malgré leur coût élevé, ces sondes de température sont très répandues pour les applications de mesure de précision.

D’une manière générale, la résistance électrique des métaux augmente avec la température. En effet, la température se traduit par la vibration des atomes constitutifs de la matière autour de leur position d’équilibre. Plus la température est élevée, plus l’amplitude de vibration est grande.

Le modèle communément utilisé pour décrire les métaux est le suivant: on considère un réseau de noyaux atomiques aux positions d’équilibre fixes baignant dans une « mer d’électrons ». C’est cette mer d’électrons qui permet aux métaux de conduire l’électricité. Une forte amplitude de vibration des atomes, donc des noyaux, va rendre le mouvement des électrons de conduction plus difficile: la résistance électrique augmente.

La loi de variation de résistance des métaux est la suivante:

R(\theta ) = R_0\cdot (1 + \alpha \cdot \theta + \beta \cdot \theta^2 + \gamma \cdot \theta^3 + ...)

Thêta correspond à la température du fil en °C et R0 correspond à la résistance du fil à 0°C. La finesse du modèle peut être adaptée à l’application de la sonde et à la précision recherchée. Pour le platine les coefficients sont les suivants:
\alpha = 3.9083\cdot 10^{-3} K^{-1}
\beta = -5.775\cdot 10^{-7} K^{-2}
\gamma = -4.183\cdot 10^{-12} K^{-3}
Ma sonde est une Pt500. Cela signifie qu’elle utilise un fil de platine et que sa résistance à 0°C est 500 Ohms. Le conditionneur que je propose peut bien sûr être modifié pour utiliser des Pt100, PT1000 et autres sondes résistives comme les thermistances (CTN et CTP à oxydes métalliques). Le traitement du signal devra être adapté en conséquence.

La mesure de la température se résume donc à une mesure de résistance. Il est possible d’appliquer simplement la loi d’Ohm: faire circuler un courant dans la sonde et mesurer la tension à ces bornes. Cette méthode d’apparence simpliste offre de bons résultats. Cependant, le principal inconvénient de cette méthode est la présence d’un mode commun. En claire, la tension correspondant à une température nulle n’est pas 0V mais U/R0. Pour pallier à cet inconvénient, j’ai préféré utiliser un pont de Wheatstone.

Le pont de Wheatstone est basé sur le principe du diviseur de tension. Il est très utilisé pour les applications de mesure, notamment le conditionnement de jauges de déformation résistives. L’idée est de réaliser un pont diviseur de référence avec des résistances fixes de précision et un autre contenant le capteur, puis de mesurer la tension différentielle entre les deux points milieux des ponts. Si les résistances fixes du pont sont choisies judicieusement, il est possible d’annuler le mode commun. S’il n’y a qu’un capteur dans le pont, le montage est dit « quart de pont ». Il est possible d’augmenter la sensibilité du pont en mettant deux ou quatre capteurs (montages demi-pont ou pont complet) à condition d’avoir des capteurs dont la résistance varie dans des directions opposées pour une même stimulation.

Pour conditionner ma Pt500, j’ai réalisé un montage quart de pont avec des résistances fixes de 500 Ohms (deux 1k en parallèle). Ainsi à 0°C, la tension de sortie du pont est égale à E/2 – E/2 = 0V (où E est la tension d’alimentation du pont)!

La mesure de la tension différentielle est confiée à un amplificateur d’instrumentation: l’INA126. Basiquement, il s’agit d’un montage soustracteur de tension. À la différence d’un montage traditionnel mettant en jeu un seul amplificateur opérationnel, l’amplificateur d’instrumentation présente une très grande impédance sur ses deux entrées (environ 10^12 Ohms). Pour cette application, l’INA126 peut avantageusement être remplacé par son petit frère l’INA125 qui propose en plus une référence de tension pour alimenter le pont. Le gain de l’amplificateur d’instrumentation est fixé par une résistance externe: G = 5 + 80k/Rg. Je ne l’ai pas connectée, ce qui m’offre un gain de 5 qui convient parfaitement à mon application.

L’INA126 est alimenté comme tous les composants du montage par le 5V issu de l’alimentation. On se place en limite de fonctionnement de l’amplificateur (tension mini d’alimentation: +/- 1.35V soit 2.70V). Comme tous les amplificateurs opérationnels (à part la série des LM124, 224 et 324) il a besoin d’une alimentation symétrique, ou au moins d’une partie négative et d’une partie positive, pour pouvoir amplifier des signaux tantôt positifs, tantôt négatifs. L’INA126 à un fonctionnement un peu particulier: il a besoin d’une tension alimentation et d’une tension de référence. La sortie de l’INA126 est alors: dans la mesure où Vout est inférieure à la tension d’alimentation.

Dans une application classique, l’INA126 serait alimenté en +15V / -15V avec Vref = 0V. Ainsi, il pourrait amplifier tous les signaux positifs ou négatifs qui ne feraient pas saturer la sortie. Dans mon montage, je l’ai alimenté en +5V / 0V avec Vref fixé à 1V par un potentiomètre bufferisé par un LM124 (lui aussi alimenté en +5V / 0V). Ainsi les signaux négatifs donneront ne valeur comprise entre 1V et 0V quand les signaux positifs donneront une sortie comprise entre 1V et 5V. J’ai délibérément choisi Vref différent 2.5V pour obtenir une plus grande dynamique dans les températures positives (voir le chapitre 4 – Calculs).

NB:
La mesure de température est l’une des plus compliquées à réaliser: on mesure tout sauf ce qui nous intéresse (en réalité, on mesure la température de l’élément sensible, qui peut différer sensiblement de la température que l’on souhaite mesurer). En effet, pour mesurer une résistance électrique, il faut faire circuler un courant dedans! C’est là qu’intervient l’effet Joule: P = R.I². En mesurant la résistance de la sonde de température, on l’échauffe. Tout est question de compromis: il faut maintenir le courant assez faible pour limiter l’échauffement, mais il faut que la tension de point milieu du pont de Wheatstone soit suffisante pour polariser l’amplificateur d’instrumentation. Donc en alimentant le pont avec une tension faible, on s’assure de peut échauffer la sonde, mais l’amplificateur risque de ne pas fonctionner (j’ai eu des problèmes en alimentant le pont sous 50mV), par contre, en alimentant le pont avec une tension plus importante, on augmente le rapport signal sur bruit et on s’assure la polarisation de l’amplificateur, mais on chauffe la sonde… En alimentant le pont en 5V avec des résistances de 500 Ohms, j’ai un courant d’à peu près 5mA qui circule dans ma sonde, soit une puissance dissipée de 12.5mW à 0°C. À la mise sous tension, on observe une légère variation du signal de sortie due à l’auto échauffement de la sonde, mais l’effet reste négligeable pour des mesures courantes. Par contre si la sonde sert à mesurer la température d’un cryostat, il faut apporter un soin tout particulier au choix du courant traversant la sonde. Pour remplacer la Pt500 par une Pt100, il est souhaitable de monter une résistance de 100 Ohms en série avec le pont pour abaisser la tension d’alimentation du pont à 2.5V. Dans ces conditions, l’INA126 fonctionne et la sonde ne chauffe pas trop. Une astuce consistant à alimenter la sonde uniquement pendant l’acquisition de la tension de pont peut être utilisée pour limiter l’échauffement.

2 – L’alimentation

Schéma de l'alimentation

Pour ce projet, j’ai eu envie d’essayer quelque chose de nouveau: une alimentation mixte sur USB et sur batterie avec possibilité de recharge de la batterie par l’USB. Voici les problèmes auxquels je me suis heurté.

Tout d’abord, pour alimenter un montage fonctionnant en 5V à partir d’une source de tension aussi fluctuante que des piles ou une batterie, qui plus ai offrant une tension inférieure à 5V, il faut un régulateur de tension particulier. Une fois n’est pas coutume, Powertrend (racheté par TI) va nous simplifier la vie ! Pour l’histoire, Powertrend est une entreprise spécialisée dans la conception de régulateurs de tension à découpage. Il propose un régulateur BOOST, le PTN04050, qui peut fournir une tension ajustable entre 5V et 15V sous 12W à partir d’une alimentation comprise entre 2.65V et 5.5V. La seule contrainte est que la tension d’alimentation doit être au moins inférieure à la tension de sorties de 0.5V. C’est parfait me direz-vous, en mettant deux piles en série on atteint 3V, avec trois batteries en série, on monte à 3.6V, donc pas de quoi s’inquiéter ! En effet, si le montage était exclusivement alimenté par cette source d’énergie, il n’y aurait pas de problème. Mais je souhaite aussi alimenter mon thermomètre depuis l’USB, qui fournit lui du 5V… Il peut sembler idiot de réguler du 5V pour obtenir du 5V, mais dans le cas d’une alimentation double, c’est nécessaire.

Une petite pirouette électronique permet de s’en sortir honorablement! Pour choisir la source d’alimentation, je monte en série avec chaque source une diode AU SILICIUM (nous verrons pourquoi c’est important…).

Supposant une alimentation sur batterie, donc 3.6V en entrée. Quand la batterie alimente le montage, la tension à l’entrée du régulateur est 3.6V moins la tension de seuil de la diode (0.6V pour le silicium, cf diagramme d’énergie des semi-conducteurs => Eg = 0.6 eV pour le silicium) donc 3V (juste aux limites de fonctionnement du régulateur!). Quand l’USB est connecté, la tension à l’entrée du régulateur est donc 5V – 0.6V = 4.4V (là encore aux limites de fonctionnement du régulateur). Comme les 4.4V sont supérieurs aux 3.6V de la batterie, la diode en série avec la batterie se retrouve bloquée. C’est là que l’utilisation de diodes au silicium est obligatoire. En mettant une diode au germanium en série avec l’USB, on obtient en entrée du régulateur une tension de 5V-0.3V = 4.7V, trop proche du 5V de sortie, et le régulateur ne fonctionne pas correctement.

Enfin, une résistance de 10 Ohms entre l’alimentation USB et une diode montée en inverse en parallèle de l’interrupteur permettent la charge de la batterie sous un courant de (5V-3.6V-0.6V)/10 = 80mA (en réalité, les 80mA correspondent au courant de maintien, quand la batterie est complètement chargée).

3 – Le montage complet

Schéma général

La tension fournie par l’INA126 est directement appliquée à une entrée analogique du PIC18F4550, ainsi que la tension Vref. J’ai ajouté un LM35 pour pouvoir mesurer la température ambiante même sans la sonde Pt500. Le PIC travaille à une fréquence de 48MHz, à partir d’un quartz oscillant à 20MHz (cf: interface HID). Les températures sont affichées sur un écran LCD 2 lignes 16 caractères monté en mode 4bits. Le contraste et la luminosité du rétroéclairage (selon modèle) sont ajustés par deux potentiomètres. Un connecteur ICSP permet de programmer le PIC directement avec un pickit ou un autre programmateur afin de se passer d’un bootloader USB qui ralentit considérablement le démarrage du PIC.

Le schéma proposé peut être amélioré en connectant l’afficheur LCD sur un autre port pour récupérer les lignes 4 à 7 du port B (qui envoient des interruptions au microprocesseur) pour y connecter des boutons poussoirs.

4 – Calculs

Une fois le montage réalisé, il faut savoir comment, à partir des deux entrées analogiques du PIC, remonter à la température mesurée. Un peu de maths nous donnent rapidement la réponse:

Partons de la sonde. Pour une utilisation courante, je me suis fixé une dynamique de mesure allant de -40°C à +100 °C. Calculons les résistances de la sonde pour ces deux extrêmes (j’utilise un modèle à l’ordre un, négligeant les coefficients bêta, gamma et supérieurs):
R(-40) = 500\cdot (1 + 3.9\cdot 10^{-3}\cdot (-40)) = 422\Omega
R(100) = 500\cdot (1 + 3.9\cdot 10^{-3}\cdot 100) = 695\Omega

On obtient donc deux valeurs de Delta_R pour les deux extrêmes:

\Delta R_{min} = -78\Omega
\Delta R_{max} = 195\Omega

En introduisant cette sonde dans le pont suivant, on obtient:

Pont de Wheatstone

V = E\cdot \frac{R2\cdot R3-R1\cdot R4}{(R1+R3)\cdot (R2+R4)}

On prend: R1 = R2 = R3 = R_0 ; R4 = R_0 + \Delta R en supposant de petites variations de Delta_R (inférieures à 10%), l’expression devient:

V = \frac{E}{4}\cdot \frac{\Delta R}{R}

Cette expression bien connue est très souvent prise pour argent comptant. Cependant, pour de grandes variations de résistances, comme pour notre application, ce modèle linéaire n’est plus valable:

Simulation de la réponse d'un pont de Wheatstone

Je vais donc utiliser la formule de base du pont. En la renversant, on obtient l’expression de R(Thêta) en fonction de R0, E et V la tension mesurée aux bornes du pont.

R(\theta ) = \frac{-R_0\cdot (2\cdot V-E)}{2\cdot V+E}

En introduisant l’expression de R(Thêta) en fonction de la température, on obtient l’expression suivante:

R_0\cdot (1+\alpha \cdot \theta) = \frac{-R_0\cdot (2\cdot V-E)}{2\cdot V+E} \Leftrightarrow \theta = \frac{-4\cdot V}{\alpha \cdot V+E}

Nous tenons donc l’expression de la température en fonction de la tension de déséquilibre du pont. Calculons maintenant les tensions correspondant à -40°C et 100°C afin de choisir le gain de l’amplificateur pour bénéficier de la pleine capacité des convertisseurs du PIC. Pour ce faire, je vais utiliser le modèle linéaire du pont.

V(100^oC) = \frac{5}{4} \cdot \frac{195}{500} = 488mV
V(-40^oC) = \frac{5}{4} \cdot \frac{-78}{500} = -195mV

Ce qui donne une excursion de 488+195 = 683 mV. Pour occuper l’excursion maximale des convertisseurs du PIC, il faut amener cette variation de 683mV au plus proche des 5V de pleine échelle. Donc un gain théorique de 5/0.683 = 7.32. J’ai choisi de me simplifier l’existence et de me contenter d’un gain de 5 (qui me permet de ne pas monter la résistance Rg de l’INA126). Avec ce gain de 5, une entrée de -40°C donne une tension de -975mV. Je choisis donc la tension Vref de l’INA126 à 1V. La température minimale mesurable est obtenue pour une tension de déséquilibre de -1/5 = -0.2V et devient donc:

\Delta R = \frac{4\cdot R\cdot V}{E} = \frac{4\cdot 500\cdot -0.2}{5} = -80\Omega
\theta = \frac{-(R_0-R(\theta )}{\alpha \cdot R_0} = \frac{-(500-420)}{3.9\cdot 10^{-3} \cdot 500} = -41.0^oC

Pour les valeurs positives, on refait le même calcul, avec cette fois-ci une tension de déséquilibre de 4/5 = 0.8V:
\Delta R = \frac{4\cdot R\cdot V}{E} = \frac{4\cdot 500\cdot 0.8}{5} = 200\Omega
\theta = \frac{-(R_0-R(\theta )}{\alpha \cdot R_0} = \frac{-(500-700)}{3.9\cdot 10^{-3} \cdot 500} = 102.5^oC

Calculons maintenant le quantum de température dû à l’échantillonnage à l’entrée du PIC. Les convertisseurs du PIC travaillent sur 10 bits, ce qui fait 1024 points:

q = \frac{102.5+41}{1024} = 0.14^oC

5 – Programmation

Comme on ne change pas une équipe qui gagne, j’ai utilisé MikroC pour programmer mon PIC. Le programme que je vous propose ci-dessous fait juste l’acquisition des tensions, le traitement et l’affichage. Je ne me suis pas encore penché sur l’interface USB et le logiciel PC de traitement de données.

// LCD module connections
sbit LCD_RS at LATB0_bit;
sbit LCD_EN at LATB1_bit;
sbit LCD_D4 at LATB2_bit;
sbit LCD_D5 at LATB3_bit;
sbit LCD_D6 at LATB4_bit;
sbit LCD_D7 at LATB5_bit;
 
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
// End LCD module connections
 
#include "USBdsc.c"
#define TAILLE_BUFFER  64
#define TAILLE_MOYENNE 10
#define PE             5.
#define N              1024.
#define ALPHA          0.0039
#define E              5.
#define VOIE_OFFSET    2
#define VOIE_PT500     1
#define VOIE_LM35      0
#define GAIN_INA126    5
 
char ReadBuffer[TAILLE_BUFFER], WriteBuffer[TAILLE_BUFFER];
 
void Vider_Buffer(char * Buffer)
{
     char i;
     for (i=0;i<TAILLE_BUFFER;i++) Buffer[i]=0;
}
 
void interrupt()
{
    if (PIR2.USBIF == 1)
    {
      USB_Interrupt_Proc();
    }
}
 
void InitPic() {
     ADCON1=0b1011;
     CMCON = 7;
     TRISB = 0;
     
//------------- USB -------------
    TRISC.f4=1;  //D-
    TRISC.f5=1;  //D+
    HID_Enable(&ReadBuffer,&WriteBuffer);
}
 
int GetSample (int channel) {
    int i;
    int mean;
    
    mean = 0;
    
    for (i=0; i<TAILLE_MOYENNE; i++)
    {
      mean += ADC_Read(channel);
      Delay_ms(1);
    }
    mean /= TAILLE_MOYENNE;
    return mean;
}
 
void main() {
     float value;
     float offset;
     float temp_pt500 = 0;
     
     char ligne1[17];
     char ligne2[17];
     
     InitPic();
     Lcd_Init();
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Cmd(_LCD_CURSOR_OFF);
     while(1) {
              value = GetSample(VOIE_LM35) * PE / N;
              sprintf(ligne2, "LM35: %2.1f °C  ",value/0.01);
              Lcd_Out(2,1,ligne2);
              
              offset =  (GetSample(VOIE_OFFSET) * PE / N);
              value = ((GetSample(VOIE_PT500) * PE / N) - offset)/GAIN_INA126;
              temp_pt500 = (4. * value) / (ALPHA * (2.*value + E));
              sprintf(ligne1, "Pt500: %2.1f °C  ",temp_pt500);
              Lcd_Out(1,1,ligne1);
 
              Delay_ms(100);
     }
}

 

Libre à vous de modifier ce code pour l’adapter à votre application ! Bonne réalisation à vous et à la prochaine 😉 .

Mise à jour: Envoie des températures par USB

Afin d’exploiter au mieux ce thermomètre, j’ai enfin implanté un protocole de communication sur USB. Il s’inspire de la norme SCPI (prononcez skeepi…) utilisée pour les communications avec les instruments de mesure sur le bus GPIB. Le thermomètre est donc capable de répondre à certaines questions, par exemple *IDN? qui lui demande son nom.

Voici le code source du PIC:

// LCD module connections
sbit LCD_RS at LATB0_bit;
sbit LCD_EN at LATB1_bit;
sbit LCD_D4 at LATB2_bit;
sbit LCD_D5 at LATB3_bit;
sbit LCD_D6 at LATB4_bit;
sbit LCD_D7 at LATB5_bit;
 
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
// End LCD module connections
 
#include "USBdsc.c"
#define TAILLE_BUFFER  64
#define TAILLE_MOYENNE 10
#define PE             5.
#define N              1024.
#define ALPHA          0.0039
#define E              5.
#define VOIE_OFFSET    2
#define VOIE_PT500     1
#define VOIE_LM35      0
#define GAIN_INA126    5
 
#define TMR0_PRECHARGE 28036
 
#define name           "Thermometre USB"
#define soft_rev       "1.1.0"
#define hard_rev       "1.0"
#define mcu            "PIC18F4550"
#define clk            "48MHz"
#define developper     "Amaury LAURENT"
#define release_date   "03/11/2012"
 
char ReadBuffer[TAILLE_BUFFER] absolute 0x500;
char WriteBuffer[TAILLE_BUFFER] absolute 0x540;
 
int GetSample (int channel);
char toogle = 0;
 
void Vider_Buffer(char * Buffer)
{
     char i;
     for (i=0;i<TAILLE_BUFFER;i++) Buffer[i]=0;
}
 
void interrupt()
{
    float value;
    float offset;
    float temp_pt500 = 0;
 
    char ligne1[17];
    char ligne2[17];
    
    if (PIR2.USBIF == 1)
    {
      INTCON.TMR0IE = 0;
      USB_Interrupt_Proc();
 
      if (HID_Read() != 0) {
        Vider_Buffer(WriteBuffer);
        if (strstr(ReadBuffer, "LM35?") != 0) {
           value = GetSample(VOIE_LM35) * PE / N;
           sprintf(WriteBuffer, "%2.1f",value/0.01);
        }
        else if (strstr(ReadBuffer, "MAX35?") != 0) {
           value = 4.99;
           sprintf(WriteBuffer, "%2.1f",value/0.01);
        }
        else if (strstr(ReadBuffer, "MIN35?") != 0) {
           value = 0.0;
           sprintf(WriteBuffer, "%2.1f",value/0.01);
        }
        else if (strstr(ReadBuffer, "PT500?") != 0) {
           offset =  (GetSample(VOIE_OFFSET) * PE / N);
           value = ((GetSample(VOIE_PT500) * PE / N) - offset)/GAIN_INA126;
           temp_pt500 = (4. * value) / (ALPHA * (2.*value + E));
           sprintf(WriteBuffer, "%2.1f",temp_pt500);
        }
        else if (strstr(ReadBuffer, "MAX500?") != 0) {
           offset =  (GetSample(VOIE_OFFSET) * PE / N);
           value = (4.99 - offset)/GAIN_INA126;
           temp_pt500 = (4. * value) / (ALPHA * (2.*value + E));
           sprintf(WriteBuffer, "%2.1f",temp_pt500);
        }
        else if (strstr(ReadBuffer, "MIN500?") != 0) {
           offset =  (GetSample(VOIE_OFFSET) * PE / N);
           value = (0.0 - offset)/GAIN_INA126;
           temp_pt500 = (4. * value) / (ALPHA * (2.*value + E));
           sprintf(WriteBuffer, "%2.1f",temp_pt500);
        }
        else if (strstr(ReadBuffer, "*IDN?") != 0) {
           strcpy(WriteBuffer, name);
        }
        else if (strstr(ReadBuffer, "*SREV?") != 0) {
           strcpy(WriteBuffer, soft_rev);
        }
        else if (strstr(ReadBuffer, "*HREV?") != 0) {
           strcpy(WriteBuffer, hard_rev);
        }
        else if (strstr(ReadBuffer, "*MCU?") != 0) {
           strcpy(WriteBuffer, mcu);
        }
        else if (strstr(ReadBuffer, "*CLK?") != 0) {
           strcpy(WriteBuffer, clk);
        }
        else if (strstr(ReadBuffer, "*AGE?") != 0) {
           strcpy(WriteBuffer, release_date);
        }
        else if (strstr(ReadBuffer, "*DEV?") != 0) {
           strcpy(WriteBuffer, developper);
        }
        else {
             strcpy(WriteBuffer, "Unknown command");
        }
        while(!HID_Write(&WriteBuffer, TAILLE_BUFFER));
        /*
        Lcd_Out(1,1,ReadBuffer);
        Lcd_Out(2,1,WriteBuffer);
        */
        Vider_Buffer(ReadBuffer);
      }
 
      INTCON.TMR0IE = 1;
    }
 
    if (INTCON.TMR0IF == 1) {
       PIE2.USBIE = 0;
       TMR0L = TMR0_PRECHARGE % 256;
       TMR0H = TMR0_PRECHARGE / 256;
       
       if (toogle == 0) {
          Lcd_Init();
          Lcd_Cmd(_LCD_CLEAR);
          Lcd_Cmd(_LCD_CURSOR_OFF);
          toogle = 1;
       }
 
       value = GetSample(VOIE_LM35) * PE / N;
       sprintf(ligne2, "LM35: %2.1f °C  ",value/0.01);
       Lcd_Out(2,1,ligne2);
 
       offset =  (GetSample(VOIE_OFFSET) * PE / N);
       value = ((GetSample(VOIE_PT500) * PE / N) - offset)/GAIN_INA126;
       temp_pt500 = (4. * value) / (ALPHA * (2.*value + E));
       sprintf(ligne1, "Pt500: %2.1f °C  ",temp_pt500);
       Lcd_Out(1,1,ligne1);
 
       INTCON.TMR0IF = 0;
       PIE2.USBIE = 1;
    }
}
 
void InitPic() {
     ADCON1=0b1011;
     CMCON = 7;
     TRISB = 0;
     TRISD.f0 = 0;
     TRISD.f1 = 0;
     
     LATD.f0 = 1;
     LATD.f1 = 1;
     
     //------ Display Timer IT -------
    INTCON.GIE = 1;
    INTCON.PEIE = 1;
    INTCON.TMR0IE = 1;
    PIE2.TMR1IE = 1;
 
    TMR0L = TMR0_PRECHARGE % 256;
    TMR0H = TMR0_PRECHARGE / 256;
    T0CON = 0b110000100; // PS = 32
     
    //------------- USB -------------
    TRISC.f4=1;  //D-
    TRISC.f5=1;  //D+
    HID_Enable(&ReadBuffer,&WriteBuffer);
}
 
int GetSample (int channel) {
    int i;
    int mean;
    
    mean = 0;
    
    for (i=0; i<TAILLE_MOYENNE; i++)
    {
      mean += ADC_Read(channel);
    }
    mean /= TAILLE_MOYENNE;
    return mean;
}
 
void main() {
     
     InitPic();
 
     while(1) ;
}

 

Pour communiquer avec le thermomètre, vous pouvez utiliser LabVIEW et les drivers VISA, ou bien faire appel à la dll hid (sous Windows) pour accéder au périphérique avec d’autres langages. Voici un exemple de logiciel écrit en C# (prononcer C sharp).

Télécharger le projet MikroC

Laisser un commentaire