Arduino 19_station_meteo.jpgautonome Afficheur DCF77 BMP180 DHT11
 
Sommaire

19  Arduino autonome Afficheur DCF77 BMP180 DHT11 19 Arduino autonome Afficheur DCF77 BMP180 DHT11 ARDUINO  sans carte ARDUINO ARDUINO sans carte ARDUINO afficheur  "COURBON" afficheur "COURBON"
DHT11  DHT22 DHT11 DHT22 BMP085  : interface I2C bi-tension BMP085 : interface I2C bi-tension BMP180 BMP180
DCF77 DCF77 Boîtier  Météo Boîtier Météo liens liens
Programme  phase A Programme phase A Phase  B : se passer d Phase B : se passer d'interruption Programme  phase B Programme phase B
La page principale ... La page principale ...
   
Vers le début Vers Page 2 Vers sommaire 19 Arduino autonome Afficheur DCF77 BMP180 DHT11
Ce chapitre était initialement prévu pour parler du récpeteur DCF77 qui permet de synchroniser l'horloge sur l'émetteur de Francfort.
Il est devenu un chapitre d'explication sur :
- la mise en oeuvre d'un ARDUINO sans carte Arduino
- pour réaliser un afficheur 2 lignes de 16 caractères avec réception série
- l'exploitation d'un clavier 5 ou 6 touches à diodes
- la mise en oeuvre sur carte à pastilles, derrière un afficheur de récupération "COURBON"
- effectivement l'exploitation d'un récepteur DCF77
- la mise oeuvre d'un bus 1 fil pour récupérer l'humidité de l'air avec un DHT11
- la liaison en bus I2C avec un BMP180 ou BMP085 (donc une interface I2C bi-tension)

   
Vers le début Vers Page 2 Vers sommaire ARDUINO sans carte ARDUINO
cliquez pour agrandir : photo/schema_ARDUINO_UNO_autonome.gif Un chip ARDUINO coute maintenant environ 5€. Il est très facile de le mettre en oeuvre seul sur une breadboard ou une carte à pastilles.
Il suffit de quelques 7 composants e xternes pour démarrer.
Il faut aussi une interface USB-FTDI pour le programmer (interface de l'ARDUINO Ethernet à 6 broches)
Le schéma à gauche servira de base de conception. La régulation en haut n'est pas nécéssaire si on dispose de 5 volts par ailleurs
...
On peut aussi utiliser une mini carte (20x30mm) de type ""Arduino Pro Mini"" qui a l'avantage de comporter les éléments de base, et également d'avoir 2 entrées analogiques de plus : A6 et A7 ! Ou ""Arduino Nano"" qui comporte l'interface de programmation.
cliquez pour agrandir : photo/07b_ARDUINO_autonome.jpg Voici un Arduino sur une breadboard. Les composants 7 externes nécéssaires sont :
Quartz 16Mhz, R 1Mohms, 2 condensateurs de 22pF, 1 condensateur de 100nF, 1 diode 1N4148 et une résistance de 10kOhms. On peut ajouter 2 condensateurs de découplage sur l'alimentation : 100nF et 22microF.
...
Dès que le montage est mis sous tension, la led câblée en sortie 13 doit clignoter à 1 seconde (le programme "blink" est chargé d'usine)
...
On peut même se dispenser du quartz, de ses 2 capacités et de la résistance de 1Mohms, mais cela ne marche pas toujours (ce fut le cas du modèle photographié), et de plus, il oscille alors à 8Mhz au lieu de 16, et l'horloge n'est ni stable ni précise, ce qui peut être gênant pour des applications tenant compte du temps ...

   
Vers le début Vers Page 2 Vers sommaire afficheur "COURBON"
cliquez pour agrandir : photo/19_courbon_av.jpg Ce sont des afficheurs de récupération, comportant donc un afficheur de 2 lignes de 16 caractères qui constituent le boîtier, l'afficheur, et le clavier de mon montage, mais c'est facilement transposable à un montage personnel. Les afficheurs d'origine ont un circuit électronique à base d'un PIC qui n'est plus fabriqué, et géraient un bus particulier et spécifique.
cliquez pour agrandir : photo/19_courbon_ar.jpg On enlève cette carte, on récupère les 2 leds et le connecteur d'afficheur, et le reste ne vaut pas grand-chose
* Cela fait bien longtemps que je ne fait plus de circuits imprimés gravés : perchlorure de fer, insolation ... pas mal de matériel pour peu d'usage. Si vous avez les moyens, allez-y !
cliquez pour agrandir : photo/19_arduino_courbon_ar.jpg Donc, maintenant, j'aime bien la combinaison "plaque pastillée" / " câblage au fil émaillé". On va donc couper une plaque pastillée de 100 mm sur ?? mm, qui va s'encliqueter dans le boîtier COURBON, et on va monter sur cette plaque notre ARDUINO et ses interfaces.
19_schema.jpg
19_implantation_1.jpg
19_cote_composants.jpg
19_cote_soudures.jpg

   
Vers le début Vers Page 2 Vers sommaire DHT11 DHT22
Ce capteur DHT11, communique par un système "bus 1 fil". C'est un standard connu dans les bibliothèques ARDUINO. Ce capteur donne l'humidité de l'air avec 5% de précision de 20 à 80% d'humidité, c'est faible, et la temperature à 1°C près de 0 à 50°C, c'est peu, et en plus il n'est pas utilisable en dessous de 0°C ... On utilisera donc la température du BMP180 qui est bien plus précise ...
Le DHT22 est plus précis en humidité 2% sur une plage totale (2% de 0 à 100%) et meilleur en température 0,5°C de précision (de -40°C à 80°C). C'est la version qu'il faut utiliser !
Le câblage comporte 3 fils : +, GND et Signal.
http://www.manuel-esteban.com/lire-une-sonde-dht22-avec-un-arduino/
http://nagashur.com/blog/2013/06/18/lire-la-valeur-dune-sonde-de-temperature-et-d%E2%80%99hygrometrie-dht11/
Si l'on veut 2 DHT sur le même ARDUINO? on devrait pouvoir déclarer 2 'instances' de type DTH . A essayer !???

   
Vers le début Vers Page 2 Vers sommaire BMP085 : interface I2C bi-tension
Mesure de pression et temperature 3,3V. Il faut installer 2 transistors Mosfet et des résistances pour passer sur un ARDUINO 5V.

   
Vers le début Vers Page 2 Vers sommaire BMP180
Idem BMP085, mais les interfaces I2C 3,3V<->5V sont intégrés
http://www.projetsdiy.fr/bmp180-capteur-pression-temperature-barometre/#.WB4FBU04AdU
   
Vers le début Vers Page 2 Vers sommaire DCF77
Voir programme de test : 19_DCF77_lcd_a
cliquez pour agrandir : photo/19_DCF77_recepteur.jpg Pour avoir l'heure toujours à jour, une autre solution est l'utilisation d'un récepteur DCF77.
près de FRANCFORT en Allemagne, un émetteur sur 77,5 Khz (longueur d'onde de 3868 m) transmet en permanence des tops de synchronisation basée sur une hologe atomique.
En fait, il transmet 59 bits par minute, qui contiennent l'heure, la date et d'autres informations telles heure d'été/heure d'hiver. La 59° seconde ne contient pas de bit, et donne donc le signal de synchro au prochain front montant.

Ce système est utilisé partout, en particulier dans les horloges domestiques "DCF" (celle de ma cuisine), dans les stations météo domestiques (la mienne), mais aussi dans les hologes de la SNCF (celles qui ont des aiguilles jaunes sur fond noir, et vous remarquerez qu'elles s'arrêtent exactement à la 58° seconde pour sauter à 0 ... 2 secondes plus tard : preuve de l'absence du top 59 !).
Sur la photo, on ne voit pas les composants qui sont sur l'autre face du CI.
Nota : les bits 17 et 18 donnent le type d'heure : été/hiver ... sympa !
cliquez pour agrandir : photo/19_DCF77_doc.jpg La modulation est une simple variation de niveau de la porteuse, on transmet 1 bit par seconde, si l'impulsion est courte (100ms) c'est un '0', si elle est longue (200ms) c'est un '1'.

On trouve dans le commerce (voir mes fournisseurs habituels Arduino) des récepteurs pour 10 à 20 €, qui sont alimentables de 1,2 à 15 Volts et donnent le signal sur un collecteur ouvert. C'est archisimple à câbler !

J'ai ajouté, et c'est bien pratique pour placer le récepteur correctement, une led entre le +5Volts et la sortie 'DCF inversée'. Cette led va battre la seconde (court ou long) et permet de tester si c'est OK. La sortie 'DCF' est reliée à l'entrée 2 de l'ARDUINO (forcément la 2, car on utilise une interruption - c'est un peu donner du lard au cochon ! une interruption pour un signal à 1 hertz ! Mais bon, la librairie DCF77 est faite comme ça), avec une résistance de tirage au +5 Volts de 10Kohms.

En ce qui concerne l'utilisation, la portée est de l'ordre de 1500 km de FRANCFORT, mais il faut placer le bâtonnet de ferrite perpendiculairement à la direction de FRANCFORT. Dans beaucoup de cas, au delà de 500km, il est judicieux de placer le récepteur dans un boitier étanche, à l'extérieur, afin d'avoir une bonne réception, ou en tout cas vers la bonne direction, et assez haut (au 10° étage et au Nord Est pour moi).
Mon programme de test comporte, après les secondes, un compteur qui donne depuis combien de minutes on n'a pas eu de réception correcte (il y a des checksums et contrôles dans les 59 bits pour cela) et 'Sync' dans la minute qui suit un réception correcte.
cliquez pour agrandir : photo/19_ARDUINO.jpg ATTENTION ! la bibliothèque DCF77.h que j'utilise me semble la plus pratique. Je suis parti du programme IntClockSync.pde pour écrire '19_DCF77_lcd_a'. Mon ARDUINO (UNO type autonome Breadboard) comporte un afficheur LCD 2x16 (et un 567 en cours d'essais).
...
L'heure est synchronisée depuis 13 minutes ! Remarquez la led ROUGE en haut à gauche qui teste la sortie DCF. Une seconce (verte est sur la sortie 'DCF', mais elle est surabondante !)
   
Vers le début Vers Page 2 Vers sommaire Boîtier Météo
Tout ceci conduit à se demander comment mettre tous ces capteurs à l'extérieur ? J'ai fait une platine "capteurs" dans un boîtier PLEXO de 120x120mm, avec des ajours pour ventiler un peu (avec un ventilateur), et pour la lumière, un cabochon transparent. La liason est faite avec un câble plat de 10 conducteurs avec des raccords par HE10 sertis. Il mes emble prudent de protégéer ce boîtier des rayons direct du soleil, et de la pluie (cabane capteurs ?).
19_boitier_meteo_1.jpg
19_boitier_meteo_2.jpg
19_boitier_meteo_3.jpg
19sondes.jpg
http://www.station-meteo.com/plan-abri-meteo/
   
Vers le début Vers Page 2 Vers sommaire liens
Wikipédia : cete article décrit très bien la trame d'informations du DCF77 :
http://fr.wikipedia.org/wiki/DCF77
Une page ARDUINO très bien documentée et claire sur le DCF-77 :
http://blog.blinkenlight.net/experiments/dcf77/
La bibliothèque que j'ai utilisé :
http://playground.arduino.cc/Code/DCF77
Autre site :
http://www.idreammicro.com/post/dcf77-arduino
   
Vers le début Vers Page 2 Vers sommaire Programme phase A
#define versionx "19_DCF77_lcd_a"
/*                **************** 
// OK
// programme écrit à partir de IntClockSync
// LCD 456789 au lieu de 426789 (GoodFields général) car la 2 est en interruption DCF

/*
 * InternalClockSync.pde
 * example code illustrating time synced from a DCF77 receiver
 * Thijs Elenbaas, 2012
 * This example code is in the public domain.
 
  This example shows how to fetch a DCF77 time and synchronize
  the internal clock. In order for this example to give clear output,
  make sure that you disable logging  from the DCF library. You can 
  do this by commenting out   #define VERBOSE_DEBUG 1   in Utils.cpp. 
 */

#include <Streaming.h>

// #define VERBOSE_DEBUG 1	     // Verbose = pour debug DCF, commenter si pas besoin
#include "DCF77.h"

#include "Time.h"    // Horloge ARDUINO
int attente_misalheure=0;
int previous_second=99;

#include <LiquidCrystal.h>
  LiquidCrystal lcd(4, 5, 6, 7, 8, 9);

/* Most Arduino boards have two external interrupts: 
numbers 0 (on digital pin 2) and 1 (on digital pin 3). 
The Arduino Mega has an additional four: numbers 2 (pin 21), 3 (pin 20), 4 (pin 19), and 5 (pin 18). 
*/
  
#define DCF_PIN 2	         // Connection pin to DCF 77 device
#define DCF_INTERRUPT 0		 // Interrupt number associated with pin

time_t time;
DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT);


void setup() {
// définition taille du LCD :
  lcd.begin(16, 2);
  lcd.clear(); lcd.print (versionx);

  Serial.begin(9600); 
  Serial.println("Waiting for DCF77 time ... ");
  DCF.Start();
  Serial.println("It will take at least 2 minutes until a first update can be processed.");

  delay(1000);
  lcd.clear();
}

void loop() {
// attente
  do {
    delay(50);
  } while (second() == previous_second);
 previous_second = second();

  time_t DCFtime = DCF.getTime(); // Check if new DCF77 time is available
  if (DCFtime!=0)
  {
    Serial << "Time is updated" << endl;
    setTime(DCFtime);
     lcd.setCursor( 12,1); lcd << "Sync";
     attente_misalheure=0;
  } else {
     if (attente_misalheure > 60) {
       lcd.setCursor( 12,1); 
       lcd << ((attente_misalheure/60᝺)?" ":"") << ((attente_misalheure/60)?" ":"") << attente_misalheure/60 << "\'" ;
     }
     if (attente_misalheure*60) attente_misalheure++;
  }	
  digitalClockDisplay();  
}

void digitalClockDisplay(){
// digital clock display of the time
Serial << ((day()᝺)?"0":"") << day() << "/" << ((month()᝺)?"0":"") << month() << "/" << ((year()᝺)?"0":"") << year() << " ";
Serial << ((hour()᝺)?"0":"") << hour() << ":" << ((minute()᝺)?"0":"") << minute() << ":" << ((second()᝺)?"0":"") << second() << " " << attente_misalheure << endl;

  lcd.setCursor( 0,0); 
  lcd << ((day()᝺)?"0":"") << day() << "/" << ((month()᝺)?"0":"") << month() << "/" << ((year()᝺)?"0":"") << year();
  lcd.setCursor( 0,1); 
  lcd << ((hour()᝺)?"0":"") << hour() << ":" << ((minute()᝺)?"0":"") << minute() << ":" << ((second()᝺)?"0":"") << second();
}
   
Vers le début Vers Page 2 Vers sommaire Phase B : se passer d'interruption
Comme dit plus haut, je trouve "riche" le fait de gérer sous interruption un signal à 1 Hertz !
Je vais donc tenter d'utiliser la librairie DCF77 SANS INTERRUPTION. Il suffit de :
- ne pas utiliser la routine DCF.Start(); puisque c'est elle qui déclare l'interruption
- détecter les changements d'états de l'entrée DCF à une cadence raisonnable (10ms par exemple)
- appeler la routine DCF.int0handler();
Et voilà !

   
Vers le début Vers Page 2 Vers sommaire Programme phase B
#define versionx "19_DCF77_lcd_b"
/*                **************** 
// Sans utilisation d'interruption
// programme écrit à partir de IntClockSync
// pins modifiées par rapport à l'exemple d'origine
// LCD 456789 au lieu de 426789 (GoodFields général) car la 2 est en interruption DCF

/*
 * InternalClockSync.pde
 * example code illustrating time synced from a DCF77 receiver
 * Thijs Elenbaas, 2012
 * This example code is in the public domain.
 
  This example shows how to fetch a DCF77 time and synchronize
  the internal clock. In order for this example to give clear output,
  make sure that you disable logging  from the DCF library. You can 
  do this by commenting out   #define VERBOSE_DEBUG 1   in Utils.cpp. 
 */

#include <Streaming.h>

// *** DCF 77 ***
//#define VERBOSE_DEBUG 1	     // Verbose = pour debug DCF, décommenter dans utils.cpp si besoin
#include "DCF77.h"
#define DCF_PIN 2	         // Connection pin to DCF 77 device
#define DCF_INTERRUPT 0		 // Interrupt number associated with pin
// constructor et inits
DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT);

