Utiliser des capteurs avec le port GPIO - Partie 2

Capteur de température 1-Wire

Jacob Marsh

Traducteur

f-leb

Dans le tutoriel précédent, nous avons exploité un capteur de mouvement simple dont la sortie ne prenait que deux états, haut ou bas, selon qu'un mouvement est détecté ou non. La sortie du capteur PIR était connectée à une entrée du port GPIO du Raspberry Pi. Le tutoriel décrit alors la façon de récupérer l'état de l'entrée en Python afin d'afficher un message à l'écran lorsqu'un mouvement est détecté dans le champ du capteur.

NDLR : cet article fait appel à des bases de programmation en Python, mais aussi à la mise en œuvre du port GPIO du Raspberry Pi. Si nécessaire, nous invitons le lecteur à se familiariser avec ces notions en consultant tout d'abord le tutoriel :

- Raspberry Pi - Python et le port GPIO

Les commentaires et les suggestions d'amélioration sont les bienvenus, alors, après votre lecture, n'hésitez pas. Commentez

- Titre : Utiliser des capteurs avec le port GPIO - Partie 2

- Auteur : Jacob Marsh

- Traducteur : f-leb

- Parution : 29 juillet 2015

- Public visé :

- Licence : Le contenu de cet article est rédigé par Jacob Marsh et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 3.0 non transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2013 Developpez.com.

Voir également :

- Raspberry Pi - Déballage et installation

- Raspberry Pi - Python et le port GPIO

Sommaire

- I. Les capteurs 1-Wire

- II. Faire les branchements

- III. Programmation

- IV. Programme Python

- V. Plusieurs capteurs

- VI. Notes de la Rédaction de Developpez.com

I - Les capteurs 1-Wire

Que se passe-t-il si nous connectons cette fois un capteur plus sophistiqué et que nous voulons acquérir des données plus complexes ? Dans ce tutoriel, nous allons connecter un capteur de température numérique 1-Wire (OneWire) et programmer notre Raspberry Pi afin d'acquérir en sortie de capteur la température mesurée par celui-ci !

Les données numériques délivrées par un capteur 1-Wire passent par un unique fil, ce qui permet d'économiser aussi bien les entrées-sorties des microcontrôleurs que celles du Raspberry Pi puisque, pour ce dernier, une seule broche du port GPIO sera utilisée pour communiquer les données. En plus de cela, la plupart des capteurs 1-Wire sont livrés avec un numéro de série unique, ce qui permet de connecter plusieurs unités sur le même bus de données sans qu'elles interfèrent entre elles.

Le capteur que nous allons utiliser dans ce tutoriel est un capteur de température numérique à résolution programmable 1-Wire Maxim DS18B20+. Le DS18B20+, encapsulé dans son boîtier TO-92, présente un aspect similaire à beaucoup de transistors et comporte trois pattes : GND (masse), DQ (données) et VDD (alimentation à 3,3 V). Vous aurez aussi besoin de quelques fils, une plaquette de câblage et une résistance électrique de 4,7 kΩ (ou 10 kΩ).

Dans notre montage, la résistance est utilisée pour « tirer » le niveau de tension de la ligne de données au +3,3 V (pull-up) et elle doit pour cela être connectée entre la sortie DQ et l'alimentation VDD. Cela permet d'assurer que la ligne de données soit bien définie à un niveau logique haut ou bas et d'éviter les états incertains dus aux bruits électriques qui ne manqueraient pas de se produire si l'entrée était laissée flottante.

Nous allons prendre la broche 7 « GPIO 4 » pour piloter la sortie du capteur de température, car c'est la broche dédiée du Raspberry Pi au protocole 1-Wire.

II - Faire les branchements

Connectez la broche 6 « GPIO GND » du Raspberry Pi à une ligne de la plaquette dédiée à la masse (ligne bleue ou noire sur la plaquette).

Connectez la broche 1 « 3.3 V » du Raspberry Pi à une ligne de la plaquette dédiée à l'alimentation (ligne rouge).

Connectez le DS18B20+ sur la plaquette. Assurez-vous que chacune des trois broches est connectée à une rangée de trous différente. Familiarisez-vous avec la disposition des broches, attendu qu'il est très facile de revenir en arrière dans les branchements.

