Serveur d'impression

Synchronisation temporelle Arduino du serveur NTP utilisant le module WiFi ESP8266 – Bien choisir son serveur d impression

Le 3 mai 2019 - 17 minutes de lecture

Le temps est l'unité qui mesure notre vie. Chaque mécanisme dans le monde de l'électronique et des ordinateurs est basé sur le temps. L'automatisation en tant que concept est définie par des actions intelligentes coordonnées dans le temps ou dans le temps. Lorsqu'on parle d'ingénierie d'automatisation, les projets intelligents reposent sur des déclencheurs et des calculs très précis basés sur la synchronisation et le minutage. Mais comment pouvons-nous obtenir le temps parfait sans ajustement manuel? Une façon d'y parvenir est de demander à un serveur NTP. Dans cet article, vous trouverez toutes les informations sur l’utilisation de ESP8266 comme source de temps pour vos projets Arduino sans module externe RTC.

Utilisation du module compatible WiFi ESP8266 Arduino comme source en temps réel

Comment obtenir l'heure exacte d'un serveur NTP en utilisant le module Arduino ESP8266 en tant que client UDP sans module RTC. Utilisez ESP8266 comme horloge temps réel pour Arduino.
Remarque: Si vous ne savez pas ce qu'est un module ESP8266, je vous recommande de lire une critique complète et un didacticiel ici, puis de revenir.

Qu'est-ce que le serveur NTP?

L'acronyme NTP signifie Protocole de temps réseau, un protocole de communication réseau pour la synchronisation d’horloge entre clients du réseau, en service depuis 1980. Le travail NTP consiste à synchroniser tous les participants du réseau pour Temps universel coordonné (UTC) dans quelques millisecondes. Pour accomplir cette tâche, il utilise le «Algorithme d'intersection», un algorithme d'accord inventé par Keith Marlzullo estimer l'heure exacte à partir de différentes sources bruyantes. NTP peut maintenir le temps avec une précision inférieure à 50 millisecondes sur l'Internet public et inférieur à 5 millisecondes dans un environnement LAN. Dans une description plus conviviale, je dirais qu'un NTP est un service client-serveur qui peut être implémenté en envoyant ou en recevant des horodatages via des requêtes UDP ou en diffusant / multidiffusant.

Comment pouvons-nous utiliser les serveurs NTP?

Les implémentations NTP peuvent être trouvées dans de nombreuses applications. Vos systèmes d'exploitation obtiennent probablement l'heure d'un serveur NTP, des serveurs de temps, des bases de données, des stations météo, des applications de courtage et d'échange de marché en ligne tirent également parti des serveurs NTP en demandant une heure précise. Afin d'interroger un serveur NTP, votre environnement devrait pouvoir ouvrir une connexion UDP sur un port local, puis envoyer et recevoir des paquets UDP sur le même réseau que le serveur. Les packages reçus contiennent de multiples informations, telles que l’horodatage, la précision, le délai ou le fuseau horaire UNIX, et de nombreux environnements de développement fournissent des méthodes conviviales pour extraire les données dans un format plutôt objectif.

Quelle est la précision d'un serveur NTP?

Avant de savoir à quel point un serveur NTP peut être précis, vous devez connaître son architecture. Un serveur NTP est un hiérarchique, semi-stratifié système de niveaux d'horloges. Voir ci-dessous Niveaux de strates NTP:

Synchronisation temporelle Arduino du serveur NTP utilisant le module WiFi ESP8266

De nombreux facteurs peuvent affecter l'exactitude de l'heure synchronisée par NTP. Une influence visible peut avoir les effets suivants:

  • Vitesse (latence) de la connexion Internet du client.
  • Strates du ou des serveurs de temps choisis pour la synchronisation.
  • Distance du signal depuis les serveurs (y compris vers et depuis les satellites en orbite).
  • La qualité et la complexité de l'algorithme logiciel utilisé.