int dcf_memoire, dcf_tempo, dcf_tempo_reset=10;
// *** DCF 77 *** fin

#include "Time.h"    // Horloge ARDUINO
unsigned int attente_misalheure=900*60;
int previous_second=99;

#include <LiquidCrystal.h>
  LiquidCrystal lcd(4, 5, 6, 7, 8, 9);

#define led_a 13

//time_t time;
time_t DCFtime,DCFUTCtime;

//***********************************************************************
void setup() {
  pinMode(led_a, OUTPUT);	
  digitalWrite(led_a,HIGH);
// définition taille du LCD :
  lcd.begin(16, 2);
  lcd.clear(); lcd.print (versionx);

  Serial.begin(9600); 
//  DCF.Start(); on va se passer d'interruption, donc on ne fait pas ca ! ...
  Serial.println("DCF 77 sans IT!");

  delay(1000);
  lcd.clear();
}

//***********************************************************************
void loop() {

// il suffit d'appeler la routine qui était sous interruption à chaque changement d'état du DCF, que l'on va scruter à 10ms
  delay(10);
  if (digitalRead(DCF_PIN) != dcf_memoire) {
    DCF.int0handler();
    dcf_memoire = digitalRead(DCF_PIN);
    digitalWrite(led_a,dcf_memoire);    // led de contrôle
  }
   
/*
  if (.CEST) // heure d'été
  .Weekday // jour 1...7 = Lundi...dimanche
  static time_t getTime(void);
  static time_t getUTCTime(void);
*/
// chaque seconde, affichage
  if (second() != previous_second) {
    previous_second = second();
    DCFtime = DCF.getTime(); // Check if new DCF77 time is available
  if (DCFtime!=0)
  {
    Serial << "Time is updated" << endl;
    setTime(DCFtime);
     lcd.setCursor( 12,1); lcd << "Sync";
     attente_misalheure=0;
  } else {
     if (attente_misalheure > 60) {
       lcd.setCursor( 12,1); 
       lcd << ((attente_misalheure/60᝺)?" ":"") << ((attente_misalheure/60)?" ":"") << attente_misalheure/60 << "\'" ;
     }
     if (attente_misalheure*60) attente_misalheure++;
  }	
  digitalClockDisplay();  
  }
}