Connectez la patte GND du DS18B20+ à la ligne de masse de la plaquette.

Connectez la patte VDD du DS18B20+ à la ligne d'alimentation de la plaquette.

Placez la résistance de 4,7 kΩ entre la patte DQ du DS18B20+ et une rangée de trous libre de la plaquette.

Connectez l'extrémité libre de la résistance de 4,7 kΩ à la ligne d'alimentation de la plaquette avec un fil.

Finalement, connectez la patte DQ du DS18B20+ à la broche 7 « GPIO 4 » avec un fil.

C'est tout ! Nous voilà prêts pour la partie programmation.

III - Programmation

Avec un peu de paramétrage, le DS18B20+ peut être accédé directement en ligne de commande sans passer par un programme en Python. En contrepartie, cela requiert que nous entrions une commande chaque fois que nous voulons acquérir la température.

Afin d'introduire certains concepts de l'interfaçage avec le protocole 1-Wire, nous commencerons par accéder au capteur via la ligne de commande. Plus tard, nous écrirons un programme en Python qui acquerra la température automatiquement à intervalles réguliers.

Le Raspberry Pi est équipé d'un certain nombre de pilotes d'interface avec des périphériques. Pour autant, il n'est pas faisable de charger tous les pilotes lorsque le système démarre sans augmenter significativement le temps de démarrage et utiliser une considérable quantité de ressources pour des processus redondants. Ces pilotes sont par conséquent d'abord stockés comme des modules prêts à charger et la commande modprobe est employée pour les charger à la demande dans le noyau Linux.

Les deux commandes suivantes chargent les pilotes du protocole 1-Wire et du capteur de température connecté à la broche « GPIO 4 ». Au prompt, saisissez les lignes :

sudo modprobe w1-gpio
sudo modprobe w1-therm

Ensuite, nous avons besoin de nous déplacer dans le répertoire du périphérique 1-Wire et lister les périphériques afin de s'assurer que notre capteur de température est reconnu correctement. Saisissez les lignes :

cd /sys/bus/w1/devices
ls

Dans la liste des périphériques, votre capteur doit apparaître avec une série de lettres et de chiffres. Dans mon cas, le périphérique est identifié avec le numéro 28-000005e2fdc3. Vous devez alors accéder au capteur avec la commande cd, en n'oubliant pas de remplacer le numéro de série par celui de votre propre capteur :

cd 28-000005e2fdc3

Les données provenant du capteur sont périodiquement écrites dans le fichier w1_slave. Nous pouvons utiliser la commande cat pour lire son contenu :

cat w1_slave

On obtient alors deux lignes de texte, avec en sortie t qui indique la température en millidegrés Celsius.

72 01 4b 46 7f ff 0e 10 57 : crc=57 YES
72 01 4b 46 7f ff 0e 10 57 t=23125

Divisez ce nombre par 1 000 pour obtenir la température en degrés. Ici, la température acquise est donc de 23,125 degrés Celsius.

En ce qui concerne l'acquisition de la température, c'est tout ce dont nous avons besoin depuis la ligne de commande. Détenez le capteur entre vos doigts quelques secondes, faites une nouvelle lecture de température et constatez son élévation. Avec ces commandes à l'esprit, nous pouvons maintenant écrire un programme en Python afin d'acquérir la température automatiquement.

IV - Programme Python

La première étape consiste à importer les modules Python dont nous avons besoin. Le module os nous permet d'accéder aux pilotes du protocole 1-Wire et de s'interfacer avec le capteur. Le module Time permet la gestion du temps et de définir des intervalles de temps dans notre code.

import os
import time

Nous chargeons ensuite les pilotes :

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

L'étape suivante consiste à définir le fichier de sortie du capteur (le fichier w1_slave) comme nous l'avons vu précédemment. Souvenez-vous de bien utiliser le numéro de série de votre propre capteur !

temp_sensor = '/sys/bus/w1/devices/28-000005e2fdc3/w1_slave'

