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.