Arduino
autonome Afficheur DCF77 BMP180 DHT11
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)
| ARDUINO sans carte ARDUINO |
 | | 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. |
 | | 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 ... |
 | | 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. |
 | | 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 ! |
 | | 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
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 !???
| 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.
Idem BMP085, mais les interfaces I2C 3,3V<->5V sont intégrés
http://www.projetsdiy.fr/bmp180-capteur-pression-temperature-barometre/#.WB4FBU04AdU
Voir programme de test : 19_DCF77_lcd_a
 | | 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 !
 | | 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.
 | | 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 !) |
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/
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
#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();
}
| 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à !
#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";
}
//***********************************************************************
Photos de la page :
|
|
|
|
|
19_ARDUINO |
19_DCF77_doc |
19_DCF77_recepteur |
19_sondes |
19_station_meteo |
Dernière mise à jour : 11:40:05 18/09/2020