Projet Lazy Compagny -> Température/Hygrométrie via 433mhz + Site internet
26 mars 2019Salutation, camarades!
Cet hiver, j’ai eu une problématique: “Comment surveiller à distance l’environnement de la Lazy Compagny pendant leur hibernation?”
J’ai donc décomposé le problème en trois:
- Quelles variables du champs de bataille dois-je mesurer et comment?
- Comment coder et transmettre l’information au QG?
- Comment débriefer facilement les informations?
Pour information, tout le code et la liste du matériel sera disponible en fin de post.
Pour information, Les sources sont CC-BY-NC-SAhttps://creativecommons.org/licenses/by-nc-sa/3.0/fr/
PARTIE I : Quelles variables du champs de bataille dois-je mesurer et comment?
Pour l’hibernation des tortues, les deux variables les plus importantes à surveiller sont la température car il ne faut pas qu’elle soit en dessous de 0°C et l’hygrométrie qui doit être aux alentours de 70%.
Pour résoudre cette première problématique, je me suis orienté vers un capteur DHT22 car la plage de température est idéal (-40°C à 125°C pour 0.5°C de précision)
Son utilisation est extrêmement simple car une librairie Arduino est disponible et permet de récupérer facilement les informations et qu’il est plug and play.
Voici le code que j’ai utilisé pour le faire fonctionner
#include "DHT.h"// DHT22 #define DHTPIN 3 // Pin de lecture des donnees DHT #define DHT5VPIN 2 // Pin pour alimentation DHT #define DHTTYPE DHT22 // DHT 22 (AM2302) //global vars DHT dht(DHTPIN, DHTTYPE); void setup() { //setup led pinMode(13,OUTPUT); //setup DHT22 pinMode(DHT5VPIN, OUTPUT); digitalWrite(DHT5VPIN, HIGH);//enable power dht.begin(); //for debugging Serial.begin(9600); } void loop(){ //read from dht22 digitalWrite(13,HIGH); float h = dht.readHumidity(); float t = dht.readTemperature(); //Check if any reads failed and exit early (to try again). if (isnan(h) || isnan(t)) { Serial.println("Failed to read from DHT sensor!"); return; } //some debug info Serial.println("Humidity "); Serial.println(h); Serial.println("Temperature: "); Serial.println(t); delay(3000); }
Voila maintenant que nous sommes capable de mesurer l’environnement des tortues, nous pouvons passer à la transmission de données.
PARTIE II : Comment coder et transmettre l’information au QG?
Pour cela je suis partie sur une solution de transmission sans fil via un module 433Mhz
Pour la partie transmission, au premier abord cela est simple car comme pour le capteur DHT22 une librairie arduino existe et le transmitter est plug and play. Cependant, il ne faut pas oublier que le nombre de caractères transmissible par trame est limité, ce qui m’a obligé à tronquer les informations venant de la partie mesure.
Voici le code que j’ai utilisé pour le faire fonctionner
#include// 433MHz tx #include "DHT.h"// DHT22 #define DHTPIN 3 // Pin de lecture des donnees DHT #define DHT5VPIN 2 // Pin pour alimentation DHT #define DHTTYPE DHT22 // DHT 22 (AM2302) //global vars DHT dht(DHTPIN, DHTTYPE); char data[50]; //char *data; int identifier; int hnew; int tnew; int tmaxnew=000; int tminnew=900; int hmaxnew=000; int hminnew=900; int tbuff; int hbuff; char tch; char hch; void setup() { //setup led pinMode(13,OUTPUT); //setup virtualwire vw_set_ptt_inverted(true); // vw_set_tx_pin(12); vw_setup(4000);// Vitesse de transmission des donnees Kbps //setup DHT22 pinMode(DHT5VPIN, OUTPUT); digitalWrite(DHT5VPIN, HIGH);//enable power dht.begin(); //for debugging Serial.begin(9600); Serial.println("This is the transmitter!"); identifier = 0; } void loop(){ //read from dht22 digitalWrite(13,HIGH); float h = dht.readHumidity(); float t = dht.readTemperature(); //Check if any reads failed and exit early (to try again). if (isnan(h) || isnan(t)) { Serial.println("Failed to read from DHT sensor!"); return; } //some debug info Serial.println("Humidity "); Serial.println(h); Serial.println("Temperature: "); Serial.println(t); //format data string h = h*10; t= t+40; t = t*10; hnew= h; tnew =t; if (tnew>tmaxnew){tmaxnew=tnew;} if (tnew hmaxnew){hmaxnew=hnew;} if (hnew =2000) for the next reading identifier++; delay(3000); }
Pour la partie réception, la récupération d’information est plutôt simple car la librairie arduino utilisée gère aussi bien la transmission que la réception de données.
Voici le code pour le récepteur (to do commenter mon code)
#includechar temperature[3]; char temperaturemax[3]; char temperaturemin[3]; char humidity[3]; char humiditymax[3]; char humiditymin[3]; int t; int tmax; int tmin; int h; int hmax; int hmin; float tf; float tfmin; float tfmax; float hf; float hfmax; float hfmin; void setup() { //setup virtualwire vw_set_ptt_inverted(true); // Required for DR3100 vw_set_rx_pin(12); vw_setup(4000); // Bits per sec //setup led pinMode(13, OUTPUT); //setup serial for debugging Serial.begin(9600); Serial.println("Receiver test"); // Start the receiver PLL vw_rx_start(); } void loop() { //read and print! uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) // Non-blocking { Serial.println((char*)buf); //Serial.println(buflen); char dummy[VW_MAX_MESSAGE_LEN]; temperature[0] = (int)(char*)buf[1]; temperature[1] = (int)(char*)buf[2]; temperature[2] = (int)(char*)buf[3]; temperaturemax[0] = (int)(char*)buf[5]; temperaturemax[1] = (int)(char*)buf[6]; temperaturemax[2] = (int)(char*)buf[7]; temperaturemin[0] = (int)(char*)buf[9]; temperaturemin[1] = (int)(char*)buf[10]; temperaturemin[2] = (int)(char*)buf[11]; humidity[0] = (int)(char*)buf[13]; humidity[1] = (int)(char*)buf[14]; humidity[2] = (int)(char*)buf[15]; humiditymax[0] = (int)(char*)buf[17]; humiditymax[1] = (int)(char*)buf[18]; humiditymax[2] = (int)(char*)buf[19]; humiditymin[0] = (int)(char*)buf[21]; humiditymin[1] = (int)(char*)buf[22]; humiditymin[2] = (int)(char*)buf[23]; t = (int(temperature[0]) - 48) * 100 + (int(temperature[1]) - 48) * 10 + (int(temperature[2]) - 48); tf = t; tf = tf / 10; tf = tf - 40; tmax = (int(temperaturemax[0]) - 48) * 100 + (int(temperaturemax[1]) - 48) * 10 + (int(temperaturemax[2]) - 48); tfmax = tmax; tfmax = tfmax / 10; tfmax = tfmax - 40; tmin = (int(temperaturemin[0]) - 48) * 100 + (int(temperaturemin[1]) - 48) * 10 + (int(temperaturemin[2]) - 48); tfmin = tmin; tfmin = tfmin / 10; tfmin = tfmin - 40; h = (int(humidity[0]) - 48) * 100 + (int(humidity[1]) - 48) * 10 + (int(humidity[2]) - 48); hf = h; hf = hf / 10; hmax = (int(humiditymax[0]) - 48) * 100 + (int(humiditymax[1]) - 48) * 10 + (int(humiditymax[2]) - 48); hfmax = hmax; hfmax = hfmax / 10; hmin = (int(humiditymin[0]) - 48) * 100 + (int(humiditymin[1]) - 48) * 10 + (int(humiditymin[2]) - 48); hfmin = hmin; hfmin = hfmin / 10; Serial.print("TActuel:"); Serial.print(tf); Serial.print(", TMin:"); Serial.print(tfmin); Serial.print(", TMax:"); Serial.println(tfmax); Serial.print("HActuel:"); Serial.print(hf); Serial.print(", HMin:"); Serial.print(hfmin); Serial.print(", HMax:"); Serial.println(hfmax); } }
Maintenant que nous savons mesurer, transmettre les informations, il faut pouvoir les lire sur n’importe quel écran.
PARTIE 3: Comment débriefer facilement les informations?
Pour cela, je suis parti sur une solution où un Arduino s’occupe de faire le serveur. J’ai donc rajouté un module ENC28J60 sur mon Arduino Mega
J’avoue que j’ai bien galéré car c’est un domaine qui m’était jusque là totalement inconnu. Le plus difficile a été d’interfacer correctement le serveur Arduino avec le reste de mon réseau.
Ii faut aussi penser aux Pins utilisées car pour les Mega, il vaut mieux utiliser la Pin 53
Je ne préfère pas rentrer pour l’instant dans le détail car trop de souvenirs douloureux sont encore présent donc…
Voici le code complet pour le site internet
#include#include #define STATIC 0 // set to 1 to disable DHCP (adjust myip/gwip values below) static word homePage(); // ethernet interface mac address, must be unique on the LAN static byte mymac[] = { 0x74, 0x69, 0x69, 0x2D, 0x30, 0x31 }; static byte myip[] = { 192, 168, 51, 177 }; static byte gwip[] = { 192, 168, 51, 1 }; byte Ethernet::buffer[500]; BufferFiller bfill; // Initialisation des variables char temperature[3]; char temperaturemax[3]; char temperaturemin[3]; char humidity[3]; char humiditymax[3]; char humiditymin[3]; int t; int tmax; int tmin; int h; int hmax; int hmin; static int tf; int tfmin; int tfmax; static int hf; int hfmax; int hfmin; void setup() { //setup virtualwire vw_set_ptt_inverted(true); // Required for DR3100 vw_set_rx_pin(12); vw_setup(4000); // Bits per sec //setup led pinMode(13, OUTPUT); //setup serial for debugging //Serial.println("Receiver test"); // Start the receiver PLL vw_rx_start(); Serial.begin(9600); if (ether.begin(sizeof Ethernet::buffer, mymac, 53) == 0) Serial.println( "Failed to access Ethernet controller"); #if STATIC ether.staticSetup(myip, gwip); #else if (!ether.dhcpSetup()) Serial.println("DHCP failed"); #endif //ether.staticSetup(myip, gwip); } static word homePage() { //ReadDHT11(); bfill = ether.tcpOffset(); bfill.emit_p(PSTR( "HTTP/1.0 200 OKrn" "Content-Type: text/htmlrn" "Pragma: no-cachern" "rn" "" " Tortues server " "Temperature actuel: $D C
"), tf, tfmax, tfmin, hf, hfmax, hfmin); return bfill.position(); } void loop() { digitalWrite(13, HIGH); //read and print! uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; if (vw_get_message(buf, &buflen)) // Non-blocking { //Serial.println((char*)buf); //Serial.println(buflen); char dummy[VW_MAX_MESSAGE_LEN]; temperature[0] = (int)(char*)buf[1]; temperature[1] = (int)(char*)buf[2]; temperature[2] = (int)(char*)buf[3]; temperaturemax[0] = (int)(char*)buf[5]; temperaturemax[1] = (int)(char*)buf[6]; temperaturemax[2] = (int)(char*)buf[7]; temperaturemin[0] = (int)(char*)buf[9]; temperaturemin[1] = (int)(char*)buf[10]; temperaturemin[2] = (int)(char*)buf[11]; humidity[0] = (int)(char*)buf[13]; humidity[1] = (int)(char*)buf[14]; humidity[2] = (int)(char*)buf[15]; humiditymax[0] = (int)(char*)buf[17]; humiditymax[1] = (int)(char*)buf[18]; humiditymax[2] = (int)(char*)buf[19]; humiditymin[0] = (int)(char*)buf[21]; humiditymin[1] = (int)(char*)buf[22]; humiditymin[2] = (int)(char*)buf[23]; t = (int(temperature[0]) - 48) * 100 + (int(temperature[1]) - 48) * 10 + (int(temperature[2]) - 48); tf = t; tf = tf / 10; tf = tf - 40; tmax = (int(temperaturemax[0]) - 48) * 100 + (int(temperaturemax[1]) - 48) * 10 + (int(temperaturemax[2]) - 48); tfmax = tmax; tfmax = tfmax / 10; tfmax = tfmax - 40; tmin = (int(temperaturemin[0]) - 48) * 100 + (int(temperaturemin[1]) - 48) * 10 + (int(temperaturemin[2]) - 48); tfmin = tmin; tfmin = tfmin / 10; tfmin = tfmin - 40; h = (int(humidity[0]) - 48) * 100 + (int(humidity[1]) - 48) * 10 + (int(humidity[2]) - 48); hf = h; hf = hf / 10; hmax = (int(humiditymax[0]) - 48) * 100 + (int(humiditymax[1]) - 48) * 10 + (int(humiditymax[2]) - 48); hfmax = hmax; hfmax = hfmax / 10; hmin = (int(humiditymin[0]) - 48) * 100 + (int(humiditymin[1]) - 48) * 10 + (int(humiditymin[2]) - 48); hfmin = hmin; hfmin = hfmin / 10; //Serial.println(int(temperature[0])-48); //Serial.println(int(temperature[1])-48); //Serial.println(int(temperature[2])-48); //Serial.println(int(temperature[3])-48); //Serial.print("TActuel:"); Serial.print(tf); //Serial.print(", TMin:"); //Serial.print(tfmin); //Serial.print(", TMax:"); //Serial.println(tfmax); //Serial.print("HActuel:"); //Serial.print(hf); //Serial.print(", HMin:"); //Serial.print(hfmin); //Serial.print(", HMax:"); //Serial.println(hfmax); digitalWrite(13, LOW); } word len = ether.packetReceive(); word pos = ether.packetLoop(len); if (pos) // check if valid tcp data is received { ether.httpServerReply(homePage()); // send web page data Serial.print("Echo"); } }
Temperature Maximale: $D C
Temperature Minimale: $D C
Humidite actuel: $D %
Humidite Maximale: $D %
Humidite Minimale: $D %
Ce qui donne après plusieurs heures de batailles et de souffrances.
C’est ainsi que la Lazy Compagny pu commencer son hibernation en toute sérénité!
Ressources:
Matériel utilisé
- Capteur DHT22
- Arduino nano
- Arduino mega 2560
- Kit transmission/réception 433mhz
- Module ENC28J60
Code