Skyduino:~#
Articles
arduino, Corrigé, programmation, tutoriel

[Arduino] Capteur de température DS18B20

Le contenu de cet article a été entièrement réécrit et mis à jour sur le site Carnet du Maker.

Liens vers les nouveaux articles :

N.B. Les commentaires de l’article ont été pris en compte lors de la rédaction des nouveaux articles 😉

Discussion

114 réflexions sur “[Arduino] Capteur de température DS18B20

  1. Salut,
    Pour ma part, j’avais fait la même chose mais avec un LM355 et ça marchait plutôt pas mal 😉

    Publié par Olivier NOEL (@noel_olivier) | 26 avril 2012, 12 h 14 min
  2. Bon article et belles manip’ en gérénal sur le site.
    On a également publié un article sur ce composant avec une façon différente d’obtenir la température, voir : http://forum.snootlab.com/viewtopic.php?f=38&t=454

    Publié par Snootlab | 27 avril 2012, 12 h 58 min
  3. Merci Skywodd, j’adore ton site, du bon boulot !

    Tu m’as fait découvrir la carte Duinomite et je m’amuse bien avec.
    pour ma part j’ai monté un TMP102 en I2C sur une duinomite mini et 5 lignes de code :

    10 I2CEN 10,1000
    20 DIM TEMPER(2)
    100 I2CRCV &H48,1,2,TEMPER(0)
    110 PRINT « la temperature est de = « ;TEMPER(0); »deg « ;TEMPER(1)
    120 GOTO 100

    cool !

    Publié par \fab\ | 6 mai 2012, 19 h 22 min
  4. Hello j’ai essayé,
    il me manque juste la résistance donc j’ai fait sans et j’ai modifié juste le if(getTemperature(&temp)) {
    j’air rajouté } else {
    Serial.print(« c’est mort !! »);
    Serial.println();
    }

    Effectivement je tombe bien dans le c’est mort, le gnd et le 5v ok et je me suis bien mis sur la broche 7 …
    est ce que c’est du a la resistance que ça ne fonctionne pas ?

    merci pour ton blog il est cooooool 🙂

    Publié par johan | 17 août 2012, 22 h 05 min
    • >> est ce que c’est du a la resistance que ça ne fonctionne pas ?

      Oui, sans résistance cela n’as aucune chance de fonctionner 😉

      Publié par skywodd | 18 août 2012, 14 h 30 min
      • et je n’ai pas de résistance de ce type, est ce que je peux mettre autre chose ?
        désolé je ne connait pas l’électronique.
        Merci pour tes réponses

        Publié par johan | 19 août 2012, 8 h 52 min
      • Si tu as une résistance de 10K ça marchera (dans ce montage) exactement pareil qu’avec une 4k7 😉

        Publié par skywodd | 19 août 2012, 9 h 18 min
      • Impec avec la résistance en 10k, et si maintenant j’ai plusieurs sonde ? il faut jouer avec les différentes entrées ? normalement sur le bus 1-wire on peut mettre différentes sondes

        Merci encore

        Publié par johan | 19 août 2012, 9 h 41 min
      • Que tu ais une sonde ou 10 sondes elles doivent toute être sur le même bus, avec une seule résistance au bout 😉
        C’est le code arduino qui doit gérer les adresses des différentes sonde.

        (Ici il suffit d’appeler getTemperature() autant de fois que tu as de sonde)

        Publié par skywodd | 19 août 2012, 9 h 47 min
      • Ok merci beaucoup

        Publié par johan | 19 août 2012, 10 h 14 min
  5. Bonsoir,
    je suis débutant est test actuellement votre programme mais je rencontre des difficultés dans l’exécution de ce dernier, lorsque je le vérifie, j’ai l’erreur suivante:’onewire does not name a type’
    cela intervient dès les premières lignes…
    Que dois je faire?
    merci

    Publié par Mathieu | 11 novembre 2012, 23 h 47 min
  6. Bonjour, je viens de recevoir 2 de ces capteurs, j’attend ma résistance de 4.7K impatiemment pour pouvoir essayer mais… comme dans la plupart des exemples pour Arduino que je vois sur internet, il y a un vilain delay() qui va bloquer tout le programme pendant presque une seconde… Pourrais-tu faire un exemple sans delay()? Merci je débute 🙂

    Publié par Anonymousse | 13 décembre 2012, 13 h 53 min
    • Le delay n’est pas vilain, il a un joli commentaire juste à côte !

      Publié par kaloskagatos | 13 décembre 2012, 21 h 45 min
    • Le DS18B20 ne peut pas lire la température à plus de 1.25Hz … d’où le delai de 800ms 😉

      Publié par skywodd | 13 décembre 2012, 22 h 05 min
      • Non mais je sais qu’il faut un délai pour la mesure mais seulement en utilisant delay() le programme ne sait rien faire pendant ce temps perdu… et par exemple si j’ai un bouton et que je le presse alors que le delay() est en cours ben mon bouton ne fonctionnera pas. Je sais qu’il est possible d’utiliser millis() comme dans l’exemple blink without delay mais je ne comprends pas comment l’appliquer ici.

        Publié par Anonymousse | 13 décembre 2012, 22 h 24 min
      • Pour tes boutons utilise des interruptions 😉
        Sinon regarde du côté de DuinOS (et des RTOS en général) ça pourrait t’intéresser.

        Publié par skywodd | 14 décembre 2012, 18 h 36 min
  7. Comment faire pour afficher la valeur de plusieurs ds18b20 ?

    Je bloque depuis pas mal de jours.

    Merci

    Publié par jhonny | 17 mars 2013, 0 h 07 min
  8. Bonjour, merci beaucoup pour votre programme car il m’a énormément aidé pour mon projet de PPE. Par contre j’ai une question: Peut t’on afficher qu’une seule température? Car l’affichage successif de toutes les températures remplissent très vite l’écran ^^’ A très bientôt et bonne continuation !!

    Publié par pastorino | 28 mars 2013, 12 h 10 min
    • Le port série ne fait qu’afficher ligne par ligne, il n’y a pas moyen d’effacer l’écran ou une ligne pour réécrire par dessus.

      Si tu veut vraiment faire ça il te faut un « vrai » terminal série (terminalBpp, TeraTerm, …) compatible VT100.

      Publié par skywodd | 28 mars 2013, 13 h 04 min
  9. Bonjour,

    Je voudrai débuter avec Arduino et souhaiterai acquérir des températures (au sein d’une paroi composée, de volume) pour caractériser le principe de fonctionnement de la bioclimatique d’un bâtiment.
    Avec votre tutorial, on peut relever une température quasiment instantanément (1s).
    Mais peut t’on stocker les températures de plusieurs sondes (par exemple une prise de mesures par heure) sur une durée de 1 mois ? Je voudrais ensuite exploiter ses données sur Excel. Cordialement

    Publié par xolossusx | 31 mars 2013, 16 h 51 min
    • Si l’alimentation de la carte est possible pendant toute la durée de la prise de mesure (via une alimentation secteur par exemple) c’est tout à fait possible.

      Voici un code d’exemple réalisant un log de la température par heure :

      #include <OneWire.h> // Inclusion de la librairie OneWire
      #include <SPI.h>     // Inclusion de la librairie SPI (communications bas niveau)
      #include <SD.h>      // Inclusion de la librairie SD (carte SD en format FAT)
      
      #define DS18B20 0x28     // Adresse 1-Wire du DS18B20
      #define BROCHE_ONEWIRE 7 // Broche utilisée pour le bus 1-Wire
      
      File logFile; // Fichier de log
      const unsigned long pauseBetweenReadings = 3600000UL; // 3 600 000 ms = 3 600 secondes = 1 heure
      OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds
      
      // Fonction récupérant la température depuis le DS18B20
      // Retourne true si tout va bien, ou false en cas d'erreur
      boolean getTemperature(float *temp){
        byte data[9], addr[8];
        // data : Données lues depuis le scratchpad
        // addr : adresse du module 1-Wire détecté
      
        if (!ds.search(addr)) { // Recherche un module 1-Wire
          ds.reset_search();    // Réinitialise la recherche de module
          return false;         // Retourne une erreur
        }
      
        if (OneWire::crc8(addr, 7) != addr[7]) // Vérifie que l'adresse a été correctement reçue
          return false;                        // Si le message est corrompu on retourne une erreur
      
        if (addr[0] != DS18B20) // Vérifie qu'il s'agit bien d'un DS18B20
            return false;         // Si ce n'est pas le cas on retourne une erreur
      
        ds.reset();             // On reset le bus 1-Wire
        ds.select(addr);        // On sélectionne le DS18B20
      
        ds.write(0x44, 1);      // On lance une prise de mesure de température
        delay(800);             // Et on attend la fin de la mesure
      
        ds.reset();             // On reset le bus 1-Wire
        ds.select(addr);        // On sélectionne le DS18B20
        ds.write(0xBE);         // On envoie une demande de lecture du scratchpad
      
        for (byte i = 0; i < 9; i++) // On lit le scratchpad
          data[i] = ds.read();       // Et on stock les octets reçus
      
        // Calcul de la température en degré Celsius
        *temp = ((data[1] << 8) | data[0]) * 0.0625; 
      
        // Pas d'erreur
        return true;
      }
      
      // setup()
      void setup() {
        Serial.begin(9600); // Initialisation du port série
        pinMode(10, OUTPUT); // SS SPI en OUTPUT (obligatoire même si non utilisé)
      
        /* Initialisation de la carte SD (SS = 4) */
        if (!SD.begin(4)) {
          Serial.println(F("Initialisation de la carte SD : echec !"));
          for(;;); // Boucle infini
        }
        Serial.println(F("Initialisation de la carte SD : succes !"));
      
        /* Ouverture du fichier de log */
        logFile = SD.open("log.csv", FILE_WRITE);
        if (logFile)
          Serial.print(F("Ouverture du fichier de log : succes !"));
        else {
          Serial.println(F("Ouverture du fichier de log : echec !"));
          for(;;); // Boucle infini
        }
      }
      
      // loop()
      void loop() {
        float temp;
      
        // Lit la température ambiante à ~1Hz
        if(getTemperature(&temp)) {
      
          // Enregistre la température
          logFile.print(millis() / 1000); // NOTE un affiche de la date/heure via un DS1307 serait plus approprié
          logFile.print(';');
          logFile.print(temp);
          logFile.println();
          
          // Attente avant la prochaine mesure
          delay(pauseBetweenReadings);
        }
      }
      

      (sortie sous format CSV dans « log.csv » directement importable dans excel, calc, …)

      Celui-ci peut être amélioré en ajoutant un module RTC (DS1307 par exemple) pour avoir la date/heure courante et pas juste un temps depuis l’allumage de la carte.

      Publié par skywodd | 31 mars 2013, 18 h 45 min
      • Merci pour ces précisions ultra rapides et ton code.

        Je vais me lancer. Peux tu me dire si ce que je commande convient ?

        – Arduino Uno Atmel Atmega 328 MCU board (pour l’alimentation externe et se passer du pc pour les mesures ?)

        – DS18B20 digital temperature sensor kit for Arduino (avec résistance)

        http://shop.snootlab.com/146-ds18b20par-temperature-kit.html

        – SD log shield for Arduino with RTC and a square pads prototyping area (pour la datation et sauvegardé des données sur la SD)

        http://shop.snootlab.com/86-memoire-en.html

        Par contre, je ne trouve pas le protoshield, mais peut on sans passer et se raccorder directement sur la Uno ?

        Après coup, je voudrai avoir des sondes encapsulées pour les intégrer directement dans la paroi (là le prix des sondes est déjà plus élevés) et recueillir les mesures à distances en wifi ou autres, mais je n’en suis pas encore là.

        Publié par xolossusx | 31 mars 2013, 19 h 40 min
      • >> – Arduino Uno Atmel Atmega 328 MCU board (pour l’alimentation externe et se passer du pc pour les mesures ?)

        Prend une carte arduino officielle et une alimentation de pas trop mauvaise qualité, exemple :
        http://shop.snootlab.com/arduino/142-arduino-uno-rev3.html
        http://shop.snootlab.com/alimentations/358-alimentation-9v-1a.html

        >> – DS18B20 digital temperature sensor kit for Arduino (avec résistance)

        Parfait, tu as même un DS1307 pour la date/heure dessus !
        Et une zone de prototypage suffisante pour câbler ton DS18B20 😉

        >> Par contre, je ne trouve pas le protoshield, mais peut on sans passer et se raccorder directement sur la Uno ?

        Pas besoin la shield ci dessus a déjà une petite zone de prototypage largement suffisante pour un capteur.

        Publié par skywodd | 31 mars 2013, 19 h 45 min
      • bonjour. j’ai rentré le code pour faire des essais avec la carte Arduino Uno,mais je rencontre des problèmes. il ne veut pas prendre en compte File logFile;?,ds.search?pouvez_vous me dire pourquoi? les données sont bien ecrites. à vous lire salutations

        Publié par lievin | 20 octobre 2015, 15 h 39 min
      • La bibliothèque OneWire est bien installée ?
        Quel est le message d’erreur complet ?

        Publié par Skywodd | 11 novembre 2015, 18 h 15 min
      • Bonjour, j’ai réalisé le code, j’affiche sur un LCD 4×20 l’heure à la seconde en première ligne et 3 températures sur les suivantes,
        le problème : comment rafraichir l’heure toutes les secondes sur le LCD, alors que la lecture des sondes prend environ 3x750ms. j’ai essayé avec « si les secondes lu sont !=0 => affichage, mais le temps de lecture des sondes est trop long. Faut-il intercaler entre chaque mesure de sonde la condition.
        Avez-vous une idée ou un lien?
        Merci.
        Marc.

        Publié par Marc | 22 janvier 2016, 8 h 56 min
      • Il faudrait reprendre le code de lecture en non bloquant.
        Dans l’idée, au lieu de faire le delay(800), il faudrait couper la fonction de lecture en deux à ce niveau, puis faire un système un peu comme dans l’exemple « BlinkWithoutDelay ».

        Publié par Skywodd | 25 janvier 2016, 12 h 13 min
  10. Nickel, je commande tout ça et je te tiens au courant de la suite.

    Merci

    Publié par xolossusx | 31 mars 2013, 19 h 54 min
  11. Salut,

    J’ai reçu mon matériel et assembler ma carte « prototypage ». Une question bête, comment se font les raccordement dans la partie prototypage ? Je ne comprends pas grand chose au ligne et colonne, j’avais bien dit que je débutais …

    Publié par xcolossusx | 6 avril 2013, 16 h 48 min
  12. svp est-ce-que vous pouvez nous écrire le code pr afficher et l’heure et la température et la date sur un écran lcd!! SVP

    Publié par binrokh | 13 juin 2013, 19 h 59 min
  13. bonjour messieurs les experts arduino!!

    j’ai acheté un DS18b20 récemment sur le site dealextrem (je ne sais pas si vous connaissez). Bref, le fait est que plus j’avance, plus je doute sur la qualité de l’engin… En gros, voici ce que j’ai fait :
    1/ Copie/colle de votre code
    2/ lancement
    3/ prise de tête pour installer la librairie OneWire.h (finalement ça a marché)
    4/ lancement du code et : pas d’erreur
    5/ prise de conscience d’un problème : rien ne s’affiche sur le moniteur série…
    6/ incrustation de plusieurs « Serial.print » dans le code
    7/ je n’arrive pas à lire la température… (j’ai bien la résistance de pull-up de 4.7k pourtant…
    8/ en bidouillant un peu le code, je n’arrive qu’à afficher « Température : 0.00 °C »

    est ce que vous pensez qu’il faut que j’achète un « vrai DS18b20 » ou qu’il y a une erreur autre part?

    Merci !!

    Publié par aubry | 21 juin 2013, 16 h 44 min
  14. Bonjour,

    Je débute en arduino, votre tuto est très intéressant, mais je souhaite le tester en utilisant un ATtiny 45. Je voulais savoir, si des modifications sont à faire ? J’ai surtout un problème au niveau du Serial.
    J’ai cette erreur : ‘Serial’ was not declared in this scope’
    Après quelque heure de recherche sur le net, j’ai pas vraiment trouver de réponse.
    Peut être qu’il faut déclarer les sortie utilisées pour les RX et TX en utilisant un ATtiny45 ?

    Si vous pouviez m’éclairer.

    Merci d’avance,

    Cordialement,
    Chris

    Publié par Chris | 31 juillet 2013, 12 h 45 min
  15. Bonsoir, et merci pour le tuto.
    Je l’ai testé et j’ai une valeur nulle en température.
    Par contre sur le site de snootlab et l’officiel arduino, il y a une variable en plus :byte: present = DS.reset();
    Et si je la rajoute dans le code d’ici avant de lire le scratchpad, ça fonctionne.
    Quelqu’un sait m’expliquer le pourquoi du comment ?
    Merci 😉

    Publié par totche59 | 23 octobre 2013, 19 h 13 min
  16. Ca tombe, c’est le même souci qu’Aubry (du 21 juin)

    Publié par totche59 | 23 octobre 2013, 19 h 17 min
  17. Salut a tous, j’aimerai récuperer la température uniquement lorsque j’envoi la touche « a » par exemple dans le moniteur ( case « a » 🙂 et tant que je n’envoi pas la touche j’aimerai que la arduino reste en attente et ne dialogue plus avec le capteur (j’ai remarqué aussi que ma led 13 intégrer a la carte reste constamment allumé c’est synonyme de travail de la carte ou pas) Merciii

    Publié par Philippe | 3 février 2014, 15 h 40 min
    • Juste après la déclaration du float dans loop() :

      do { //  Faire
        while(Serial.available() < 1); // Attente d'un octet sur le port série
      } while(Serial.read() != 'a'); // Tant que l'octet est différent de 'a'
      

      Un minimum de recherche serait pas mal avant de poser une question 😉

      Pour la led pin13 ça ne veut rien dire. Si tu ne l’utilise pas elle reste dans l’état qu’elle était lors du boot.

      Publié par skywodd | 9 février 2014, 13 h 17 min
  18. Hello,

    je viens de lancer un blog domo-flats.com
    Il y a un tuto pour utiliser le ds18b20 via le réseau n’hésité pas à venir !

    Bonne chance !

    Publié par domoflats | 9 février 2014, 17 h 13 min
  19. Bonsoir,

    Merci pour le zoli tuto.

    J’ai toutefois 2 remarques :
    1/ le délai peut sembler long, mais en fait moi je le trouve trop court. En effet, avec le délai de l’exemple, la température qu’il m’envoie est supérieure de presque 2 degrés à la température de la pièce. Il m’a fallu ajouter un délai supplémentaire en fin de loop pour avoir une température correcte. J’ai d’ailleurs été surpris de l’inertie du capteur qui a mis un 5 minutes à redescendre à la bonne température.
    2/ comme je suis curieux et que la fonction getTemperature renvoie false en cas d’erreur, j’ai voulu loguer les éventuelles erreur. Et là je constate qu’avec le code de l’exemple, un appel sur 2 sort en erreur sur le « if (!ds.search(addr)) { // Recherche un module 1-Wire ». Alors comme c’est mon premier cablage de ce capteur et comme c’est ma première utilisation de OneWire je suis pas allé plus loin pour le moment. Affaire à suivre donc. Si je trouve je poste.

    Publié par mazkagaz | 10 février 2014, 2 h 37 min
    • Problème getTemperature résolu en passant la recherche d’adresse du module et les 2 vérifications qui suivent dans le setup. Pas besoin de le refaire à chaque fois.
      Maintenant j’ai plus d’erreur.

      Publié par mazkagaz | 10 février 2014, 3 h 01 min
      • Hi,
        super tuto, merci skywodd
        en regardant la librairie,
        myWire.search(addrArray) :Search for the next device. The addrArray is an 8 byte array. If a device is found, addrArray is filled with the device’s address and true is returned. If no more devices are found, false is returned.
        myWire.reset_search() :Begin a new search. The next use of search will begin at the first device.

        search() permet de retrouver l’adresse du module suivant sur le bus (dans le cas ou il y en a plusieurs).

        Dans le code proposé, cela permet d’afficher la température de tous les capteurs présents. Une fois tous les capteurs traités, il est alors nécessaire d’effecteur un reset pour redemarrer l’interrogation (polling) à partir du premier capteur.

        Si on a un seul capteur, il est efficace de déplacer le test dans la fonction setup(), mais si désire gérer plusieurs capteurs, le return false du code proposé ne semble pas adapté car ce n’est pas vraiment une erreur. J’ai donc transformé le test proposé
        if (!ds.search(addr)) { // Recherche un module 1-Wire
        ds.reset_search(); // Réinitialise la recherche de module
        return false; // Retourne une erreur
        }

        par une boucle while

        while (!ds.search(addr)) { // Recherche adresse du prochain module 1-Wire
        ds.reset_search(); // Si on les a tous parcouru, on réinitialise la recherche de module
        }

        (Tant que l’on trouve un module sur le bus, on récupère son adresse, quand on n’en trouve plus, on reset)

        ps : pour info, peu de risque si lors du cablage on inverse la polarité du ds18b20, bien sur pas de réponse et il se transforme alors simplement en radiateur!! Sacrément robuste la bestiole!!
        Merci à tous

        Publié par alkado21 | 17 février 2014, 22 h 09 min
      • En fait c’est une question de point de vue.

        Normalement tu connais le nombre de module 1W sur le bus, de même que leurs types.

        Ce serait donc logique tu fasses manuellement le reset_search() quand tu sait qu’il n’y aura plus de capteurs après. Dans ce cas le return false prend tout son sens, si il retourne false c’est qu’il manque un capteur.

        Pareil pour le test du type de module 1W. Si tu as plusieurs types de capteurs sur le bus, une boucle « tant que » sur le type pourrait être intéressante. Mais si tu n’as qu’un seul type de capteur (ici des DS18B20) le return false te permet de gérer le fait qu’il y a des capteurs inconnus sur le bus.

        Le code de l’article est fait pour coller à une utilisation vraiment basique, à chacun de faire les petites modif qui vont bien pour que ça colle à son utilisation 😉

        Publié par skywodd | 22 février 2014, 16 h 01 min
  20. interessant article,
    juste une petite coquille

    « La température étant une valeur à virgule celle ci est stockée sous la forme d’un flottant avec un exposant, une mantisse et un signe. »

    Pour avoir la température en degré Celsius il faut appliquer la formule suivante :
    temp = ((MSB << 8) + LSB) * 0.0625;

    heeeuuu en fait ca s'appel du fix-pointed (virgule fixe) en little-endian.
    MSB<<8+LSB est la meme valeur que MSBLSB juxtapose en littele-endian, out LSBMSB en big-endian.

    0.0625=1/16
    Donc une seule decimale est juste.

    Publié par laurent | 30 mars 2014, 11 h 48 min
  21. lors de l’exécution de mon programme de tous se passe bien mais lorsque j’ouvre le terminal rien ne s’affiche, j’ai donc rajouter dans le setup un serial.println avec un message et celui-ci s’affiche, je pense donc que c’est le if du void loop qui ne fonctionne pas, si celui-ci ne fonctionne pas est-ce que ça signifie que mon capteur est mort (y a -t-il un moyen rapide pour le savoir ?)

    Publié par Valentin | 3 avril 2014, 11 h 24 min
  22. Bonsoir, Bonsoir à tous 🙂

    Alors j’ai une pitite question

    Je souhaiterais activer une led rouge (quand il fait chaud) ou une led verte (bonne température) en fonction de la température. Malheureusement je n’y arrive pas.

    J’ai utilisé ce qui suit dans loop.

    if (temp > 30)
    Ledchaud = HIGH;
    else
    Ledchaud = LOW;

    if (temp < 30)
    Ledfroid = HIGH;
    else
    Ledfroid = LOW;

    Bien entendu j'ai parametrer pinmode dans setup et nommée mes pins en correlation au tout debut.

    Un petit coup de pouce serait le bienvenue ami arduino.

    Cdlt,
    Visvic.

    Publié par visvic | 9 juin 2014, 0 h 40 min
    • Allez un petit coup de pouce 😉

      void loop() {
        float temp;
         
        if(getTemperature(&temp)) {
           
          if(temp > 30) {
            digitalWrite(Ledchaud, HIGH);
            digitalWrite(Ledfroid, LOW);
          } else {
            digitalWrite(Ledchaud, LOW);
            digitalWrite(Ledfroid, HIGH);
          }
        }
      }
      

      Publié par Skywodd | 9 juin 2014, 19 h 43 min
      • Han merci beaucoup, j’essaye ca dès demain.

        Pour info a long terme je souhaite remplacer cette commande et la peaufiner pour rendre autonome un système de gestion de chauffage et de climatisation.

        Je vous remercie encore je vais ainsi pouvoir continuer de tester et apprendre 🙂

        Bonne soirée 😀

        Publié par visvic | 10 juin 2014, 0 h 23 min
  23. Coucou =),

    merci beaucoup SKYWODD ca à fonctionner du tonnerre, et maintenant, parce que je ne comprend pas pourquoi voici mon code que j’ai téléverser sur mon mega 2560.

    #include
    #include
    #include

    #define DS18B20 0x28
    #define BROCHE_ONEWIRE 7

    RCSwitch mySwitch = RCSwitch();
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    OneWire ds(BROCHE_ONEWIRE);
    int ledfroid = 8;
    int ledchaud = 9;

    boolean getTemperature(float *temp){
    byte data[9], addr[8];

    if (!ds.search(addr)) {
    ds.reset_search();
    return false;
    }

    if (OneWire::crc8(addr, 7) != addr[7])
    return false;

    if (addr[0] != DS18B20)
    return false;

    ds.reset();
    ds.select(addr);

    ds.write(0x44, 1);
    delay(800);

    ds.reset();
    ds.select(addr);
    ds.write(0xBE);

    for (byte i = 0; i < 9; i++)
    data[i] = ds.read();

    *temp = ((data[1] <= 30)
    {//activation ledchaud & prise B (ventilateur)
    digitalWrite(ledchaud, HIGH);
    digitalWrite(ledfroid, LOW);
    mySwitch.switchOn(« 11001 », « 0100 »);
    delay(1500);
    mySwitch.send(332113, 24);
    delay(1500);
    mySwitch.send(« 000001010001000101010001 »);
    delay(1500);
    mySwitch.sendTriState(« 00FF0F0FFF0F »);
    delay(1500);
    }
    else
    {//activation ledfroid & desactivation prise B
    digitalWrite(ledchaud, LOW);
    digitalWrite(ledfroid, HIGH);
    mySwitch.switchOff(« 11001 », « 0100 »);
    delay(1500);
    mySwitch.send(332116, 24);
    delay(1500);
    mySwitch.send(« 000001010001000101010001 »);
    delay(1500);
    mySwitch.sendTriState(« 00FF0F0FFF0F »);
    delay(1500);
    }

    }

    }

    Alors mon problème est que même si la température dépasse ou non la température, j’ai l’activation et la désactivation de la prise tout le temps.

    (temp >= 30)= + de 30 ==> activation désactivation activation etc
    (temp >=30)= – de 30 ==> activation désactivation activation désactivation etc

    Au secours, j’ai tout essayé mais rien y fait ca fonctionne pas 😥

    est ce que la void loop active quand meme le else ???

    merci d’avance a l’aide que vous m’apporterez

    Cordialement,
    VISVIC

    Publié par VISVIC | 12 juin 2014, 21 h 42 min
  24. bonjour et merci pour l’article,

    cela fonctionne parfaitement, mais si je veux changer la résolution sans passer par une librairie de type DallasTemperature, comment puis-je procéder ? Il faut écrire dans data[3] (4ème paramètre du scratchpad) un octet sous la forme x11xxxxx ? (ici pour avoir une résolution de 12 bits sur ma valeur).

    Merci d’avance pour la réponse 🙂

    Publié par Alex | 1 septembre 2014, 17 h 25 min
    • Je dois t’avouer que j’ai pas regardé comment on change la résolution du capteur.

      D’après la doc il faut envoyer la commande 0x4E suivi de trois octets pour écrire la configuration
      Octets 1&2 pour l’alarme de température, octet 3 pour le registre de configuration.

      A tester dans setup() :

      ds.reset(); 
      ds.select(addr);
      ds.write(0x4E); 
      ds.write(0x00);
      ds.write(0x00);
      ds.write(0b00011111); // 0 R1 R0 1 1 1 1 1, 00 = 9 bits, 01 = 10 bits, 10 = 11 bits, 11 = 12 bits
      

      Publié par Skywodd | 3 septembre 2014, 20 h 05 min
  25. Bonjour,
    Merci beaucoup pour ce tutoriel !!
    Je suis débutant avec Arduino. J’aurais voulu savoir si on peut ne pas acheter le protoshield que tu mentionnes dans ton tuto mais juste la breadboard. Et relier la breadboard à la carte arduino directement ?

    Publié par josharchibal | 28 septembre 2014, 3 h 45 min
  26. Bonjour,

    Très bon Tuto, mais hélas ne marche pas sur mon Uno, impossible de transferer le programme sur la bête!
    j’ai copié le programme ci-dessus, j’ai copié la librairie de plusieurs façons , impossible de compiler une erreur s’affiche :
    C:\Documents\Arduino\libraries\OneWire\OneWire.cpp:85:24: fatal error: WConstants.h: No such file or directory
    #include « WConstants.h »
    ^
    compilation terminated.
    Erreur lors de la compilation.

    Quelqu’un a une idée, merci d’avance.

    Publié par Dogo | 24 octobre 2014, 22 h 41 min
  27. bonjour
    nous sommes eleves en PT, classe preparatoire, et le programme ne veut pas se lancer car au cours de la verification il ne reconnait pas ONEWIRE . merci d’avance

    Publié par Corbier thomas | 6 novembre 2014, 18 h 14 min
  28. Bonjour,
    Le microcontrolleur de arduino qui fait 8 bits peut-il supporter un capteur de temperature faisant 12 bis ?
    SVP URGENT

    Publié par poi | 26 janvier 2015, 13 h 59 min
  29. Merci de votre réponse, mais est-ce que vous auriez svp ce programme arduino au format FLOWCODE SVP ?

    Publié par poi | 28 janvier 2015, 18 h 54 min
  30. Bonjour,
    Dans le cas oû on utilise la librairie « DallasTemperature.h » ,le délai d’attente de 750 ms necessaire normalement pour une prise correcte de la température est inutile dans le code ??
    dans des exemples trouvés sur net,l’instruction « delay(750); » n’apparait pas après les instructions « sensors.requestTemperatures(); » et « sensors.getTempCByIndex(0);  »
    Merci beaucoup

    Publié par Denis Casini | 15 février 2015, 21 h 38 min
  31. bonjour je n’ai que a ma disposition une breadboard, une arduino uno et un capteur ds18b20 ainsi que une resistance de la valeur que tu demande mais je nai pas de protoboard voici ma question
    est ce que le programme doit etre change? et a quelle branche de l’arduino faut t-il connecter le capteur
    merci de ta reponse

    Publié par grougrou | 4 mars 2015, 15 h 53 min
  32. Hello question d’hypernewb..

    En quoi (langage) il est écrit le script proposé??

    Et question corolaire ..
    Outre votre très instructif site… le(s)quel(s) conseilleriez vous pour bien (hyper)debuter avec un arduino ?

    Merci !

    Publié par noob | 12 avril 2015, 1 h 37 min
  33. Bonjour,
    Je suis sur le même capteur et j’ai le programme ci dessous qui me permet de lire la température et en donné une afin de réguler une résistante chauffante.
    Cependant j’aimerai le faire fonctionné sans mon PC et le faire chauffé une résistance sans interaction de ma part mis a part l’appuie sur un bouton qui régule le temps et l’allumage.je lui donnerai une certaine valeur de température : 93°C.
    Mon but est donc de retirer la recherche de capteur et tout les Simple.timer.
    Cependant après de nombreux essai je n’y arrive pas car il me manque de la compréhension de quelque ligne.

    Le programme :
    #include
    #include

    SimpleTimer timer ;
    const int modeLecture = 0xBE ;
    const int lancerMesure = 0x44;
    const int broche_OneWire = 2;

    byte data[12] ;
    byte adresse[8] ;
    float ma_tempetf = 0.0 ;

    OneWire capteur(broche_OneWire) ;

    int commande_relais = 5 ;

    float frequence_echantillonnage = 15 ;
    float kp = 1.0 ;
    float ki = 0.0 ;
    float kd = 0.0 ;
    float somme_erreur ;
    float erreur_precedente ;
    float consigne_temperature ;
    boolean isInitialized = false ;

    double cmd_prev ;

    void setup()
    {
    Serial.begin(115200) ;
    capteurInit() ;
    ma_tempetf = capteurMesureTemp() ;
    Serial.print(« La temperature de l’eau est actuellement de : « ) ;
    Serial.println(ma_tempetf) ;
    //Serial.println(« Degres Celsius ») ;
    pinMode(commande_relais, OUTPUT) ;
    }

    ///
    /// Boucle principale
    ///
    void loop()
    {
    if(!isInitialized)
    isInitialized = Initialise();
    else
    {
    timer.run();
    isInitialized = !CheckStop();
    }
    }

    void Asservissement()
    {
    ma_tempetf = capteurMesureTemp() ;
    //Serial.print(« Temperature = « ) ;
    Serial.println(ma_tempetf,4) ;
    //Serial.println(« Degres Celsius ») ;

    //Calcul de l’erreur
    float erreur = consigne_temperature – ma_tempetf ;
    //Serial.print(« L’erreur est : « ) ;
    //Serial.println(erreur,2) ;

    somme_erreur += erreur ;
    float delta_erreur = erreur – erreur_precedente ;
    erreur_precedente = erreur ;

    //PID
    double cmd = kp * erreur + ki * somme_erreur + kd * delta_erreur ;
    //Serial.print(« La valeur cmd est : « ) ;
    //Serial.println(cmd,2) ;

    //Normalisation et controle du relais
    if (cmd 0.1)
    cmd = 0 ;
    else cmd = cmd_prev ;

    analogWrite(commande_relais, 255 – cmd) ;

    cmd_prev = cmd ;
    }

    boolean CheckStop()
    {
    if(Serial.available())
    {
    int c = Serial.read() ;
    if (c == ‘S’)
    {
    Serial.println(« STOP »);
    analogWrite(commande_relais, 0);
    return true ;
    }
    }
    return false;
    }

    ///
    /// Initialise les valeurs
    ///
    boolean Initialise()
    {
    if(Serial.available())
    {
    int c = Serial.read();
    if (c == ‘H’)
    {
    // Affiche l’aide
    Serial.println(« ********* HELP ******** »);
    Serial.println(« Help: H »);
    Serial.println(« Consigne: C »);
    Serial.println(« Echantillonnage: E »);
    Serial.println(« Kp: P »);
    Serial.println(« Ki: I »);
    Serial.println(« Kd : D »);
    Serial.println(« tick_par_tour_codeuse: T »);
    Serial.println(« Start/Stop: S »);
    Serial.println(« *********************** »);
    }
    else if (c == ‘S’)
    {
    if (consigne_temperature != 0)
    {
    Serial.println(« START »);
    // Appele de la methode Asservissement suivant l’intervalle
    timer.setInterval(1000/frequence_echantillonnage, Asservissement);
    timer.enable(0);
    return true;
    }
    else
    Serial.println(« Aucune consigne. »);
    }
    else if (c == ‘C’)
    {
    // Set la valeur de la consigne
    consigne_temperature = Serial.parseFloat();

    if (consigne_temperature > 100)
    {
    Serial.print(« Vous devez mettre une consigne inferieure à 100 degres Celsius. ») ;
    Serial.println(« Rentrez une nouvelle consigne. ») ;
    consigne_temperature = 0.0 ;
    }
    else
    {
    Serial.print(« consigne: « );
    Serial.println(consigne_temperature);
    }
    }
    else if (c == ‘E’)
    {
    // Set la valeur d’echantillonage
    frequence_echantillonnage = Serial.parseInt();
    Serial.print(« echantillonnage: « );
    Serial.println(frequence_echantillonnage);
    }
    else if (c == ‘P’)
    {
    // Set la valeur de kp
    kp = Serial.parseFloat();
    Serial.print(« kp: « );
    Serial.println(kp);
    }
    else if (c == ‘I’)
    {
    // Set la valeur de ki
    ki = Serial.parseFloat();
    Serial.print(« ki: « );
    Serial.println(ki);
    }
    else if (c == ‘D’)
    {
    // Set la valeur de kd
    kd = Serial.parseFloat();
    Serial.print(« kd: « );
    Serial.println(kd);
    }
    }
    return false;
    }

    void capteurInit(void)
    {
    Serial.println(« ****Detection du capteur ») ;
    while (capteur.search(adresse)==false)
    {
    Serial.println(« Aucun capteur 1-Wire present sur la broche ! ») ;
    delay(1000) ;
    }

    Serial.print(« 1 capteur 1-Wire present avec code adresse 64 bits : « ) ;
    for (int i=0 ; i<8 ; i++)
    {
    if (adresse[i]<16) Serial. print('0');
    Serial.print(adresse[i], HEX);
    Serial.print(" ");
    }
    Serial.println() ;

    if (adresse[0] == 0x28)
    {
    Serial.println ("Type du capteur present : Capteur temperature DS18B20.") ;
    }
    else
    {
    Serial.println("Le capteur présent n'est pas un capteur de temperature DS18B20.") ;
    }

    if (capteur.crc8(adresse, 7) == adresse[7])
    {
    Serial.println("Verification du code CRC de l'adresse 64 bits de ce capteur : VALIDE !") ;
    }
    else
    {
    Serial.println("Verification du code CRC de l'adresse 64 bits de ce capteur : NON VALIDE !");
    }

    Serial.println("—Fin de la recherche du capteur—");
    Serial.println("");
    }

    float capteurMesureTemp(void)
    {
    int tempet = 0 ;
    float tempetf = 0.0;

    capteur.reset() ;
    capteur.select(adresse);
    capteur.write(lancerMesure, 1);
    delay(1000);

    capteur.reset() ;
    capteur.select(adresse);
    capteur.write(modeLecture,1);

    for (int i=0; i<9; i++)
    {
    data[i] = capteur.read();
    }

    data[1] = data[1] & B10000111;
    tempet = data[1];
    tempet = tempet<<8;
    tempet = tempet + data[0] ;

    tempetf = float(tempet) * 6,25;
    tempetf = tempetf / 100.0 ;

    return (tempetf) ;
    }

    Publié par Henri | 13 mai 2015, 11 h 06 min
    • Bonjour à tous et merci pour cette mine d’informations.

      Je débute et il m’est demandé de lire la température sur la base d’un arduino nano artméga 328.

      La sonde one wire 18b20 est connectée sur le pin D4

      A ceci se rajoute un problème, comme dit plus haut j’ai ce problème :

      *************************************
      Bonjour,

      Très bon Tuto, mais hélas ne marche pas sur mon Uno, impossible de transferer le programme sur la bête!
      j’ai copié le programme ci-dessus, j’ai copié la librairie de plusieurs façons , impossible de compiler une erreur s’affiche :
      C:\Documents\Arduino\libraries\OneWire\OneWire.cpp:85:24: fatal error: WConstants.h: No such file or directory
      #include « WConstants.h »
      ^
      compilation terminated.
      Erreur lors de la compilation.

      Quelqu’un a une idée, merci d’avance.
      **********************************

      J’ai bien essayé de remplacer la librairie Onewire par la OneWireSlave
      prise ici et compilée en .zip

      et rien n’y fait :-/

      Cela fait 2 jours que j’y suis …..

      Merci d’avance A tous

      Bien à vous

      Fabrice

      Publié par Fabrice | 8 juin 2015, 14 h 28 min
      • Bon j’ai essayé sur une autre machine toujours su linux et ça marche impec … je comprens pas pourquoi sur un autre linux la librairie n’est pas acceptée …

        Publié par fabrice | 8 juin 2015, 19 h 06 min
  34. Bonjour,
    J’ai chargé votre sketch qui fonctionne parfaitement avec 2 sondes branchées.
    Je souhaite pouvoir gérer le fait qu’il ne pourrait y avoir qu’une seule sonde ou deux et pouvoir récupérer la température de l’une et/ou l’autre sélectivement.

    Il faudrait donc pouvoir associer un nom à chaque adresse.

    Y a t-il un moyen simple de faire ceci ?

    Merci,

    Publié par Patrick Egloff | 2 juillet 2015, 10 h 24 min
  35. Bonjour,
    Tout d’abord merci pour ce tuto parfaitement clair.
    J’ai appliqué la procédure sur un arduino nano.
    Dans le moniteur serie j’ai une température affichée de 90°
    valeurs DATA[0] = 173 et data[1] = 173
    une idée ?

    Publié par kld | 8 juillet 2015, 16 h 35 min
  36. bonjour j’ai un problème avec le code. Le capteur indique 0°C alors qu’il devrait afficher environ 20°C. Et cela pour toutes les températures. Pouvez vous m’aider ? Merci d’avance

    Publié par Laloux | 14 décembre 2015, 17 h 31 min
  37. Bonjour tout le monde , je ne m’y connais pas en électronique, je dois faire un programme sur flowcodeV6 pour capter une température avec le Dallas 18B20, j’utilise une carte Eblock 16F877A.
    Je n’arrive pas a acquérir les donné du capteur et de les traiter , de façon a les integrer a mon programme.
    Merci de votre aide!

    Publié par Ruffy | 27 janvier 2016, 14 h 37 min
  38. Bonjour,
    Quelqu’un saurait il comment on peut retourné une valeur négative ?
    J’aimerais mesurer des valeurs en dessous de zero mais je ne sais absolument pas comment faire..

    Publié par julienguerder | 18 mars 2016, 15 h 41 min
    • Bonjour,

      j’ai implémenté le code avec 2 x DS18B20 sur 2 broches differentes donc 2x le code (ds1 et ds2)
      et j’ai eu des soucis, soit systématiquement une erreur sur deux lectures.

      Après la modif suivante :

      ————– code d’origine ———————————————-
      if (!ds.search(addr)) // Recherche un module 1-Wire
      {
      ds.reset_search(); // Réinitialise la recherche de module
      return false; // Retourne une erreur
      }
      ——————————————————————————–

      devient
      ————– code modifié ————————————————
      ds.reset_search(); // Réinitialise la recherche de module
      if (!ds.search(addr)) // Recherche un module 1-Wire
      return false; // Retourne une erreur
      ——————————————————————————–

      et la c’est tout bon !!

      Pour les valeurs négatives, j’ai pas compris vu que la fonction retourne un « float » donc négatif sans problème.

      Publié par Alain | 2 avril 2016, 18 h 59 min
    • Voici un exemple qui affiche des valeurs positives ou négatives:

      int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
      LowByte = data[0];
      HighByte = data[1];
      TReading = (HighByte << 8) + LowByte;
      SignBit = TReading & 0x8000; // test bit du signe
      if (SignBit) // negatif
      {
      TReading = (TReading ^ 0xffff) + 1; // 2's comp
      }
      Tc_100 = (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25
      // — en mode 12 bits, la résolution est de 0.0625°C – cf datasheet DS18B20
      tempetf = Tc_100 / 100.0;
      Serial.print("temperature = ");
      if (SignBit) // Si négatif
      {
      Serial.print("-");
      }
      Serial.println(tempetf,2);
      Serial.println (" Degres Celsius. ");
      int dizaine = tempetf / 10;
      int unite = tempetf – (dizaine * 10);
      int decimale = (float)((tempetf – (dizaine * 10) – unite) * 100);
      decimale = (decimale + 5) / 10; // + 5 pour arrondir
      Serial.print ("signe = ");
      if (SignBit) // Si négatif
      {
      Serial.print("-");
      } else {
      Serial.print("+");
      }
      Serial.print (" dizaine = ");
      Serial.print (dizaine);
      Serial.print (" unité = ");
      Serial.print (unite);
      Serial.print (" decimale = ");
      Serial.println (decimale);
      }

      Publié par Guine | 2 décembre 2016, 11 h 13 min
  39. olla et jolie taf (surtout dans le suivie des reponses, ce qui n’est pas toujours evident)
    moi je suis juste interressé par la ligne 62
    Serial.write(176); // caractère °

    c’est le caractère car sur mon afficheur 4×20 j’ai remplacé par la ligne

    lcd_4x20.print(176);

    et bien je te le donne dans le mille il m’affiche 176 et non °

    as tu une piste ou une idée? (ce qui revient à la meme chose)
    cordialement

    PS mon projet https://forum.arduino.cc/index.php?topic=391036.0

    Publié par nicolas | 11 avril 2016, 3 h 11 min
  40. Bonjour
    J’ai une question est ce que quelqu’un aurait une idée de cablage et de programmation à fin que je puisse rajouter au premier programme du capteur de température BS18B20 deux ventillateurs allimentés en 12V
    Merci d’avance
    Cordialement

    Publié par pilgrimy | 20 avril 2016, 15 h 33 min
  41. Bonjour,
    Excellent Tutoriel, Merci !

    J’ai une petite question : je compte Utiliser une carte NodeMCU à base d’ESP8266 qui tourne en 3.3 V.
    Si j’ai bien compris la DataSheet on peut alimenter le DS18B20 en 3.3V, mais dans ce cas la résistance de 4k7 est elle toujours valable ? Est que je dois modifier le code (faire un mapping) pour compenser l’écart de tension ou est-ce transparent ?

    Merci beaucoup !
    Nicolas.

    Publié par Nicolas | 25 mai 2016, 21 h 07 min
  42. Bonsoir et merci pour ce tutoriel
    Ma question va sûrement être très simple, mais en plus d’afficher la valeur de température, j’aimerais faire tourner un servo moteur pour actionner une trappe d’aération lorsque la température excède 30°C
    Pourriez-vous m’indiquer comment ajouter la condition (si T° supérieure à 30° faire tourner le servomoteur de 180° sinon faire tourner le servomoteur à 0°)
    merci
    bonne soirée

    Publié par liscornet | 18 octobre 2016, 19 h 07 min

Rétroliens/Pings

  1. Pingback: Electronique | Pearltrees - 25 novembre 2012

  2. Pingback: Tutoriaux généraux et spécifiques | Pearltrees - 30 juin 2013

  3. Pingback: [Arduino] Capteur de température DS18B20... - 9 mars 2014

  4. Pingback: Arduino | Pearltrees - 24 août 2014

  5. Pingback: Robot-électronique | Pearltrees - 18 août 2015

  6. Pingback: Arduino | Pearltrees - 12 juin 2016

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Skyduino devient Carnet du Maker

Le site Carnet du Maker remplace désormais le blog Skyduino pour tout ce qui touche à l'Arduino, l'informatique et au DIY.