(http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2012/10/100_3301 NULL.jpg)A la maison j’ai une petite “station météo” Oregon Scientific BAR310HG avec un capteur distant sans fil. Elle m’a donné toute satisfaction pendant 5 ans pour son prix très correct, mais les conditions du climat tropical commence à avoir raison des contacts et le capteur sans-fil ne fonctionne plus… Ce type de produit là n’étant pas fait pour être réparé je me suis fait une raison.
(http://xv4y NULL.radioclub NULL.asia/wp-content/uploads/2012/10/100_3303 NULL.jpg)En cherchant après des composants électroniques à Hong Kong, je suis tombé sur la série de capteurs DHT11 et DHT22 qui sont à la fois économique et suffisamment performant pour un usage domestique. Le DHT22 est plus précis mais un peu plus cher, pour mes premier essais j’ai donc choisi le modèle moins cher.
Voici un premier jet d’un programme pour Arduino qui va interroger le capteur, affiche les valeurs en temps réel, mais surtout les sauvegarde dans la mémoire EEPROM pour en faire des statistiques. L’avantage de les sauvegarder en EEPROM c’est qu’on peut faire une mesure, éteindre la station météo, la rallumer bien plus tard pour faire une autre mesure et avoir la moyenne. Pour des raisons de rapidité de traitement seules 10 valeurs sont sauvegardées, mais la mémoire disponible en permet bien d’avantage.
La commande est simple, il suffit d’appuyer brièvement sur le bouton pour sauvegarder une valeur. Un appui long (plus d’une seconde) efface toutes les valeurs en mémoire.
Une version plus évoluée et utilisant un capteur DHT22 sera prochainement proposée en kit sur la boutique (http://xv4y NULL.radioclub NULL.asia/boutique/). Elle utilisera une horloge RTC pour faire de statistiques sur une période calendaire. Les sauvegardes seront interrogables par port série, et la possibilité d’interroger un capteur à distance via des modules radio 433 MHz sera incluse.
/* Arduino Thermometer and Humidity display with EEPROM saved statistics using DHT11 sensor v1.00 By Yannick DEVOS - XV4Y http://xv4y.radioclub.asia/ Copyright 2012 Yannick DEVOS under GPL 3.0 license Any commercial use or inclusion in a kit is subject to author approval ==== This program sense and displays the current temperature and relative humidity It saves 10 values in memory when button is pressed and display an average Pressing the button more than 1 second will erase all the values Values are stored in EEPROM, you can do measuring, turn off the Arduino, then do other measuring the day after... The display is on a 16x2 LCD Display with HD44780 compatible driver, use the traditional 4 bits interface on pins 10, 9, 8, 7, 6, 5 In order to compile this program with Arduino 1.0.1, you will need to install 3 libraries : - Arduino Bounce Library http://www.arduino.cc/playground/code/bounce - New LiquidCrystal https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home - DHT-sensor Library by Adafruit https://github.com/adafruit/DHT-sensor-library ==== Revision history : v1.00 2012-10-26 First release ==== The DHT11 Sensor need to be connected as described here below - Connect pin 1 (on the left) of the sensor to +5V - Connect pin 2 of the sensor to whatever your DHTPIN is (here pin D12) - Connect pin 4 (on the right) of the sensor to GROUND - Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor We also need a push button on pin D2. ==== This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You can download a copy of the GNU General Public License at <http://www.gnu.org/licenses/> */ #include <Wire.h> #include <EEPROM.h> #include <LiquidCrystal.h> #include <Bounce.h> #include "DHT.h" #define DHTPIN 12 // What pin we have connected the DHT sensor #define BUTTON 2 // What #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); LiquidCrystal lcd(10, 9, 8, 7, 6, 5); // You can change this settings to your convenance, please see the library documentation Bounce button_debounce = Bounce( BUTTON, 10 ); int t = 0, h = 0, a = 0, b = 0, avg_t = 0 , avg_h = 0, saved_t = 0, saved_h = 0; int current_address = 1, i_address = 1; void setup() { lcd.begin(16,2); lcd.home (); dht.begin(); pinMode(BUTTON,INPUT_PULLUP); // We read where was the last saved value current_address = int(EEPROM.read(0)); } void loop() { button_debounce.update ( ); // Reading temperature or humidity takes about 250 milliseconds! // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) h = int(dht.readHumidity()); // we convert to integer since the DHT11 has not enough precision anyway t = int(dht.readTemperature()); // check if returns are valid, 0 degrees and 0 percent humidity is impossible with the DHT11 sensor... if (h == 0 && t == 0) { lcd.clear (); lcd.home (); lcd.print("Sensor Error"); delay(1000); lcd.clear (); lcd.home (); } else { lcd.setCursor ( 0, 0 ); lcd.print("T: "); lcd.setCursor ( 3, 0 ); lcd.print(t); lcd.setCursor ( 5, 0 ); lcd.print("*C"); lcd.setCursor ( 0, 1 ); lcd.print("H: "); lcd.setCursor ( 3, 1 ); lcd.print(h); lcd.setCursor ( 5, 1 ); lcd.print("%"); } int button_status = button_debounce.read(); // If the button is pressed if (button_status == LOW) { if (button_debounce.duration()>1000) { // For more than 1 second we erase the saved values in the EEPROM lcd.clear (); lcd.home (); lcd.print("Erasing"); lcd.setCursor ( 0, 1 ); lcd.print("All values"); for (int i = 0; i <= 45; i++) // We erase the 10 sets of values EEPROM.write(i, 0); current_address = 1; EEPROM.write(0, 1); delay(1000); lcd.clear (); lcd.home (); } else { // For shorter we save the value in the EEPROM lcd.clear (); lcd.home (); lcd.print("Saving value"); lcd.setCursor ( 0, 1 ); lcd.print("in memory "); lcd.setCursor ( 10, 1 ); lcd.print(round((current_address/4)+1)); EEPROM.write(current_address, byte(t & 0xFF)); EEPROM.write(current_address+1, byte(t >> 8)); EEPROM.write(current_address+2, byte(h & 0xFF)); EEPROM.write(current_address+3, byte(h >> 8)); current_address = current_address + 4; if (current_address >= 41) current_address = 1; EEPROM.write(0, byte(current_address & 0xFF)); delay(500); lcd.clear (); lcd.home (); } } // Here we read the saved values in the EEPROM and do the average avg_t = 0; avg_h = 0; for (i_address = 1; i_address <= 41; i_address = i_address + 4) { a = EEPROM.read(i_address); b = EEPROM.read(i_address+1); saved_t = (b << 8 | a); if (saved_t != 0) if (avg_t == 0) { avg_t = saved_t; } else { avg_t = (saved_t + avg_t) / 2; }; a = EEPROM.read(i_address+2); b = EEPROM.read(i_address+3); saved_h = (b << 8 | a); if (saved_h != 0) if (avg_h == 0) { avg_h = saved_h; } else { avg_h = (saved_h + avg_h) / 2; }; } // Here we display the averaged values lcd.setCursor ( 8, 0 ); lcd.print("Avg "); lcd.setCursor ( 12, 0 ); if (avg_t != 0) { // Display only when the value is significant lcd.print(avg_t); } else { lcd.print("--"); } lcd.setCursor ( 14, 0 ); lcd.print("*C"); lcd.setCursor ( 8, 1 ); lcd.print("Avg "); lcd.setCursor ( 12, 1 ); if (avg_h != 0) { // Display only when the value is significant lcd.print(avg_h); } else { lcd.print("--"); } lcd.setCursor ( 14, 1 ); lcd.print("%"); }