Internet LCD Clock

Setting Clocks

Manually setting clocks on all your electronic devices is such a pain. They all seem to have a different user pushbutton interface and if you don't have the manual handy, trial and error may be required. Some clocks automatically sync using a special radio time signal from an atomic clock time standard. WWV is one such example of this radio signal that is broadcast in the United States and there are even low cost ICs available to pick up this signal, but it might take several days for them to receive a strong signal indoors. If it is not located near a window, it might not ever pick up the signal. One of the more widely used WWVB receiver modules is shown below. They are found in many battery operated automatic setting wall clocks. There are several projects available on the web using the module's digital output with a microcontroller to set time. The newer triple frequency CMMR-8 module that can pick up WWVB, DCF77, JJY ,MSF, and HBG may be a bit easier to find. Despite a reputation as clockmakers, the frugal Swiss just pulled the plug on their HBG radio time transmitter to avoid costly antenna repairs and they now use the German DCF77 signal. The mbed time APIs can set and read the internal real time clock (RTC) and even convert the time to a character string for I/O.

/media/uploads/4180_1/_scaled_cmmr6p60bs.jpg
WWVB CMAX CMMR-6 receiver module with ferrite antenna

Time is also provided in GPS signals. The time can be obtained by parsing the ASCII NEMA strings output by a GPS receiver, but most devices do not have a GPS receiver and GPS will not work inside a large building. Devices such as cell phones with a GSM radio module can obtain the time from the cell service provider. TV signals contain embedded data including time. Coordinated Universal Time (UTC) is the primary time standard used to regulate clocks and time. It is one of the successors to Greenwich Mean Time (GMT). Why does Coordinated Universal Time have an acronym of UTC and not CUT? You can blame the French for saying it backwards and forcing a compromise in international standards notation.

/media/uploads/4180_1/_scaled_royal_observatory_greenwich.jpg
Royal Observatory in Greenwich where time starts on the Prime Meridian.

Using NTP to set time

If an embedded device has a network connection, it can be used to set the time. This Internet of Things example features a clock that is automatically set to the correct time using a network time protocol (NTP) time server on the internet. It combines two existing cookbook code examples, NTP Client and Text LCD with a small amount of additional code. In addition to a text LCD display, a breakout board or baseboard with a ethernet jack is required. The Sparkfun Ethernet breakout board is used in the example seen below.

IC

The time on the LCD is automatically set using an NTP time server on the internet. Larger Image

Wiring

Ethernet Magjack Connector

MbedSparkfun Ethernet Breakout
TD+P1
TD-P2
RD+P7
RD-P8

Note: Different magjack connectors can use different pin outs even though they look the same. These pins are for connectors from Sparkfun in 2011. If you are having trouble with your initial network setup, try this example code first. Once it works, it will confirm correct wiring on the connector (at least on the input side). Magjack Pinouts are posted for other common connectors. More connections to the unused pins including one to 3.3V and a capacitor should be added for long cables, but this setup works well with short cables. If you still get the network error message, make sure that DHCP service is enabled for your mbed. On some networks, you need to add the module's MAC address to enable the DHCP server to give it an IP address. It times out with an error, if no IP address is returned in about fifteen seconds. If your clock sets to a strange Jul 2010 date, you may have DNS problems or a very slow network (see comments below)

Text LCD

Mbed pinsText LCD pins
GNDGND
5V or 3.3V*VCC
VO to GND via 1k resistor
P15RS
GNDRW
P16E
N/CD0
N/CD1
N/CD2
N/CD3
P17D4
P18D5
P19D6
P20D7

Where N/C is not connected and the top left pin of the TextLCD’s header is GND and the right most pin is D7 in the LCD orientation shown in the images above. The resistor sets the contrast and some LCDs may need a different value or a contrast adjust potentiometer. See Text LCD for additional help, if needed.

(*) Note: some older LCDs may use 5V, but 3.3V is more common on current LCDs. If you cannot find a data sheet to confirm this, try 3.3V first and if the display is still blank (after double checking all other connections and code) it might need 5V. To save jumper wires, this setup uses the four bit interface to transfer ASCII characters to the LCD.

Example Code

Internet_LCD_Clock

