Getting the date and time with Parallax WiFi module

I have a couple of project now that use the Parallax WiFi module and thought I should be able to get the date and time from the network right?

One could use one of the RTC modules but why not get it from the network.

So an NTP server is what there called and they use a 48 byte packet that contains date and time information. So you need to format a date time packet and send the request to say time.windows.com on port 123.

Well to do this you need to send a UDP packet and not make a TCP connection. I have modified the firmware on my Parallax WiFi module to send and receive UDP packets so all that is needed is build the packet and send it.

This is done using the C language and some dumpster diving to find some function implementations. I also wrote my own esp functions that interface into the Parallax WiFi module.
#include "esp8266.h"
#include "simpletools.h"

#define ESPRx 3
#define ESPTx 4

unsigned char NTP[48];
char *Data;
char rqs[] = "time.windows.com";
time_t t;
struct tm *x;
int i;
unsigned long t1;

int main()
{
  putenv("TZ=CST6CDT");
  
  esp8266_open(ESPRx, ESPTx);
  
  Data = esp8266_check("module-name");
  
  print(Data);
  NTP[0] = 0x1b;
  i = esp8266_udp(rqs, 123);
  if (i >= 0)
  {
    print("Status: %d\n", i);
    esp8266_sendbin(i, NTP, 48);

    esp8266_recv(i, NTP, 48);
    esp8266_close(i);
    t1 = NTP[40] << 24 | NTP[41] << 16 | NTP[42] << 8 | NTP[43];
    t1 = t1 - (25567 * 24 * 60 * 60);
    x = localtime(&t1);
    print("Date: %d/%d/%d\n", x->tm_mon+1, x->tm_mday, x->tm_year+1900);
    print("Time: %02d:%02d:%02d\n", x->tm_hour, x->tm_min, x->tm_sec);
  }
  
  print("%x %x %x %x\n", NTP[40], NTP[41], NTP[42], NTP[43]);
  
  while(1)
  {
    pause(1000);
    
  }  
}

First off to get the time correct the time needs to be converted from 1/1/1900 which is what NTP uses to 1/1/1970 which is what the Unix and the C code use. That turns out to be 25567 days or 70 years.

So the only value that NTP needs filled in is 0x1B in position 0 of the packet. Then calling the time server we get back in position 40, 41, 42 and 43 the time in ticks of the server that gave you the answer. This is the time since 1/1/1900 so we need to subtract 70 years, 25567 * 24 * 60 * 60, to get the ticks since 1/1/1970.

Now to get the local time for my area we need to set a time zone so that it knows to subtract 6 hours from GMT time to get my time. Hours may vary based on your location in the world. This is done be setting an environment variable with TZ=CST6CDT.

So windows time returns a value of 0xe1d42116. This is 3788775701- 2208988800 = 1579786901 or 1/23/2020 07:41:40.

Now when I send a packet from my logger or want to display the time on my weather station I can get the time and set it in my program using an NTP server.

Mike
Sign In or Register to comment.