Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Commentez, partagez et proposez des Tutos en langage C !
Capteur de température numérique : DS18B20+
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#1 Message par Jérémy » dim. 23 juil. 2017 20:02

Bonjour à tous,


Petit tutoriel sur le célèbre capteur de Température numérique : le DS18B20+ !


Configuration :
Plaque easyPIC7.jpg

- Capteur de température : DS18B20+
- Carte de développement : Plaque EasyPIC V7
- Compilateur : Mikro prog suite fo PIC V 2.51
- IDE : MikroC Pro for PIC Version 7.1.0
- PIC : PIC18F46K22



Pré-requis nécessaire:

- Savoir afficher des infos sur un LCD ( tuto à venir).
- Connaitre le protocole One-Wire. Vous trouverez toutes les explications en suivant ce lien : Tutoriel 1-Wire

Le but :

Le but sera de vous familiariser avec ce capteur de température numérique afin de pouvoir l'utiliser simplement.

Vous permettant par exemple d'afficher la température sur un écran LCD pour un faire thermomètre, une surveillance de température pour la charge de batterie, , faire un thermostat etc ....
On peut envisager de très nombreuses applications.

Pour mettre en œuvre ce capteur de température nous utiliserons le protocole One-Wire inclue dans les librairies de MikroC.
Ici je n'expliquerais pas le principe de ce protocole One-Wire. Voici un lien trés bien documenté : Tutoriel 1-Wire

1/ Préambule:

Ce genre de capteur est très précis par rapport à ces homologues analogiques ( +/- 0.5 °C) . Tous comme les analogiques, Il en existe de nombreux types dans cette catégorie et avec beaucoup de variantes DS18B20, PT100, la série MCP... .

Si vous possédez une référence fiable il sera toujours possible de "l'étalonner" en tronquant légèrement les valeurs .

Pour dialoguer avec notre capteur nous utiliserons la librairie de mikroC. celle-ci automatise le dialogue avec le capteur. On va pouvoir écrire, lire et "reseter" notre capteur en un coup de cuillère a pot. La plupart des compilateur ont leur propre librairie One-Wire.

Les points clés à regarder pour faire votre choix sont :

  • La tension d'alimentation suivant votre montage. Dans ce Tutoriel la tension d'alimentation sera de 5V. Ce qui rentre dans les caractéristiques du DS18B20+ (page 19, 3.0V à 5.5V).
  • La plage de température désirée. ici avec le DS18B20+ elle s'étend de -55°C à +125°C.
  • La précision souhaitée. Le DS18B20+ à une précision de +/-0.5°C entre -10°C et 85°C.
  • Le type de communication souhaité : le DS18B20+ utilise le protocole One-Wire (1-W).



2/ Le capteur DS18B20+ et son schéma :

La Data-Sheet est plus compliquée qu'un capteur analogique du fait qu'il va falloir "dialoguer" avec lui.
schema.png

Pour ce tutoriel nous admettrons qu'il y a UN et un SEUL capteur sur le BUS One-Wire.
Chaque capteur possède un "numéro de série" codé sur 64 bits. Ainsi cela autorise plusieurs capteur sur le BUS 1-wire. Ce sujet ne sera pas abordé dans ce tutoriel car cela complique un peu les choses. ( peut être un tuto à venir qui sait .... :shock: ).

Les capteurs numériques proposent quelques options du fait qu'ils embarquent une petite mémoire (nommée : SCRATCHPAD). On peut par exemple régler une alarme à une température voulue ou encore régler la résolution de la lecture .
Il est même possible de l’alimenter par le fil du bus 1-W ( 2 fils nécessaire en tout au lieu de 3).

Une résistance de tirage vers Vdd (pull-up) est nécessaire sur la ligne du BUS pour le faire fonctionner correctement.



3/ La mémoire : Scratchpad

Scratchpad.jpg

Le scratchpad, mise à part que ce soit dur à écrire et à dire :lol: , est une sorte de mémoire tampon. Elle est composée de seulement 9 octets. Certains sont réservés et donc non accessible.

C'est dans cette mémoire que l'on va écrire notre configuration, mais également que l'on va lire nos valeurs de température.
Voici comment est composée cette mémoire.