#include "mbed.h"
#include "EthernetNetIf.h"
#include "NTPClient.h"
#include "TextLCD.h"
// Internet of Things clock example: LCD time is set via internet NTP time server
TextLCD lcd(p15, p16, p17, p18, p19, p20); // rs, e, d0-d3
EthernetNetIf eth;
NTPClient ntp;

int main() {
//system time structure
    time_t ctTime;
    //clear LCD
    lcd.cls();
    // lcd.printf prints to LCD display;
    lcd.printf("Get IP addr...");
    EthernetErr ethErr = eth.setup();
    //Get an Internet IP address using DHCP
    if (ethErr) {
        //error or timeout getting an IP address
        lcd.cls();
        lcd.printf("Network Error \n\r %d",ethErr);
        return -1;
    }
    lcd.cls();
    lcd.printf("Reading Time...\n\r");
    //specify time server URL
    Host server(IpAddr(), 123, "0.uk.pool.ntp.org");
    //Read time from server
    ntp.setTime(server);
    lcd.printf("Time set");
    //Delay for human time to read LCD display
    wait(1);
    while (1) {
        // loop and periodically update the LCD's time display
        lcd.cls();
        ctTime = time(NULL);
        lcd.printf("UTC:  %s", ctime(&ctTime));
        wait(.25);
    }
}

Import programInternet_LCD_Clock

LCD clock display set using NTP server



Video Demo


Video demo of Internet LCD clock power up

In the video above, the USB cable is plugged in to power up mbed. The code connects to the DHCP server to obtain an IP address and the LCD displays "Get IP Addr...". If the cable is not connected correctly or DHCP is not enabled for the mbed device, a network error message will appear on the LCD. Everything is OK in the video, and an IP address is obtained within a few seconds. Next the code displays "Reading Time" on the LCD and contacts an NTP server to obtain the time in UTC format and it uses this data to set the real time clock. When the time is set, the LCD briefly displays "Time Set" and then enters a infinite loop where the UTC time and date is periodically updated on the LCD.

The time can also be set with the set_time API, it uses the traditional Unix seconds count since 1970. Here is handy web page that will show you the current time for use with set time, https://www.epochconverter.com/clock .

If you wire up the Internet LCD clock demo and run it, you will also want to run the weather LCD display demo, News LCD Display and Geolocation LCD Display. They use the same exact hardware setup, so you only need to download the new code.

Saving the time using battery backup

With battery backup of the real time clock (RTC) circuit, the time will not be lost and the clock will continue to run when the device is turned off or when a power outage occurs. A similar circuit is found on most PC motherboards and batteries can last a few years. Depending on the application, devices that have a reliable network connection and use NTP to set the clock might not need a battery backup on the clock. The Vb pin on the mbed module is a low current battery backup input for the real time clock (1.8-3.3V). Some early mbed modules with an extra diode draw a bit more current from the battery, but this has been fixed on newer mbeds. See http://mbed.org/users/chris/notebook/rtc-battery-backup-current/ for more information. This RTC battery calculator will predict battery life given the battery amp hour rating and RTC current load.

LCC
Sparkfun has a handy coin cell battery breakout board.

Rechargeable coin cell batteries are also an option. Rechargeable batteries will eventually wear out after a number of charge and discharge cycles. A typical rechargeable battery will last for only a couple hundred deep charge and discharge cycles.

In some circuits, supercapacitors can be used to replace the lithium coin cell batteries used for backup of real time clocks. Supercapacitors will work for perhaps a million charge and discharge cycles. They have a longer lifetime, but with their lower energy density will only power the circuit for several hours or perhaps days without a recharge while coin cell batteries can last weeks. Studies have shown that 99.5% of power outages are less than 4 hours. Since most power outages have a short duration, supercapacitors often have an advantage given the longer lifetime. Lithium batteries also have a limited operating temperature range and also present assembly and end of life disposal issues. There are even some hybrid circuits that try to use both supercapacitors and batteries to extract the advantages from each. In many hybrid cars, supercapacitors are used for acceleration and regenerative braking along with lithium batteries since they can store and release energy at a faster rate than batteries. A .1f 5.5V supercapacitor such as the one seen below from VB to gnd will work for several minutes on mbed's RTC, but it also requires several minutes to fully charge. Below around 1.8V on VB with power off, the clock stops running, but the current time is saved and it will restart. When VB drops too low with power off (<.7?), the RTC locks at Jan 1 1900 until a new set_time().

