L’objectif de ce tutoriel est de concevoir un capteur de température et d’humidité sans fil avec un Arduino Pro Mini sur batterie et de récupérer ces informations sur le logiciel de domotique Jeedom tournant sur un Raspberry Pi.
Côté émetteur, l’Arduino Pro Mini est alimenté par une batterie Li-Ion de 3,7 V et les mesures de température et d’humidité sont réalisées grâce à un capteur DHT22. Les données sont envoyées au récepteur via un module radio HC12.
Côté récepteur, les données sont reçues par une Raspberry Pi grâce à un autre module radio HC12. Les données sont transmisses au serveur domotique Jeedom via le protocole MQTT. Les données stockées dans le serveur Jeedom sur le Raspberry Pi peuvent être visualisées depuis n’importe quel équipement (smartphone, tablette…) si le Raspberry Pi est connecté au réseau wifi.
Ce tutoriel est composé de deux parties :
- Réalisation du capteur sans fil avec un Arduino Pro Mini
- Intégration des données dans le logiciel domotique Jeedom sur un Raspberry Pi
Mots clés : Arduino ; Capteur sans fil HC12 ; RF 433 MHz; Raspberry Pi ; Jeedom ; MQTT
Première partie : réalisation du capteur sans fil avec un Arduino Pro Mini
Le Matériel
Liste du matériel nécessaire pour le capteur sans fil :
- Module radio HC12
- Capteur de température et d’humidité AM2302 DHT22
- Arduino Pro Mini 3,3V 8MHz
- Pile Li-Ion 3,7V
Arduino Pro Mini
Il existe deux versions de l’Arduino Pro Mini : la version 3,3 V / 8 MHz et la version 5 V 16 MHz.
L’Arduino Pro Mini version 3,3 V / 8 MHz convient parfaitement à notre émetteur radio, pour plusieurs raisons :
- sa taille idéale pour un petit boitier extérieur
- sa consommation minimale lorsque la LED a été supprimée (dessoudée ou détruite avec un fer à souder comme montré sur la photo ci-dessous)
- son alimentation 3,35 – 12 V parfaite pour une batterie Li-Ion de 3,7 V
- sa puissance à 8 MHz largement satisfaisante pour notre application
Le module radio HC12
Le module radio HC12 permet des communications radio longue distance (jusqu’à 1000m), il est donc particulièrement adapté dans le cas où le capteur sans fil extérieur est placé dans le jardin et que le récepteur est à l’intérieur de la maison.
La communication avec le module HC12 se fait au travers d’une interface série, ce qui simplifie grandement son utilisation sur divers équipements (Arduino, Raspberry Pi…).
Le module opère sur une bande de fréquence de 433.4 MHz à 473 MHz, avec une puissance de transmission maximale de 100mW (20dBm).
Configuration du module HC12
Il faut passer le module en mode « commande » afin de pouvoir configurer le module. Pour ce faire, il faut mettre la valeur de la pin SET à un niveau bas (broche 4 l’Arduino mise à LOW) et envoyer la commande au module.
Canal :
Le choix du canal se fait par la commande « AT+Cxxx » où xxx est le numéro du canal. Dans ce tutoriel nous choisirons le canal 1 qui correspond à la fréquence 433,4 MHz.
Puissance :
La puissance d’émission est réglée par la commande « AT+ Px » ou x correspond à la puissance de transmission. Afin de limiter la puissance au seuil autorisé en France, nous utiliserons x=4 qui correspond à 6.3mW (8dBm).
Mode de communication radio série :
Le module supporte 4 modes différents de communication radio série (FU1, FU2, FU3 et FU4). Le mode est sélectionné par la commande « AT+FUx ».
Attention : Par défaut, le module est configuré pour transmettre sur le canal 1 (433.4 MHz) à la puissance de 100mW. Afin de respecter la réglementation locale, la puissance d’émission maximale sur la bande de fréquence 433 MHz est de 10mW (10dBm). Et la bande de fréquence 433 MHz s’étend de 433.05 à 434.79 MHz. Donc sur le module HC 12 seuls les canaux 1 (433.4 MHz), 2 (433.8 MHz), 3 (434.2 MHz) et 4 (434.6 MHz) seront autorisés, ainsi qu’une puissance P4 (8 dBm, 6.3 mW). Les canaux 5 à 100 et les puissances P5 à P8 sont interdits en France.
Le capteur de température et humidité DHT22
Le capteur de température/humidité utilisé est le AM2302 – DHT22. Il communique avec le microcontrôleur via un port série. Il peut être alimenté de 3,3 V à 6 V et convient donc à notre montage alimenté par batterie de 3,7 V nominal et 4,2 V maximal.
L’autre intérêt de ce capteur est sa faible consommation au repos: 50 µA. Ce qui est très important car nous ne remontons les températures que toutes les 30 minutes et le montage sera donc la plupart du temps en veille.
Schéma du montage
Il faut relier le module HC12 au microcontrôleur (Arduino) via une liaison série. Nous utiliserons les PIN 2 et 3 de l’Arduino avec une liaison série logicielle (SoftwareSerial), afin de laisser la liaison série de l’Arduino disponible pour la mise au point du projet.
La pin SET du HC12 permet de sélectionner le mode programmation de ce module. Elle est reliée à la PIN 4 de l’Arduino afin de pouvoir sélectionner le mode « normal » ou « commande » via l’application.
La communication des données du capteur de température/humidité AM2302 – DHT22 vers le microcontrôleur se fait au travers d’une seule broche, la PIN 7 de l’Arduino sera utilisée.
Le circuit est alimenté par une batterie Li-Ion de 3.7V (tension maximale de 4.2V et tension nominale de 3,7V).
Programme Arduino
Inclure la bibliothèque simplesleep (http://sparks.gogo.co.nz/SimpleSleep.zip) via le menu de l’IDE Arduino «Croquis / Inclure une bibliothèque / Ajouter la bibliothèque .ZIP ». Cette bibliothèque permet de mettre l’Arduino en veille prolongée afin d’en limiter la consommation électrique.
Inclure la bibliotheque « DHT sensor library » via le menu « Outils / Gérer les bibliothèques ».
Le programme se contente de lire les données du capteur DHT22 toutes les 30 minutes et d’envoyer la température et l’humidité sur la liaison radio via le module HC12.
Le message radio envoyé est formaté sous la forme de chaîne de caractères de format « S1:XX.XX:YY.YY:ZZ.ZZ » ou S1 indiqeur que c’est le capteur numéro 1, XX.XX de type float est la température en °C et YY.YY de type float est l’humidité et ZZ.ZZ de type float est la tension de la batterie. Par exemple, si la température est de 19,5°C, l’humidité de 51 % et la tension de la batterie 3,7 V, la chaîne envoyée sera par le capteur 1 sera « S1:19.50:51.00:3.70 ».
Afin de limiter la consommation électrique, le module HC12 et l’Arduino sont mis en veille entre deux émissions radio. Le capteur DHT-22 se positionne en veille automatiquement lorsque il n’y a pas de lecture via son port série.
#include "DHT.h"
#include "SoftwareSerial.h"
#include "SimpleSleep.h"
#define DHTPIN 7 // PIN 7 reliée à DAT du DHT22
#define DHTTYPE DHT22 // Capteur de type DHT22
#define HC12RXPIN 2 // PIN 2 reliée au RX du HC12
#define HC12TXPIN 3 // PIN 3 reliée au TX du HC12
#define HC12SETPIN 4 // PIN 4 reliée au SET du HC12
#define IDENTIFIANT_CAPTEUR 1 // Utiliser un identifiant différent pour chaque capteur
DHT dht(DHTPIN, DHTTYPE); // Configuration du capteur DHT22
SoftwareSerial HC12Serial(HC12TXPIN, HC12RXPIN); // Configuration du port série logiciel pour le HC12
SimpleSleep Sleep; // Sleep permet la mise en veille basse consommation de l'arduino
const float InternalReferenceVoltage = 1.105; // Cette valeur dépend de chaque micro-contrôleur et doit être mesurée par un voltmètre
// Mesure la tension de la batterie qui alimente l'Arduino
// en utilisant cette tension comme référence et en mesurant
// la référence interne à 1,1 V avec le convertisseur
// Analogique-Numérique
// **
// **
float getBatteryVoltage(){
float batteryVoltage=0.0;
ADCSRA = bit(ADEN); // Active le convertisseur ADC
ADCSRA |= bit (ADPS0) | bit (ADPS1) | bit (ADPS2); // Prescaler de 128
ADMUX = bit (REFS0); // Positionne AVcc (tension d'alimentation du convertisseur) comme tension de référence
ADMUX |= bit (MUX3) | bit (MUX2) | bit (MUX1); // Le canal d'entrée de l'ADC est mis sur la référence interne de 1.1V
delay (10); // Laissons la mesure se stabiliser
bitSet (ADCSRA, ADSC); // Demarrons la conversion
while (bit_is_set(ADCSRA, ADSC)) // Attendons que la conversion soit finie
{ }
batteryVoltage = InternalReferenceVoltage / ADC * 1024.0;
Serial.print("ADC=");
Serial.print(ADC);
Serial.print(" , Voltage=");
Serial.println(batteryVoltage);
return(batteryVoltage);
}
// Met le HC12 en veille en lui envoyant la commande AT+SLEEP
// **
// **
void SleepHC12() {
//Serial.println("HC12 entre en veille");
// Positionne le HC12 en mode programmation (AT) et envoie la commande "AT+SLEEP"
digitalWrite(HC12SETPIN,LOW);
delay(250);
HC12Serial.println("AT+SLEEP");
delay(250);
// Vérifie la réponse de la commande, doit être "OK+SLEEP"
if(HC12Serial.available() > 0) {
String input = HC12Serial.readString();
if (input != "OK+SLEEP\r\n") {
Serial.println("Erreur lors de l'entree en veille");
Serial.println(input);
}
}
// Positionne le HC12 en mode normal afin que le module entre en veille
digitalWrite(HC12SETPIN,HIGH);
delay(250);
}
// Sors le HC12 du mode veille en lui envoyant la commande AT
// **
// **
void wakeupHC12() {
//Serial.println("HC12 sors du mode veille");
// Positionne le HC12 en mode programmation (AT) et envoie la commande "AT"
digitalWrite(HC12SETPIN,LOW);
delay(250);
HC12Serial.println("AT");
delay(250);
// Vérifie la réponse de la commande, doit être "OK"
if(HC12Serial.available() > 0) { // send data FROM HC-12
String input = HC12Serial.readString();
if (input != "OK\r\n") {
Serial.println("Erreur lors de la sortie de veille");
Serial.println(input);
}
}
// Positionne le HC12 en mode normal
digitalWrite(HC12SETPIN,HIGH);
delay(250);
}
// Configuration
// -------------
void setup() {
pinMode(HC12TXPIN, INPUT); // TX du HC12 est une PIN en entrée sur l'arduino
pinMode(HC12RXPIN, OUTPUT); // RX du HC12 est une PIN en sortie sur l'arduino
pinMode(HC12SETPIN,OUTPUT); // SET du HC12 est une PIN en sortie sur l'arduino
Serial.begin(9600);
Serial.setTimeout(20);
HC12Serial.begin(9600);
HC12Serial.setTimeout(20);
// Démarrage du DHT22
dht.begin();
Serial.println("Capteur DHT 22 opérationnel");
// Positionne le HC12 en mode programmation (AT)
digitalWrite(HC12SETPIN,LOW);
delay(250);
// Configuration par default du HC12 (canal 1, 20dBm, FU3, 9600 bauds)
HC12Serial.println("AT+DEFAULT");
delay(250);
// Vérifie la réponse de la commande, doit être "OK+DEFAULT"
if(HC12Serial.available() > 0) {
String input = HC12Serial.readString();
if (input != "OK+DEFAULT\r\n") {
Serial.println("Erreur lors de la configuration par default");
Serial.println(input);
}
}
// Configuration de la puissance d'emission à 8 dBm (P4)
HC12Serial.println("AT+P4");
delay(250);
// Vérifie la réponse de la commande, doit être "OK+P4"
if(HC12Serial.available() > 0) {
String input = HC12Serial.readString();
if (input != "OK+P4\r\n") {
Serial.println("Erreur lors de la configuration par default");
Serial.println(input);
}
}
// Positionne le HC12 en mode normal
digitalWrite(HC12SETPIN,HIGH);
delay(250);
// Vérifie si le HC12 est prêt
if (HC12Serial.isListening()) {
Serial.println("Module radio HC12 opérationnel");
} else {
Serial.println("Erreur du module radio HC12");
}
// Configure la PIN de la LED en sortie
pinMode(LED_BUILTIN, OUTPUT);
}
// Boucle principale
// -----------------
void loop() {
String myStr;
// Lit la température et l‘humidité du capteur DHT22
float h = dht.readHumidity();
float t = dht.readTemperature();
float batt = getBatteryVoltage();
// Si la lecture du capteur est valide, envoyer les informations par radio
if (isnan(h) || isnan(t)) {
Serial.println("Erreur de lecture du DHT22 !");
}
else {
// Allume la LED pour signifier le début de l'emission radio
digitalWrite(LED_BUILTIN, HIGH);
// Reveille le HC12
wakeupHC12();
// Envoi le message "S1:XX:YY:ZZ" par radio (XX = temperature ; YY = humidité ; ZZ = batterie voltage)
myStr = "S"+ String(IDENTIFIANT_CAPTEUR) + ":" + String(t) +':'+String(h) +':'+String(batt);
HC12Serial.print(myStr);
// Eteind la LED pour signifier la fin de l'emission radio
digitalWrite(LED_BUILTIN, LOW);
}
// Attente pour permettre la fin de l'emission du message radio
delay(250);
// Mise en veille du HC12
SleepHC12();
// Mise en veille de l'arduino pendant 30 minutes
Sleep.deeplyFor(1800000);
}
Consommation électrique
Afin de réduire la consommation électrique, j’ai choisi les options suivantes :
- Suppression de la LED Power de l‘Arduino (dessoudée ou détruite)
- Mise en veille du module radio HC12 entre deux mesures
- Mise en veille de l’Arduino entre deux mesures
Ces différentes options permettent de réduire l’intensité du circuit en mode veille à 68 µA. Ce qui est crucial car le circuit sera en veille 99,94 % du temps.
Lorsque l’Arduino n’est pas en veille pour effectuer la mesure et émettre le message radio, l’intensité du courant passe à 23mA mais ne dure que 1 seconde. Puisque les émissions radio sont effectuées toutes les 30 minutes, l’intensité moyenne en mode émission est donc de 23 mA * 1/1800 = 12,7 µA.
Avec une intensité moyenne totale de 80,7 µA le dispositif aura une autonomie d’environ 12391 heures (516 jours) avec une batterie de 1000 mAh.
Tension de la batterie
Le convertisseur analogique-numérique de l’Arduino est paramétrer de la façon suivante afin de mesurer la tension d’alimentation du circuit :
- Tension de référence = AVcc (la tension d’alimentation du convertisseur analogique-numérique, qui correspond à la tension de la batterie dans notre circuit)
- Tension d’entrée à mesurer = tension interne 1,1 V
La mesure de la tension interne fixe de 1,1 V par le convertisseur nous permet de déduire la tension de la batterie par la formule suivante :
Tension de la batterie = (1.1 V / résultat de la conversion analogique-numérique) * 1024
Choix du canal radio
Si vous possédez un tuner radio, vérifiez que la fréquence du canal choisi n’est pas trop encombrée dans votre entourage.
Comme on le voit dans l’image ci-dessous, le canal 2 (433,8 MHz) est assez encombré chez moi et j’ai donc sélectionné le canal 1 (433,4 MHz).
C’est la fin de la première partie de ce tutoriel, nous allons voir dans la seconde partie comment récupérer les données dans un serveur Jeedom tournant sur un Raspberry Pi.
salut , s’il vous plait j’aimerai vous demandé comment peut-on connaitre la puissance autorisée dans les autres pays ?
merci beaucoup pour ce tutoriel ca ma été de grand aide et j’aimerai vous demandé comment je peux ajouter le hc12 et dht22 ci je veux suivre le montage et le faire dans isis merci d’avance , j’espère que qlq peut me répondre le plutôt possible cest important
bonjour
tres bon tuto pour un novice comme moi
peux t’on avoir plusieurs capteur avec un seul récepteur ?
merci
franck
Oui tout à fait c’est possible, il suffit de changer le numéro du capteur (S1, S2, S3,…) prévu dans la remontée d’information « S1:XX.XX:YY.YY:ZZ.ZZ »
Très bonne pédagogie, texte explications très clair. Merci, bravo
Merci pour ce commentaire, cela motive 🙂