WiFi Kit 32 NTP Clock

6,295

15

26

About: The more mistakes I make, the more knowledge I gain.

WiFi Kit 32 NTP Clock is another of my learning forays into the numerous features of the ESP32.

During startup, the clock obtains the current date and time from an ntp server, adjusts for time zones (see the Software step), writes the result to the ESP32 rtc (real time clock), then uses the ESP32 rtc to update the built in OLED display with the date and time.

The source code is included in the Software step and should be documented well enough to explain how it works. If you have any questions, please feel free to comment and I will do my best to answer them.

In the interest of full disclosure, I receive no samples or compensation for the use of this board.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Software.

The software requires the include files "time.h", "WiFi.h", "WiFiUdp.h" and "U8g2lib.h", and as such these libraries must be included in the Arduino environment.

The software connects to an ntp time server via wifi and a udp port, obtains the ntp time from the server, adjusts then writes the time to the ESP32 rtc (real time clock), then displays the date and time on the built in OLED display.

Upon startup, the code initializes the serial port, wifi, graphics and udp port. The serial port is used during initialization to display when the wifi is connected and when the ntp time has been received from the ntp server. Wifi is used to communicate with the ntp server. The graphics is used to display the initialization and operational displays on the built in OLED. Finally, the udp port receives the ntp time from the ntp server.

The main loop performs two major functions; obtains the time from the ntp server and to update the oled. The time is obtained from the ntp server only once, and upon receipt, is adjusted for time zone then written into the ESP32 rtc (real time clock), after which wifi is turned off. The OLED is updated once per pass, and there is a 200ms delay in the main loop so the OLED is updated 5 times a second.

Before compiling and downloading the code, adjust the following settings:

1) TIME_ZONE - currently set to -6 for Oklahoma (my home state), adjust to your timezone.

2) chPassword - currently set to "YourWifiPassword", adjust to your wifi password.

3) chSSID - currently set to "YourWifiSsid", adjust to your wifi ssid.

Next, connect the board to a USB port on your computer via a USB to micro USB cable, then compile and download the software. While awaiting the download, start the serial monitor. When the download is complete, the software will send status messages to the serial monitor as shown in the video and, if successful, the OLED will display the date and time.

