Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 23:29 02 Jul 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : NTP Clock

Author Message
jman

Guru

Joined: 12/06/2011
Location: New Zealand
Posts: 711
Posted: 12:34pm 29 Nov 2014
Copy link to clipboard 
Print this post

Hi

After much trial and error with NTP I finally have a working clock.
Two challenges had to be over come.
1st how to send a valid request via UDP
2nd decipher the response from the NTP Server

The request is done via UDP and consists of a 48 Bytes
the 1st byte is the important one as this contains the LI, Version and Mode
so we set the byte with the following
LI 00 = no warning (2 bits)
VN 010 = version 2 (3bit)
Mode 111 = reserved for private use (I assume I am private :) )
so the first byte = &B1011 or 23 decimal or Chr$(27) that's what we have to use to send the correct value via the com port (Would be a great feature to be able to send hex values from via the com port)

The returned data consists of 48 bytes with the data we are after in bytes 40-43
the value of the returned data is a 32 bit number made up of the 4 bytes with byte 40 MSB and byte 43 LSB. This number is the number of seconds since 00:00:00 1/1/1900 to get to Epoch time (1/1/1970) we need to - 2208988800 (Seventy years in seconds)

From there we can work out the time.
If anybody has better or cleaner way to convert the Epoch time to human readable
time please do share.

To connect to the internet this system uses an ESP8266 WiFi module connected to com1 these are really cheap and make a great way to connect a Mite to the internet

note we are NOT concerned or using the advanced NTP features such as request latency etc..






' Configuration constants
TZ = 12 'From GMT (+ or -)
PowerSave=0 '1 moudule Off after update 0 Allways On
'1 Will cause a small delay during update
UpDate=60 'Update frequency in Minutes
DST=1 '1 Use DST 0 Disable
DMS=9 'Month DST Time Starts
DHS=2 'DST Start Hour
DME=4 'Month DST Time Starts
DHE=3 'DST Stop Hour

SSID$ = "PutYourSSIDHere" 'name of wireless access point To connect To
PASS$ = "Password" 'WiFi Password
Port$ = "123" 'NTP UDP port
NTP$="27.116.36.44" 'NTP Server you want to use

SetPin 14,DOUT

Dim Months(12) 'Array for Months
For I=1 To 12
Read Months(I)
Next I

Dim Days$(7)
For I=0 To 6
Read Days$(I)
Next I

Dim Mnths$(12) 'Array for Months Names
For I=1 To 12
Read Mnths$(I)
Next

LeapMnth=2505600 'Seconds in Leap Year February
Lcount=48
Dim Line$(48) 'UDP data array

Memory

PWM 2, 2500, 2, 10 'Adjust Freqency for contrast adjustment
LCD Init 2, 3, 4, 5, 6, 7 'Setup the LCD for display

Reset

Open "COM1:115200, 1024" As #1 'Module must be set to same rate

Print #1, "AT+CWMODE=1"
Pause 1000

Print #1, "AT+CIPMUX=0" ' Set Single connection
Pause 2000

ConnectToWiFi:
LCD Clear
Print #1,"AT+CWJAP="+Chr$(34)+SSID$+Chr$(34)+","+Chr$(34)+PASS$+Ch r$(34)
LCD 1, 1, "Connecting To"
LCD 2, 1, SSID$
Pause 8000 'give it time to connect

Flushbuf

Print #1, "AT+CIFSR"
Pause 1500
Line Input #1,IP$
Line Input #1,IP$
Line Input #1,IP$
LCD 1, 1, "Connected IP "
LCD 2, 1, IP$

Print IP$

Line$(1)=Chr$(27) '1st byte Minimum requirement for valid respone
Line$(2)="" 'Incase we end up back here
For I = 1 To 47 'Load next 47 bytes with null
Line$(2)=Line$(2)+Chr$(0)
Next I

GetNTPTime:
flushbuf
Print #1, "AT+CIPSTART="+Chr$(34)+"UDP"+Chr$(34)+","+Chr$(34)+NTP$+Chr $(34)+",123"
Delay
Print #1,"AT+CIPSEND=48" '+Str$(Len(&hE3))
Delay
Print #1, Line$(1)+Line$(2) '+Line$(3)+Line$(4);
Delay
Print #1, "AT+CIPCLOSE"
Pause 1500

For I =1 To 10
Line Input #1,IP$ 'Unrelated info
Print IP$
Next I

