Ci-dessous, les différences entre deux révisions de la page.
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> | ||