Arduino, température, humidité, et signal radio

Voici un petit projet sur lequel je travaille depuis quelques temps : il s’agit d’une petite station météo autonome. L’idée est de pouvoir consulter les tendances de la journée en un clin d’œil, sans avoir à allumer ou toucher son PC ou son smartphone.

On peut investir dans des appareils tout à fait convenables pour une centaine d’Euros… Mais, personnellement, ça ne me convenait pas : je souhaitais pouvoir personnaliser l’affichage à volonté, sans rien sacrifier à l’esthétique de l’ensemble. Dans ce cas, pourquoi ne pas essayer de le faire soi-même ?

Je vais vous expliquer ici ce que j’ai fait, mon cheminement, les problèmes que j’ai rencontrés, etc… Comme c’est un peu long, je vais découper tout ça en plusieurs articles, au fur et à mesure. A tout moment, vous pouvez retrouver l’ensemble de mon projet sur mon GitHub.

Le principe

Les stations météo portatives sont, la plupart du temps, composées d’une console qui contient l’affichage (et autres), et d’une sonde ou d’un module qui récupère les informations brutes pour les transmettre à la console. La connexion entre les deux éléments peut être filaire ou radio.

Quand on récupère des informations brutes de température, d’humidité et de pression atmosphérique, le tout à un instant t, cela vous donne l’état actuel de la météo (et peut-être – dans des situations idéales – une tendance pour le prochaines heures). Un baromètre mécanique fonctionne de cette façon.

Or, la (science de la) prévision météorologique repose sur la combinaison de toutes les données suivantes :

  • température
  • humidité
  • pression
  • heure de la journée
  • période de l’année
  • localisation géographique
  • altitude
  • exposition aux vents
  • évolution des variables précédentes sur les dernières heures
  • statistiques sur les dernières années

Vous l’aurez compris, ça demande de gérer pas mal de données sur la durée, et un peu de calcul (!). A ce stade, vous pouvez soit vous la jouer roots et logger les données nécessaires, soit faire appel à une API externe. Voici un lien qui devrait vous en apprendre plus sur le sujet et vous aider à vous décider : http://www.infoclimat.fr/api-previsions-meteo.html?id=2988507&cntry=FR

Pour ma part, je vais déjà commencer à recueillir les informations d’une petite sonde et  les transmettre à un afficheur. Pour le prototypage de montages électroniques, j’utilise Arduino. Je vais faire un montage Arduino qui va recueillir les informations et les transmettre par radio (ce qui est expliqué dans ce tuto). Puis je ferai un autre montage, avec un autre Arduino, qui servira à récupérer les informations et à les afficher (ce que je vous expliquerai dans un prochain tuto).

Comment ça marche

Pour récupérer la température et l’humidité, je vais utiliser un module DHT11. Pour envoyer des données courtes, je vais utiliser un couple de modules RF 433MHz : un TX (dont je vais parler ici pour l’émission), et un RX (dont je parlerai plus tard pour la réception). Ces composants sont compatibles Arduino et sont à utiliser avec leurs librairies que vous trouverez facilement sur le Net.  J’ai trouvé les composants eux-mêmes sur eBay pour quelques Euros : le DHT11 est vendu seul, et les modules RF 433MHz sont vendus ensemble (1 émetteur + 1 récepteur).

Là où je vis, en Région Parisienne (France), on peut dire que la température ne monte jamais au-dessus des +40°C, et ne descend jamais en dessous des -10°C. L’humidité est un taux (pourcentage), donc, techniquement elle est comprise entre 0 et 100%.

Dans ce tuto, je vais juste envoyer ces 2 valeurs par signal radio… et tant qu’à faire, je vais les envoyer ensemble dans une seule chaîne de caractères… Et pourquoi pas juste un seul integer ? Je vais utiliser 2 chiffres pour la valeur absolue de la température, et 1 chiffre qui me donnera le signe (version alternative : mon amplitude thermique est de 40+abs(-10) = 50 degrés, donc au lieu d’utiliser 1 chiffre pour le signe, j’aurais tout aussi bien pu décaler mes valeurs de températures perçues entre 0 et 50°C et refaire le calcul inverse au moment d’afficher le résultat, et donc je n’aurais eu que deux chiffres à envoyer au lieu de trois). Pour l’humidité, on peut considérer qu’au delà d’un certain pourcentage, il y a un réel problème ! Donc je pars du principe qu’elle n’excédera jamais les 99%, ce qui me permet de la coder sur 2 chiffres. Et comme vous l’avez remarqué, je ne traite qu’avec des valeurs entières.