SC
A 5.5V .1F Supercapacitor can be used for clock battery backup. Actual case diameter is 13.5mm and cost is similar to a coin cell battery.

Video Demo


Real Time clock using a supercapacitor for battery backup

In the video, the real time clock is running and note the seconds value. Near 10, the USB cable is unplugged to remove power to the mbed module and the LCD blanks out as the blue power LED goes out. After about eight seconds at 18, the USB cable is plugged back in. As the clock value reappears on the LCD note that the clock has continued to run during power off and the time and date setting was saved. The .1f supercapacitor near the upper left corner of the LCD provided backup power to the RTC circuit. The clock was first initialized using the earlier NTP demo code, and then another program was loaded for the demo once the clock was set and running. The new code for this demo does not use NTP to set the clock at power up (this code is only the while loop at end of earlier NTP demo code). If the backup battery ever runs down too low, a set_time() command will be needed to restart the clock at power on. Using a larger supercapacitor will increase backup time, but cost and size also increases with capacitance and at some point the charge current may become too large for the power supply. Most data sheets specify the voltage rating as the maximum operating voltage and a lower voltage rating just above 3.3V (3.6 or 4V) would reduce the size and cost although a rating too low could cause problems if a voltage surge occurs. This .1f 5.5V supercapacitor is a bit easier to find off the shelf and will plug into a breadboard since the pin spacing is almost .2 inch.

Supercapcitor Charging Circuit and Backup Time

The early mbed seen in the video has a diode from Vb to 3.3V that was removed in later production mbeds. See http://mbed.org/users/chris/notebook/rtc-battery-backup-current/ for more information, photos for confirmation of missing diode, and the circuit. Later production mbeds that have the diode removed from the battery backup circuit will not charge the supercapacitor. If the supercapacitor is charged, run time increases without the diode since there is a significant reverse leakage current through the diode (it was removed for increased coin cell battery life). For a quick prototype test using a supercapacitor on the newer mbeds, add the (removed) diode from Vb to 3.3V on a breadboard or jumper it to 3.3V for a few minutes to charge it and then remove the jumper. The run time can be computed using the voltage range, capacitance, and current draw using this supercapacitor calculator. In an actual device, a more complex trickle charge circuit would likely be used to both charge the supercapacitor, and provide longer run times with lower backup current (less diode leakage). Some RTC ICs like the Maxim DS12R855 have this circuit builtin.

Chapter 27 of the LPC1768 user manual contains additional details on the RTC hardware. It is possible to calibrate the clock to improve accuracy, set an alarm using hardware, and store battery backed up data in five extra general purpose registers. These features are currently not directly available using mbed I/O APIs and it will be necessary to write directly to the registers using the register names from the mbed register definition *.h file or by directly using the register's address from the manual to use these features.

Using the RTC registers to save user data when power is off

Once the RTC runs off of battery backup, user data can be saved in the five 32-bit RTC general purpose registers (GPREG0…GPREG4) that will persist across a power cycle and will also not be cleared out by a reset. This can come in handy in some embedded device applications for a small amount of non-volatile critical data. The code seen below displays the low 4-bits of data from one of these registers in the LEDs. It then increments the register value and enters an infinite while loop. Note that the register names (i.e., "LPC_RTC->GPREG0" from LPC17xx.h) are used to directly transfer data to the hardware since this operation is not currently supported by APIs.

#include "mbed.h"
// RTC battery backed up register test
// RTC has five registers - GPREG0…GPREG4
// Should see LEDs increment on each power cycle (or reset)
DigitalOut leds[] = {(LED4), (LED3),(LED2),(LED1)};
// use leds as an array
int main() {
int i;
    // set LEDs using low 4-bits of RTC GP register 0
    for (i=0; i<4; i++) {
        leds[i] = (LPC_RTC->GPREG0>>i) &0x01;
    }
    // increment value in battery backed up RTC GP register 0
    LPC_RTC->GPREG0 = LPC_RTC->GPREG0 + 1;
    while(1) {}
}

Video Demo


Saving non-volatile data in RTC GP registers

