start:projets:capteurweb

Les idées & projets


Les données, du capteur au Web

Aussi appelé "IOT" pour "Internet des Objets" (Internet Of Things)


Cet atelier va permettre de découvrir toutes les techniques utilisées pour lire une donnée (température, pression, qualité de l'air, puissance consommée, …) et pour l'utiliser et l'afficher sur Internet :

  • Utiliser des capteurs avec Arduino ou RaspberryPi afin d'obtenir des données. Commencer par un capteur de température: le DS18B20. On en utilisera plusieurs sur une même broche Arduino
  • Enregistrer les données obtenues. L'arduino sera connecté à un Pi (Raspberry ou Orange). Cela permet d'alléger le sketch Arduino qui reste ainsi solide. Il est aussi possible de faire un prétraitement des informations fournies, et éventuellement de servir rapidement une ou plusieurs pages HTML. Il va fallor commencer à apprendre à communiquer avec l'Arduino, en Python, via le port série.
  • Server MQTT, pour distribuer les données à d'autres appareils, comme par exemple une box domotique
  • Server de base de données SQL afin de conserver un historique de toutes les données
  • Traiter éventuellement ces données (moyenne journalière par exemple)
  • Afficher ces données sous formes graphique, dans un navigateur. Server Web - HTML - EcmaScript (js)

Plusieurs technologies seront abordées et utilisées :

  • Arduino et sa programmation
  • RaspberryPi et sa programmation en Python
  • Réseau et transport des données, protocoles TCP IP, MQTT, HTTP
  • Eventuellement , communication radio
  • Bases de données, SQL
  • Serveur Web, HTML, JavaScript

Voici la liste non exhaustive et dans le désordre des ateliers à venir.
Noter que certains de ces ateliers se feront sans doute en plusieurs séances.

  • Arduino + DS18B20. Envoie des données sur le port série, en JSON
  • Installation & Configuration d'un RaspberryPi (raspbian) et d'un OrangePi (armbian)
  • Programmation en Python pour communiquer avec le port série grace à la bibliothèque pySerial
  • Programmation en Python avec Bottle pour monter un premier server Web servant des pages statiques. Découverte du HTML.
  • Ajouter de la dynamique dans les pages, c'est à dire des données vivantes et fraiches. Utilisation de bibliothèques JavaScript.
  • Installation de Linux sur un PC et initiation
  • Quelques notions de réseau et du protocole TCP IP v4
  • Server MQTT Mosquitto
  • Server SQL PostgreSQL ou SQLite pour enregistrer toutes les données
  • Augmentation du server web pour servir des historiques de données.
  • Server Node-RED pour éventuellement faire interagir les différents capteurs et actionneurs : IOT

Découverte du capteur DS18B20.
Apparence physique du capteur simple (boitier TO92), et du capteur tel qu'on peut le trouver inséré dans un bulbe métallique étanche.
Connexion du capteur DS18B20 à l'Arduino:
Le DS18B20 est un capteur numérique qui communique ses données selon le protocole “OneWire”. Il présente l'avantage de pouvoir utiliser une seule broche de l'Arduino pour lire plusieurs capteurs disposés en réseau parallèle ou en étoile.
Un schéma de montage pour un seul capteur nu est disponible ici (image) ou ici (fritzing). Le fil rouge correspond au +5V, le fil noir à la masse et le fil jaune sera connecté à la broche de lecture, soit la broche 2 en utilisant le sketch ci-dessous.
A noter qu'il existe des capteurs intégrés dans un bulbe étanche qui utilisent les codes couleur suivant:

Masse +5V Data
Bulbe Noir Rouge Jaune Noir Rouge Jaune
Bulbe Jaune Rouge Vert Jaune Rouge Vert
Bulbe cable réseau Orange Rouge Vert

Dans le cas de capteurs en réseau, il est nécessaire de découvrir l'adresse unique de chaque capteur.
Cela se fait par exemple avec ce programme .

Fritzing est un logiciel libre qui permet de faire facilement des schémas électriques simples afin de documenter ses projets.


La distribution souhaitée est Xubuntu. C'est un Ubuntu, avec une interface XFCE, assez légère et réactive
Bien entendu, cette distribution existe en 64 bits et 32 bits. Pour des machines anciennes, il est nécessaire de choisir la version 32 bits.
Une page est dédiée à cela.


Le langage de programmation “Python” est le langage officiel du Raspberry Pi. En outre, je trouve que Python est aisément accessible et polyvalent.
On trouve énormément de documenation et de tutoriels sur Internet, en français qui plus est. Le site OpenClassRoom par exemple propose une bonne porte d'entrée. Il y a aussi un MOOC python.
Enfin, José a préparé “Une introduction à l’environnement Linux pour des bricoleuses et bricoleurs”, document qui contient aussi “Une introduction au langage Python pour des bricoleuses et bricoleurs”.
J'ai aussi trouvé une “Initiation à Python par l’exemple”.

Avec Python, on découvre aussi ce qui est un peu une curiosité : la simultanéité de 2 versions pas tout à fait compatibles : la 2 et la 3, cette dernière étant disponible depuis plus de 10 ans. Toutefois, les 2 versions ont continué à évoluer. On considère actuellement que la version 2 touche à sa fin et que la majorité des bibliothèques en cours de vie ont actuellement migrées vers la version 3.

Sur la plupart des machines, les 2 versions maintenant sont installées, mais la version 2 reste encore souvent la version par défaut.
Pour exécuter un code python en version 3, il faut explicitement appeler python3. Par exemple, le script toto.py devra être exécuter avec la commande

python3 toto.py

la commande par défaut

python toto.py

utiliserait la version 2 de Python.

Pour commencer, il est possible d'identifier la version par défaut en tapant la commande

python --version

Ensuite, il est possible de spécifier la version par défaut à utiliser en utilisant la commande “update-alternatives
La version par défaut sera celle pour laquelle il aura été spécifié le plus grand numéro en fin de commande. Il est même possible de gérer ainsi différentes versions 2.x et versions 3.x.
Voici un exemple de commande mettant une version 3 par défaut :

sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.5 2
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1

Il est maintenant possible de faire un script Python permettant de connaître la version utilisée:

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import sys
print(sys.version)

Le but est de récupérer les informations envoyées par l'Arduino, éventuellement de les afficher, mais surtout de les traiter.
Pour cela, on va utiliser le port USB de l'Arduino et on va essayer de faire le tri entre les informations de fonctionnement ou de débuggage, et les informations utiles, qui elles, seront présentées en json.
Il sera aussi intéressant de pouvoir envoyer des commandes à l'Arduino.
Pour commencer, il est nécessaire d'avoir un sketch Arduino qui va nous servir à tester tout cela. Le sketch testJson1.ino est disponible.
Ce sketch récupère une tension sur une borne analogique de l'Arduino, en prépare 3 valeurs et les envoie sur le port USB formattées en json, parmi d'autres informations de contrôle et de débuggage.
Un site intéressant pour vérifier le bon formattage d'un document json : jsonchecker.com.

Coté miniPC, c'est donc le script python testSerial.py qui sera chargé de communiquer avec l'Arduino, en utilisant la bibliothèque pyserial.

Noter que j'utilise python3.
La bibliothèque pyserial n'est pas installée par défaut sur Linux. Il est donc nécessaire de l'installer. Cela se fait par la commande :

sudo apt install python3-serial

Le fichier testSerial.py est donc un fichier qui s'ouvre avec n'importe que éditeur de texte. Pour l'exécuter, ouvrir une fenêtre de terminal dans le dossier dans le quel se trouve le fichier et lancer la commande

python3 testSerial.py

ou simplement

python testSerial.py

si python3 est la version de python utilisée par défaut sur votre PC.
Penser à vérifier le port série utilisé par le code. Comme il s'agit d'une boucle infinie, il est nécessaire d'arrêter le programme manuellement. Cela se fait avec la combinaison de touche “Ctrl + C”


Pour servir les pages web qui nous intéressent, qui affichent notamment des données issues de capteurs locaux, le framework web léger Bottle suffit amplement. Et sans alourdir l'ensemble, il est facile d'utiliser un autre Framework web minimaliste supportant le multitache: CherryPy.
Il est donc nécessaire d'installer Bottle et CherryPy avec la commande suivante:

sudo apt install python3-bottle python3-cherrypy3

Et maintenant, un premier exemple, avec le traditionnel “Bonjour le monde !” :

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
from bottle import route, run
 
@route('/hello')
def hello():
    return 'Bonjour le monde de <b>Python</b>! '
 
run(host='localhost', port=8080, server='cherrypy')

Pour voir cette page s'afficher dans votre navigateur, exécuter ce script python, puis, aller à l'adresse http://locahost:8080/hello.
Noter que les page web sont servies sur le port 8080, qui est spécifié dans la dernière ligne. “localhost” est l'adresse IP de votre machine.
Ensuite, la page s'appelle “hello”. Dans le code, c'est le décorateur “@route” qui spécifie cela.

Mais comment faire pour transmettre des images et d'autres fichier ?
C'est relativement simple, avec l'exemple suivant :

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
from bottle import route, run, static_file
 
@route('/static/<filename>')
def serverStatic(filename):
    return static_file(filename, root='myStaticsFiles')
 
@route('/hello')
def hello():
    return 'Bonjour le monde de <b>Python</b>! '
 
run(host='0.0.0.0', port=8080, server='cherrypy')

La nouvelle fonction “serverStatic” a été ajoutée, avec le décorateur “@route('/static/') ”. Cela signifie que le server pourra répondre aux adresses commençant par http://locahost:8080/static/... avec un nom de fichier valide à la place des “…”. Ce fichier devra se trouver dans le sous-dossier “myStaticsFiles” du dossier courant. Il est bien entendu possible de spécifier un chemin absolu, du style “/home/user/softs/testBottle/myStaticsFiles”.
Autre nouveauté par rapport au premier exemple, le contenu de “host” dans la dernière ligne. Dans le premier exemple, seul l'ordinateur local, nommé “Localhost” pouvoir interroger le server. Maintenant, “0.0.0.0” signifie que le server web va répondre à toutes les adresse IP. Si vous avez une autre machine sur le réseau local, il lui est maintenant possible d'interroger le server web, une fois celui-ci en cours d'exécution bien sûr.
Avec Linux, pour obtenir l'adresse IP locale de sa machine, c'est la commande:

ip addr

L'installation d'un OrangePi est décrite sur cette page dédiée.

Un tuto complet est aussi disponible sur le site developpez.com. Toujours sur ce même site, et du même auteur, un tutoriel explique comment contrôler un RaspberryPi depuis un PC Linux.


MQTT est un protocole de transport particulièrement adapté à véhiculer les données fournies par les capteurs.
MQTT pourrait être l'abréviation de “Message Queuing Telemetry Transport”.
Il existe des librairies qui permettent d'utiliser MQTT pour Arduino et pour la plupart des microcontroleurs utilisés pour des capteurs.

Chaque information est assuciée à un sujet, ou “topic”. Les topics sont organisés de façon arborescente, et sont laissé au bon soin des utilisateur. Il n'y a aucune structure prédéfinie.

  • Installation
sudo apt install mosquitto
  • Lancer le server :
mosquitto -d

Normalement, il se lance automatiquement après l'installation.
Le port n'a pas besoin d'être précisé si on utilise le port par défaut qui est 1883. C'est l'option “-p” qui permet de spécifier un port différent. Il sera alors nécessaire de toujours spécifier le port à utiliser avec les commandes clients que l'on verra plus bas.

  • modifier le fichier /etc/mosquitto/mosquitto.conf
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto
listener 1883
listener 8083
protocol websocket
log_dest topic
log_type error
log_type warning
log_type notice
log_type information
connection_messages true
log_timestamp true
include_dir /etc/mosquitto.conf.d
  • Installer les clients mosquitto
sudo apt-get install mosquitto-clients

Un fois le client installé, il est possible de :

S'abonner

Par exemple souscrivant aux données du topic “test” et de tout ses enfants:

mosquitto_sub -t test/# -v

Les options suivantes sont disponibles (entre autres):

-t : pour spécifier le topic auquel on souhaite souscrire ou s'abonner. Le caractère # est un caractère générique qui signifie, dans l'exemple ci-dessus, que l'on souhaite tous les topics commençant par la racine “test”

-v : pour afficher le topic. Cela est utile quand on s'abonne en utilisant le caratère générique #.

-h : pour spécifier l'adresse IP ou le nom d'une autre machine

-p : pour spécifier un port différent

Publier des données

en alimentant le topic “test/a” :

mosquitto_pub -t test/a -m "toto fait du vélo" -r

Les options suivantes sont disponibles (entre autres):

-t : pour spécifier le topic sur lequel on souhaite publier.

-m : pour spécifier le message ou la valeur à publier. Les guillemets sont nécessaire si le message comporte des espaces.

-r : pour demander au server de conserver la dernière valeur pour le topic en question

-h : pour spécifier l'adresse IP ou le nom d'une autre machine

-p : pour spécifier un port différent.

Enfin, voici quelques liens intéressants :

Enfin, on va pouvoir interragir avec toutes les données via des scripts écrit en Python.
Avant cela, il va être nécessaire d'installer la librairie ad-hoc via l'utilitaire PIP :

sudo apt install python3-pip
sudo pip3 install paho-mqtt

Nous voilà maintenant paré à pouvoir triturer et croiser facilement toutes nos données issues des différents capteurs.

Il peut être aussi extrèmement intéressant de construire une page web dynamique sans server. ce est possible via des scripts JavaScript utilisant l'interface WebSocket du server MQTT.

Dans le fichier de configuration du server Mosquitto, nous avons ajouter 2 lignes :

listener 8083
protocol websocket

Cela pour spécifier que le protocole WebSocket doit être disponible sur le port 8083.

C'est en effet ce protocole qui sera utilisé par les pages HTML pour souscrire au flux MQTT et récupérer directement les données publiées au fur et à mesure.

Un projet exemple est disponible ici : dans ce fichier zip

Ce projet comprend 5 fichiers à déposer dans le même dossier:

  • SteelTemp.html : Le fichier html que nous devons construire, avec un peu de javaScript pour personnaliser les interactions avec le server MQTT.
  • jquery-1.8.3.min.js : une bibliothèque javaScript très utile
  • tween-min.js : une autre bibliothèque javaScript
  • mqttws31.js : la bibliothèque javaScript qui gère tout le code permettant de souscrire à un server MQTT
  • steelseries.js : une bibliothèque javascript qui permet d'afficher un thermomètre graphique

—-

Une petite démo d'un capteur de température sans fil en utilisant la bibliothèque MySensors.
Plutôt orienté domotique, le système repose sur le composant radio NRF24L01 et un arduino nano. D'un coté, un ensemble (arduino + radio) doté d'un capteur de température DS18B20, et de l'autre, un ensemble seul faisant office de passerelle via le port série.
Il est possible de connecter toute une série de capteurs et d'actionneurs.
Plusieurs box domotiques sont capables d'utiliser ce système.


  • start/projets/capteurweb.txt
  • Dernière modification: 2021/11/26 23:59
  • de finizi