IP$ = Input$(1, #1)
Print ip$
IP$ = Input$(8, #1) ' Sanity Check
If Ip$<> "+IPD,48:" Then
Print "Connection Error"
LCD Clear
LCD 1, 1, "Connection Error"
LCD 2, 1, "Retrying"
Pause 3000
GoTo ConnectToWiFi
EndIf

IP$ = Input$(48, #1)

flushbuf

lw1$=Str$(Asc(Mid$(ip$,41,1))) 'Extract 1st Byte
lw2$=Str$(Asc(Mid$(ip$,42,1))) 'Extract 2nd Byte
lw3$=Str$(Asc(Mid$(ip$,43,1))) 'Extract 3rd Byte
lw4$=Str$(Asc(Mid$(ip$,44,1))) 'Extract 4th Byte
lb1% = Val(lw1$) << 8
lb1% = (lb1% Or Val(lw2$)) <<16 'MSB 32 Bit Number
lb2% = Val(lw3$) << 8
lb2% = lb2% Or Val(lw4$) 'LSB 32 Bit Number

LB%=LB1% Or LB2%
LB% = LB% - 2208988800 ' - 70 Years start @ 1/1/1970 Epoch time

Jan2014 = LB% - 1388534400 'Start at Jan 1/1/2014
TimeZone = (TZ*60*60) 'Set TimeZone
Jan2014=Jan2014+TimeZone 'Adjust for Timezone
Year=2014 'Set Year to 2014

GetYear:
LEAP = Year Mod 4 '0 if leap year
If LEAP = 0 Then
SecondsInYear = 31622400 '366*60*60**24
Else
SecondsInYear = 31536000 '365*60*60*24
EndIf
If Jan2014 > SecondsInYear Then
Jan2014 = Jan2014 - SecondsInyear
Year = Year + 1
GoTo GetYear
EndIf

Month = 1 ' Start with Month = 1

GetMonth:
SecondsInMonth = Months(Month)
If Leap = 0 Then
If Month = 2 Then
SecondsInMonth=LeapMnth
EndIf
EndIf
If Jan2014 >= SecondsInMonth Then
Jan2014 = Jan2014 - SecondsInMonth
Month = Month+1
GoTo GetMonth
EndIf

FindDays:
Day = Int(Jan2014/86400)
Jan2014 = Jan2014 Mod 86400
Hour = Int(Jan2014/3600)
Jan2014 = Jan2014 Mod 3600
Min = Int(Jan2014/60)
Jan2014 = Jan2014 Mod 60
Sec = Jan2014
Day = Day + 1

If DST = 1 Then
GoSub DsTime
If CurrDT < DsStop Or CurrDT > DsStart Then
Hour = Hour + 1
EndIf
EndIf

If Hour=24 Then hour=0

Date$=Str$(Day)+"/"+Str$(Month)+"/"+Str$(Year)
Time$=Str$(Hour)+":"+Str$(Min)+":"+Str$(Sec)

Print Time$
Print Date$

LCD Clear
Timer=0
Do While Timer < (UpDate*60*1000) 'Update frequency
DayOfWeek
LongDate$=Days$(Dow)+" "+Left$(Date$,2)+" "+Mnths$(Val(Mid$(Date$,4,2)))

LengthCheck:
If Len(LongDate$) < 16 Then
LongDate$=LongDate$+" "
GoTo LengthCheck
EndIf

LCD 1, 1, LongDate$
LCD 2, 1, "NTP "+Time$

If PowerSave=1 Then Pin(14)=0 'PowerSave
Loop
Pin(14)=1
If PowerSave Then Pause 5000
LCD 2, 1, "Updating.. "
GoTo GetNTPTime

End

DsTime:
'DSTime is used to find the stop and start dates for DST
'Reference http://delphiforfun.org/programs/math_topics/dstcalc.htm

Local YT
YT=Int((5*Year)/4)
DsdStop=7-((4+YT) Mod 7) 'NZ 1st Sunday in April
DsdStart=31-((YT-1) Mod 7) 'NZ Last Sunday in September

'You will need modify the above lines to suit your DST
'DsdStart=14-((1+Year*5/4) mod 7) 'USA 2nd Sunday in March
'DsdStop=7-((1+YT) mod 7) 'USA 1st Sunday November
'DsdStart=31-((4+YT) mod 7) 'EU Last sunday in March
'DsdStop=31-((1+YT) mod 7) 'EU Last Sunday October

DsStart=(DMS*10000)+(DsdStart*100)+DHS
DsStop=(DME*10000)+(DsdStop*100)+DHE
CurrDT=(Val(Mid$(Date$,4,2))*10000)+(Day*100)+Hours

Return

Sub DayOfWeek 'TZ's Method
A = Int((14-Val(Mid$(Date$,4,2)))/12)
M = Val(Mid$(Date$,4,2)) + 12*a - 2
Y = Val(Mid$(Date$,7,4)) -a
D = Val(Mid$(Date$,1,2))
Dow=(D+Y+Int(Y/4)-Int(y/100)+Int(Y/400)+Int(31*M/12)) Mod 7
End Sub

Sub Delay
Pause 500
End Sub

Sub FLUSHBUF
Do:Z$=Input$(1,#1):Loop While Loc(#1) <> 0
End Sub

Sub Reset
Pin(14)=0 ' Reset Module Disabled
Pause 500
Pin(14)=1
End Sub

Data 2678400,2419200,2678400,2592000,2678400,2592000,2678400
Data 2678400,2592000,2678400,2592000,2678400
Data "Sunday","Monday","Tuesday","Wednesday","Thursday"
Data "Friday","Saturday"
Data "Jan","Feb","Mar","Apr","May","June"
Data "July","Aug","Sep","Oct","Nov","Dec"



Regards
Jman
 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 02:07pm 29 Nov 2014
Copy link to clipboard 
Print this post

Hi Jman, again, a very cool project using the esp8266. Nice work. Have you run across any issues with the 8266 and the "busy s..." response from it? Looking at different sources, it seems like this creeps up every once in a while making things a bit of a pain. When I do encounter it, it seems like the only way out is a power cycle, (for me anyway). I see that Expressif has added new .bin files today. I am hoping that will fix some of the issues.

Thanks again for a great project!
 
jman

Guru

Joined: 12/06/2011
Location: New Zealand
Posts: 711
Posted: 02:36pm 29 Nov 2014
Copy link to clipboard 
Print this post

Hi Viscomjim

When you get the "busy s..." problem have you tried a AT+RST ?

Regards
Jman
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6266
Posted: 03:54pm 29 Nov 2014
Copy link to clipboard 
Print this post

A good bit of detective work, sorting out the NTP packets and a good example of the esp8266.

I prefer wired ethernet but I have realised that the price of the esp8266 is a lot cheaper and easier to use than any ethernet solution.

Geoff's article in December Silicon Chip makes then too good to ignore!

I have just started a new post with unix time routines that may be of interest.

Jim
VK7JH
MMedit
 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 03:58pm 29 Nov 2014
Copy link to clipboard 
Print this post

@Jman, yes, I have done the AT+RST and also a hardware reset like it looks like you do. It is hard to pin down this error and what actually works to correct it, but for now the power cycle is 100%, which for me is a fail. I am hoping the new .bin files have corrected the problem. Again, its not all the time, just seems somewhat random...
 
centrex

Guru

Joined: 13/11/2011
Location: Australia
Posts: 320
Posted: 06:53pm 29 Nov 2014
Copy link to clipboard 
Print this post

A bit off topic but dealing with the ESP8266 module.
The article in Silicon Chip page 32 Nov2014, the connections are not correct pin 23 should be pin 21 on the micromite.

cliff


Jman thanks for the code.
Cliff
 
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1329
Posted: 12:46am 30 Nov 2014
Copy link to clipboard 
Print this post

Here's the Australian Daylight Saving Time info for JMan's "dstime" routine.

From April 2008, Daylight Saving dates have been synchronised across Tasmania, New South Wales, Victoria, the ACT and South Australia, although South Australia remains half an hour behind throughout the year due to the observance of Australian Central Standard Time. Daylight saving time commences at 2am (AEST) on the first Sunday in October and ending at 2am AEST (3am DST) on the first Sunday in April.

Queensland, West Australia and the Northern Territory do not observe Daylight saving.


Greg
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2931
Posted: 03:18am 30 Nov 2014
Copy link to clipboard 
Print this post

  TassyJim said  Geoff's article in December Silicon Chip makes then too good to ignore!


Please can someone let me know what this article is . . .

Thanks
WW
 
centrex

Guru

Joined: 13/11/2011
Location: Australia
Posts: 320
Posted: 11:18am 30 Nov 2014
Copy link to clipboard 
Print this post

my note about the connection to the ESP module should have read Dec issue of Silicon Chip.

White Wizard, Geoffg has written an article in the magazine on the use of the module and a pointer to a web site http://garden.geoffg.net which gives the temp and humidity in his garden it also has a pointer to the software that runs the device.

As far as getting a copy of the article you may have to Google Silicon Chip or someone may be able to purchase the magazine and fwd it to you.
It is a worthwhile read and along with Jman code very helpful.

regards
cliff
Cliff
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2931
Posted: 11:32am 30 Nov 2014
Copy link to clipboard 
Print this post

Thanks for the info Cliff.

Just checked it out and I reckon Geoff has a bug in his code - 19.7°C at 05:23 (surely not!!!!)
 
BobD

Guru

Joined: 07/12/2011
Location: Australia
Posts: 935
Posted: 11:39am 30 Nov 2014
Copy link to clipboard 
Print this post

  WhiteWizzard said  
Just checked it out and I reckon Geoff has a bug in his code - 19.7°C at 05:23 (surely not!!!!)

it was a warm night last night. We had 25.1 at 4:30am and Melbourne CBD was a bit higher.
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2931
Posted: 12:02pm 30 Nov 2014
Copy link to clipboard 
Print this post

  BobD said  it was a warm night last night. We had 25.1 at 4:30am and Melbourne CBD was a bit higher.

You must be running the same 'buggy' code as Geoff!
 
plasma
Guru

Joined: 08/04/2012
Location: Germany
Posts: 437
Posted: 12:13am 01 Dec 2014
Copy link to clipboard 
Print this post

Thx a lot for the code
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025