- Informatique
- Arduino
- Projets
- Mécanique
Lors de mes divers tests et réalisations avec Arduino, j'ai eu besoin d'interroger un serveur NTP pour obtenir une date/heure depuis le réseau. Diverses fonctions et libraires existent mais j'ai voulu à des fins de découverte écrire ma propre fonction pour cela
Vu que sont fonctionnement est relativement simple et qu'il fonctionne, je partage ce code librement.
Le fonctionnement est assez simple, la fonction ne prends que 2 arguments.
La fonction va envoyer des paquets UDP au serveur NTP toutes les 200ms et arrêtera si on dépasse le timeout choisi. Si la fonction réussi a récupérer l'heure du serveur elle renverra un long contenant l'heure UTC exprimé en secondes depuis le 01.01.1900. Si la fonction échoue, elle renverra 0.
// 2012-05-15 David Goncalves // Simple function to get time from an NTP server // // This code is provided as is for testing purpose. // You can use it for free at your own risks. unsigned long GetTimeFromNTPServer( byte *address, byte timeout ) { static EthernetUDP udp_handler; // Create a 48 byte buffer and clear it as NTP data is 48 bytes long byte PacketBuffer[ 48 ]; memset( PacketBuffer, 0, 48 ); PacketBuffer[0] = 0b11100011; // [11] Leap Indicator // [100] NTP Version 4 // [011] Mode 3 -> NTP Client PacketBuffer[1] = 0; PacketBuffer[2] = 6; PacketBuffer[3] = 0xEC; udp_handler.begin( 9999 ); udp_handler.beginPacket( address, 123 ); udp_handler.write( PacketBuffer, 48 ); udp_handler.endPacket(); unsigned long time_sent = millis(); unsigned long secs = 0; while ( millis() < ( ( timeout * 1000 ) + time_sent ) ) { if ( udp_handler.parsePacket() ) { udp_handler.read( PacketBuffer, 48 ); // We only get the 32 bits containing the seconds ( bytes 40 -> 43 ) as we // do not need microseconds precision. // NTP protocol gives time in seconds since 1900.01.01 so 2208988800s earlier // than unix time which is from 1970.01.01. unsigned long msb = word( PacketBuffer[40], PacketBuffer[41] ); unsigned long lsb = word( PacketBuffer[42], PacketBuffer[43] ); secs = msb << 16 | lsb; secs -= 2208988800UL; break; } delay( 200 ); // wait 200ms before each try } return( secs ); }
Voici un sketch Arduino d'exemple.
#include <Ethernet.h> #include <EthernetUdp.h> #include <SPI.h> #include "ntp_client.h" byte mac[] = { 0x00, 0x04, 0x25 , 0x15, 0x48, 0x12 }; byte ip[] = { 10, 1, 1, 1 }; byte ntp_server[] = { 10, 1, 1, 254 }; void setup() { Ethernet.begin( mac, ip ); Serial.begin( 9600 ); } void loop() { unsigned long time_ntp; Serial.println( "Doing NTP sync..." ); // Poll the server with 4s timeout time_ntp = GetTimeFromNTPServer( ntp_server, 4 ); Serial.print( "Response : " ); Serial.println( time_ntp ); // Wait 10s delay( 10 * 1000 ); }