Je me retrouve donc avec un entier à 5 chiffres à envoyer, ce qui est vraiment négligeable. L’entier est composé de la sorte : abbcc. Où le “a“, le 1er chiffre, déterminera s’il s’agit d’une valeur de température positive ou négative. “bb“, le 2ème et 3ème chiffre, détermine la valeur absolue de la température en Celsius. “cc“, le 4ème et 5ème chiffre, est utilisé pour l’humidité. Pour obtenir un entier qui contienne ces valeurs sans qu’elle interfèrent les unes avec les autres, je vais utiliser une petite formule qui me garantira que mon entier fera toujours 5 chiffres, même si certaines valeurs sont à zéro : mon entier = a * 10000 + bb * 100 + cc. Ce qui, dans le code, se traduit par :

  // Température, sur 3 chiffres
  absDeg = DHT.temperature;
  if (absDeg < 0) {
    absDeg = abs(DHT.temperature);
    isNeg = 1;
  } else {
    absDeg = DHT.temperature;
    isNeg = 2;
  }
  if(absDeg > 99) {
    absDeg = 99;
  }

  // Humidité, sur 2 chiffres
  moist = DHT.humidity;
  if (moist < 0) {
    moist = 0;
  }
  if (moist > 99) {
    moist = 99;
  }

  // Assemblage des valeurs en un seul entier
  TXstr = isNeg*10000 + absDeg*100 + moist;

Pour le reste, la LED est optionnelle : je l'utilise pour avoir un retour visuel des émissions radio. Et je reviendrai sur la pression atmosphérique plus tard.

Composants

  • Arduino Nano
  • module émetteur (TX) RF 433Mhz, compatible Arduino et librairie VirtualWire
  • module DHT11, compatible Arduino
  • alimentation pour l'Arduino
  • quelques fils électriques, dont un de 20-30cm pour l'antenne de l'émetteur
  • éventuellement une boîte de montage pour que la sonde puisse être placée à l'extérieur
  • éventuellement une LED

Comment connecter le tout

Sur la photo ci-jointe, c'est le montage que vous voyez en arrière-plan.

Le module capteur

Rien de bien compliqué. Les modules DHT ont souvent 1 broche pour la masse (ground), 1 broche VCC (+5V), et 1 broche data. La masse et VCC se connectent sur les ports Arduino usuels. et data est à raccorder au connecteur 5 de l'Arduino.

Ensuite il ne reste plus qu'à initialiser le tout dans le programme :

#include 
dht DHT;
#define DHT11_PIN 5

Le module radio TX

Rien de bien compliqué là non plus. Les broches d'alimentation sont à utiliser comme d'habitude. Par contre, la broche data est à brancher au connecteur 12 de l'Arduino.

Comme précédemment, il faut initialiser le module pour pouvoir l'utiliser :

#include 
char Message[VW_MAX_MESSAGE_LEN]; 

Code à téléverser dans l'Arduino

Voici donc, en un seul morceau, le code pour l'Arduino :

// Ce qu'il nous faut pour émettre des données
#include 
char Message[VW_MAX_MESSAGE_LEN]; 

// Ce qu'il nous faut pour recueillir des données
#include 
dht DHT;
#define DHT11_PIN 5

// Initialisation des variables
int absDeg = 0; // Température en Celsius (deux chiffres)
int isNeg = 2;  // Un chiffre pour le signe de la température : 2 si positive, 1 si négative 
int moist = 0;  // Deux chiffres pour l'humidité (pourcentage) : de 00 à 99
int TXstr = 0;  // cinq chiffres
int led = 13;   // LED pour feedback visuel

void setup() {
  pinMode(led, OUTPUT);     
  vw_setup(2000); // Taux de transmission (bits par seconde)
}

void loop() {
  int chk = DHT.read11(DHT11_PIN);

  // Température, sur 3 chiffres
  absDeg = DHT.temperature;
  if (absDeg < 0) {
    absDeg = abs(DHT.temperature);
    isNeg = 1;
  } else {
    absDeg = DHT.temperature;
    isNeg = 2;
  }
  if(absDeg > 99) {absDeg = 99;}

  // Humidité, sur 2 chiffres
  moist = DHT.humidity;
  if (moist < 0)  {moist = 0;}
  if (moist > 99) {moist = 99;}

  // Assemblage des valeurs en un seul entier
  TXstr = isNeg*10000 + absDeg*100 + moist;

  // Conversion de l'entier en un tableau de caractères
  itoa(TXstr, Message, 10);

  // Séquence d'émission
  digitalWrite(led, HIGH);
  vw_send((uint8_t *)Message, strlen(Message));
  vw_wait_tx(); // On attend la fin de transmission
  digitalWrite(led, LOW);
  delay(2000); // Une petite pause avant que ça reparte...
}

Remerciements

Je vous invite à visiter electroniqueamateur.blogspot.fr qui a été ma référence pour les émetteurs-récepteurs radio compatibles Arduino. Vous y trouverez également des informations très utiles et très pratiques ainsi que d'autres tutos en Français.

Share