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 :
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 :
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);