Web Clock Version 2.0 (ESP8266 - Wemos)




Introduction: Web Clock Version 2.0 (ESP8266 - Wemos)


  • LCD screen of various sizes supported. 2x8 or 2x16 LCD Screen is recommended
  • Displays time and date
  • Web based time synchronization (No RTC Required)
  • Super accurate time keeping
  • Hourly chimes
  • Time zone friendly
  • DST switch for summer time
  • 12/24 switch
  • WiFi connection to access web
  • It can powered via micro USB cable or other 5V source
  • WiFi custom message/reminder receiver (Windows software is available to send messages to device)
  • Acknowledge/display last message button

This digital clock is based on ESP8266 WIFI micro-controller unit. The flavor used for project design and creation is WEMOS D1 mini which is equipped with a ESP-12F (ESP8266), a 5v to 3.3v regulator, a CH340G USB to UART chip and of course a micro usb connector. This module has plenty of I/O pins to connect the LCD display via the one I2C converter and to use few of them for option and command switches.

Step 1: Some Info About It

How it works

The device uses a rather unusual way to get the time from the web. It connects to an http web server (e.g. google.com) and gets the GMT time from the header file, then it calculates the current time for the time zone selected and it displays it to the LCD screen. To keep it up accurate the web time update is taking place once per 5 minutes which still is very often since the device calculation doesn't seem to have time drift. In any case you can change the update interval by tweaking the value on doloops.lua file.

System background

The whole project is based on NODEMCU firmware which should be flashed to WEMOS D1 mini module quite easy. Running NODEMCU firmware set ESP8266 to run Lua scripts which is super flexible and easy to learn, there are tons of examples and documentation online about it.