Nous avons maintenant besoin d'une variable pour enregistrer les données brutes de température, c'est-à-dire les deux lignes de texte renvoyées par le capteur et que nous avons affichées précédemment en ligne de commande, grâce à la fonction temp_raw. Nous pourrions afficher dès maintenant ces données brutes, mais nous allons plutôt les traiter pour les rendre plus exploitables. Pour cela, nous ouvrons le fichier, récupérons les lignes et clôturons le fichier du capteur. La fonction retourne alors les lignes de données brutes afin de les exploiter plus tard dans le code.

def temp_raw():
f = open(temp_sensor, 'r')
lines = f.readlines()
f.close()
return lines

Premièrement, nous allons vérifier que la variable récupérée grâce à la fonction temp_raw précédente est exempte d'erreurs. Si vous étudiez la sortie du fichier de sortie original, comme nous l'avons vu dans l'exemple en ligne de commande, vous voyez deux lignes. La première ligne contient la chaîne de caractères « 72 01 4b 46 7f ff 0e 10 57 : crc=57 YES ». Nous découpons cette chaîne en ne conservant que les trois derniers caractères et nous vérifions que son contenu est « YES », ce qui indique que l'acquisition de température par le capteur s'est déroulée correctement. En Python, la non-égalité est définie grâce à l'opérateur !=. Donc, tant que la sous-chaîne extraite est différente de « YES », nous demandons au programme de temporiser 0,2 s avant de recommencer une nouvelle lecture.

def read_temp():
lines = temp_raw()
while lines[0].strip()[-3: ] != 'YES':
time.sleep(0.2)
lines = temp_raw()

Une fois la sous-chaîne « YES » détectée, nous pouvons nous occuper de la deuxième ligne de sortie. Dans notre exemple, la chaîne obtenue est « 72 01 4b 46 7f ff 0e 10 57 t=23125 ». On cherche la position de la sous-chaîne « t= », et si elle est trouvée, la valeur de la température qui suit « t= » est extraite. Il ne reste qu'à faire deux calculs simples pour convertir la température en degrés Celsius et en degrés Fahrenheit.

temp_output = lines[1].find('t=' )
if temp_output != -1:
temp_string = lines[1].strip()[temp_output+2: ]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_c, temp_f

Finalement, le programme va boucler pour afficher la température toutes les secondes.

while True:
print(read_temp())
time.sleep(1)

Voilà notre code final !

import os
import time

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

temp_sensor='/sys/bus/w1/devices/28-000005e2fdc3/w1_slave'

def temp_raw():
f=open(temp_sensor, 'r')
lines = f.readlines()
f.close()
return lines

def read_temp():
lines = temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = temp_raw()
temp_output = lines[1].find('t=')
if temp_output != -1:
temp_string = lines[1].strip()[temp_output+2:]
temp_c = float(temp_string) / 1000.0
temp_f= temp_c * 9.0 / 5.0 + 32.0
return temp_c, temp_f

while True:
print(read_temp())
time.sleep(1)

Sauvegardez votre programme et exécutez-le :

V - Plusieurs capteurs

Plusieurs capteurs DS18B20+ peuvent être connectés en parallèle et chacun peut être accédé grâce à son numéro de série unique. Notre programme Python peut alors être édité et modifié afin d'accéder et lire la température de chacun des capteurs.

NDLR : il existe de nombreux composants 1-Wire qui peuvent être utilisés notamment en domotique où ils sont mis en réseau : capteurs de température ou d'humidité, horloges temps réel, interrupteurs, bascules, convertisseurs A/N, potentiomètre numérique, etc.

Comme toujours, le capteur DS18B20+ et tous les composants sont disponibles séparément ou font partie d'un kit de composants électroniques acheté dans une enseigne spécialisée.

VI - Notes de la Rédaction de Developpez.com

Cet article est une traduction adaptée de l'article écrit par Jacob Marsh et paru dans le n° 23 du magazine TheMagPi, sous le titre Using 1-Wire temperature sensors.

Nous remercions les membres de la Rédaction de Developpez.com pour le travail de traduction, de relecture et d'adaptation qu'ils ont effectué, en particulier :

- f-leb

- deusyss

Merci également à milkoseck pour sa relecture orthographique.