Tag Archives: rtc

A simple NTP client for ESP8266

Once you have a real time clock working on the ESP8266, you might actually want to set it. As they have a backup battery you may just set it before you connect it to the ESP8266 and forget about it, but that’s not ideal. These cheap RTCs probably aren’t perfectly accurate and if it stops for any reason (e.g. dead backup battery) you’ll need to reset it. The DS3231 has a flag to indicate it’s been stopped – ideally this should be checked on startup and the clock set via NTP if there has been any interruption.

I did find one other simple NTP implementation but it’s incomplete, there is no timeout and it doesn’t clean up the connection when it’s finished (so it’ll leak memory). I think my version should work a little better, but I can’t guarantee it’s bug free so please let me know if you find any. As well as getting the time, the code is a nice simple example of a UDP client.

To use simply call ntp_get_time( ). The NTP request is asynchronous so you get the time in the ntp_udp_recv callback function, have a look there for two simple examples of what you could do with your newly received NTP time (print it out or set an RTC).

Code now on GitHub: https://github.com/raburton/esp8266

Simple timezone support for the ESP8266

I suggest you run your RTC on GMT (aka UTC, if you’re French). If you’re just using it for data logging or the like you can probably run entirely in GMT. If you want to display it to a user you probably want to do that in localtime. The ESP8266 C API doesn’t have support for timezones, so you’ll need to add your own. Adding or subtracting a few hours is easy enough, but applying daylight savings time (DST) during the summer is a little more tricky. A quick google search found a few examples but they all assumed the adjustment happened at midnight, so I’ve created an extended version that changes at 2am, as happen here in the UK. This is an example and will need to be modified if you’re not in the UK. Ideally the function would parse a string with timezone specific definitions rather than having hard coded rules, if you want to do this hopefully this code will serve as a starting point.

Code now on GitHub: https://github.com/raburton/esp8266

Real time clock (DS1307/DS3231) for the ESP8266

Cheap DS1307 "TinyRTC" board

Continuing the time theme, I’ve recently been playing with the ESP8266 wifi soc and the common real time clocks (RTCs) DS1307 and DS3231. It seems to be popular to program these devices with LUA using NodeMCU firmware, but I can’t work out why. LUA seems to be pretty awful, but I guess if you’re new to programming it’s an easy way to get started and you aren’t likely to notice how odd LUA is. Real men use C (or assembler, if they’re showing off).

(TL;DR – skip to the bottom of the post for the attached C code.)

So you can program for them in C, using the SDK supplied by the manufacturer (which is what NodeMCU itself is built with). Actually they supply two SDKs: The first is the one they are actively pushing for development and offer bug bounties for. The second one (FreeRTOS based) seems to use more standard APIs and appears to have a few more features, but it’s future isn’t clear. It’s a bit confusing, but I’ve decided to stick to the first SDK.

So, back to the RTCs… These are easily obtained from China for about 53p from AliExpress, shipped to the UK! Amazing when you consider you can’t even send a letter inside the UK for that price. You basically have a choice of two boards, one based on the DS1307 (pictured above) and one with the DS3231 (below). The DS1307 has less features than the DS3231 and the boards, generally labelled as TinyRTC, seems to be pretty flaky – my advice would be to avoid them. Lots of people find they don’t work without modification. Mine works (after mods), but only with power applied, it doesn’t maintain it’s timekeeping on battery.

Cheap DS3231 board

The DS3231 is more accurate, has more features and the boards seems to work fine. As they’re the same price I’d go for these every time. Note that both boards are designed to be used with a rechargeable lithium cell battery, and if you put in a normal CR3032 it will try to charge them and they might explode! On the DS3231 board you can simply remove the diode to disable the trickle charge circuit. Also of note, both boards come with an AT24C32 i2c eeprom on board, which might be handy for something.

So why do you need a RTC? The device has wifi so why not just get the time from an NTP server? Well you might not want wifi enabled all the time, especially if you intend to run the ESP8266 from battery. Getting the time from the RTC is quicker than NTP,  and easier to do synchronously. You can also do other neat things, like use the alarm on the DS3231 (not available on the DS1307) to wake the ESP8266 from sleep, it could then connect to the network check in with a server to send data/ receive instructions, then go back to sleep again. The DS3231 can even tell you the temperature.

I found a few simple examples of using these RTCs for LUA, but nothing much for the C API, so I’ve written drivers for both. I think they are pretty comprehensive in their support for the features of the chips and the code is thoroughly commented so you should be able to work out how to use/ modify it easily.

Code now on GitHub: https://github.com/raburton/esp8266