Youtube channel

Check out my youtube channel!

Thursday, 31 December 2015

ESP8266 based NTP Clock




A little over a year ago, the ESP8266 WiFi SoC started getting attention and quickly became a little chip of wonder. On a fully self-contained breakout board with this chip, a complete WiFi enabled controller is well under $5! It's gathered huge interest from the hobbyist world.

Since the device first made its appearance, I've been watching news on the evolution of its development environments. My play time is very limited at the moment, so I was very excited to learn that a standard C++/Arduino environment is available for this - rather than spending time learning a new SDK, I can just use already familiar environments. More time playing with it, less time stuffing around with compilers, etc.

So as you do, the first thing I decided to make of this was a clock. Home made clocks have been in the news a bit lately. Clocks are great as first projects for new MCUs, as they are always useful, and in one project you get to learn a lot about the device:

  • General MCU behaviour and features
  • Display / output interfacing (leading to tight I/O operations)
  • Precision interval/timekeeping/interrupts.
  • Interfacing with the device for time adjustment.
Given that the device is primarily a WiFi / network device, the clock had to interface with the network, and what better than to have it as an NTP client. I also had a spare 4 digit LED display, and the 3-wire interface works perfectly with the 4 GPIO pins broken out on the ESP-1.

An so began my design for this clock. A brief overview of what I envisaged for it:
  • Synchronised over NTP (Network Time Protocol, RFC 5905)
  • Browser based configuration of WiFi credentials, NTP settings, etc.
  • Configuration saved into non volatile memory.
  • Single button to enter AP mode for configuration.
  • IP Address display (again, single button)
  • Indication of NTP sync loss.
  • Absolute minimal component count.
As this was also a learning exercise, the development was not a straight-forward linear process. Each (software) component in the clock involved some tinkering and hacking, but as I found comfortable solutions, I refactored into clean sections.

There are quite a few examples to be found of fetching NTP time with this device, but very few show a standalone day to day device.

Hardware

The clock hardware is really really simple. I doubt it could be distilled down to anything less than the following components:
  • ESP-1 module.
  • 4-digit 7 segment display (SPI interface) [this Sure Electronics one]
  • LM1117 3.3v regulator.
  • 10uF bypass cap
  • PCB mount pushbutton switch
Diagram of the setup:

The most notable aspect of this is the interfacing between the ESP-1 and the LED display.

Firstly, two of the GPIO pins (GPIO1 and GPIO3) are normally used as TX and RX on UART0. These are used for flashing the ESP as well as the default Serial interface. I want to use them for the clock. Not a problem though, in setup(), I configure them as outputs and this works well.


Secondly, the display is sold as operating at 5v. But I do not need 3.3-5v level converters as the driver chips (74HC164) are 3.3v compatible by virtue of them registering a high level at ~2.1v. That really trims the component count.

Lastly, whilst the interface on the display is SPI-like, and the ESP8266 has a hardware SPI, I could not use this as the ESP has SPI on GPIO12-15 which are not broken out on this board. Not to worry, it only takes a dozen or so lines of code to bit-bang.



As for accurrate timekeeping, there is no point incorporating an RTC here. Early experiments with the millis() call showed that the ESP's main oscillator can keep time with an accuracy of about 1s/day, so I just use this and have NTP re-sync at a configurable interval.

Software

The software is based on the Arduino ESP8266 core. As explained above, I would have like to learn the other environments like NodeMCU, but have a severe lack of time. Instead I stuck with something already familiar.

The software is designed for the clock to be configured entirely over WiFi, with a single helper button for a couple of extra features. This is a clock that anyone can build and use, without having to configure in the code or connect to a PC to set the time.

The code is available at everyone's favourite repository, Github. See https://github.com/buxtronix/arduino/tree/master/esp8266-ledclock

I welcome any patches.

Operation

The clock is written to be really simple to setup and use. Here are some details on various features:

Setup

After initial powerup, the clock should detect that there is no configuration and automatically enter AP mode. The display should show 'AP'. If not, press the button within 5s of powerup. Once in AP mode, you can connect your phone/etc to the 'ESP-CLOCK' SSID (no security creds), and then point a browser to the clock. The IP address should be 192.168.4.1, but you can press the button and the address will be displayed.

