Electronique : sonde thermique avec un ds18b20

27 décembre 2017 rdorigny 0 commentaires

La société Dallas propose un petit composant électronique qui mesure la température : le ds18b20. Ce capteur dispose d'une sortie numérique pour transmettre la température, et il suffit de lire les données directement sans se casser la tête.

Pour moins de 15 euros, nous allons fabriquer une sonde thermique avec ce composant et un raspberry pi qui supporte le wifi (modèle pi zero w).





1) Le composant Ds18b20

Ce composant électronique est dédié à la mesure de température. Le datasheet se trouve ici. On notera qu'il est capable de mesurer des températures allant de -55°C à +125°C avec ±0.5°C d'erreur.

Pour la connectivité, l'interface numérique utilise utilise le protocole 1-wire. C'est un protocole créé par Dallas et qui est supporté par le Raspberry pi.

Selon le datasheet, il est nécessaire de placer une résistance de tirage entre le circuit de données et l’alimentation tel que:

Mais il existe des plaques qui implémentent la résistance et le ds18b20 directement, très pratique pour éviter de faire les soudures! Evidemment, j'en ai acheté quelques une (1,15€ l'unité sur amazon).

2) Intégration sur le raspberry

Il s'agit d'intégrer notre composant sur les ports GPIO du raspberry pi zero w, pour cela sortons notre carte des ports GPIO:

Le connecteur VCC doit être alimenté en 3.3v, donc on prend le port P1-01; le port data sur le GPIO n°4 (P04-01) et le port 3 sur le GPIO P03-03.


Sur le raspberry, il faut d'abord vérifier que le bus 1-wire est activé. Pour cela il faut taper la commande raspi-config sur raspbian, dans le menu Interfacing options choisir 1-wire puis enable pour l'activer.


3) Lire la température

Par défaut le GPIO P03-03 est celui affecté au 1-wire. Si vous souhaitez le modifier, il faut aller sous/boot/cmdline.txt et ajouter bcm2708.w1_gpio_pin=numéro_pin (redémarrage nécessaire).
Ensuite il faut vérifier que les modules w1_therm et w1_gpio sont chargés par la commande lsmod. Sinon, il faut les rajouter sous /etc/modules.

Ensuite, il suffit de lire le fichier /sys/bus/w1/devices/w1_bus_master1/28-0316a08badff/w1_slave. Pour cela taper la commande cat /sys/bus/w1/devices/w1_bus_master1/28-0316a08badff/w1_slave
La première ligne indique que le CRC est correct, et la seconde affiche "t=5437". Cela est en millième, donc la température est de +5,437°C.

4) Automatiser la lecture de la température

Nous avons vu comment lire la température. Je vous propose désormais d'automatiser la récupération de la mesure, de la sauvegarder dans une base de données. Et ensuite de l'afficher sur une page web. Pour cela, il vous faudra un serveur web qui supporte du code php et doté d'une base de données (mysql par exemple).

La première étape consiste à récupérer la donnée et à la transmettre au serveur. Voici le script python qui fait cela. Ce programme fonctionnera en tant de démon sur le raspberry pi.

Et pour éviter tout plantage, je fais comme d'habitude, je dédie un thread au traitement unitaire. Il faut considérer que ce traitement est à risque.Een effet, si le réseau n'est pas disponible, ou quoi que ce soit, le démon plantera et ce sera la fin de nos mesures. En revanche, si le thread plante, pas de soucis, le démon transmets une requête web vers un script php toutes les 15 minutes (900 secondes).


#*****************************************************************************************************
#
#                  Robert DORIGNY - www.doritique.fr le 17 decembre 2017
#
# Ce script pour recuperer la temperature sur un DS18B20
#
#*****************************************************************************************************

import os
import sys
#import pexpect
import time
import urllib2
import urllib
import threading	


