When it comes to clocks, we have plenty of design and models available. From mechanical to digital, there are plethora of products. Starting from Sun dial to atomic clocks plenty of architecture are available to keep pace of time.
Designing a clock that stands apart from rest is a mammoth task considering the fact that the time measurement tool is available since the start of civilization. So, to make this unique, I was looking for some of the features that are missing in conventional clock.
- Accurate time keeping (Digital clocks are the best with + or - 5 minutes a year)
- Display Calendar (Most digital version of clocks can do this)
- Support various Time zone
- Support Daylight savings that are observed around the world
- Manage time when there is loss of power
- Absolutely no need to set the time after initial setting - even during the daylight savings duration.
- Easily configurable (One-time only needed)
- Cheap and readily available parts
Phones and computers that are connected to Internet will have all the above features. But to design a clock with that features would mean having a connectivity to Telephone tower or Internet. There is another alternative and that would be to use GPS module. Of the three, I chose Internet which works out inexpensive. Once you connect to Internet then time-keeping becomes very easy. But not everyone has Internet facility. So a backup alternative needs to be provided. Time needs to be maintained during power failure as well.
Wifi Clock DesignWith the above constraints, I came up with a design that used ESP8266 the well known WiFi break-out board for Arduino to connect to Internet. For backup of maintaining the clock, a CMOS based RTC DS3231 module is used. Displaying time and calendar, 2 line, 16 character display was chosen. Here is the design diagram:
First and foremost is the WiFi configuration. Obviously this cannot be hard-coded. That defeats the purpose for common usage. So a simple webserver is programmed which can be easily accessed by any browser. This model eliminates installing any new application. The moment a web client (browser) access the server, Time and Time-zone are automatically updated. The clock will advertise on the network as ESP_xxxxx where xxxxx is the unique Id of the ESP8266 board. Connect to this network open up your browser and point to http://172.23.1.1 or http://wificlock001.local. Inital password to connect to will be - password.
In this screen you can provide your WiFi Router credentials to connect to your home routers. Up to 6 networks credentials can be stored giving you the flexibility to move between routers. The program itself will automatically connect to available router should the connection fail. The credentials itself are stored in EEPROM which means, it is maintained even when there is power failure. The credentials can be easily deleted if no more required.
Configuration of DST and preferencesThe next configuration would be Day-light savings. Since this varies country to country and even place to place managing a huge database for this is not possible with the limited memory of ESP8266. Though it can be ignored if the clock is connected to internet, in the absence of connectivity, keeping time would be difficult. Hence this is configured and stored initially.
Here you can select your preference of display AM/PM or 24 hour display. Depending upon your location enable Daylight Savings Time (DST). With DST there are few tricky situations. Some countries change on last week of Saturday or Sunday. In such situation having Start / End Week as 5 (maximum weekday possible in a month), the program will calculate the last week of the day. Yet some other country have hard-coded date like 21st of the month. In that case, Start / End week can be the date. Program will consider any no. greater than 5 in Start Week / End Week will as Date.
Technical ConfigurationRunning a web server on the network will slow down the ESP8266. Hence it will only run when you Power-on the clock and only if it cannot connect to WiFi. Also this will run only up to the first 10 minutes. This is configured on the field "Server On Time". '0' Mins in this field will run the server indefinitely though not a prescribed option. Host name can be used to connect to the clock instead of remembering the complicated IP address. This is configured in Host Name field. To access the clock you will typically use http://wificlock001.local or the host name you choose. The clock itself will have a local IP address of 172.23.id.1 where id is the clock ID. This clock ID can be changed in 'Clock Id' field. Selecting a class B IP address, gives the flexibility of having 254 clocks on the same network. The password to connect to this web can also be changed from - 'password' to whatever you choose. Please note though that if you forget the password you must do a factory reset! Final configuration is the connection time-out for Wifi network connectivity. Every 20 minutes the clock will try to connect to a wifi-network if it is not already connected. The entire process will take about 10 to 20 seconds depending upon WiFi LAN availabilities and no. of WiFi credentials stored. Having a short time-out would be ideal, but in some instances may not be adequate to connect to your configured router. Having a long timeout means few seconds are wasted (do not worry, the clock will adjust to right time after the connection try-out) during connection try-outs. You will see the clock freeze for few seconds during these times. 8 seconds is generally adequate for connection even on slow routers. If you think it is not, you can increase to a maximum of 30 seconds. Time-zone is automatically filled and barely needs any change.
Time KeepingThe clock itself depends on two methods to keep time to accuracy.
- CMOS RTC module
- Connectivity to Internet
Initially the clock will get its time from RTC (Real Time Clock). Most computers manage the time by the same mechanism. Hence to adjust the initial time, it is pertinent to connect to the clock first through web. This will update the RTC to local time and time zone. (Note: You do not have to save any settings. As soon as you connect with your browser, the time will get adjusted). If you do not want to configure any Wifi then ensure the preference are updated - especially DST. This will ensure proper timings are maintained during the DST period. RTC also has battery backup, which will last for 5 to 8 years when there is no power. As the clock will be connected to mains, the backup will be required only during power failures or when the clock is moved. Since the battery will be used for a very short duration it will almost last forever - at least theoretically. Changing the battery is trivial though it does involve soldering.
As soon as connectivity is available the clock will update the time from network. It will connect to Time-keeping server using NTP (Network Time Protocol) to get a time that is synchronised with atomic clock. This time is also updated in RTC. Thus accuracy of clock is managed. RTC in general as an accuracy of + or - 3 seconds per year.
Code DetailsThere is no need to go into the code in details. Most of the code is based on libraries already available in Arduino. I will highlight the DST code here:
//Called at the start of the year, will fill the DST structure
void InitialiseDST()
{
//startAEST[] = {10,0,1,2};
//0 = StartMonth, 1= StartDay 2= StartWeek 3 = StartTime
//Get the weekday of the first date of DST Start month
int firstDayOfWeek = getWeekDay(1,pref.DSTStartMonth,currentYear);
//Now get the first DST Start day
int firstDSTday = firstDayOfWeek > pref.DSTStartDay ? 8 - firstDayOfWeek + pref.DSTStartDay : pref.DSTStartDay- firstDayOfWeek + 1;
currentDST.startMonth = pref.DSTStartMonth;
if ((pref.DSTStartWeek-1) > 5) //Day is used
currentDST.startDate = pref.DSTStartWeek;
else
{
currentDST.startDate = firstDSTday + (7*(pref.DSTStartWeek-1));
if (currentDST.startDate > (30 + LastWeek[currentDST.startMonth]))
currentDST.startDate = currentDST.startDate - 7;
}
currentDST.startTime = pref.DSTStartTime;
//Get the weekday of the first date of DST End month
firstDayOfWeek = getWeekDay(1,pref.DSTEndMonth,currentYear);
//Now get the first DST End day
firstDSTday = firstDayOfWeek > pref.DSTEndDay ? 8 - firstDayOfWeek + pref.DSTEndDay : pref.DSTEndDay - firstDayOfWeek + 1;
currentDST.endMonth = pref.DSTEndMonth;
if ((pref.DSTEndWeek-1) > 5) //Day is used
currentDST.endDate = pref.DSTEndWeek;
else
{
currentDST.endDate = firstDSTday + (7*(pref.DSTEndWeek-1));
if (currentDST.endDate >(30 + LastWeek[currentDST.endMonth]))
currentDST.endDate = currentDST.endDate - 7;
}
currentDST.endTime = pref.DSTEndTime;
/* Serial.printf("Year: %d startMonth:%s, startDate:%d, startTime:%d, EndMonth:%s, EndDate:%d, EndTime:%d\n", currentYear,
MONTHS[currentDST.startMonth-1],currentDST.startDate,currentDST.startTime,
MONTHS[currentDST.endMonth-1],currentDST.endDate,currentDST.endTime);*/
}
At the start of every year, DST is initialised (or when the clock is first initialised). The idea is to get the date for end of DST and start of DST. Since the DST is provided as first or second or last week of the month, we need to get the week day of the 1st of day of the month. Once that obtained, appropriate date for the DST start or end week can be calculated. Then it is easier to calculate last week-day's date.
The clock itself is never updated during the DST period. Instead a running hour keeps track of the DST and updates only the clock display. Here is the code:
void displayTime()
{
.
.
.
..
//Initialise the DST settings. Once a year only
if (runningYear != currentYear)
{
runningYear = currentYear;
InitialiseDST();
}
currentHour = hrs;
hrs += getDST(currentHour);
.
.
.
}
//Check if the time falls under DST
int getDST(int Hour)
{
//Not yet reached DST month or past DST month
if (currentMonth < currentDST.startMonth && currentMonth > currentDST.endMonth)
return 0;
//Current month is DST start month
if (currentMonth == currentDST.startMonth)
{
if (currentDate < currentDST.startDate)
return 0;
if (currentDate > currentDST.startDate)
return 1;
if (currentDate == currentDST.startDate)
{
if (Hour < currentDST.startTime)
return 0;
else
return 1;
}
}
//Current month is DST end month
if (currentMonth == currentDST.endMonth)
{
if (currentDate < currentDST.endDate)
return 1;
if (currentDate > currentDST.endDate)
return 0;
if (currentDate == currentDST.endDate)
{
if (Hour < currentDST.endTime)
return 1;
else
return 0;
}
}
return 0;
}
The complete handling of Web pages are done by HTMLhandlers.ino. The entire code can be obtained from git hub: https://github.com/vdevan/Wifi-Clock
Factory Reset - Panic ButtonFinally, the clock has only one reset button. Since all the settings are to be done only once, which is also done through web browser, we can easily dispense of numerous switches that are found in conventional digital clocks. The reset button has two functionality. When pressed for 2 seconds, will start the web server and thus you can access the web page to change preferences or add network credentials. If pressed for over 10 seconds, then the clock will enter reset mode erasing all the contents and reverting the clock to factory defaults. RTC time will not be affected by this! Here is a simple code that handles it:
//Monitor the config pin and call Config function if required
void MonitorConfigPin()
{
if (digitalRead(RESET) == HIGH)
return;
int elapse = 0;
//Serial.println("Detected Config Request");
while (digitalRead(RESET) == LOW)
{
elapse++;
if (elapse > 2)
{
lcd.setCursor(0, 1); //Calendar line
lcd.print(" Settings Req. ");
}
if (elapse > 10)
{
lcd.setCursor(0, 1); //Calendar line
lcd.print(" Factory Reset ");
}
delay(1000);
}
if (elapse > 10)
{
WiFi.disconnect();
EraseStoredValue();
}
if (elapse >2)
{
bConnect = false;
startServer();
}
}
Finally:That's about it. The only addition is the symbol for connectivity that is displayed on the first line. the DS3231 module also has a temperature monitor which can be accessed, but not used here. The clock is housed with power supply in a tight space and is generally stuffy inside. The temperature will not reflect the outside environment and for a layman, inside temperature is useless.
Some of the pictures of the design of clock are provided below:
Comments
Please log in or sign up to comment.