Mesure de température depuis le raspberry

A/ Liens utiles

D'autres l'ont déja fait :

  1. Franboise 3.14
  2. Domolio
  3. Bandinelli
  4. Matthew Kirk
  5. Jahislove314

B/ Matériel

Il faut une ou plusieurs sondes 1-wire DS18B20 et une résistance 4.7 kΩ

J'ai pris aussi une breadboard et du cable supplémentaire

Prix du matos : 14 € (Pour 5 sondes)

C/ Montage

1 Schéma électrique

schema

2. Schéma avec le raspberry

schema

3. Résultat final pour 3 sondes

schema

D/ Raspberry

Pour que le noyau Linux sache gérer le composant 1-wire DS18B20, il faut déclarer le bus 1-wire et le module de la famille 28h (capteurs de température).

Pour cela, dans /etc/modules, ajouter deux lignes w1-gpio et w1-therm.

sudo cat  /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
# Parameters can be specified after the module name.

snd-bcm2835

w1-gpio
w1-therm

A noter que la commande modprobe permet de charger un module sans avoir à redémarrer

modprobe w1-therm
modprobe w1-gpio

un petit redémarrage ...

shutdown -r now

Pour vérifier que le système a bien reconnu les sondes, il suffit de regarder le répertoire /sys/bus/w1/devices.

Chaque sonde est identifiée par un numéro unique qui commence toujours par "28" donc. On doit trouver autant de répertoire avec ce numéro que de sondes utilisées

ls /sys/bus/w1/devices/
28-031574449aff  28-03157474cdff  28-0315747700ff  w1_bus_master1

Mes trois sondes sont bien détectées :-).

Dans chaque répertoire, un fichier w1_slave qui est mis à jour régulièrement par la sonde. Ce fichier contient deux lignes :

  1. Le checksum a YES pour dire que le fichier est ok.
  2. La température après le "t=" en celcius (sans virgule et donc multiplié par 1000)
cat w1_slave    
72 01 4b 46 7f ff 0e 10 57 : crc=57 YES
72 01 4b 46 7f ff 0e 10 57 t=23125

1. Script

Le but de mon script est de parcourir ces trois fichiers pour stocker à intervalle régulier dans une base de données externe mes trois températures.

Externe dans le sens "pas sur la carte", car d'après ce que j'ai lu, il faut éviter autant que possible les opérations trop fréquentes d'écriture sur une carte SD.

En l'occurence, j'ai ouvert un compte chez MongoLab.

Le plus simple pour lire des données, les formatter et les déverser dans une base, c'est certainement de faire du python.

Ma version du script (inspiré d'autres scripts et certainement à améliorer) :

 #!/usr/bin/env python
# NAME: teleinfoERDF.py
# AUTHOR: Lionel Capdecomme
# DATE  : 24/01/2016
# COMMENT: Lecture des températures issus des sondes et sauvegarde dans BD MongoLab

import serial, json, sys, pymongo, datetime
from pymongo import MongoClient

# 0. Initialisation variable Mongo
MONGODB_URI = 'mongodb://user:password@adresseServeur:portServeur/nomDB' 
MONGODB_COLLECTION='nomCollection'

# Initialisation temperature 
base_dir = '/sys/bus/w1/devices/'
nbSondes=3
nbProps=3 # 1:lieu, 2: nom du fichier, 3:valeur
sondes=[[0 for row in range(0,nbProps)] for col in range(0,nbSondes)]
sondes[0][0]="salon"
sondes[0][1]="28-031574449aff"
sondes[1][0]="chambre"
sondes[1][1]="28-03157474cdff"
sondes[2][0]="exterieur"
sondes[2][1]="28-0315747700ff"

# Fonction ouverture et lecture d'un fichier
def lireFichier(fichier):
    f = open(fichier, 'r')
    lignes = f.readlines()
    f.close()
    return lignes

data = {}
# Lecture des temperatures
for i in range(nbSondes):
    sonde = base_dir + sondes[i][1] + "/w1_slave"
    lignes = lireFichier(sonde)
    while lignes[0].strip()[-3:] != 'YES': # lit les 3 derniers char de la ligne 0 et recommence si pas YES
        sleep(0.2)
        lignes = lireFichier(sonde)

    # Fichier ok, lecture seconde ligne 
    temp_raw = int (lignes[1].split("=")[1])
    value = round(temp_raw / 1000.0, 2)
    sondes[i][2] += value # le 2 arrondi a 2 chiffres apres la virgule
    print sondes[i][0],"=",sondes[i][2] 

# Le tableau sauvegarde en BD
data['sondes']=sondes
data['date']=datetime.datetime.now()

#3. Sauvegarde dans le compte mongolab
client = pymongo.MongoClient(MONGODB_URI)
db = client.get_default_database()
# Choix de la collection 
teleinfo = db[MONGODB_COLLECTION]
teleinfo.insert(data)
Code python mis en forme par pygments

Dernière remarque, si j'avais choisi de ne pas charger les modules au lancement du raspbery, je devrais le faire dans le script python (au début)

## module GPIO 1-wire et capteur de temperature #####
system('modprobe w1-gpio')
system('modprobe w1-therm')