As seen in the video above, when the RTC GP register demo code is run on an mbed with RTC battery backup power, the binary value seen in the LEDs will increment each time power is cycled on mbed. The easiest way to do this is to pull mbed’s USB cable out of your computer and plug it back in. Once power returns, the program runs again and displays the incremented value in the LEDs. A manual reset will also increment the count, since it runs the program again (but does not clear out the RTC registers). On this mbed without battery backup or the first time the program is run, all of the LEDs are on. It appears that without backup power during power off, the register values will go to all "1"s at least on this chip.

Ideas for Further Enhancements

1. Add correction for local time zone and display local time in AM/PM format. Check the handbook's mbed time APIs for help.
2. Add pushbutton(s) to set time zone.
3. Automatically resync clock late at night each day.
4. In case of a network error, delay several seconds and automatically retry.
5. Investigate using the IP address to automatically guess the local time zone.
6. Add an alarm feature with pushbuttons and a speaker. The speaker will likely need a driver circuit.
7. Use an NTP server nearer to your location.
8. Save the local time zone and alarm setting to mbed's flash file system and use it automatically at power on.
9. Use a wireless network connection with a WiFly module or other wireless device.
10. Add battery backup for the real time clock using a coin cell battery.
11. Use a supercapacitor for battery backup.
12. On power up, determine if the real time clock was still running properly off of battery backup. If it is, do not set time and use the current value.
13. Use the RTC calibration register to improve the accuracy of your clock.
14. Use one of the RTCs GPIO registers to save the time zone and alarm setting during a power loss.
15. By checking the time periodically using NTP, develop an algorithm that automatically calibrates the clock to improve accuracy.
16. Add some weather information and alerts to the clock's LCD display using a weather RSS news feed.
17. Use Power over Ethernet (PoE) to power the clock and avoid the extra wires for power. Sparkfun has one PoE option.
18. Instead of pushbuttons, use touch switch input.
19. Add a temperature sensor and add indoor temperature to the display. "lcd.locate(col,row)" will move the cursor and might come in handy.
20. Add a humidity sensor and add indoor humidity to the display.
20. Upgrade to a larger display such as a color LCD or VGA.
21. Using the speaker make a clock that chimes each hour.
22. Instead of a dull alarm, play a wave file using the speaker and perhaps an MP3 decoder.
23. Add a radio chip and make a clock radio.


12 comments on Internet LCD Clock:

18 Apr 2012

Just flashed this code, and the date & time is wrong ..

UTC: Sat Jul 24 19:33:37 2010 UTC: Sat Jul 24 19:33:37 2010 UTC: Sat Jul 24 19:33:37 2010 UTC: Sat Jul 24 19:33:37 2010

I have tested this a few times, and always the same time !!

Is this the correct address for time ??

I do remember not being able to get this to work, as one of my first Ethernet MBED programs.

Cheers

Ceri

18 Apr 2012

Wow! Really strange mine works everytime?

I have probably run it fifty times and recompiled almost that much for over a week. Never had any issues.

I wonder if it could be some sort of network error that the NTP code does not catch?

Perhaps I should try a couple more mbeds and different networks, before I tear down the breadboard.

I did clean it up and add some comments, might have done something to it and will double check that.

18 Apr 2012

Just imported the published code, recompiled, and tried it on another mbed on the more secure network here at work. Still works like a champ every time?

Could you try http://mbed.org/cookbook/NTP-Client again to make sure that is the problem.

Could it be a firewall type issue?

Might also add a debug printf("\nTime is now (UTC): %s\n", ctime(&ctTime)); in that inner while loop and confirm it has the same time.

Is it also the case that your clock does not run (ever change the value). I saw that while working on battery backup and it can lock up needing an initial set_time() call - but on my mbed it seemed to not need it with the ntp.setTime(); - Perhaps the two problems are related.

I also noticed there is an NTP return error code no one checks: - http://mbed.org/users/donatien/programs/NetServicesSource/5zh9t/docs/NTPClient_8h.html#a7226e0ca074670587f307229c9b6443c Might be a good idea to check it in the example code. I will look into adding that, but it will be a few days. Errors include DNS lookup and timeout. Maybe its a time timeout!

19 Apr 2012