On peut voir dans ce scratchpad plusieurs parties:

  1. Les 2 premiers Octets de température contenues sur les Bytes 0 et 1.
    2Octet de temperature.jpg
    Le symbole "S" c'est le signe de la température. Si elle est positive (S=0) sinon négative(S=1).
    On voit que la température est stocké sur les bit 0 à bit11 donc 12 bits au max( signe compris). Il nous suffira de lire et de convertir cette valeur pour obtenir une température en degré Celsius.


  2. Les 2 Bytes suivantes contiennent les les alarmes hautes et basses respectivement Byte2 et Byte3.
    Pour par exemple, faire un thermostats avec hystérésis. Je ne m'étendrais pas dessus car on va pouvoir s'en passer comme nous le verrons plus tard!
    Mais sachez qu'il est possible de régler une alarme haute et basse, la capteur activera un flag en cas de dépassement de ces valeurs.


    configuration.jpg
  3. L'Octet suivant le byte4 contient la configuration.
    Par défaut le DS18B20+ est configuré avec une résolution de 12bits. C'est ici que nous allons écrire nos réglages de résolution. Dans cet Octet seul les bit5 et bit 6 nous concerne .

    resolution.jpg

    Nous les réglerons suivant le tableau pour obtenir une résolution de 9,10,11 ou 12 bits. Vous remarquerez que pour chaque résolutions, le temps de conversion n'est pas le même. Il faudra donc veiller à respecter ce temps après avoir demandé une conversion de température.
    Résolution de T°C = 256 / résolution. soit , à 12bits nous aurons une résolution de la température de 256/4096= 0.0625 °C/bit



4/ Le fonctionnement:

J'enfonce un peu le clou, mais ici nous utiliserons qu'UN seul capteur sur le BUS. Ceci facilite grandement la compréhension et surtout ce sera le cas dans 99.9% des cas.

Voici un résumé des points clefs à retenir sur le fonctionnement de ce protocole et des procédures à respectées.

  • Avant chaque communication il faut "initialiser" la ligne ! ceci se fera avec la commande Ow_Reset();

  • Après il faudra envoyer une des 5 commandes ROM grâce à la fonction Ow_Write() :
    ==> - SEARCH ROM [0xF0]
    ==> - READ ROM [0x33]
    ==> - MATCH ROM [0x55]
    ==> - SKIP ROM [0xCC]
    ==> - ALARM SEARCH [0xEC]

    Ces commandes vont nous permettre de trouver notre capteur ou une alarme par exemple. Je vous renvoie à la DS pour le détail de chaque commande. Comme nous utilisons un seul capteur, elle ne nous sont pas utiles. On utilisera seulement la commande SKIP ROM, pour parler à tout le BUS. Comme nous avons qu'un seul capteur c'est parfait !.

  • Ensuite on enverra une des fonctions du capteur:
    ==> - CONVERT T [0x44h]
    ==> - WRITE SCRATCHPAD [0x4E]
    ==> - READ SCRATCHPAD [0xBE]
    ==> - COPY SCRATCHPAD [0x48]
    ==> - RECALLE [0xB8]
    ==> - READ POWER SUPPLY [0xB4]

  • Pour finir suivant la fonction demandée, il faudra bien évidemment "écouté" la réponse du capteur ou plutôt "allé lire" les valeurs dans le Scratchpad avec la fonction Ow_Read()

5/ La conversion :

Après avoir lancé une demande de conversion, nous devront lire dans le scratchpad notre valeur de température. Après avoir attendu le temps de conversion suivant la résolution.
Celle-ci se trouve dans 2 Octets car elle est composée de 12bit. On retrouvera donc un LSB (Less Signifiant Byte) et un MSB (Most signifiant Byte).

Grace à une première lecture on récupère nos 8bits de poids faible.
Ensuite on fait une deuxième lecture pour récupérer la deuxième partie. Comme c'est censé être nos bits de poids fort on effectue un décalage de 8 à gauche (cela revient a multiplié par 256).
On additionne le byte de poids faible et celui de poids fort pour obtenir notre température sur 12bits.
Ensuite on multiplie cette valeur par notre coefficient de 0.0625 (coefficient pour 12 bits).