Note: Using a lightweight firmware leaves more memory space for operation and the device will be more stable. NODEMCU can be customized by using the online build service (https://nodemcu-build.com/) in order to contain only the project required libraries. Modules required by the code are: bit, file, GPIO, I2C, net, node, PWM, timer, UART and WiFi. You are highly advised to use master branch to build your firmware and select only the modules required. NODEMCU acts like an operating system on the module which means more flexibility because of the code modular structure. The code is separated in different files with different scope, during development we can run just some parts of the code instead the full project and we can check variables and system state during the run-time. In addition future changes or additions to the code will be very simple without messing with the entire system and code.

Step 2: The Hardware

Hardware required

Note: The easiest way to find the serial’s interface address is to use an Arduino board and run a simple detection sketch (http://playground.arduino.cc/Main/I2cScanner). If you don’t have and Arduino board available you can just try some standard addresses in the code and see which one is giving you results. Normally module’s address is set between 0X20 and 0X27. There is descriptive video for I2C addressing available here:

Step 3: Connections

System wiring

The required connections are very limited.

Start by connecting the I2C module to your LCD module. This can be done by using a straight header pinout to connect all the 16 lines of I2C module one by one to the LCD's 16 line header. The only critical is to check that pin 1 on I2C is connected to pin 1 of LCD.

Second step is to connect the I2C to WEMOS D1. This requires just 4 wires 5V, GND, SDA and SCL connections. Please note that SCL is connected to D5 and SDA is connected to D4.

Next connect buzzer, switches and button as in illustration. The switches illustrated are ON-ON type switches with three pins to connect either to 3v3 level either to GND level. This way pull down resistors can be avoided, but if you want you can use simple two pin switches by connecting 10K pull down resistors to D1 and D7 terminals and just use conenction from 3V3 and digital pin to each switch avoiding the ground connection.

Step 4: The Code (FileTo Download Is Here)


Startup file. The file contains essential info for device setup and some trap routine to display splash screens only on hardware reset. If the device reset caused by software reason or a low memory issue the routine will send it back to operation ASAP. The code here triggers googleTime.lua, udpserver.lua and button.lua (and lcdprint.lua every time we need to display something).


Display to LCD functionality. This file is responsible to display the info to LCD module. It is called several times on the code (in most of the files there is a reference for lcdprint). The only parameters you should set are the pins connected to SDA and SCL signal lines and device address (DEV).


Get the current time from web. It is the system cornerstone functionality. The code here get the header file from google.com and retrieves the GMT date and time. After this the doloops.lua file is kicked in.


Sets device looping routine for 5 minutes. During this routine the time is calculated and after that calculateTime.lua is called. When 5 minutes period is reached the looping routine is stopped to ask for a fresh synchronization from the web using googleTime.lua file again.


Converts GMT time to time zone time and calculates summer time. The code is responsible for checking the switches state, to convert the GMT time to local time and display it to LCD.


Plays sounds.


Sets UDP server waiting for network messages. The UDP server can set custom messages to be displayed on LCD screen and accept some other diagnostic commands.


Enables the acknowledge button. The button can acknowledge/display last message received by UDP Server.

Step 5: Code Changes


Only two plus one changes are essential to be made on the provided code to set the device up and running:

  1. Set your WiFi credentials: Open init.lua file and navigate to lines 76 and 77 to set WiFi SSID and password.
  2. Set your timezone difference: Open calculateTime.lua file and navigate to line 6 and change the value on variable "zonedrift" which represents time zone difference.


  1. Set your 12C module's address in lcdprint.lua file. The address is located on line 29 of the file. Note:normally the default address for modules sold is 0x27, so no change is needed. Please try the provided file first before change the module's address

Save your files and upload them to your device.

Step 6: How to Flash Firmware - How to Upload the Code

Firmware flashing

There are lot of examples and tutorials online about firmware flashing on ESP8266. The most complete (and up to date) guide is https://nodemcu.readthedocs.io/en/master/en/flash/

Code uploading

Once the board is flashed with the firmware and it's file system formatted (the format process takes place upon its first boot after flashing), Lua scripts can be uploaded very easily suing one of several tools available online. A guide can be found here: https://nodemcu.readthedocs.io/en/master/en/upload...

I personally have created one tool for Lua file uploading this called Selene.exe which can be downloaded here:

Step 7: Clock Commander Software

Control the device via network

This little utility is created to send commands via LAN to web clock and control the displayed messages. Its interface is straightforward. The only thing you have to configure is web clock's IP address and server port (default port used is 7333). After the network setup you can use the utility to send messages to the device which should immediately display them.


  • "Send sound command" causes device to sound an alarm sound when the message is received
  • "Send clear command" caused device to clear display before the received text is displayed.
  • "Use half display" is a special mode which keep the clock running and only the first line is used to display the custom message
  • Use raw command is used to send commands used for diagnostic and control purposes.

Raw commands

The following raw commands are accepted currently by the device:

  • stop
  • start
  • credits
  • diag
  • sound

Note 1: When a message arrives to the clock the clock functionality is suspended. The message will be displayed until user hold down the acknowledge button for 3 seconds and release it.

Note 2: Using the button once again you can display the last message sent by Clock Commander.

Step 8: Improvements - Things to Add - Issues

Improvements - Things to add

  • A case to look as a complete device.
  • UDP server function can be altered to accept more commands and functions.
  • Function needs to be added to calculate date during the period we have difference between DST and local time zone.
  • More hourly chimes. More alarm sounds.
  • Remote messages with expiration.
  • Code cleanup to be more lightweight and run even more stable.


Memory limitations: WEMOS D1 mini is based on ESP-12F (ESP8266) so hardware limitations of ESP-12F apply to WEMOS as well. Adding more code leaves less free memory for runtime operations and this can lead the device to low memory issue. When such event occurs the device will restart automatically. The project code can handle a restart due memory loss by using different startup up routine and set the device up and running within few seconds and set back to normal operation without letting the end user notice about it.

Date calculation: Currently the date is not calculated on the code. The displayed date is what the system received from the web. To avoid wrong date indication a routine takes place during the midnight (+/- time zone difference) to avoid display the date. This will be corrected in next code version.

Microcontroller Contest 2017

Participated in the
Microcontroller Contest 2017

Be the First to Share


    • For the Home Contest

      For the Home Contest
    • Game Design: Student Design Challenge

      Game Design: Student Design Challenge
    • Big and Small Contest

      Big and Small Contest



    5 years ago

    https://nodemcu-build.com/ is running again, so I was able to get the firmware. Now I have the clock running.

    When I have some more time, I will investigate using SNTP https://nodemcu.readthedocs.io/en/master/en/modules/sntp/
    from a local server as a fix for the date issue, and also to possibly automate the DST change.


    Reply 5 years ago

    Sorry for replying late to your messages... It seems that notifications went to spam folder.
    As I can tell you are OK with the firmware. It is strange, nodemcu-build is quite stable service I'm using it for a long period without problems.
    Please notice that UDP server part is going to be changed soon so rebuilding the firmware in the near future will cause "PANIC" messages with the current lua code. I will update the source files with new compatible version. As for the moment he code is working.


    5 years ago

    As I looked closer comparing my log to pepperm's, I see that somehow I2C was not included in my build, even though I'm 99% sure I selected it...

    Anyway I went back to https://nodemcu-build.com/, and the service is down. That's always the risk of depending on somebody else's servers...

    Anyway, it looks like pepperm has a working firmware, perhaps you could send it to me somehow?


    5 years ago

    Hi! I'm also new to NodeMCU and Lua.

    For anyone else following along, the code above in WebClockv2.0.zip still has the obsolete Wi-Fi calls, so don't forget to apply the patch from Dropbox (see comment from limbo on 2017-10-27)

    After I fixed Wi-Fi, there is now a different problem:

    NodeMCU custom build by frightanic.com
    branch: master
    commit: 5073c199c01d4d7bbbcd0ae1f761ecc4687f7217
    SSL: true
    modules: file,gpio,net,node,tmr,uart,wifi,tls
    build built on: 2017-12-27 23:07
    powered by Lua 5.1.4 on SDK 2.1.0(116b762)
    Boot reason: 3 Whatever that means
    lua: lcdprint.lua:31: attempt to index global 'i2c' (a nil value)
    stack traceback:
    lcdprint.lua:31: in main chunk
    [C]: in function 'dofile'
    init.lua:62: in function 'normalboot'
    init.lua:126: in main chunk
    [C]: ?

    Maybe the I2C code has changed too?

    The offending line 31 is:

    i2c.setup(id, sda, scl, i2c.SLOW)


    5 years ago

    Hi, great looking project.

    I am new to LUA and am having fun getting the firmware etc but I have a question... Which modules should I get built into the firmware please?


    Reply 5 years ago

    Thanks for you message.
    Modules required by the code are: bit, file, GPIO, I2C, net, node, PWM, timer, UART and WiFi.


    Reply 5 years ago

    Thanks for that list. sadly it would appear that some of your code no longer works with the latest build. I get the following error at startup now:


    NodeMCU custom build by frightanic.com

    branch: master

    commit: 443e8219527f5b2190324a969a4586f9d3d731bf

    SSL: false

    modules: bit,file,gpio,i2c,net,node,pwm,tmr,uart,wifi

    build built on: 2017-10-26 14:37

    powered by Lua 5.1.4 on SDK 2.1.0(116b762)

    Boot reason: 4 Whatever that means

    > Warning, deprecated API! net.createServer with net.UDP type. It will be removed in next version. See documentation for details.

    UDP Server



    and no IP address gets set


    Reply 5 years ago

    Thanks, It gets a bit further, I now get the following:

    > Just synched

    Warning, deprecated API! net.createServer with net.UDP type. It will be removed in next version. See documentation for details.

    UDP Server


    At the moment however, I am having difficulty getting anything displayed on the i2C LCD so am only going on the serial data being sent from the WeMos D1 mini back to Selene. I have no LCD display.


    Reply 5 years ago

    Well, I thing your are OK!

    You can issue a print command to see the time on the serial output on SELENE.

    That is: print((gmthours)..":"..(gmtmins)..":"..(gmtsecs).." "..(gmtdate).." "..(gmtmonth))

    If you experience any problem just restart the module and check if it is connected to your wifi correctly. A get ip (that is: print(wifi.sta.getip())) command it will return ether your IP details either nil, which is actually means no connectivity.

    If you like to get every second a line with the calculated time just un-commend the line 29 on "doloops.lua" file. or use the one provided in the link below


    Keep on!


    Reply 5 years ago


    I can confirm that that all works as expected. I get an IP and the correct time printed out with an old version of Lua and the latest, just the i2C comms/display to sort.