Be the First to Share

    Recommendations

    • Made with Math Contest

      Made with Math Contest
    • Multi-Discipline Contest

      Multi-Discipline Contest
    • Robotics Contest

      Robotics Contest

    26 Discussions

    0
    None
    CarlosV170

    Question 12 days ago

    Hi, I try to check in Arduino ide but has some error in the
    line 139 - WiFi.localIP().toString().toCharArray(chIp, sizeof(chIp) - 1);
    error: 'class IPAddress' has no member named 'toString'
    Arduino: 1.8.9 (Windows Store 1.8.21.0) (Windows 10), Board: "Arduino/Genuino Uno"
    C:\Users\Familia\Downloads\wifi_kit_32_ntp_clock\wifi_kit_32_ntp_clock.ino: In function 'void setup()':
    wifi_kit_32_ntp_clock:139:22: error: 'class IPAddress' has no member named 'toString'
    WiFi.localIP().toString().toCharArray(chIp, sizeof(chIp) - 1);
    ^
    C:\Users\Familia\Downloads\wifi_kit_32_ntp_clock\wifi_kit_32_ntp_clock.ino: In function 'void loop()':
    wifi_kit_32_ntp_clock:243:31: error: variable 'loop()::timeval tvTimeValue' has initializer but incomplete type
    struct timeval tvTimeValue = {0, 0};
    ^
    wifi_kit_32_ntp_clock:255:47: error: 'settimeofday' was not declared in this scope
    settimeofday(& tvTimeValue, NULL);
    ^
    wifi_kit_32_ntp_clock:271:20: error: 'class WiFiClass' has no member named 'mode'
    WiFi.mode(WIFI_OFF);
    ^
    wifi_kit_32_ntp_clock:271:25: error: 'WIFI_OFF' was not declared in this scope
    WiFi.mode(WIFI_OFF);
    ^
    wifi_kit_32_ntp_clock:288:23: error: aggregate 'loop()::timeval tvTimeValue' has incomplete type and cannot be defined
    struct timeval tvTimeValue;
    ^
    wifi_kit_32_ntp_clock:289:39: error: 'gettimeofday' was not declared in this scope
    gettimeofday(& tvTimeValue, NULL);
    ^
    Multiple libraries were found for "U8g2lib.h"
    Used: D:\OneDrive\Documents\Arduino\libraries\U8g2
    Not used: D:\OneDrive\Documents\Arduino\libraries\U8g2-2.26.14
    exit status 1
    'class IPAddress' has no member named 'toString'
    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.

    1 answer
    0
    None
    gzumwaltCarlosV170

    Answer 1 day ago

    I'm sorry for the difficulties, it appears as if a library is missing somewhere, but I cannot determine which from the report you provided.

    Greg

    0
    None
    gzumwaltjackschlitz

    Reply 1 day ago

    Ahhhh, living rent free in yet another cavernous cranium...

    0
    None
    WikiJM

    Question 2 months ago

    Hi,

    Thanks for those instructions :-)

    I encounters few issues during the compilation and injection.
    At the end of the compilation, I get this error: "variable 'loop()::timeval tvTimeValue' has initializer but incomplete type".

    Here is the complete error log:
    https://gist.github.com/wikijm/3bda4dfe18dd4bcfc46...

    Could you please give me a track or some clues?

    Sincerely,
    WikiJM

    0
    None
    dsSidhu

    4 months ago

    Nice example, no hassles ,no file found message,no debug.
    oly thing time lap is 2hrs late, how to set it

    0
    None
    robiv8

    Question 6 months ago

    One more question!
    I live in Germany, can one change the date to German language?
    I mean the Tue in Di ore Sun in So

    3 answers
    0
    None
    gzumwaltrobiv8

    Answer 6 months ago

    hi daisyd15,

    The answer provided by Gruntfuttock sounds like a great start!

    You could also use two arrays, one for the day of the week, and a second for the month, to contain the text, for example:

    char* DayOfWeek[7] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};

    Then display the day of the week as:

    sprintf(chBuffer, "%s", DayOfWeek[n]);

    Where "n" is the day of the week 0, through 6.

    Best wishes!

    Greg
    0
    None
    Gruntfuttockrobiv8

    Answer 6 months ago

    To see how the date string is generated, take a look at http://www.cplusplus.com/reference/ctime/strftime/

    You can see that the sketch uses this line:
    strftime(chBuffer, sizeof(chBuffer), "%a, %d %b %Y", tmPointer);
    to assemble a string with the date in the format DAY, dd MMM yyyy

    You want to change the values substituted for %a and %b to their German equivalents, but I don't think strftime() knows how to do that (it can substitute locale-specific values for some of the placeholders, but not, I think, %a or %b). I think you will have to put in a look-up table, perhaps using switch...case or an array holding the day and month abbreviations.

    You might also want to change the time format to 24-hr: try changing
    strftime(chBuffer, sizeof(chBuffer), "%I:%M:%S", tmPointer);
    to
    strftime(chBuffer, sizeof(chBuffer), "%H:%M:%S", tmPointer);

    0
    None
    elsediekuh

    7 months ago

    Don't lucky
    Some help would be nice

    Arduino: 1.8.5 (Mac OS X), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled, 4M (no SPIFFS), v2 Lower Memory, Disabled, None, All Flash Contents, 115200"
    In file included from /Applications/Tools/Arduino.app/Contents/Java/libraries/WiFi/src/WiFi.h:32:0,
    from /Users/robi/Downloads/wifi_kit_32_ntp_clock/wifi_kit_32_ntp_clock.ino:2:
    /Applications/Tools/Arduino.app/Contents/Java/libraries/WiFi/src/WiFiServer.h:37:14: error: invalid abstract return type for member function 'WiFiClient WiFiServer::available(uint8_t*)'
    WiFiClient available(uint8_t* status = NULL);
    ^
    In file included from /Applications/Tools/Arduino.app/Contents/Java/libraries/WiFi/src/WiFi.h:31:0,
    from /Users/robi/Downloads/wifi_kit_32_ntp_clock/wifi_kit_32_ntp_clock.ino:2:
    /Applications/Tools/Arduino.app/Contents/Java/libraries/WiFi/src/WiFiClient.h:27:7: note: because the following virtual functions are pure within 'WiFiClient':
    class WiFiClient : public Client {
    ^
    In file included from /Applications/Tools/Arduino.app/Contents/Java/libraries/WiFi/src/WiFiClient.h:24:0,
    from /Applications/Tools/Arduino.app/Contents/Java/libraries/WiFi/src/WiFi.h:31,
    from /Users/robi/Downloads/wifi_kit_32_ntp_clock/wifi_kit_32_ntp_clock.ino:2:
    /Users/robi/Library/Arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Client.h:29:21: note: virtual int Client::connect(const IPAddress&, uint16_t)
    virtual int connect(CONST IPAddress& ip, uint16_t port) =0;
    ^
    /Users/robi/Library/Arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Client.h:37:22: note: virtual bool Client::flush(unsigned int)
    virtual bool flush(unsigned int maxWaitMs = 0) = 0;
    ^
    /Users/robi/Library/Arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Client.h:38:22: note: virtual bool Client::stop(unsigned int)
    virtual bool stop(unsigned int maxWaitMs = 0) = 0;
    ^
    wifi_kit_32_ntp_clock:32: error: cannot declare variable 'Udp' to be of abstract type 'WiFiUDP'
    WiFiUDP Udp;
    ^
    In file included from /Users/robi/Downloads/wifi_kit_32_ntp_clock/wifi_kit_32_ntp_clock.ino:3:0:
    /Applications/Tools/Arduino.app/Contents/Java/libraries/WiFi/src/WiFiUdp.h:27:7: note: because the following virtual functions are pure within 'WiFiUDP':
    class WiFiUDP : public UDP {
    ^
    In file included from /Applications/Tools/Arduino.app/Contents/Java/libraries/WiFi/src/WiFiUdp.h:23:0,
    from /Users/robi/Downloads/wifi_kit_32_ntp_clock/wifi_kit_32_ntp_clock.ino:3:
    /Users/robi/Library/Arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Udp.h:82:27: note: virtual IPAddress UDP::remoteIP() const
    virtual IPAddress remoteIP() const =0;
    ^
    /Users/robi/Library/Arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Udp.h:84:26: note: virtual uint16_t UDP::remotePort() const
    virtual uint16_t remotePort() const =0;
    ^
    /Users/robi/Downloads/wifi_kit_32_ntp_clock/wifi_kit_32_ntp_clock.ino: In function 'void loop()':
    wifi_kit_32_ntp_clock:230: error: 'class WiFiClass' has no member named 'mode'
    WiFi.mode(WIFI_OFF);
    ^
    wifi_kit_32_ntp_clock:230: error: 'WIFI_OFF' was not declared in this scope
    WiFi.mode(WIFI_OFF);
    ^
    exit status 1
    cannot declare variable 'Udp' to be of abstract type 'WiFiUDP'

    1 reply
    0
    None
    robiv8elsediekuh

    Reply 6 months ago

    Sorry,was my mistake! It works great.
    Thanks for the great code.

    0
    None
    gzumwaltMarkS_MN

    Reply 6 months ago

    Hi MarkS_MN,

    Your are very welcome, glad you were successful!

    Greg

    0
    None
    Trev_A

    8 months ago on Introduction

    Worked perfectly straight off. Just had to install the olikraus u8g2 lib.
    I found changing the line "strftime(chBuffer, sizeof(chBuffer), "%I:%M:%S", tmPointer);" to "strftime(chBuffer, sizeof(chBuffer), "%H:%M:%S", tmPointer);" gave me 24 hour display format instead of 12 hour.

    Really great for trying my first EP32 program. Thank you

    1 reply
    0
    None
    gzumwaltTrev_A

    Reply 8 months ago

    Congratulations! Great work on converting the time to 24 hours!

    Greg

    0
    None
    JensH29

    1 year ago

    sorry, I have to correct the nonsense I wrote regarding a locate() function, which doesn't exist. In fact, none of any locale.h which I found for Arduino offered a working 'setlocale (LC_TIME, "de_DE", ...)' function

    0
    None
    JensH29

    1 year ago on Step 1

    Hi Greg,

    with your code, I did my very first step into arduino programming and finally succeeded in adopting it to display with German wording for the days and months. It was a bit complicated, because the locate() function doesn't work for Arduino.

    Python's and Java's handling of string variables is much easier...

    If you're interested, just write a note to j811195 at hotmail dot com.