Arduino: RTC DS3231 NTP Sync: Difference between revisions
From OnnoCenterWiki
Jump to navigationJump to search
Onnowpurbo (talk | contribs) Created page with "==Source== #include "Wire.h" #include <Time.h> #include <SPI.h> #include <Ethernet.h> #include <EthernetUdp.h> #define DS3231_I2C_ADDRESS 0x68 // Ethernet library configur..." |
Onnowpurbo (talk | contribs) No edit summary |
||
| Line 2: | Line 2: | ||
#include "Wire.h" | #include "Wire.h" | ||
#include <Time.h> | #include <Time.h> | ||
#include <SPI.h> | #include <SPI.h> | ||
#include <Ethernet.h> | #include <Ethernet.h> | ||
#include <EthernetUdp.h> | #include <EthernetUdp.h> | ||
#define DS3231_I2C_ADDRESS 0x68 | #define DS3231_I2C_ADDRESS 0x68 | ||
// Ethernet library configuration | // Ethernet library configuration | ||
byte mac[] = { 0x24, 0x7B, 0xA2, 0x4A, 0x52, 0x10 }; | byte mac[] = { 0x24, 0x7B, 0xA2, 0x4A, 0x52, 0x10 }; | ||
IPAddress timeServer(128, 138, 140, 44 ); // time.nist.gov | IPAddress timeServer(128, 138, 140, 44 ); // time.nist.gov | ||
unsigned int localPort = 8888; | unsigned int localPort = 8888; | ||
const int NTP_PACKET_SIZE= 48; | const int NTP_PACKET_SIZE= 48; | ||
byte packetBuffer[NTP_PACKET_SIZE]; | byte packetBuffer[NTP_PACKET_SIZE]; | ||
EthernetUDP Udp; | EthernetUDP Udp; | ||
void setup() | void setup() | ||
{ | { | ||
// Setup Communication | |||
Wire.begin(); | |||
Serial.begin(9600); | |||
Serial.print("OK Serial\n"); | |||
Ethernet.begin(mac); | |||
Serial.print("OK LAN\n"); | |||
Udp.begin(localPort); | |||
Serial.print("OK Comm\n"); | |||
setSyncInterval(10); // Set seconds between re-sync | |||
setSyncProvider(getNtpTime); | |||
getNtpTime; | |||
Serial.print("OK NTP\n"); | |||
// set the initial time here: | |||
// DS3231 seconds, minutes, hours, day, date, month, year | |||
// setDS3231time(30,33,9, 2 ,28,11,16); | |||
} | } | ||
void loop() | void loop() | ||
{ | { | ||
setSyncProvider(getNtpTime); | |||
// set the initial time here: | |||
// DS3231 seconds, minutes, hours, day, date, month, year | |||
setDS3231time(second(), minute(), hour()+7, 5 , 7, 6, 18); | |||
displayTime(); // display the real-time clock data on the Serial Monitor, | |||
getNtpTime; | |||
// delay(1000); | |||
} | } | ||
/*----------------- DS3231 ----------------------*/ | |||
/*----------------- DS3231 ----------------------*/ | // Convert normal decimal numbers to binary coded decimal | ||
byte decToBcd(byte val) | |||
// Convert normal decimal numbers to binary coded decimal | { | ||
byte decToBcd(byte val) | return ( (val / 10 * 16) + (val % 10) ); | ||
{ | } | ||
// Convert binary coded decimal to normal decimal numbers | |||
} | byte bcdToDec(byte val) | ||
// Convert binary coded decimal to normal decimal numbers | { | ||
byte bcdToDec(byte val) | return ( (val / 16 * 10) + (val % 16) ); | ||
{ | } | ||
} | void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte | ||
dayOfMonth, byte month, byte year) | |||
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte | { | ||
// sets time and date data to DS3231 | |||
{ | Wire.beginTransmission(DS3231_I2C_ADDRESS); | ||
Wire.write(0); // set next input to start at the seconds register | |||
Wire.write(decToBcd(second)); // set seconds | |||
Wire.write(decToBcd(minute)); // set minutes | |||
Wire.write(decToBcd(hour)); // set hours | |||
Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday) | |||
Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31) | |||
Wire.write(decToBcd(month)); // set month | |||
Wire.write(decToBcd(year)); // set year (0 to 99) | |||
Wire.endTransmission(); | |||
} | |||
void readDS3231time(byte *second, | |||
} | byte *minute, | ||
void readDS3231time(byte *second, | byte *hour, | ||
byte *dayOfWeek, | |||
byte *dayOfMonth, | |||
byte *month, | |||
byte *year) | |||
{ | |||
Wire.beginTransmission(DS3231_I2C_ADDRESS); | |||
{ | Wire.write(0); // set DS3231 register pointer to 00h | ||
Wire.endTransmission(); | |||
Wire.requestFrom(DS3231_I2C_ADDRESS, 7); | |||
// request seven bytes of data from DS3231 starting from register 00h | |||
*second = bcdToDec(Wire.read() & 0x7f); | |||
*minute = bcdToDec(Wire.read()); | |||
*hour = bcdToDec(Wire.read() & 0x3f); | |||
*dayOfWeek = bcdToDec(Wire.read()); | |||
*dayOfMonth = bcdToDec(Wire.read()); | |||
*month = bcdToDec(Wire.read()); | |||
*year = bcdToDec(Wire.read()); | |||
} | |||
void displayTime() | |||
} | { | ||
void displayTime() | byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; | ||
{ | // retrieve data from DS3231 | ||
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, | |||
&year); | |||
// send it to the serial monitor | |||
Serial.print(hour, DEC); | |||
// convert the byte variable to a decimal number when displayed | |||
Serial.print(":"); | |||
if (minute < 10) | |||
{ | |||
Serial.print("0"); | |||
} | |||
Serial.print(minute, DEC); | |||
Serial.print(":"); | |||
if (second < 10) | |||
{ | |||
Serial.print("0"); | |||
} | |||
Serial.print(second, DEC); | |||
Serial.print(" "); | |||
Serial.print(dayOfMonth, DEC); | |||
Serial.print("/"); | |||
Serial.print(month, DEC); | |||
Serial.print("/"); | |||
Serial.print(year, DEC); | |||
Serial.print(" Day of week: "); | |||
switch (dayOfWeek) { | |||
case 1: | |||
Serial.println("Sunday"); | |||
break; | |||
case 2: | |||
Serial.println("Monday"); | |||
break; | |||
case 3: | |||
Serial.println("Tuesday"); | |||
break; | |||
case 4: | |||
Serial.println("Wednesday"); | |||
break; | |||
case 5: | |||
Serial.println("Thursday"); | |||
break; | |||
case 6: | |||
Serial.println("Friday"); | |||
break; | |||
case 7: | |||
Serial.println("Saturday"); | |||
break; | |||
} | |||
} | |||
} | |||
/*-------- NTP code ----------*/ | |||
unsigned long getNtpTime() | |||
{ | |||
/*-------- NTP code ----------*/ | sendNTPpacket(timeServer); // send an NTP packet to a time server | ||
delay(500); | |||
unsigned long getNtpTime() | |||
{ | if ( Udp.parsePacket() ) { | ||
Udp.read(packetBuffer,NTP_PACKET_SIZE); | |||
unsigned long hi = word(packetBuffer[40], packetBuffer[41]); | |||
unsigned long low = word(packetBuffer[42], packetBuffer[43]); | |||
unsigned long secsSince1900 = hi << 16 | low; | |||
const unsigned long seventyYears = 2208988800UL; | |||
unsigned long epoch = secsSince1900 - seventyYears; | |||
return epoch; | |||
} | |||
return 0; // return 0 if unable to get the time | |||
} | |||
unsigned long sendNTPpacket(IPAddress& address) | |||
{ | |||
} | memset(packetBuffer, 0, NTP_PACKET_SIZE); // set all bytes in the buffer to 0 | ||
unsigned long sendNTPpacket(IPAddress& address) | // Initialize values needed to form NTP request | ||
{ | packetBuffer[0] = B11100011; // LI, Version, Mode | ||
packetBuffer[1] = 0; // Stratum | |||
packetBuffer[2] = 6; // Max Interval between messages in seconds | |||
packetBuffer[3] = 0xEC; // Clock Precision | |||
// bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset | |||
packetBuffer[12] = 49; // four-byte reference ID identifying | |||
packetBuffer[13] = 0x4E; | |||
packetBuffer[14] = 49; | |||
packetBuffer[15] = 52; | |||
// send the packet requesting a timestamp: | |||
Udp.beginPacket(address, 123); //NTP requests are to port 123 | |||
Udp.write(packetBuffer,NTP_PACKET_SIZE); | |||
Udp.endPacket(); | |||
} | |||
} | |||
Latest revision as of 00:56, 7 June 2018
Source
#include "Wire.h"
#include <Time.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#define DS3231_I2C_ADDRESS 0x68
// Ethernet library configuration
byte mac[] = { 0x24, 0x7B, 0xA2, 0x4A, 0x52, 0x10 };
IPAddress timeServer(128, 138, 140, 44 ); // time.nist.gov
unsigned int localPort = 8888;
const int NTP_PACKET_SIZE= 48;
byte packetBuffer[NTP_PACKET_SIZE];
EthernetUDP Udp;
void setup()
{
// Setup Communication
Wire.begin();
Serial.begin(9600);
Serial.print("OK Serial\n");
Ethernet.begin(mac);
Serial.print("OK LAN\n");
Udp.begin(localPort);
Serial.print("OK Comm\n");
setSyncInterval(10); // Set seconds between re-sync
setSyncProvider(getNtpTime);
getNtpTime;
Serial.print("OK NTP\n");
// set the initial time here:
// DS3231 seconds, minutes, hours, day, date, month, year
// setDS3231time(30,33,9, 2 ,28,11,16);
}
void loop()
{
setSyncProvider(getNtpTime);
// set the initial time here:
// DS3231 seconds, minutes, hours, day, date, month, year
setDS3231time(second(), minute(), hour()+7, 5 , 7, 6, 18);
displayTime(); // display the real-time clock data on the Serial Monitor,
getNtpTime;
// delay(1000);
}
/*----------------- DS3231 ----------------------*/
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val / 10 * 16) + (val % 10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val / 16 * 10) + (val % 16) );
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
// sets time and date data to DS3231
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set next input to start at the seconds register
Wire.write(decToBcd(second)); // set seconds
Wire.write(decToBcd(minute)); // set minutes
Wire.write(decToBcd(hour)); // set hours
Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
Wire.write(decToBcd(month)); // set month
Wire.write(decToBcd(year)); // set year (0 to 99)
Wire.endTransmission();
}
void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set DS3231 register pointer to 00h
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
// request seven bytes of data from DS3231 starting from register 00h
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
void displayTime()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
// retrieve data from DS3231
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
&year);
// send it to the serial monitor
Serial.print(hour, DEC);
// convert the byte variable to a decimal number when displayed
Serial.print(":");
if (minute < 10)
{
Serial.print("0");
}
Serial.print(minute, DEC);
Serial.print(":");
if (second < 10)
{
Serial.print("0");
}
Serial.print(second, DEC);
Serial.print(" ");
Serial.print(dayOfMonth, DEC);
Serial.print("/");
Serial.print(month, DEC);
Serial.print("/");
Serial.print(year, DEC);
Serial.print(" Day of week: ");
switch (dayOfWeek) {
case 1:
Serial.println("Sunday");
break;
case 2:
Serial.println("Monday");
break;
case 3:
Serial.println("Tuesday");
break;
case 4:
Serial.println("Wednesday");
break;
case 5:
Serial.println("Thursday");
break;
case 6:
Serial.println("Friday");
break;
case 7:
Serial.println("Saturday");
break;
}
}
/*-------- NTP code ----------*/
unsigned long getNtpTime()
{
sendNTPpacket(timeServer); // send an NTP packet to a time server
delay(500);
if ( Udp.parsePacket() ) {
Udp.read(packetBuffer,NTP_PACKET_SIZE);
unsigned long hi = word(packetBuffer[40], packetBuffer[41]);
unsigned long low = word(packetBuffer[42], packetBuffer[43]);
unsigned long secsSince1900 = hi << 16 | low;
const unsigned long seventyYears = 2208988800UL;
unsigned long epoch = secsSince1900 - seventyYears;
return epoch;
}
return 0; // return 0 if unable to get the time
}
unsigned long sendNTPpacket(IPAddress& address)
{
memset(packetBuffer, 0, NTP_PACKET_SIZE); // set all bytes in the buffer to 0
// Initialize values needed to form NTP request
packetBuffer[0] = B11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum
packetBuffer[2] = 6; // Max Interval between messages in seconds
packetBuffer[3] = 0xEC; // Clock Precision
// bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset
packetBuffer[12] = 49; // four-byte reference ID identifying
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// send the packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
}