Outils pour utilisateurs

Outils du site


raspberry_pi:ds18b20_temperature_numerique

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Prochaine révision
Révision précédente
Prochaine révision Les deux révisions suivantes
raspberry_pi:ds18b20_temperature_numerique [06/10/2016 16:56]
sky99 créée
raspberry_pi:ds18b20_temperature_numerique [06/10/2016 17:05]
sky99
Ligne 60: Ligne 60:
 {{http://​nagashur.com/​blog/​wp-content/​uploads/​2015/​08/​shell_read_DS18B20.png | Shell affichant les données du capteur}} {{http://​nagashur.com/​blog/​wp-content/​uploads/​2015/​08/​shell_read_DS18B20.png | Shell affichant les données du capteur}}
  
 +Comme vous pouvez le voir dans l'​exemple de l'​image,​ on obtient une sortie sur deux lignes. La première ligne est terminée par YES, indiquant que notre capteur à pu lire une température,​ et la seconde ligne est terminée par t=xxxxx, ou l'on a la température en millièmes de degrés (on divise par 1000 pour obtenir la température en degrés).
  
 +Voici un exemple de ligne de code permettant de ne sélectionner que la température :
 +<code bash>
 +cat /​sys/​bus/​w1/​devices/​28-000006799670/​w1_slave | tail -n 1 | cut -f10 -d " " | cut -f 2 -d "​="​
 +</​code>​
 +
 +===== Programmation =====
 +
 +Nous verrons maintenant comment exploiter la sortie fournie par la sonde afin de surveiller une température. Nous verrons pour cela deux solutions : la première avec un script bash, et la seconde via un script python.
 +
 +Comme nous l'​avons déjà vu brièvement,​ il est possible de récupérer uniquement la température dans une variable. Nous devrons alors diviser l'​ensemble par 1000 pour pouvoir avoir une température en  degrés Celsius. Cependant, le problème est que l'​interpréteur bash ne gère pas les nombres à virgule, mais uniquement les entiers. Il existe diverses solutions, et [[http://​stackoverflow.com/​questions/​12722095/​how-can-i-get-a-float-division-in-bash|vous pourrez en apprendre davantage en suivant ce lien]]. Pour faire simple, une solution serait d'​utiliser bc, mais ce n'est pas installé par défaut sur le raspberry pi. Une autre solution qui fonctionne sans ajouter de paquets est d'​utiliser awk.
 +
 +==== Script bash ====
 +
 +Ainsi, on obtient un petit script **readTemp1.sh** basique :
 +
 +<file bash readTemp1.sh>​
 +
 +#!/bin/bash
 +temp01=`cat /​sys/​bus/​w1/​devices/​28-000006799670/​w1_slave | tail -n 1 | cut -f10 -d " " | cut -f 2 -d "​="​`
 +temp02=$(awk "BEGIN {printf \"​%.3f\",​${temp01}/​1000}"​)
 +echo $temp02
 +
 +</​file>​
 +
 +Enregistrez donc ceci dans un fichier **readTemp1.sh**,​ puis faites ajoutez les droits d'​exécution :
 +
 +<code bash>
 +chmod u+x readTemp1.sh
 +</​code>​
 +
 +Vous pouvez alors exécuter le script en faisant ​ **sudo ./​readTemp1.sh** . Il est également possible de ne pas ajouter les droits en exécution, et se contenter de faire **sudo sh ./​readTemp1.sh**.
 +
 +Dans tous les cas, on obtient un affichage en degrés Celsius avec les décimales (trois, mais on peut réduire en changeant le **%.3f** en **%.2f** dans le script pour avoir deux décimales par exemple).
 +
 +Cette approche basique fonctionne, et permet d'​obtenir la température. Mais idéalement,​ il faudrait vérifier sur la première ligne si l'on a bien un **YES**.
 +
 +C'est ce que nous ferons maintenant :
 +
 +<file bash readTemp2.sh>​
 +#!/bin/bash
 +probe_addr='​28-000006799670'​
 +res=`cat /​sys/​bus/​w1/​devices/​$probe_addr/​w1_slave | head -n 1 | grep YES | wc -l`
 +if [ $res -eq 1 ]
 +then
 +temp01=`cat /​sys/​bus/​w1/​devices/​$probe_addr/​w1_slave | tail -n 1 | cut -f10 -d " " | cut -f 2 -d "​="​`
 +temp02=$(awk "BEGIN {printf \"​%.2f\",​${temp01}/​1000}"​)
 +echo $temp02
 +fi
 +</​file>​
 +
 +Dans ce contexte, le script teste si on a bien YES sur la ligne 1, et si c'est le cas, récupère la température et l'​affiche. Dans le cas contraire, il n'​affiche rien.
 +
 +On peut ajouter un elif dans le script si on veut afficher un message d'​erreur.
 +
 +==== Script python ====
 +
 +Pour ce script, je ne vais pas réinventer la roue, et on va utiliser un script inspiré du [[https://​learn.adafruit.com/​adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/​software|code d'​exemple d'​Adafruit]] :
 +<file python readTemp.py>​
 +#​!/​usr/​bin/​env python
 +import os
 +import glob
 +import time
 +import sys
 +
 +os.system('​modprobe w1-gpio'​)
 +os.system('​modprobe w1-therm'​)
 +
 +base_dir = '/​sys/​bus/​w1/​devices/'​
 +device_folder = glob.glob(base_dir + '​28*'​)[0]
 +device_file = device_folder + '/​w1_slave'​
 +
 +def read_temp_raw():​
 + f = open(device_file,​ '​r'​)
 + lines = f.readlines()
 + ​f.close()
 + ​return lines
 +
 +def read_temp():​
 + lines = read_temp_raw()
 + while lines[0].strip()[-3:​] != '​YES':​
 + ​time.sleep(0.2)
 + lines = read_temp_raw()
 + ​equals_pos = lines[1].find('​t='​)
 + if equals_pos != -1:
 + ​temp_string = lines[1][equals_pos+2:​]
 + ​temp_c = float(temp_string) / 1000.0
 + ​temp_f = temp_c * 9.0 / 5.0 + 32.0
 + ​return temp_c, temp_f
 +
 +try:
 + while True:
 + ​print(read_temp()[0])
 + ​time.sleep(0.3)
 +except KeyboardInterrupt:​
 + ​sys.exit(0)
 +</​file>​
  
  
raspberry_pi/ds18b20_temperature_numerique.txt · Dernière modification: 06/10/2016 17:12 par sky99