Température, humidité et pression en 4 fils sur un Raspberry avec un BM280
Dans le cadre d’un POC pour un autre projet, j’ai réalisé un object connecté type IOT à base de Raspberry et d’un BME280 pour mesurer température, humidité et pression atmosphérique. Eclairages.
Raspberry Pi Zero W
Pour ce projet, j’ai choisi un RPI Zero W (wifi) pour les raisons suivantes (versus un Arduino) :
- moins cher qu’un arduino avec un module RJ45 (10€ vs 20€)
- wifi
- permet de faire tourner un serveur web
- j’avais que ca sous la main 🙂
J’ai utilisé un capteur BME280, fabriqué par Bosch qui permet de mesurer la température, l’humidité et la pression atmosphérique. C’est le même utilisé que pour le projet Mini station météo.
L’objectif de ce tuto est de vous montrer comment cabler le capteur, paramétrer un rpi zero w de A à Z et de mettre les scripts qui vont bien pour récupérer les valeurs du capteur et les afficher dans une page json, que ma domotique ira chercher.
Le capteur se connecte via I2C sur les ports SDA/SCL (pin 3 et 5) du raspberry, avec l’alimentation en 3,3V et un GND.
Raspberry GPIO | BME280 Pin |
Pin 6 ou 9 ou 14 | GND |
Pin 1 | 3,3V |
Pin 3 | SDA |
Pin 5 | SCL |
Paramétrages du Raspberry
Configuration initiale
Tout d’abord, il faut récupérer l’image de Raspian en version strech lite ici.
Ensuite, il faut l’écrire sur votre carte SD (Win32diskImager sous Windows, Etcher sous Mac). Une fois la carte SD écrite, et avant d’éjecter la carte SD du pc, il faut aller sur le disque (vu comme une clé usb nommée boot) et créer un fichier vide nommé « ssh » à la racine, afin d’activer le SSH au premier boot.
Ensuite, il faut créer un fichier wpa_supplicant.conf et le remplir avec les infos ci dessous. Remplacer les infos wifi (ssid et psk) par les vôtres évidement.
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
country=US
update_config=1
network={
ssid="MonSSID"
psk="mypassword"
key_mgmt=WPA-PSK
}
Première connexion
Mettez la carte SD dans le Raspberry et démarrer le. Pour le retrouver sur le réseau, le plus simple est d’aller sur votre box et de chercher l’ip attribuée au Raspberry. Connectez vous en SSH dessus avec l’utilisateur pi (mot de passe par défaut : raspberry).
Il est vivement conseillé de le changer de suite avec :
sudo passwd pi
Ensuite, il faut configurer le raspberry pour activer les GPIO. Pour cela, éditer le fichier /etc/modules
sudo nano /etc/modules
Et ajouter les lignes suivantes au fichier
w1-gpio
w1-therm
i2c-dev
Rebooter le Raspberry.
Puis nous allons installer les outils i2c afin de tester que notre module branché fonctionne.
sudo apt-get install i2c-tools
On vérifie avec la commande suivante que le bus i2c fonctionne et détecte le capteur
sudo i2cdetect -y 1
Il doit répondre avec l’adresse 76 normalement (vous pouvez activer le capteur en 77 en soudant deux jonctions entre elles, cela permet d’avoir 2 sondes en parallèles sur le bus).
pi@raspberrypi:~ $ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- 76 --
Nous allons maintenant télécharger un script python tout fait qui interroge le bus i2c et affiche les valeurs. Placez vous dans /home et télécharger le.
cd /home
sudo wget -O bme280.py http://bit.ly/bme280py
Lancer le script et vérifier que les valeurs s’affichent
pi@raspberrypi:~ $ sudo python /home/bme280.py
Chip ID : 96
Version : 0
Temperature : 23.29 C
Pressure : 991.80407074 hPa
Humidity : 33.6661236663 %
pi@raspberrypi:~ $
La première étape est réalisée avec succès.
Serveur web
Nous allons maintenant installer un serveur web sur notre RPI pour afficher notre page JSON.
sudo apt install nginx php-fpm
sudo nano /etc/nginx/sites-available/default
Sur cette page, il faut chercher la ligne
index index.html index.htm index.nginx-debian.html;
et la remplacer par
index index.html index.htm index.php;
Ensuite, il faut activer php-fpm pour Nginx. Pour cela, toujours dans le même fichier, chercher le paragraphe suivant
location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php5-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php5-fpm:
# fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
#}
Et remplacer le par
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
}
Redémarrer Nginx
sudo /etc/init.d/nginx restart
Nginx est désormais installé, son répertoire de travail est dans /var/www/html
Nous allons créer un deuxième script python qui va générer un fichier texte avec les valeurs de la sonde dans le répertoire du serveur web.
Pour cela, créer un nouveau script
sudo nano /home/temp.py
Voici le script que j’utilise
import bme280
import time
temperature,pression,humidite = bme280.readBME280All()
print "Temp : ", temperature, " ^b C \t P : ", pression, "hPa \t HR : ", humidite, "%"
text_file = open("/var/www/html/temp.txt", "w")
text_file.write("%s;%s;%s" % (temperature,pression,humidite))
text_file.close()
Le script va générer le fichier /var/www/html/temp.txt à son exécution. Testons le immédiatement
pi@raspberrypi:~ $ sudo python /home/temp.py
Temp : 23.24 °C P : 991.748272092 hPa HR : 33.7615298981 %
Allez dans /var/www/html et vérifier que le fichier texte a bien été créé.
Nous sommes presque au bout, il nous reste à faire un script php qui génèrera la page json et planifier l’exécution du script toutes les minutes.
Créer un fichier index.php dans /var/www/html
sudo nano /var/www/html/index.php
Voici le script que j’ai écrit. Quelques particularités : j’ai écrit une fonction getP qui corrige la pression en fonction de l’altitude (car le capteur nous donne la pression au niveau de la mer !). 350 est l’altitude où ma maison se situe, à vous de mettre votre altitude.
Ensuite, dans le json généré, j’ai ajouté un champ Date qui m’a aidé au début pour vérifier que le script générait bien le fichier toutes les minutes.
<?php
$fp = fopen ("temp.txt", "r");
$sonde = fgets ($fp, 255);
fclose ($fp);
$sonde = explode(';',$sonde);
$alti = 350;
//fonction qui corrige la pression en fonction de l'altitude
function getP($Pact, $temp, $altitude) {
return ($Pact * pow((1 - ((0.0065 * $altitude) / ($temp + 0.0065 * $altitude + 273.15))), -5.257));
}
header('Access-Control-Allow-Origin: *');
header('Content-type: application/json');
$response = array();
$response[0] = array(
'Temp'=> $sonde[0],
'Pression'=>round(getP($sonde[1],$sonde[0],$alti),0),
'Humidite'=>round($sonde[2],0),
'Date'=>date ("H:i", filemtime('temp.txt'))
);
echo json_encode($response);
?>
Voici le résultat :
[{"Temp":"23.37","Pression":1032,"Humidite":34,"Date":"21:49"}]
Dernière étape, il faut planifier l’exécution du script. Pour cela, il faut faire une tâche cron. Pas de sudo ici, la tâche s’exécute avec l’utilisateur pi
crontab -e
puis ajouter la ligne
* * * * sudo python /home/temp.py
Conclusion
En quelques minutes, on obtient un serveur de température opérationnel et tout à fait exploitable en production. Il ne reste plus qu’à lui faire une petite boite en 3D, qui arrivera très prochainement !
Bonjour,
Bravo pour votre site. il donne des points de repères et des idées. C’est cool.
J’utilise beaucoup mes raspberry pour des mesures de température, (brassage de la biere, ect..)
Je programme principalement python pour mon travail mais l’utilise pour mes projets perso ainsi que le php (laravel) bref, je m’amuse pas mal même si le temps me manque un peu ^^.
Petite question, quel gestionnaire de snippets utilisez vous ? parce que conserver ses codes à droite à gauche au gré des ide , pas très pratique..
Encore bravo !
Bonne année,
Pascal
Bonjour,
Desole pour le retard.
Pour l’instant rien, tout mes scripts sont php dans un repertoire sur mon synology et backupés.
Sinon pour le code arduino il est pushé dans github pour conserver le versionning.