Station météo température, pression, humidité
Ce deuxième programme de station météo utilise un capteur Adafruit BME280
qui permet de récupérer sous forme numérique la température, la pression
atmosphérique et le taux d'humidité.
Idéalement, une station météo complète donnerait ces informations ainsi
que les informations sur le vent fournies par le programme précédent.
Cependant ce programmes ont été mis au point avec une carte Arduino Uno
qui dispose d'une quantité de mémoire très limitée. La mémoire disponible
est en grande partie utilisée par le module éthernet et son lecteur de
carte SD, mais dans ce programme-ci, l'utilisation du capteur Adafruit
BME280 consomme aussi de la mémoire.
Avec une carte Arduino Uno, il n'en reste plus assez pour rajouter les
informations relatives au vent. On pourrait regrouper les possibilités
des 2 programmes en utilisant un modèle de carte Arduino disposant de
davantage de mémoire comme la carte Arduino Leonardo et surtout la carte
Arduino Mega.
Pour téléverser ce programme sur la carte Arduino, il faut d'abord mettre
dans un répertoire les 3 fichiers suivants :
Sur la carte SD, on mettra les fichiers
meteo.htm et
err404.htm
Structure de la page HTML
Le programme Arduino envoie au navigateur web une page HTML qui a la
structure suivante :
Dans cette page, il y a 3 valeurs à afficher :
- La température en °C,
- La pression atmosphérique en mbar,
- Le taux d'humidité en %.
Comme dans tous les exemples de programme qui précèdent, le programme
Arduino va remplacer les chaînes de caractères du fichier HTML commençant
par
XXX par les informations à afficher.
Le programme Arduino
Comme tous les programmes Arduino, celui-ci possède une fonction
setup () qui initialise le matériel, à savoir la carte
Ethernet et le lecteur de carte SD.
On supposera que l'adresse MAC et l'adresse IP de la carte Ethernet
ont été configurées conformément à ce qui est dit dans la page
Généralités
Voici le code source complet du programme.
Utilisation du capteur
Pour utiliser le capteur BME280, un fichier d'inclusion est nécessaire
au début du programme :
#include <Adafruit_BME280.h>
Une variable est associée à ce capteur :
Adafruit_BME280 capteur;
et dans la fonction
setup () le capteur est initialisé.
if (! capteur.begin ())
Serial.println (F("Echec !"));
else
Serial.println (F("Succès"));
Du point de vue électrique, la capteur est branché sur l'un des ports
I2C de la carte Arduino.
Les mesures
Trois fonctions de mesure sont disponibles :
float mesure_temper ()
{
return (capteur.readTemperature ());
}
Le résultat de la mesure de température sera mémorisé dans une variable
de type
float capable de mémoriser des nombres décimaux.
int mesure_pres_atm ()
{
return (capteur.readPressure () / 100);
}
La pression atmosphérique retournée par le capteur est exprimées en pascal
qui est une petite unité de pression correspondant à des Newton par m².
Il est plus courant d'exprimer la pression atmosphérique en hectopascal,
appelé aussi millibar, ce qu'on fait en divisant le valeur mesurée par
100.
Une précision d'un millibar étant suffisante dans la mesure de
la pression atmosphérique, la valeur retournée par la fonction
mesure_pres_atm () est une valeur entière.
int mesure_humidite ()
{
return (capteur.readHumidity ());
}
Le taux d'humidité retourné par le capteur est exprimées en %. Il ne
nécessite donc pas de conversion et une valeur entière suffit pour
mémoriser la valeur mesurée avec une précision suffisante.
Les fonctions de conversion
Les valeurs mesurées sont stockées dans des variables numériques. Or,
pour les afficher dans la page HTML, il faut les convertir en une série
de chiffres.
Pour cela, on utilise deux fonctions de conversion.
// pour convertir une valeur entière en chaine de caractères
char *conv_int_str (int valeur)
{
sprintf (valconv, "%d", valeur);
return (valconv);
}
Cette fonction a déjà été utilisée dans le premier programme de station
météo et la conversion qu'elle effectue est aussi employée dans le compteur
de passages.
C'est la fonction
sprintf qui est une fonction standard du langage
C qui convertit la variable entière
valeur en un série de chiffres
qui seront stockés dans la variable globale
valconv dont l'adresse
en mémoire est retournée par la fonction.
La fonction
conv_int_str (...) est utilisée pour l'affichage
de la pression atmosphérique et du taux d'humidité.
Par contre, la température mesurée est en général une valeur non entière.
Pour la convertir, on utiliser une autre fonction :
// pour convertir une valeur décimale en chaine de caractères
char *conv_float_str (float valeur)
{
int val;
// le format %f ne marchant pas, on découpe les parties entière et décimales comme 2 entiers
// il faudrait faire un peu mieux pour les nombre négatifs
val = valeur * 10;
sprintf (valconv, "%d,%d", val / 10, val % 10);
return (valconv);
}
Comme expliqué dans le commentaire, normalement, on aurait du pouvoir
faire un traitement similaire à celui de la fonction précédente en
remplaçant le
"%d" de la fonction
sprintf par
"%3.1f" (conversion d'un nombre "flottant" en une chaine d'au
moins 3 caractères dont un après les point décimal), mais le compilateur
C/C++ pour Arduino ne fait pas cette conversion !
Donc, on décompose le travail :
- On commence par multiplier la température par 10 pour l'exprimer
en dixièmes de °C
- La division entière par 10 de cette nouvelle valeur de température
correspond à la partie entière de la température en °C
- Le reste de la division par 10 de correspond au nombre de dixièmes
de °C à rajouter à la valeur précédente
- Le format "%d,%d" permet de regrouper les 2 calculs
précédents sous la forme de 2 nombres séparés par une virgule.
Au passage, ce traitement permet d'écrire les nombres décimaux avec
une virgule, comme ils doivent l'être dans une langue romane, au
lieu du point décimal des anglophones.
Le calcul décrit marche bien pour les températures positives (ce qui est
courant pour la température d'une salle de classe), mais si on voulait
aussi traiter les température négatives, il faudrait utiliser la valeur
absolue de la température mesurée au moins pour la calcul de la partie
décimale;
Le programme serveur
Lorsque la navigateur web demande l'affichage de la page, la fonction
loop () commence par récupérer les résultats des
mesures :
// valeurs des mesures
float temper;
int pres_atm;
int humidite;
(...)
// faire les mesures
temper = mesure_temper ();
pres_atm = mesure_pres_atm ();
humidite = mesure_humidite ();
En utilisant les valeurs récupérées et les fonctions de conversion, on peut
maintenant envoyer au navigateur la page HTML en mettant les informations
à afficher au bon endroit :
// envoi de la page
coprep_chaine (descfic, client, "XXXTEMP", conv_float_str (temper));
coprep_chaine (descfic, client, "XXXPRES", conv_int_str (pres_atm));
coprep_chaine (descfic, client, "XXXHUMID", conv_int_str (humidite));
copie_jusque_fin (descfic, client);