B4R Tutorial [ESP8266] Requesting time from a server

Cableguy

Expert
Licensed User
Hi guys...

The equipment's I install all get the "current clock" from the server on first connection...
I wonder if this is possible to implement with such boards... like requesting the correct timer once per day or every time it (re)connects to a network...?? (then keeping a timer thus simulating an RTC?)
 
Last edited:

derez

Expert
Licensed User
The idea thrilled me and I built this night clock:
upload_2016-8-31_20-15-3.png


It is built of the following HW:
NodeMcu, LCD + I2C adapter, Power supply , logic converter.
There is no user interface, just plug the power. It shall need adjustment of the hour per the daylight saving change. May be the next product will have a button to do it.
Please do not comment on the box, I know it is very much non-professional, I built it as a prototype just to find the exact required size.
The most important feature is that it does not suffer from electric power down like other clocks that start to blink or show wrong time.
 

Erel

Administrator
Staff member
Licensed User
Nice work!

It is better to change the code to call the NIST server every 10 minutes (or more). When I ran it for a long time I saw that the server started rejecting some of the requests.
 

derez

Expert
Licensed User
I have found Gauss's formula to calculate the Day of Week from the date, added it to the clock display:

B4X:
Private dayofweek(7) As String = Array As String("Sat","Sun","Mon","Tue","Wed", _
            "Thu","Fri")
....
    Private mx, mi As UInt
    mx = (month-2)Mod(12)
    mi = 2.6*mx-0.2
    Private DoW As UInt = (day + mi  + 5*(year Mod 4) + 4* (year Mod 100) + 6*(year Mod 400) + 1) Mod 7

    lcd.SetCursor(1,1)
    lcd.Write(dayofweek(DoW))
EDIT: found an error in today's result (12,2,2017) so I modified the algorithm:
B4X:
Sub DayOfTheWeek(day As Int, month As Int, year As Int) As Int  ' Sunday = 1
    Private mx, mi, y As Int
    Private c As Int = year / 100
    mx = (month+9)Mod(12) +1
    mi = Floor(2.6*mx-0.2)
    If month < 3 Then y = year -1 Else y = year
    Return (day + mi  -2 *c + y + Floor(y/4) + Floor(c/4))Mod 7
End Sub


How can I write the days' names in Hebrew ?
 
Last edited:

Cableguy

Expert
Licensed User
I think you will need to create your own "font" and set the correct segments on in each 7seg digit
Edit: just saw it was an LCD... search the arduino forums, I'm sure I've seen a font hard-nosed in some projects
 

derez

Expert
Licensed User
I think you will need to create your own "font" and set the correct segments on in each 7seg digit
Edit: just saw it was an LCD... search the arduino forums, I'm sure I've seen a font hard-nosed in some projects
You can define 8 characters but it is not enough, I need 13
 

whcir

Member
Licensed User
Is it possible to use the Mega and Ethernet shield to receive NIST time information instead of the ESP8266? If so how would I go about doing this as the library is only for the ESP8266
 

Erel

Administrator
Staff member
Licensed User
It is not a library, it is an example. You can remove the ESP8266 Wifi library and use rEthernet instead (you will need to make very few changes to the code).
 

pappicio

Active Member
Licensed User
Dear friends ,
Is there a library/function to convert from UTC to Local time?
change this sub:

B4X:
Public Sub GetHours As UInt
   Return Floor(GetUpdatedTotalSeconds/ 3600)
End Sub
into:

B4X:
Public Sub GetHours As UInt
   dim u as uint=Floor(GetUpdatedTotalSeconds/ 3600)
   u = u + 2  'for ROME
   if u> 23 then
     u= u - 24
  end if
Return    u
End Sub
 
Last edited:

Hypnos

Active Member
Licensed User
Hi All,

The Date is not correct on my local time, how to convert the Date with local timezone? Thanks!
 

derez

Expert
Licensed User
Hi All,

The Date is not correct on my local time, how to convert the Date with local timezone? Thanks!
In general, you have to know the rules of your timezone - the offset from 0 and the dates when daylight saving times are changing. Then - implement the data on the basic time from NIST. I attach an example on how I do it for the local time in Israel which has offset of 2 but the DST changing is dependent on day of week, so I just got the dates of change for the coming years until 2030 and put them in an array (I don't think the clock will still work after so many years):
B4X:
Private dst3() As Byte  = Array As Byte(30,29,28,26,25,31,30,28,27,26,25,30,29,28)
Private dst10() As Byte = Array As Byte(29,28,27,25,31,30,29,27,26,25,31,29,28,27)
dst3 stores the dates for the change in March and dst10 for October, index is year-17.
Then for each time I get from NIST server, I check the real-time offset:
B4X:
               ...
               hour = st2
               Dim y As Short = year - 17
               offset = find_offset(dst3(y), dst10(y))
               If hour + offset >= 24 Then add = True Else add = False ' add =true will change the date later on in the code
...
               hour = hour + offset
If hour >= 24 Then
        hour = hour Mod 24
        day = day + 1
End If
               ....

B4X:
Sub find_offset(MD3 As UInt, MD10 As UInt) As UInt
    Select month
        Case 4,5,6,7,8,9
            Return 3
        Case 11,12,1,2
            Return 2
        Case 10
            If day < MD10 Then
                Return 3
            Else
                Return 2
            End If
        Case 3
            If day < MD3 Then
                Return 2
            Else
                Return 3
            End If
        Case Else
            Return 0
    End Select
End Sub
The add boolean controls a select case where the added day will change the month if necessary, per the actual month length.
B4X:
...
If add Then
        Select month
            Case 1,3,5,7,8,10
                If day = 31 Then
                    month = month + 1
                    day = 1
                End If
            Case 2
                If (year/4 )* 4 = year  Then  ' valid until 2100
                    If day = 29 Then
                        month = 3
                        day = 1
                    End If
                Else
                    If day = 28 Then
                        month = 3
                        day = 1
                    End If
                End If
              
            Case 4,6,9,11
                If day = 30 Then
                    month = month + 1
                    day = 1
                End If
              
            Case 12
                If day = 31 Then
                    month = 1
                    day = 1
                End If
              
        End Select
        add = False
    End If
 
Last edited:
Top