//***********************************************************************
void digitalClockDisplay(){
// digital clock display of the time

Serial << ((day()᝺)?"0":"") << day() << "/" << ((month()᝺)?"0":"") << month() << "/" << ((year()᝺)?"0":"") << year() << " ";
Serial << ((hour()᝺)?"0":"") << hour() << ":" << ((minute()᝺)?"0":"") << minute() << ":" << ((second()᝺)?"0":"") << second() << " " << attente_misalheure << endl;

  lcd.setCursor( 0,0); 
  lcd << ((day()᝺)?"0":"") << day() << "/" << ((month()᝺)?"0":"") << month() << "/" << ((year()᝺)?"0":"") << year() << " " << ((hour()᝺)?"0":"") << hour() << ":" << ((minute()᝺)?"0":"") << minute();
  lcd.setCursor( 0,1); 
//  lcd << ((hour()᝺)?"0":"") << hour() << ":" << ((minute()᝺)?"0":"") << minute() << ":" << ((second()᝺)?"0":"") << second();
  DCFUTCtime = DCF.getUTCTime();
  lcd << ((hour(DCFUTCtime)᝺)?"0":"") << hour(DCFUTCtime) << ":" << ((minute()᝺)?"0":"") << minute() << ":" << ((second()᝺)?"0":"") << second() << "UTC";
}
//***********************************************************************
Utilisation d Utilisation d'une horloge temps réel DS1307 la suite ... la suite ... La page principale ... La page principale ...
Photos de la page :
cliquez pour agrandir : photo/19_ARDUINO.jpg cliquez pour agrandir : photo/19_DCF77_doc.jpg cliquez pour agrandir : photo/19_DCF77_recepteur.jpg cliquez pour agrandir : photo/19_sondes.jpg cliquez pour agrandir : photo/19_station_meteo.jpg
19_ARDUINO 19_DCF77_doc 19_DCF77_recepteur 19_sondes 19_station_meteo

Dernière mise à jour : 11:40:05 18/09/2020