Remarque: pour obtenir une meilleure précision, il est recommandé de choisir des serveurs physiquement proches de votre point de sortie (point de fin de fournisseur d'accès Internet). Cela réduira le risque que le signal ne soit pas acheminé vers un satellite géostationnaire. Exemples de serveurs publics:

  • Global; www.pool.ntp.org/zone/@
  • Asie; www.pool.ntp.org/zone / asie
  • Iran; www.pool.ntp.org/zone / ir

En règle générale, l'URL sera quelque chose comme x.asia.pool.ntp.org où x = 0,1,2 ou 3.

Le kit de démarrage Arduino le plus complet

Exemple de code Arduino pour ESP8266 – Pooling de serveurs NTP

Afin d’obtenir des données du serveur NTP, nous devons programmer le module ESP pour qu’il soit un client UDP. Je préfère programmer l'ESP8266 à l'aide de l'IDE Arduino, mais le même résultat peut être obtenu avec le code LUA ou via les commandes AT. Pour ce faire avec Arduino, j’ai utilisé deux bibliothèques disponibles: ESP8266WiFi.h et WiFiUdp.h. La première bibliothèque autorise et gère les connexions WiFi tandis que la seconde gère l’envoi et la réception de paquets UDP. Les deux bibliothèques sont disponibles après l’installation du ESP8266 conseil du gestionnaire de la carte dans l'IDE Arduino.

Remplacer SSID et mot de passe avec les identifiants WiFi de votre routeur domestique, remplacez le ntpServerName avec le serveur sur lequel vous souhaitez obtenir du temps et télécharger le code suivant sur votre ESP. Vous pouvez pointer une adresse IP directe du serveur NTP, mais probablement vous perdrez le BASSIN avantages.

/ *********************
- www.geekstips.com
- Synchronisation de l'heure Arduino à partir du serveur NTP à l'aide du module WiFi ESP8266
- Exemple de code Arduino
 ********************* /

#comprendre 
#comprendre 

chars ssid[] = "*************"; // votre SSID de réseau (nom)
passe char[] = "********"; // votre mot de passe réseau


unsigned int localPort = 2390; // port local pour écouter les paquets UDP

/ * Ne connectez pas l’adresse IP, sinon nous n’obtiendrons pas les avantages du pool.
 * Recherchez l'adresse IP du nom d'hôte à la place * /
// IPAddress timeServer (129, 6, 15, 28); // serveur NTP time.nist.gov
IPAddress timeServerIP; // time.nist.gov adresse du serveur NTP
const char * ntpServerName = "time.nist.gov";

const int NTP_PACKET_SIZE = 48; // l'horodatage NTP est dans les 48 premiers octets du message

octet packetBuffer[ NTP_PACKET_SIZE]; // tampon pour contenir les paquets entrants et sortants

// Une instance UDP pour nous permettre d'envoyer et de recevoir des paquets via UDP
WiFiUDP udp;

void setup()

  Serial.begin (115200);
  Serial.println ();
  Serial.println ();

  // On commence par se connecter à un réseau WiFi
  Serial.print ("Connexion à");
  Serial.println (ssid);
  WiFi.begin (ssid, pass);
  
  while (WiFi.status ()! = WL_CONNECTED) 
    retard (500);
    Serial.print (".");
  
  Serial.println ("");
  
  Serial.println ("WiFi connected");
  Serial.println ("adresse IP:");
  Serial.println (WiFi.localIP ());

  Serial.println ("Démarrer UDP");
  udp.begin (port local);
  Serial.print ("Port local:");
  Serial.println (udp.localPort ());


boucle vide ()

  // récupère un serveur au hasard dans le pool
  WiFi.hostByName (ntpServerName, timeServerIP);

  sendNTPpacket (timeServerIP); // envoie un paquet NTP à un serveur de temps
  // attend de voir si une réponse est disponible
  délai (1000);
  
  int cb = udp.parsePacket ();
  si (! cb) 
    Serial.println ("pas de paquet pour le moment");
  
  autre  lowWord;
    Serial.print ("secondes depuis le 1er janvier 1900 =");
    Serial.println (secsSince1900);

    // convertit maintenant le temps NTP en temps quotidien:
    Serial.print ("Unix time =");
    // l'heure Unix commence le 1 janvier 1970. En quelques secondes, cela correspond à 2208988800:
    const unsigned long soixante-dix ans = 2208988800UL;
    // soustrais soixante-dix ans:
    longue période non signée = secondes depuis 1900 - soixante-dix ans;
    // affiche l'heure Unix:
    Serial.println (epoch);


    // affiche l'heure, la minute et la seconde:
    Serial.print ("L'heure UTC est"); // UTC est l'heure au méridien de Greenwich (GMT)
    Impression série ((epoch% 86400L) / 3600); // affiche l'heure (86400 secondes par jour)
    Serial.print (':');
    si (((epoch% 3600) / 60) <10) 
      // Dans les 10 premières minutes de chaque heure, nous voulons un '0' en tête
      Serial.print ('0');
    
    Serial.print ((epoch% 3600) / 60); // affiche la minute (3600 secondes égales par minute)
    Serial.print (':');
    si ((epoch% 60) <10) 
      // Dans les 10 premières secondes de chaque minute, nous voulons un "0" en tête
      Serial.print ('0');
    
    Serial.println (epoch% 60); // imprimer la seconde
  
  // attend dix secondes avant de demander à nouveau l'heure
  retard (10000);


// envoie une requête NTP au serveur de temps à l'adresse indiquée
unsigned long sendNTPpacket (IPAddress & address)

  Serial.println ("envoi d'un paquet NTP ...");
  // met tous les octets du tampon à 0
  memset (packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialise les valeurs nécessaires pour former une requête NTP
  // (voir URL ci-dessus pour plus de détails sur les paquets)
  packetBuffer[0] = 0b11100011; // LI, Version, Mode
  packetBuffer[1] = 0; // strate ou type d'horloge
  packetBuffer[2] = 6; // Intervalle d'interrogation
  packetBuffer[3] = 0xEC; // Précision d'horloge homologue
  // 8 octets de zéro pour le délai et la dispersion des racines
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // tous les champs NTP ont reçu des valeurs, maintenant
  // vous pouvez envoyer un paquet demandant un horodatage:
  udp.beginPacket (address, 123); // Les requêtes NTP doivent porter le port 123
  udp.write (packetBuffer, NTP_PACKET_SIZE);
  udp.endPacket ();

Cet exemple de code a été inspiré d'ici. Ouvrez votre terminal de surveillance série et réinitialisez le module ESP. Vous devriez voir un résultat comme celui-ci:

Synchronisation temporelle Arduino du serveur NTP utilisant le module WiFi ESP8266

Dans cet exemple, j'ai utilisé un serveur NTP global (time.nist.gov), mais venant d’Europe, ce n’est pas le meilleur choix. Pour mes projets, j'utilise un serveur NTP plus proche de mon emplacement physique, comme dans l'exemple suivant:

const char * ntpServerName = "0.europe.pool.ntp.org";

Pour obtenir le NTP qui correspond à votre emplacement, allez à www.pool.ntp.org et dans la barre latérale droite, cliquez sur votre zone / continent pour voir la liste complète:
Synchronisation temporelle Arduino du serveur NTP utilisant le module WiFi ESP8266
Synchronisation temporelle Arduino du serveur NTP utilisant le module WiFi ESP8266

Configuration de l'ESP8266 en tant que source de temps

Il existe plusieurs façons d’utiliser le module ESP comme source de temps, mais nous devons en choisir une avec le Meilleure performance pendant la transaction, afin de réduire ou éliminer le temps supplémentaire. Le moyen le plus rapide, et celui que j’ai utilisé dans mes projets, est d’obtenir le temps de l’ESP8266 via terminaux série. Vous pouvez également configurer un serveur Web sur l'ESP et renvoyer l'heure via une réponse HTTP à la demande, mais cela dépend du réseau et nécessite un projet connecté au réseau. N'oubliez pas que tout retard créé par la transaction de sortie affectera directement l'exactitude du temps renvoyé.

Dans l’exemple suivant, nous connecterons l’ESP8266 à un ordinateur standard Arduino UNO R3 via les terminaux série et configurez le RTC interne Arduino UNO pour qu'il se synchronise avec l'heure NTP donnée. Pour ce faire, nous devrons utiliser le LogicielSerial bibliothèque pour émuler la communication série sur les GPIO numériques 2 et 3 et réserver cette ligne pour l’écoute du module ESP.

Synchronisation temporelle Arduino du serveur NTP utilisant le module WiFi ESP8266

Comme vous le savez probablement dans les tutoriels précédents, je vous recommande fortement d’utiliser un alimentation externe 3.3v pour ESP8266, mais à des fins de démonstration, nous utiliserons le 3.3v VCC de l’ONU. Avant de faire quoi que ce soit sur votre Arduino UNO, nous devons d'abord nettoyer le code que nous venons de télécharger sur ESP8266.

Parce que la bibliothèque de temps Arduino nous donne la possibilité de synchroniser le RTC interne ou externe uniquement en passant le paramètre de temps UNIX, nous pas besoin la autre sortie série utilisé dans l'exemple, le code de production du module ESP doit donc ressembler à ceci:

/ *********************
- www.geekstips.com
- Synchronisation de l'heure Arduino à partir du serveur NTP à l'aide du module WiFi ESP8266
- Exemple de code Arduino
 ********************* /

#comprendre 
#comprendre 

chars ssid[] = "***********"; // votre SSID de réseau (nom)
passe char[] = "***********"; // votre mot de passe réseau


unsigned int localPort = 2390; // port local pour écouter les paquets UDP
IPAddress timeServerIP;
const char * ntpServerName = "time.nist.gov";

const int NTP_PACKET_SIZE = 48;

octet packetBuffer[ NTP_PACKET_SIZE];
WiFiUDP udp;

void setup()

  Serial.begin (115200);
  WiFi.begin (ssid, pass);
  
  while (WiFi.status ()! = WL_CONNECTED) 
    retard (500);
  
  udp.begin (port local);


boucle vide ()

  WiFi.hostByName (ntpServerName, timeServerIP);

  sendNTPpacket (timeServerIP);
  délai (1000);
  
  int cb = udp.parsePacket ();
  si (! cb) 
    retarder (1);
  
  autre 
    udp.read (packetBuffer, NTP_PACKET_SIZE); // lit le paquet dans le tampon
    unsigned long highWord = word (packetBuffer[40], packetBuffer[41])
    unsigned long lowWord = word (packetBuffer[42], packetBuffer[43])
    non signés longues secondes depuis le début du mois = highWord << 16 
  retard (10000);


unsigned long sendNTPpacket (IPAddress & address)

  Serial.println ("envoi d'un paquet NTP ...");
  memset (packetBuffer, 0, NTP_PACKET_SIZE);
  packetBuffer[0] = 0b11100011; // LI, Version, Mode
  packetBuffer[1] = 0; // strate ou type d'horloge
  packetBuffer[2] = 6; // Intervalle d'interrogation
  packetBuffer[3] = 0xEC; // Précision d'horloge homologue
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
  udp.beginPacket (address, 123);
  udp.write (packetBuffer, NTP_PACKET_SIZE);
  udp.endPacket ();

Comme vous pouvez le constater, nous n’imprimons que le Heure UNIX (époque), car nous allons l’utiliser pour passer en paramètre à la configuration de l’horloge interne d’Arduino. J'ai aussi imprimé une ficelle Jeton "UNX" avant l’horodatage pour s’assurer que ESP ne nous fournit pas de données erronées.

Maintenant, sur l’ONU Arduino, nous devons écouter la transmission série ESP8266. Lorsque l'ESP envoie des données sur le canal série TX, nous devons vérifier si l'heure actuelle est UNIX et non des erreurs ou des erreurs. Nous pouvons le faire en vérifiant les 3 premiers caractères qui devraient être = "UNX" jeton. Si cela est vrai, alors le 10 prochains personnages devrait représenter l’époque UNIX. Voir la démonstration dans l'exemple ci-dessous:

/ *********************
- www.geekstips.com
- Synchronisation de l'heure Arduino à partir du serveur NTP à l'aide du module WiFi ESP8266
 ********************* /
#comprendre 
#comprendre 

// configure une vitesse de transmission commune pour UNO et ESP
int baudRate = 115200;
char unixString[11];
long unixTime;
boolean dataSync = false;
// configuration du canal série émulé ESP
SoftwareSerial esp8266 (2, 3);

void setup() 
  Serial.begin (baudRate);
  esp8266.begin (baudRate);


boucle vide () 
  
  tampon de char[40];
  int i = 0;

  // tant que la sortie ESP est disponible, appuyez dessus
  // dans le tampon et mettre le drapeau vrai
  while (esp8266.available ()) 
    tampon[i++] = esp8266.read ();
    dataSync = true;
  

  // si des données sont disponibles, les analyser
  if (dataSync == true) 
    si ((tampon[0] == 'U') && (tampon[1] == 'N') && (tampon[2] == 'X')) 
      // si les données envoyées sont le jeton UNX, prenez-le
      unixString[0] = tampon[3];
      unixString[1] = tampon[4];
      unixString[2] = tampon[5];
      unixString[3] = tampon[6];
      unixString[4] = tampon[7];
      unixString[5] = tampon[8];
      unixString[6] = tampon[9];
      unixString[7] = tampon[10];
      unixString[8] = tampon[11];
      unixString[9] = tampon[12];
      unixString[10] = ' 0';

      // affiche l'heure UNX sur le feuilleton UNO
      Serial.println ();
      Serial.print ("TIME FROM ESP:");
      Serial.print (unixString[0])
      Serial.print (unixString[1])
      Serial.print (unixString[2])
      Serial.print (unixString[3])
      Serial.print (unixString[4])
      Serial.print (unixString[5])
      Serial.print (unixString[6])
      Serial.print (unixString[7])
      Serial.print (unixString[8])
      Serial.print (unixString[9])
      Serial.println ();
      
      unixTime = atol (unixString);
      // Synchronise l'heure avec l'horloge interne
      // pour usage externe RTC.setTime ();
      setTime (unixTime);
      dataSync = false;
    
  

le régler le temps() La méthode a de nombreuses versions surchargées et peut être utilisée avec le paramètre timestamp UNIX mais peut également prendre comme paramètres des parties temporelles spécifiques telles que l'heure, les minutes et les secondes. Suppléments de documentation de Arduino officiel:

/ *********************
- www.geekstips.com
- Synchronisation de l'heure Arduino à partir du serveur NTP à l'aide du module WiFi ESP8266
- Exemple de code Arduino
********************* /

 setTime (t); // Définit l'heure système sur le
                          // donne l'heure t UNX timestamp
 setTime (heure, minute, seconde, jour, mois, année); // Une autre façon de définir
                                   // le temps avec le temps
 AdjustTime (ajustement); // Ajuster l'heure du système en ajoutant
                         // la valeur de réglage
                         // ATTENTION: ceci n'est pas compatible avec l'utilisation d'un fournisseur de synchronisation car
                         // ajuste uniquement l'heure système de la bibliothèque et non l'heure dans le fournisseur de synchronisation.
                         // Cet ajustement du décalage sera perdu lors de la prochaine synchronisation.
                         // Si l'heure est avancée, un appel immédiat à now () peut obtenir l'heure
                         // du fournisseur de synchronisation plutôt que de l'heure système de la bibliothèque ajustée.
                         // c’est-à-dire que ne comptez pas sur now () pour retourner une heure ajustée lors de l’utilisation de
                         // un fournisseur de synchronisation même lorsqu'il est appelé immédiatement après adjustTime ()

 timeStatus (); // Indique si le temps a été réglé et
                 // récemment synchronisé
                 // renvoie l'un des éléments suivants
                 // énumérations:
 * timeNotSet // L'heure n'a jamais été réglée,
                 // l'horloge a commencé le 1 janvier 1970
 * timeNeedsSync // L'heure avait été réglée mais une synchronisation
                 // tentative n'a pas réussi
 * timeSet // L'heure est réglée et synchronisée
                 // Les valeurs d'heure et de date ne sont pas valides si
                 // le statut est timeNotSet. Autrement
                 // les valeurs peuvent être utilisées mais la valeur retournée
                 // le temps peut avoir dérivé si le statut est
                 // timeNeedsSync.

 setSyncProvider (getTimeFunction); // Définition de l'heure externe
                                  // fournisseur
 setSyncInterval (intervalle); // Définir le nombre de
                               // secondes entre re-synchronisation

Après avoir mis à jour l'heure avec l'horodatage UNIX, vous pouvez vérifier les résultats en appelant une fonction comme dans l'exemple suivant:

void displayCurrentTime () 
  Serial.print (hour ());
  Serial.print (":");
  Serial.print (minute ());
  Serial.print (":");
  Serial.print (second ());
  Serial.println ();
  délai (1000);

J'ai utilisé exactement le même principe pour créer une horloge numérique à ajustement automatique dans ma maison et fonctionne assez bien jusqu'à présent. J'ai également mis en place quelques systèmes anti-échec pour les situations où les demandes échouaient ou la connexion Internet était morte. Vous devriez faire quelques vérifications et tester si le différence entre Heure UNIX reçu du NTP et du horodatage actuel du RTC n’est pas beaucoup plus grand que le délai entre les demandes envoyées au serveur. Par exemple, vous pouvez enregistrer dans une variable le dernier horodatage UNIX reçu du module ESP et comparer avec le module actuel. La différence entre eux devrait être égale à l'intervalle utilisé dans la structure de boucle ESP pour le retard.

Voici à quoi ressemble mon projet d'horloge numérique:

Synchronisation temporelle Arduino du serveur NTP utilisant le module WiFi ESP8266

Il affiche l’horloge d’un serveur NTP sur un ordinateur. Écran LCD commun 16 × 2, en utilisant de grandes polices personnalisées, et affiche également la température et l'humidité intérieures sur une SSD1306 OLED affichage mesuré par un Capteur DHT22. Je mets à jour l'heure toutes les 10 minutes et fais une correction de 2 secondes à chaque fois pour obtenir un match parfait à l'heure GMT.

Si vous êtes intéressé à obtenir des pièces pour votre projet, voici ce que j’ai utilisé (liens de Amazon.com):

1. Arduino Nano v 3.0 mini USB
2. ESP8266 ESP-01
3. Écran LCD 16 × 2
4. Affichage SSD1306 OLED
5. Sortie d'alimentation LM2596 1.23V-30V

C’est simplement un moyen de tirer parti d’un NTP dans vos projets Internet des objets. Vous pouvez probablement trouver beaucoup d'autres méthodes plus complexes ou peut-être mieux codées pour accomplir cette tâche. En outre, il existe de nombreuses bibliothèques et exemples UDP, rien ne vous empêche de les essayer et de trouver la meilleure solution adaptée à votre projet. À la fin de la journée, vous devriez obtenir une bonne référence de temps précise sur Internet sans faire d’ajustements manuels.

En espérant que cet article vous a inspiré, je vous invite gentiment Partagez cet article, souscrire mon Youtube canal et joindre les communautés sur les réseaux sociaux. N'hésitez pas à commenter ou à envoyer des suggestions / remarques pour que je puisse améliorer la qualité du contenu.

sauvegarder

sauvegarder

Partager sur Facebook Gazouillement Google+

Commentaires

Laisser un commentaire

Votre commentaire sera révisé par les administrateurs si besoin.