Go Down

Topic: Arduino ESP8266 and NTP (Read 5645 times) previous topic - next topic

pixelk

I'm working on the same thing, here is my capture of the NTP request and answer, both are valid and captured at the wifi hotspot, I'm working on the receiving part at this moment.

Command sent by my ESP8266 to my NTP server (from 192.168.0.242 to 192.168.0.28)
Code: [Select]
0000   64 66 b3 b0 f1 20 18 fe 34 9f 38 5e 08 00 45 00  df... ..4.8^..E.
0010   00 4c 00 4e 00 00 ff 11 38 f4 c0 a8 00 f2 c0 a8  .L.N....8.......
0020   00 1c 5b 4b 00 7b 00 38 37 6c e3 00 06 ec 00 00  ..[K.{.87l......
0030   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0040   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0050   00 00 00 00 00 00 00 00 00 00                    ..........



Command sent back by the NTP server
Code: [Select]
0000   18 fe 34 9f 38 5e 64 66 b3 b0 f1 20 08 00 45 c0  ..4.8^df... ..E.
0010   00 4c 00 00 40 00 40 11 b7 82 c0 a8 00 1c c0 a8  .L..@.@.........
0020   00 f2 00 7b 5b 4b 00 38 36 2a 24 03 06 f0 00 00  ...{[K.86*$.....
0030   0b 34 00 00 16 67 5b 79 a5 92 d9 08 d2 c7 ee d1  .4...g[y........
0040   ff 40 00 00 00 00 00 00 00 00 d9 08 d4 b3 94 c4  .@..............
0050   37 25 d9 08 d4 b3 94 db 47 72                    7%......Gr



pixelk

OK, got it working (ESP8266 in AT mode, fully reset and connected to wifi )
Code: [Select]
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

unsigned long GetTime()
{
  String cmd = "AT+CIPSTART=\"UDP\",\"192.168.0.28\",123"; // my own NTP server, synced by GPS
  Serial1.println(cmd);
  delay(2000);
  if(Serial1.find("Error")){
    Serial.print("RECEIVED: Error");
    return 0;
  }
  
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  
  Serial1.print("AT+CIPSEND=");
  Serial1.println(NTP_PACKET_SIZE);
  if(Serial1.find(">"))
  {
    for (byte i = 0; i < NTP_PACKET_SIZE; i++)
    {
      Serial1.write(packetBuffer[i]);
      delay(5);
    }
  }else{
    Serial1.println("AT+CIPCLOSE");
    return 0;
  }
  
  //Serial1.find("+IPD,48:");
  
  int acksize = NTP_PACKET_SIZE + 1 + 2 + 8; // ESP8266 adds a space, a CRLF and starts with "+IPD,48:"
  
  Serial.println("ESP2866 ACK : ");
  for (byte i = 0; i < acksize; i++)
  {
    while (Serial1.available() == 0) // you may have to wait for some bytes
    {
      //Serial.print(".");
    }
    byte ch = Serial1.read();
    if (ch < 0x10) Serial.print('0');
    Serial.print(ch,HEX);
    Serial.print(' ');
    if ( (((i+1) % 15) == 0) ) { Serial.println(); }
  }
  Serial.println();
  Serial.println();

  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  
  Serial.println("Server answer : ");

  int i = 0;
  while (Serial1.available() > 0) {
    byte ch = Serial1.read();
    if (i <= NTP_PACKET_SIZE)
    {
      packetBuffer[i] = ch;
    }
    if (ch < 0x10) Serial.print('0');
    Serial.print(ch,HEX);
    Serial.print(' ');
    if ( (((i+1) % 15) == 0) ) { Serial.println(); }
    delay(5);
    i++;
    if ( ( i < NTP_PACKET_SIZE ) && ( Serial1.available() == 0 ) )
    {
      while (Serial1.available() == 0)  // you may have to wait for some bytes
      {
        Serial.print("!");
      }
    }
  }
  
  Serial.println();
  Serial.println();
  Serial.print(i+1);
  Serial.println(" bytes received"); // will be more than 48
  
  Serial.print(packetBuffer[40],HEX);
  Serial.print(" ");
  Serial.print(packetBuffer[41],HEX);
  Serial.print(" ");
  Serial.print(packetBuffer[42],HEX);
  Serial.print(" ");
  Serial.print(packetBuffer[43],HEX);
  Serial.print(" = ");

  unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
  unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
  unsigned long secsSince1900 = highWord << 16 | lowWord;
  
  Serial.print(secsSince1900,DEC);
  
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
  const unsigned long seventyYears  = 2208988800UL;
    // subtract seventy years:
  unsigned long epoch = secsSince1900 - seventyYears;
  
  unsigned long DST = 60*60*2; // adjust to your GMT+DST
  
  unsigned long timestamp = epoch + DST;

  Serial.println();
  Serial.print("Epoch : ");
  Serial.println(epoch,DEC);        

  return timestamp;
}


you can use the output of this function to set the time of the Time library

Go Up