:!!:
Petite particularité en température négative.
Si le signe est négatif il faut faire se qu'on appel un " (complément à 2) +1 "pour retrouver notre valeur en négatif.



6/ Le programme :

Vous devriez maintenant être capable de comprendre ce petit bout de code !

Code : Tout sélectionner

/*
 * Tutoriel pour FantasPic.fr
   Mesure de température avec un capteur MCP 9701A

 * Description : Affichage de la temperature issu d'un MCP9701 sur le LCD

 * Date : Le 22 / 07 /2017

 *  configuration:
     MCU:             PIC18F46K22
                      http://ww1.microchip.com/downloads/en/DeviceDoc/41412F.pdf

     Carte:           Easypic7
                      http://www.mikroe.com/easypic/

     Oscillateur:     Crystal de 8 MHz, PLL disable, Fosc : 8.0000 MHz

     Capteur de T°c:  DS18B20+
                     http://docs-europe.electrocomponents.com/webdocs/078b/0900766b8078b130.pdf

     Compilateur:     mikroC PRO for PIC 7.1.0
                      http://www.mikroe.com/mikroc/pic/
*/

// Connexion du module LCD
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// Fin de connexion du module LCD


//---------------------------------     DECLARATION VARIABLE ET I/O     -----------------------------------------------

char Flag_alarme;
unsigned int temperature;    // Création d'une variable pour stocker la temperature sur 2 Octets
char text[15];               // Création d'une chaine de caractère pour stocker le texte à afficher

//------------------------------------------     PROTOTYPE     --------------------------------------------------------
void Calcul_temperature(unsigned int);

/*#####################################################################################################################
########################################     PROGRAMME PRINCIPAL     ##################################################
#####################################################################################################################*/
void main() {
  ANSELB  = ANSELE = 0;                 // Configure le PORTB et le PORTE en digital
  TRISB = 0;                            // Configure le PORTB en sortie pour le LCD

  Lcd_Init();                           // Initialisation du LCD
  Lcd_Cmd(_LCD_CLEAR);                  // On efface l'écran
  Lcd_Cmd(_LCD_CURSOR_OFF);             // On arrête le clignotement du curseur
  
  Lcd_Out
(1, 1, "DS18B20+");            // Texte de fond 1ere ligne
  Lcd_Out(2, 1, "Temp =       C");      // Texte de fond 2iéme ligne
  Lcd_Chr(2,13,178);                    // Rajoute le petit signe "°"
  
  Sound_Init
(&PORTE, 1);                // On initialise le buzzer sur RE1

//####################################     BOUCLE INFINIE     ########################################################
  while (1) {
  
    
//--- On effectue une lecture de température
    Ow_Reset(&PORTE, 2);             // On reset le signal sur le BUS
    Ow_Write(&PORTE, 2, 0xCC);       // Saute lecture du code 64 bits en ROM (si 1 seul DS18B20+) "SKIP_ROM"
    Ow_Write(&PORTE, 2, 0x44);       // Demande d'effectuer une conversion "CONVERT_T"
    Delay_us(800);                   // Délais d'attente de la DS. Pour une conversion sur 12 bit c'est 750ms mibimum

    Ow_Reset(&PORTE, 2);             // On reset le signal sur le BUS
    Ow_Write(&PORTE, 2, 0xCC);       // Saute lecture du code 64 bits en ROM (si 1 seul DS18B20+) "SKIP_ROM"
    Ow_Write(&PORTE, 2, 0xBE);       // On demande la lecture du scratchpad "READ_SCRATCHPAD"

    // LA température est stockée dans les deux premiers bytes du Scratchpad ( DS page 7)
    temperature =  Ow_Read(&PORTE, 2);         // On lit la premiére valeur du Scratchpad qui correspont à la valeur LSB
    temperature += (Ow_Read(&PORTE, 2) << 8);  // La seconde qui est la MSB donc on décale de 8 bit a gauche puis on rajoute le LSB
                                               // La variable "temperature" est maintenant sur 16 bit correspondant à notre temperature
    
    Calcul_temperature
(temperature);           // Fonction qui convertit les valeurs et les affichent avec l'envoi d'un argument

    delay_ms(1000);                             // Petite pause
    
  
}
}

/*#####################################################################################################################
######################################     PROGRAMME SECONDAIRE     ###################################################
#####################################################################################################################*/

