Build a Network Clock (NCLK) With Microduino-RTC
by makermodule in Circuits > Clocks
8111 Views, 21 Favorites, 0 Comments
Build a Network Clock (NCLK) With Microduino-RTC
The resolvent of clock synchronization over internet. by PKJ,
The web−based clock management system allows you to monitor clock status from wherever they are and centrally change settings. and this small device is built with PoE technology, thus IP clocks get their time, data and power from the same network that supports your other IP endpoints.
Author: https://www.facebook.com/pan.kejia
Editor: https://www.facebook.com/Microduino
Main features:
- Set automatically by SNTP (Simple Network Time Protocol)
- DHCP or static IP addressable
- Power over Ethernet (IEEE 802.3af) using the same network components as IP telephones
- Time synchronization with PCF8563
- OLED display component
Hardware partlists:
1. Microduino-Core+
2. Microduino-FT232R
3. 【Microduino-ENC28J60】 + 【Microduino-RJ45】
4. Microduino-OLED
5. Microduino-RTC
Please check technical details in http://wiki.Microduino.cc
The web−based clock management system allows you to monitor clock status from wherever they are and centrally change settings. and this small device is built with PoE technology, thus IP clocks get their time, data and power from the same network that supports your other IP endpoints.
Author: https://www.facebook.com/pan.kejia
Editor: https://www.facebook.com/Microduino
Main features:
- Set automatically by SNTP (Simple Network Time Protocol)
- DHCP or static IP addressable
- Power over Ethernet (IEEE 802.3af) using the same network components as IP telephones
- Time synchronization with PCF8563
- OLED display component
Hardware partlists:
1. Microduino-Core+
2. Microduino-FT232R
3. 【Microduino-ENC28J60】 + 【Microduino-RJ45】
4. Microduino-OLED
5. Microduino-RTC
Please check technical details in http://wiki.Microduino.cc
Microduino-RTC
Microduino-RTC is a RTC module in Microduino series.
- the main chip is PCF8563
- use I2C interface
- on-board EEPROM AT24C32
- open source files [check]
use below codes to drive and test Microduino-RTC module.
necessary library [download]
#include <Wire.h>
#include <Rtc_Pcf8563.h>
//init the real time clock
Rtc_Pcf8563 rtc;
void setup()
{
Serial.begin(9600);
//clear out the registers
rtc.initClock();
//set a time to start with.
//day, weekday, month, century(1=1900, 0=2000), year(0-99)
rtc.setDate(29, 4, 8, 0, 13);
//hr, min, sec
rtc.setTime(00, 21, 0);
}
void loop()
{
//both format functions call the internal getTime() so that the
//formatted strings are at the current time/date.
Serial.println("CODE_1:");
Serial.print(rtc.formatTime());
Serial.print(" ");
Serial.print(rtc.formatDate());
Serial.print("\r\n");
Serial.println("CODE_2:");
Serial.print("20");
Serial.print(rtc.getYear());
Serial.print("/");
Serial.print(rtc.getMonth());
Serial.print("/");
Serial.print(rtc.getDay());
Serial.print(" ");
Serial.print(rtc.getHour());
Serial.print(":");
Serial.print(rtc.getMinute());
Serial.print(":");
Serial.print(rtc.getSecond());
Serial.print("\r\n");
delay(1000);
Serial.print("\r\n");
}
}
-----
Microduino is open-source hardware, compatible with Arduino System, the most popular ecosystem where designers can get everything to build their own applications. All opensource codes can be downloaded from http://wiki.Microduino.cc
Currently, Microduino series already had 3 core modules and around 20 extension boards developed, all modules are designed and tested within Microduino community, and around 700 Microduino fans contribute effort to further develop Microduino series.
- the main chip is PCF8563
- use I2C interface
- on-board EEPROM AT24C32
- open source files [check]
use below codes to drive and test Microduino-RTC module.
necessary library [download]
#include <Wire.h>
#include <Rtc_Pcf8563.h>
//init the real time clock
Rtc_Pcf8563 rtc;
void setup()
{
Serial.begin(9600);
//clear out the registers
rtc.initClock();
//set a time to start with.
//day, weekday, month, century(1=1900, 0=2000), year(0-99)
rtc.setDate(29, 4, 8, 0, 13);
//hr, min, sec
rtc.setTime(00, 21, 0);
}
void loop()
{
//both format functions call the internal getTime() so that the
//formatted strings are at the current time/date.
Serial.println("CODE_1:");
Serial.print(rtc.formatTime());
Serial.print(" ");
Serial.print(rtc.formatDate());
Serial.print("\r\n");
Serial.println("CODE_2:");
Serial.print("20");
Serial.print(rtc.getYear());
Serial.print("/");
Serial.print(rtc.getMonth());
Serial.print("/");
Serial.print(rtc.getDay());
Serial.print(" ");
Serial.print(rtc.getHour());
Serial.print(":");
Serial.print(rtc.getMinute());
Serial.print(":");
Serial.print(rtc.getSecond());
Serial.print("\r\n");
delay(1000);
Serial.print("\r\n");
}
}
-----
Microduino is open-source hardware, compatible with Arduino System, the most popular ecosystem where designers can get everything to build their own applications. All opensource codes can be downloaded from http://wiki.Microduino.cc
Currently, Microduino series already had 3 core modules and around 20 extension boards developed, all modules are designed and tested within Microduino community, and around 700 Microduino fans contribute effort to further develop Microduino series.
Hardware Partlist
Software Part
Software part:
upload program onto your Microdino-Core+ through Microduino-FT232R.
----------------------------------
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11)
//-------font size setting, big|medium|small
#define setFont_L u8g.setFont(u8g_font_7x13)
#define setFont_M u8g.setFont(u8g_font_fixed_v0r)
#define setFont_S u8g.setFont(u8g_font_chikitar)
/*
font:
u8g.setFont(u8g_font_7x13)
u8g.setFont(u8g_font_fixed_v0r);
u8g.setFont(u8g_font_chikitar);
u8g.setFont(u8g_font_osb21);
*/
#include <Wire.h>
#include <Rtc_Pcf8563.h>
Rtc_Pcf8563 rtc;
int time_nian,time_yue,time_ri,time_shi,time_fen,time_miao,time_zhou;
#include <EtherCard.h>
#define SECONDS_IN_DAY 86400
#define START_YEAR 1900
#define TIME_ZONE +8
static int days_in_month[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static byte mymac[] = {
0x00,0x1A,0x4B,0x38,0x0C,0x5C};
byte Ethernet::buffer[700];
static byte ntpServer[] = {
193,204,114,232};
static byte srcPort = 0;
uint32_t timeStamp;
boolean NET_TIME_reply;
#define NET_TIME_INTERVAL 1000
#define TIME_OUT 10000
#define INTERVAL 100000
unsigned long lastTime = 0,TIME_cache = 0;
void setup () {
Serial.begin(57600);
volcdsetup("Load NETWORK",0,15);
delay(1000);
if (!ether.begin(sizeof Ethernet::buffer, mymac))
Serial.println( "Failed to access Ethernet controller");
else
Serial.println("Ethernet controller initialized");
if (!ether.dhcpSetup())
{
Serial.println("Failed to get configuration from DHCP");
volcdsetup("DHCP Error",0,15);
delay(1000);
}
else
{
Serial.println("DHCP configuration done");
volcdsetup("DHCP Succeed",0,15);
delay(1000);
}
ether.printIp("IP Address:\t", ether.myip);
ether.printIp("Netmask:\t", ether.mymask);
ether.printIp("Gateway:\t", ether.gwip);
//-------------------------------------------------------
volcdsetup("Load Net Time",0,15);
delay(1000);
NET_TIME_reply = true;
vonettime();
if(NET_TIME_reply)
{
volcdsetup("Time Sync. Error",0,15);
delay(1000);
}
else
{
vosettime();
volcdsetup("Time Sync. Succeed",0,15);
delay(1000);
}
//-------------------------------------------------------
Serial.println();
}
void loop() {
if(millis() - lastTime > INTERVAL)
{
NET_TIME_reply = true;
vonettime();
if(!NET_TIME_reply)
{
vosettime();
}
lastTime = millis();
}
volcd();
}
void volcd()
{
u8g.firstPage();
do {
setFont_M;
u8g.setPrintPos(0, 9);
u8g.print("TIME:");
u8g.print(rtc.formatDate());
u8g.setPrintPos(0, 20);
u8g.print(rtc.formatTime());
//-----------------------------------------
u8g.setPrintPos(0, 34);
u8g.print("TIME:");
u8g.print("20");
u8g.print(rtc.getYear());
u8g.print("/");
u8g.print(rtc.getMonth());
u8g.print("/");
u8g.print(rtc.getDay());
u8g.setPrintPos(0, 45);
u8g.print(rtc.getHour());
u8g.print(":");
u8g.print(rtc.getMinute());
u8g.print(":");
u8g.print(rtc.getSecond());
String WEEK="";
switch(rtc.getWeekday())
{
case 1:
WEEK="Monday";
break;
case 2:
WEEK="Tuesday";
break;
case 3:
WEEK="Wednesday";
break;
case 4:
WEEK="Thursday";
break;
case 5:
WEEK="Friday";
break;
case 6:
WEEK="Saturday";
break;
case 7:
WEEK="Sunday";
break;
}
u8g.setPrintPos(60, 45);
u8g.print(WEEK);
setFont_S;
u8g.drawFrame(0, 54,128,10);
u8g.setPrintPos(3, 62);
u8g.print("Microduino-RTC v1.0 201307");
}
while( u8g.nextPage() );
}
void vosettime()
{
rtc.initClock(); //set a time to start with.
rtc.setDate(time_ri, time_zhou, time_yue, 0, time_nian%100); //day, weekday, month, century(1=1900, 0=2000), year(0-99)
rtc.setTime(time_shi, time_fen, time_miao); //hr, min, sec
}
void volcdsetup(char* zi,unsigned int x,unsigned int y)
{
u8g.firstPage();
do {
setFont_L;
u8g.setPrintPos(x, y);
u8g.print(zi);
}
while( u8g.nextPage() );
}
void vonettime()
{
uint32_t timeout = millis(); //
while(NET_TIME_reply == true && millis() - timeout < TIME_OUT) //
{
ether.packetLoop(ether.packetReceive());
if(millis() - TIME_cache > NET_TIME_INTERVAL) //
{
ether.ntpRequest(ntpServer, srcPort);
TIME_cache = millis();
NET_TIME_reply = true; //标记发送
}
if(NET_TIME_reply && ether.ntpProcessAnswer(&timeStamp, srcPort)) //
{
printDate(timeStamp + 3600 * TIME_ZONE); //
TIME_cache = millis();
NET_TIME_reply = false; //
}
}
}
void printDate(uint32_t timeStamp) {
unsigned long week = (((timeStamp/3600/24)+1)%7);
Serial.print("Current date and time:");
Serial.println(timeStamp);
unsigned int year = START_YEAR;
while(1) {
uint32_t seconds;
if(isLeapYear(year)) seconds = SECONDS_IN_DAY * 366;
else seconds = SECONDS_IN_DAY * 365;
if(timeStamp >= seconds) {
timeStamp -= seconds;
year++;
}
else break;
}
unsigned int month = 0;
while(1) {
uint32_t seconds = SECONDS_IN_DAY * days_in_month[month];
if(isLeapYear(year) && month == 1) seconds = SECONDS_IN_DAY * 29;
if(timeStamp >= seconds) {
timeStamp -= seconds;
month++;
}
else break;
}
month++;
unsigned int day = 1;
while(1) {
if(timeStamp >= SECONDS_IN_DAY) {
timeStamp -= SECONDS_IN_DAY;
day++;
}
else break;
}
unsigned int hour = timeStamp / 3600;
unsigned int minute = (timeStamp - (uint32_t)hour * 3600) / 60;
unsigned int second = (timeStamp - (uint32_t)hour * 3600) - minute * 60;
Serial.print("week: ");
Serial.println(week);
if(day < 10) Serial.print("0");
Serial.print(day);
Serial.print("/");
if(month < 10) Serial.print("0");
Serial.print(month);
Serial.print("/");
Serial.println(year);
if(hour < 10) Serial.print("0");
Serial.print(hour);
Serial.print(":");
if(minute < 10) Serial.print("0");
Serial.print(minute);
Serial.print(":");
if(second < 10) Serial.print("0");
Serial.println(second);
Serial.println();
time_nian=year;
time_yue=month;
time_ri=day;
time_shi=hour;
time_fen=minute;
time_miao=second;
time_zhou=week;
}
boolean isLeapYear(unsigned int year) {
return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
}
---------------------------
upload program onto your Microdino-Core+ through Microduino-FT232R.
----------------------------------
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE); // HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are SCK = 13 and MOSI = 11)
//-------font size setting, big|medium|small
#define setFont_L u8g.setFont(u8g_font_7x13)
#define setFont_M u8g.setFont(u8g_font_fixed_v0r)
#define setFont_S u8g.setFont(u8g_font_chikitar)
/*
font:
u8g.setFont(u8g_font_7x13)
u8g.setFont(u8g_font_fixed_v0r);
u8g.setFont(u8g_font_chikitar);
u8g.setFont(u8g_font_osb21);
*/
#include <Wire.h>
#include <Rtc_Pcf8563.h>
Rtc_Pcf8563 rtc;
int time_nian,time_yue,time_ri,time_shi,time_fen,time_miao,time_zhou;
#include <EtherCard.h>
#define SECONDS_IN_DAY 86400
#define START_YEAR 1900
#define TIME_ZONE +8
static int days_in_month[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static byte mymac[] = {
0x00,0x1A,0x4B,0x38,0x0C,0x5C};
byte Ethernet::buffer[700];
static byte ntpServer[] = {
193,204,114,232};
static byte srcPort = 0;
uint32_t timeStamp;
boolean NET_TIME_reply;
#define NET_TIME_INTERVAL 1000
#define TIME_OUT 10000
#define INTERVAL 100000
unsigned long lastTime = 0,TIME_cache = 0;
void setup () {
Serial.begin(57600);
volcdsetup("Load NETWORK",0,15);
delay(1000);
if (!ether.begin(sizeof Ethernet::buffer, mymac))
Serial.println( "Failed to access Ethernet controller");
else
Serial.println("Ethernet controller initialized");
if (!ether.dhcpSetup())
{
Serial.println("Failed to get configuration from DHCP");
volcdsetup("DHCP Error",0,15);
delay(1000);
}
else
{
Serial.println("DHCP configuration done");
volcdsetup("DHCP Succeed",0,15);
delay(1000);
}
ether.printIp("IP Address:\t", ether.myip);
ether.printIp("Netmask:\t", ether.mymask);
ether.printIp("Gateway:\t", ether.gwip);
//-------------------------------------------------------
volcdsetup("Load Net Time",0,15);
delay(1000);
NET_TIME_reply = true;
vonettime();
if(NET_TIME_reply)
{
volcdsetup("Time Sync. Error",0,15);
delay(1000);
}
else
{
vosettime();
volcdsetup("Time Sync. Succeed",0,15);
delay(1000);
}
//-------------------------------------------------------
Serial.println();
}
void loop() {
if(millis() - lastTime > INTERVAL)
{
NET_TIME_reply = true;
vonettime();
if(!NET_TIME_reply)
{
vosettime();
}
lastTime = millis();
}
volcd();
}
void volcd()
{
u8g.firstPage();
do {
setFont_M;
u8g.setPrintPos(0, 9);
u8g.print("TIME:");
u8g.print(rtc.formatDate());
u8g.setPrintPos(0, 20);
u8g.print(rtc.formatTime());
//-----------------------------------------
u8g.setPrintPos(0, 34);
u8g.print("TIME:");
u8g.print("20");
u8g.print(rtc.getYear());
u8g.print("/");
u8g.print(rtc.getMonth());
u8g.print("/");
u8g.print(rtc.getDay());
u8g.setPrintPos(0, 45);
u8g.print(rtc.getHour());
u8g.print(":");
u8g.print(rtc.getMinute());
u8g.print(":");
u8g.print(rtc.getSecond());
String WEEK="";
switch(rtc.getWeekday())
{
case 1:
WEEK="Monday";
break;
case 2:
WEEK="Tuesday";
break;
case 3:
WEEK="Wednesday";
break;
case 4:
WEEK="Thursday";
break;
case 5:
WEEK="Friday";
break;
case 6:
WEEK="Saturday";
break;
case 7:
WEEK="Sunday";
break;
}
u8g.setPrintPos(60, 45);
u8g.print(WEEK);
setFont_S;
u8g.drawFrame(0, 54,128,10);
u8g.setPrintPos(3, 62);
u8g.print("Microduino-RTC v1.0 201307");
}
while( u8g.nextPage() );
}
void vosettime()
{
rtc.initClock(); //set a time to start with.
rtc.setDate(time_ri, time_zhou, time_yue, 0, time_nian%100); //day, weekday, month, century(1=1900, 0=2000), year(0-99)
rtc.setTime(time_shi, time_fen, time_miao); //hr, min, sec
}
void volcdsetup(char* zi,unsigned int x,unsigned int y)
{
u8g.firstPage();
do {
setFont_L;
u8g.setPrintPos(x, y);
u8g.print(zi);
}
while( u8g.nextPage() );
}
void vonettime()
{
uint32_t timeout = millis(); //
while(NET_TIME_reply == true && millis() - timeout < TIME_OUT) //
{
ether.packetLoop(ether.packetReceive());
if(millis() - TIME_cache > NET_TIME_INTERVAL) //
{
ether.ntpRequest(ntpServer, srcPort);
TIME_cache = millis();
NET_TIME_reply = true; //标记发送
}
if(NET_TIME_reply && ether.ntpProcessAnswer(&timeStamp, srcPort)) //
{
printDate(timeStamp + 3600 * TIME_ZONE); //
TIME_cache = millis();
NET_TIME_reply = false; //
}
}
}
void printDate(uint32_t timeStamp) {
unsigned long week = (((timeStamp/3600/24)+1)%7);
Serial.print("Current date and time:");
Serial.println(timeStamp);
unsigned int year = START_YEAR;
while(1) {
uint32_t seconds;
if(isLeapYear(year)) seconds = SECONDS_IN_DAY * 366;
else seconds = SECONDS_IN_DAY * 365;
if(timeStamp >= seconds) {
timeStamp -= seconds;
year++;
}
else break;
}
unsigned int month = 0;
while(1) {
uint32_t seconds = SECONDS_IN_DAY * days_in_month[month];
if(isLeapYear(year) && month == 1) seconds = SECONDS_IN_DAY * 29;
if(timeStamp >= seconds) {
timeStamp -= seconds;
month++;
}
else break;
}
month++;
unsigned int day = 1;
while(1) {
if(timeStamp >= SECONDS_IN_DAY) {
timeStamp -= SECONDS_IN_DAY;
day++;
}
else break;
}
unsigned int hour = timeStamp / 3600;
unsigned int minute = (timeStamp - (uint32_t)hour * 3600) / 60;
unsigned int second = (timeStamp - (uint32_t)hour * 3600) - minute * 60;
Serial.print("week: ");
Serial.println(week);
if(day < 10) Serial.print("0");
Serial.print(day);
Serial.print("/");
if(month < 10) Serial.print("0");
Serial.print(month);
Serial.print("/");
Serial.println(year);
if(hour < 10) Serial.print("0");
Serial.print(hour);
Serial.print(":");
if(minute < 10) Serial.print("0");
Serial.print(minute);
Serial.print(":");
if(second < 10) Serial.print("0");
Serial.println(second);
Serial.println();
time_nian=year;
time_yue=month;
time_ri=day;
time_shi=hour;
time_fen=minute;
time_miao=second;
time_zhou=week;
}
boolean isLeapYear(unsigned int year) {
return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
}
---------------------------