I just tried some things with the code and added full NTP return error code checking and displayed them in the LCD. If I give it a bad Hostname it returns the NTP timeout error code after about 10 seconds and has exactly the same strange 2010 time that you got. I tried increasing the default ethernet timeout using setup(60000), (I had to do this for one slow network to get an IP), but it had no effect as far as I could tell on NTP timeout. My guess is that for some reason your network takes a few seconds too long for ntp. Ten seconds seems a bit short. If I yank out the network cable when it says Reading Time, I can force an NTP DNS error return code, but it does not change the time to 2010! My setup always returns the NTP_OK code without fail and it prints the "Time Set" message less than 2 seconds after "Reading Time".

Don't think we have the NTP source code to try to fix it?

19 Apr 2012

Someone suggested a newer version of the NTPClient library with the source code - http://mbed.org/users/segundo/libraries/NetServices/ljhqix Will look into using it and increasing the timeout along with error checking.

20 Apr 2012

Here is some code to check for all NTP errors and display them on LCD - could insert this code snip to the original example (where it did not check errors on the ntp.setTime call)

NTPResult NTPerror;

    //Read time from NTP server
    NTPerror = ntp.setTime(server);
    if (NTPerror == NTP_OK) lcd.printf("Time set");
    else { //an NTPerror, but which one
        switch (NTPerror) {
            case NTP_TIMEOUT:
                lcd.printf("NTP timeout");
                break;
            case NTP_DNS:
                lcd.printf("DNS error");
                break;
            case NTP_PRTCL:
                lcd.printf("Protocol error");
                break;
        }
        return -1;
    }
    //Delay for human time to read LCD display
    wait(1);

If you get the NTP_Timeout error- you can replace the two net libraries (leave TextLCD) with an import of NetServices library, recompile and everything runs. Edit the Netservices library and under services-> NTP open NTPClient.cpp and you can increase a #define near the beginning for NTP_REQUEST_TIMEOUT from 15000 (ms) to say 60000 (ms), that does increase the timeout for NTP response. If it is a slow DNS lookup it does not look like it helps that. I have this on my code here and it still works. Might also want to change the example codes eth.setup() to eth.setup(60000) to increase the other net timeouts. I did find in the code that it sets time to that Jul 2010 date before trying to do an NTP time set.

I hate to post any code forks on the NetServices library and make the code example more complex until we know it fixes something - publish will not let me publish my code with first publishing the modified NetServices library.

18 Sep 2012

/media/uploads/Waltorg/capture.png

Sorry guys, I'm a noob. I cannot get this program to compile. I have written a few small programs that work but this is the first time I have imported someone else file.

Any suggesstions?

W

18 Sep 2012

The problem seems to be a recent update to the NTPClient library. Try the copy at http://mbed.org/users/4180_1/code/Internet_LCD_ClockOld/ - and see if it compiles. I don't have an LCD handy to try it, but when I import this one it compiles OK on my PC and it has the older NTPClient (this was the old one still in my project area). If I import the other one, I get the same errors. The networking libraries were all updated recently to work with the new RTOS and to use interrrupts and not polling. I am not sure exactly how NPTClient got updated in the other copy since import also saves? and brings in the libraries.

At some point, the older networking examples should all be updated to use the new networking code that is now supported by mbed.

19 Sep 2012

Jim,

It works great. I would never have figured this without your help. Hopefully I can use this get the other news/weather apps working. I am grateful!

Thank You!

W

19 Sep 2012

I noticed on some of the other LCD gadgets that an import seemed to sometimes? do an automatic update of libraries (I saw a dialog box pop up and say updating before it went away very quickly). Some of the old network libraries have the same names as the new ones - so some of the other LCD gadgets may have a similar problem and will need to be updated with the new network libraries.

18 Feb 2015

Hi,

About this improvement, 1. Add correction for local time zone and display local time in AM/PM format. Check the handbook's mbed time APIs for help.

How can it be done? Is there a way to manually add a TZ offset to the time_t? I couldn'd find anything in the mbed api.

Thanks, Daniel

25 Sep 2019

Hello,

I was trying to work on this project, but I kept getting an error in the process of importing the code into my online mbed compiler/IDE: /media/uploads/jlee/netservices_error.png

When I try to compile the project, a related compile error occurs:

Error: Namespace "mbed" has no member "rpc" in "NetServices/services/http/server/impl/RPCHandler.cpp", Line: 59, Col: 10

Maybe the NetServices library is no longer compatible with the newer mbed software. Even when I import the project as is (without updating anything) I still get errors. This happens for the geolocation project as well.

Please log in to post comments.