// Cette fonction recoit la valeur de la température en brute.
// On test le bit du signe positif ou négatif en premier
// Puis on convertit et enfin on l'affiche
void Calcul_temperature(unsigned int temperature_hex) {
  
  float temperature_flt 
;     // Création d'une variable locale flottante
  
  
// On regarde si la temperature est négative
  if (temperature_hex & 0x8000) {              // On test le bit du signe qui est le bit15 .
      text[0] = '-';                           // Si la réponse est 1 ,elle est négative, donc on place le signe moins dans le texte
      temperature_hex = ~temperature_hex + 1;  // On recalcule la valeur négative en faisant un complement à 2 + 1
   }
   
   temperature_flt 
= temperature_hex * 0.0625; // on convertir la valeur hexadecimale sur 16bit en float
   FloatToStr(temperature_flt, text);          // On convertit le Flottant en string pour l'afficher
   text[4] = 0;                                // On coupe la chaine de caractère à 4 valeurs
                                               // Cela revient à arrondir à un chiffre après la virgule
   
   
// On verifie la température
   if ( temperature_flt >= 29 ){   // Si la T° est supérieur à 29°C
      Sound_Play(1000, 100);       // Emission d'un BIP en guise d'alarme
    }

   Lcd_Out(2, 8, text);          // On affiche notre température


7/ Alarme :

Comme promis on y revient!

Avec ce capteur il est possible de programmer via le Scratchpad, 2 alarmes. Une alarme haute et une basse. Ces deux alarmes sont codées seulement sur 1 byte chacune. Elles seront comparées après une conversion au Bit4 à 11 (8bits) de la température relevée. Donc nous n'avons pas les chiffres après la virgule.

La gestion de ces alarmes est plutôt lourdes, il faut les configurer, ensuite à chaque conversion de température il faut détecter une alarme et enfin agir si le drapeau est levé .
c'est pourquoi, je trouve qu'il est bien plus facile de traiter ça directement avec notre PIC. En effet à partir du moment ou l'on récupère notre température, aussi bien en flottant qu'en binaire, autant en profiter pour vérifier sa valeur et faire un test si elle plus haute ou plus basse qu'un certain seuil, et ainsi agir en conséquence.

c'est exactement ce que je fais dans le bout de programme au dessus. Au dessus de 29°C j’émets un BIP.


Vidéo :

idea ! Mettre le son pour entendre les BIPs de l'alarme !


http://www.dailymotion.com/video/x5ujnoo

Comme d'habitude, pour apportés des corrections, astuces, des commentaires encourageant etc .... à la suite de ce post, sinon on vous attend sur le Forum.
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Capteur de température numérique : DS18B20+
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2586
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#2 Message par paulfjujo » lun. 24 juil. 2017 10:31

bonjour Jeremy,

:bravo:
Toujours avec une belle présentation, claire et bien organisée..
Aide toi, le ciel ou FantasPic t'aidera

Capteur de température numérique : DS18B20+
Gérard
Avatar de l’utilisateur
Expert
Expert
Messages : 1640
Âge : 65
Enregistré en : septembre 2015
Localisation : Alsace - Haut-Rhin

#3 Message par Gérard » lun. 24 juil. 2017 21:49

paulfjujo a écrit :bonjour Jeremy,

:bravo:
Toujours avec une belle présentation, claire et bien organisée..


:+1:
Jérémy, le roi de la vidéo.
Je ne me moque pas, au contraire, une vidéo parle beaucoup mieux que 100 mots.
Le 18/04/19 je suis devenu papy de jumeaux, le 01/09/23 une petite cousine des jumeaux est née.

Capteur de température numérique : DS18B20+
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2585
Enregistré en : juillet 2016
Localisation : Terre

#4 Message par Temps-x » mar. 25 juil. 2017 02:08

Bonjour Jeremy, paulfjujo, Gérard, et tous le monde,

Merci ! pour ce tutoriel, qui m'a appris des choses, que je ne connaissais pas, car la programmation est une chose,
le fonctionnement d'un module en et une autre.

Le jour ou j'arriverais à faire une présentation comme toi, ce serais content, mais c'est pas le cas, en tous cas un
grand :bravo:

A+
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 4 invités