#Fonction chargee de la transmission des donnees
def sendval(tmp):
  tempo=float(tmp)/1000
  data={}
  data['tp']=str(tempo)
  data['sonde']='2'
  url_values=urllib.urlencode(data)
  data=urllib2.urlopen("http://www.votresite.fr/integration.php"+"?"+url_values)
  #print("Transmission OK")
	


class myThread (threading.Thread):
  def __init__(self,name):
	threading.Thread.__init__(self)
	self.name=name
		
  def run(self):
    #Recuperation des donnees
    fs=open("/sys/bus/w1/devices/w1_bus_master1/28-0316a08badff/w1_slave", 'r')
    if (fs.readline().find("YES")):
      txt=fs.readline()
      indice=txt.find("t=")
      tmp=txt[indice+2:indice+7]   
      #print(tmp)
    else:
      print("erreur CRC dans le fichier")
      sys.exit()
    fs.close
    #Transmission des donnees
    sendval(tmp)
    sys.exit() 

#*******************************************Fonction principale************************************ 
def main(): 
  #Mise en daemon
  fpid = os.fork()
  if fpid!=0:
    # Fonctionne en daemon desormais. Le PID est fpid
    sys.exit(0)

  while True:
    thread1 = myThread("DS18B20")
    thread1.start()
    thread1.join()	
    time.sleep(900)
  
if __name__ == "__main__":
    main()

Ci-dessous, le script integration.php qui va copier les données dans votre base de données. Il faudra préparer sa structure avant toute chose. Ce script peut gérer plusieurs sondes, mais aussi la pression et l'humidité si vous avez d'autres sondes pour réaliser des mesures.
// Ici vous devez initialiser la variable de connexion à la base de données
$svr="leserveur";
$l="login";
$pass="paswd";

$Connection=mysqli_connect($svr,$l,$pass,$b);

/* Vérification de la connexion */
if (mysqli_connect_errno()) {
    printf("Échec de la connexion : %sn", mysqli_connect_error());
    exit();
}

if (isset($_GET["tp"])) 
  {
  $tp=$_GET["tp"];
  print("La température reçue :".$tp."
"); } else $tp=0; if (isset($_GET["hum"])) { $hum=$_GET["hum"]; print("L'humidité reçue :".$hum."
"); } else $hum=0; if (isset($_GET["pr"])) { $pr=$_GET["pr"]; print("La pression reçue :".$pr."
"); } else $pr=0; if (isset($_GET["sonde"])) { $sonde=$_GET["sonde"]; print("Le numéro de la sonde :".$sonde."
"); } else $sonde="NC"; //Insertion ds la base de l'enregistrement receptionné $date=date('d m Y H:i:s'); print("Date :".$date."
"); $requete="INSERT INTO meteo (sonde,d,pres,temp,humidite) VALUES (".$sonde.",'".$date."',".$pr.",".$tp.",".$hum.")"; print("requête :".$requete."
"); $resultat=mysqli_query($Connection,$requete); print("resultat :".$resultat."
");
Enfin pour afficher votre dernière mesure.
$b="votrebase";
$svr="leserveur";
$l="login";
$pass="paswd";

$Connection=mysqli_connect($svr,$l,$pass,$b);

/* Vérification de la connexion */
if (mysqli_connect_errno()) {
    printf("Échec de la connexion : %sn", mysqli_connect_error());
    exit();
}

$requete="select temp from meteo where sonde='2' ORDER BY num DESC LIMIT 1"; 
$resultat=mysqli_query($Connection,$requete);
$t=mysqli_fetch_row($resultat);
$temp=$t[0];

print("La température est de ".$temp."°C");

Conclusion

Avec un rapsberry pi zero w et le ds18b20, vous pourrez réaliser une sonde thermique pour pas cher. La mienne fonctionne depuis plusieurs semaines dans mon jardin sans souci.





Pseudonyme (obligatoire) :
Adresse mail (obligatoire) :
Site web :




© 2018 www.doritique.fr par Robert DORIGNY