Configuration

After entering setup above, and pointing a browser to the address, you will see a configuration page. Most of the settings are self-explanatory. Just remember to tick 'Update Wifi config' to have the SSID/PSK also updated.
The changes take effect as soon as you hit submit. Note that if you update the Wifi settings, the device will (re)associate with the given network.
TODO: Support WPS.

Normal operation

Once configured correctly, at powerup the display will display spinners. The first spinner on the right-most display lasts 5s - pressing the button in this time will cause the device to enter AP mode - useful for if you have to change Wifi credentials. Then the next spinner will appear, this displays whilst the device is attempting to associate with the given Wifi network.

Once associated, the device will fetch the NTP time from the configured server (default is time.nist.gov). Then the time will be displayed. The decimal between the hours and minutes will cycle each second. If synchronisation fails or is overdue, the rightmost decimal will be lit. This is a useful way to be assured if the clock is accurate.

Once running, you can press the button and the device IP will be displayed. You can point a browser to this IP and view the status and change the configuration.

Conclusion

Building this clock was a great way to get to know this awesome little SoC. The toolchain(s) are become quite mature now and it is an excellent alternative to AVR and PIC for when wireless networking is required. Whilst the hardware lacks some peripheral features I'd like, getting a full Wifi stack/SoC for not much more than a cup of coffee is incredible for so many projects.

Building a clock that "never needs setting" has been really quite fun.




15 comments:

  1. The ESP8266 ESP-01 I have only has the GPIO0 and GPIO2. I don't see a GPIO1.

    http://fabacademy.org/archives/2015/doc/networking-esp8266.html



    ReplyDelete
    Replies
    1. RX and TX can also be used as GPIO ports. See the paragraphs below the schematic.

      Delete
  2. Please, what is BLANK connection?

    ReplyDelete
    Replies
    1. BLANK is the blanking input of the display - or it might be called 'enable'. It's to stop the display flickering as data is pushed to it.

      Delete
    2. Sorry Ben, but where should be connected on the display?

      Delete
    3. I hope not to bother you, but the display that I bought me this is not the blanking and even the enable input, so I connected directly GPIO2 to pin 9 of the 74HC164 (are parallel to each other) and I changed the line 48 of the sketch in tab "DISPLAY" eliminating delayMicrosecond, so there is no more flickering.

      Delete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Very nice project!!!

    I recently knew that ESP8266 sdk includes sntp implementation. It makes no averaging or some other advanced techniques specified in NTP standard to get microsecond accuracy, that is SNTP (simple NTP). But its precission (from some hundreds milliseconds to a couple of seconds depend on your connection latency) is enough for a general purpose clock.
    I've made a simple to use wrapper library that allows to include NTP sync with as less a one single line (or two if you do not like default 1800 sec. update period). If you like it feel free give me your comments.

    You can get it at https://github.com/gmag11/NtpClient

    ReplyDelete
  5. Ben,
    Is it possible to share your connection detail between the display and the ESP ?
    Thank you

    ReplyDelete
  6. This is a really nice project, and a great way to get familiar with the ESP8266. It's also kinda cute...
    Thanks.

    ReplyDelete
  7. The code on your github page doesnt compile. More than one person cant get it to work (myself included). This is sad because it's very similar to a project I want to make and was hoping I could find code already written instead of having to write it all from scratch.

    ReplyDelete
  8. Hi
    thx for the code on github, but there is a problem

    it dont compile:

    exit status 1
    'hour' was not declared in this scope

    ReplyDelete
  9. ohh is it posible to use neopixel instead of your leddisplay

    ReplyDelete
  10. I modified this to use the adafruit 7 segment backpacks and added better time zone handling. Couple of thoughts: should there be a 10k resistor between 3.3 and CH_PD and also one on the GPIO3? I find that pushing the button only works once after reset otherwise. Also, I think its better to use WPA for the initial setup mode and not echo back the PSK for security. Here is my version - giving you credit of course :) https://github.com/ntsecrets/espclock

    ReplyDelete
  11. This gps tracking device spy app could is one of the best that are currently on the market. Check it out.

    ReplyDelete