Showing posts with label sync. Show all posts
Showing posts with label sync. Show all posts
2017/05/14
NTP Server Synchronized LCD DS1307 RTC Clock
Requirements:
1. Arduino Uno R3
2. RTC (DS1307) Sensor Shield
3. W5100 Ethernet Shield
4. LCD Keypad Shield
Schetch:
/*
* NTPSynchronizedRTC20170514.ino
*/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t
#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,4,5,6,7);
char dayOfWeek[9][4] = {"", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
time_t t;
int displayAtSecond;
// timeZoneOffset = (Time Zone) * 3600L eg. (+8) * 3600L = 28800L for Taipei, Taiwan
const long timeZoneOffset = 28800L;
// sync to NTP server every "ntpSyncInterval" seconds, set to 1 hour or more to be reasonable
unsigned long ntpSyncInterval = 3600;
// adjust the sync latency with computer NTP client in seconds
unsigned long syncLatency = 0;
// Enter a MAC address for your controller bellow.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(192, 168, 1, 123); // LAN NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// keep track of how long ago we updated the NTP server
unsigned long ntpLastUpdate = 0;
void setup() {
Serial.begin(115200);
lcd.begin(16,2);
lcd.print("*cheaphousetek*");
lcd.setCursor(0,1);
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
lcd.print("Unable to sync");
else
lcd.print("Sync system time ");
displayAtSecond = second();
delay(2000);
lcd.clear();
// start Ethernet and UDP
if (Ethernet.begin(mac) == 0) {
lcd.setCursor(0,1);
lcd.print("DHCP failed");
for (;;);
}
Udp.begin(localPort);
}
void loop()
{
if ((now() - ntpLastUpdate) >= ntpSyncInterval) {
ntpSyncDS1307();
// clear seconds displayed once a second when sync is needed, cause seconds blink to notify checking the network status
lcd.setCursor(9, 1);
lcd.print(" ");
}
// for LCD shield to disp date, day of the week, time and temperature once a second
t = now();
if (displayAtSecond != second(t)) {
digitalClockDisplay();
displayAtSecond = second(t);
}
}
void digitalClockDisplay(){
// digital clock display of the time
dateDisplay();
weekdayDisplay();
timeDisplay();
// display seconds since last NTP update
lcd.setCursor(9, 1);
lcd.print(now()-ntpLastUpdate);
// Serial.print(now());
// Serial.print(" ");
// Serial.println(ntpLastUpdate);
}
void dateDisplay() {
lcd.setCursor(0,0);
lcd.print(year(t));
lcd.print('-');
if (month(t) < 10) {
lcd.print('0');
}
lcd.print(month(t));
lcd.print('-');
if (day(t) < 10) {
lcd.print('0');
}
lcd.print(day(t));
// lcd.print(' ');
}
void weekdayDisplay() {
lcd.setCursor(11,0);
lcd.print(dayOfWeek[weekday()]);
}
void timeDisplay() {
lcd.setCursor(0,1);
if (hour(t) < 10) {
lcd.print('0');
}
lcd.print(hour(t));
lcd.print(':');
if (minute(t) < 10) {
lcd.print('0');
}
lcd.print(minute(t));
lcd.print(':');
if (second(t) < 10) {
lcd.print('0');
}
lcd.print(second(t));
// lcd.print(' ');
}
void ntpSyncDS1307() {
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a replay is available
delay(100);
if (Udp.parsePacket()) {
// We've received a packet, read the data from it
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
// the timstamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900)
unsigned long secsSince1900 = highWord << 16 | lowWord;
// now convert NTP time into everyday time:
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800L;
// substract seventy years:
unsigned long epoch = secsSince1900 - seventyYears + timeZoneOffset + syncLatency;
setTime(epoch);
RTC.set(epoch);
ntpLastUpdate = now();
// clear seconds displayed once ntp sync succeeded
lcd.setCursor(9, 1);
lcd.print(" ");
}
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address) {
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clodk
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123);
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
2013/10/11
NTP Server Synchronized DS1307 RTC Analog Datalogger With File Download Server
The sketch is an extension based on NTP Synchronized Analog Datalogger post on Aug. 21, 2013 by adding web interface file download server function. All datalogger files are saved in the root directory of the microSD card. With the network infrastructure settled and router proper configured, the datalogger files on the microSD can be download by any device with web browser built in from anywhere.
Requirements
1. Arduino Mega2560 R3
2. W5100 Ethernet Shield
3. RTC Sensor Shield (designed to stack on Arduino Uno cannot stack on Mega2560)
4. LM35 Temperature Sensor Breakout connect to RTC Sensor Shield A3
Connection
File Download Server Screen
Sketch
/*
* NTPSynchronizedRTCAnalogDataLoggerWithFileDownloadServer.ino
*
* This sketch calls alarm functions at 7:30 am and at 7:30 pm (19:30)
* and sync DS1307, Arduino system time
*
* At startup the system time read from DS1307, then both sync with NTP
*
* Modified by Befun Hung on Oct. 11, 2013 based on NTPSyncronizedAnalogDataLogger.ino
* by adding web interface file download server function,
* so that files can be downloaded from the remote site the data logger installed
*/
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <TimeAlarms.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SD.h>
#define analogSensorStart 3 // sensor connect to A3
#define analogSensorEnd 3 // sensor connect to A3
// Enter a MAC address for your controller bellow.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
byte ip[] = {192, 168, 1, 177};
unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(140, 112, 2, 188); // ntp2.ntu.edu.tw NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// timeZoneOffset = (Time Zone) * 3600L eg. (+8) * 3600L = 28800L for Taipei, Taiwan
const long timeZoneOffset = 28800L;
// sync to NTP server every "ntpSyncTime" seconds, set to 1 hour or more to be reasonable
unsigned long ntpSyncTime = 21600;
// adjust the sync latency with computer NTP client in seconds
unsigned int syncLatency = 2;
// sd card variables
File file; // test file
const uint8_t SD_CS = 4; // SD chip select
String file_name = ""; // file name should not prefix with "prefix_word"
char fn[] = "MMDDHHMM.CSV";
int i=0;
int displayAtSecond = 0;
time_t t;
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
// for list files
File root;
File webFile;
//------------------------------------------------------------------------------
// call back for file timestamps
void dateTime(uint16_t* date, uint16_t* time) {
time_t timeStamp = now();
// return date using FAT_DATE macro to format fields
*date = FAT_DATE(year(timeStamp), month(timeStamp), day(timeStamp));
// return time using FAT_TIME macro to format fields
*time = FAT_TIME(hour(timeStamp), minute(timeStamp), second(timeStamp));
}
//------------------------------------------------------------------------------
void setup()
{
Serial.begin(9600);
Wire.begin();
setSyncProvider(RTC.get); // the function to get the time from the RTC
if (timeStatus() != timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
// set date time callback function
SdFile::dateTimeCallback(dateTime);
// display RTC time
Serial.print(year());
Serial.print('-');
Serial.print(month());
Serial.print('-');
Serial.print(day());
Serial.print(' ');
Serial.print(hour());
Serial.print(':');
Serial.print(minute());
Serial.print(':');
Serial.print(second());
Serial.println(" --- RTC Time");
// create the alarms
Alarm.alarmRepeat(7,30,0, ntpSyncDS1307); // 7:30am every day
Alarm.alarmRepeat(19,30,0, ntpSyncDS1307); // 7:30pm every day
// start Ethernet and UDP
Ethernet.begin(mac, ip);
Udp.begin(localPort);
ntpSyncDS1307();
// process file name string
t = now();
if (month(t) < 10) {
file_name = String(file_name + '0' + String(month(t), DEC));
}
else {
file_name = String(file_name +String(month(t), DEC));
}
if (day(t) < 10) {
file_name = String(file_name + '0' + String(day(t), DEC));
}
else {
file_name = String(file_name +String(day(t), DEC));
}
if (hour(t) < 10) {
file_name = String(file_name + '0' + String(hour(t), DEC));
}
else {
file_name = String(file_name +String(hour(t), DEC));
}
if (minute(t) < 10) {
file_name = String(file_name + '0' + String(minute(t), DEC));
}
else {
file_name = String(file_name +String(minute(t), DEC));
}
file_name = String(file_name + ".CSV");
for (i=0;i<=file_name.length();i++) {
fn[i] = file_name.charAt(i);
}
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
if (!SD.begin(SD_CS)) {
Serial.println("SD failed");
// while(1);
}
// start the web server:
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
root = SD.open("/");
}
void loop(){
webServer();
t = now();
if (displayAtSecond != second(t)) {
analogSensorDataLogger();
displayAtSecond = second(t);
}
Alarm.delay(100); // wait 1/10 second between cycles
}
// functions to be called when an alarm triggers:
void ntpSyncDS1307() {
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a replay is available
delay(1000);
if (Udp.parsePacket()) {
// We've received a packet, read the data from it
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
// the timstamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900)
unsigned long secsSince1900 = highWord << 16 | lowWord;
// now convert NTP time into everyday time:
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800L;
// substract seventy years:
unsigned long epoch = secsSince1900 - seventyYears + timeZoneOffset + syncLatency;
setTime(epoch);
RTC.set(epoch);
// output time and "Sync OK" message every sync
Serial.print(year());
Serial.print('-');
Serial.print(month());
Serial.print('-');
Serial.print(day());
Serial.print(' ');
Serial.print(hour());
Serial.print(':');
Serial.print(minute());
Serial.print(':');
Serial.print(second());
Serial.print(' ');
Serial.println("Sync OK");
}
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address) {
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clodk
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123);
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
void analogSensorDataLogger() {
String data_string = "";
data_string = String(year(t), DEC);
data_string += "/";
if (month(t) < 10) {
data_string = String(data_string + '0' + String(month(t), DEC));
}
else {
data_string = String(data_string +String(month(t), DEC));
}
data_string += "/";
if (day(t) < 10) {
data_string = String(data_string + '0' + String(day(t), DEC));
}
else {
data_string = String(data_string +String(day(t), DEC));
}
data_string += " ";
if (hour(t) < 10) {
data_string = String(data_string + '0' + String(hour(t), DEC));
}
else {
data_string = String(data_string +String(hour(t), DEC));
}
data_string += ":";
if (minute(t) < 10) {
data_string = String(data_string + '0' + String(minute(t), DEC));
}
else {
data_string = String(data_string +String(minute(t), DEC));
}
data_string += ":";
if (second(t) < 10) {
data_string = String(data_string + '0' + String(second(t), DEC));
}
else {
data_string = String(data_string +String(second(t), DEC));
}
data_string += ",";
//read sensor value from A0-A3 and append to the string
for (int analogPin = analogSensorStart; analogPin <= analogSensorEnd; analogPin++)
{
int sensor = analogRead(analogPin);
data_string += String(sensor);
if (analogPin < analogSensorEnd) {
data_string += ",";
}
}
file = SD.open(fn, FILE_WRITE);
if (file) {
file.println(data_string);
file.close();
Serial.println(data_string);
}
else {
Serial.print("error opening ");
Serial.println(fn);
}
}
#define BUFSIZ 100
void webServer()
{
char clientline[BUFSIZ];
int index = 0;
EthernetClient client = server.available();
if (client) {
// an http request ends with a blank line
boolean current_line_is_blank = true;
// reset the input buffer
index = 0;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// If it isn't a new line, add the character to the buffer
if (c != '\n' && c != '\r') {
clientline[index] = c;
index++;
// are we too big for the buffer? start tossing out data
if (index >= BUFSIZ)
index = BUFSIZ -1;
// continue to read more data!
continue;
}
// got a \n or \r new line, which means the string is done
clientline[index] = 0;
// Print it out for debugging
Serial.print("clientline: ");
Serial.println(clientline);
// Look for substring such as a request to get the root file
if (strstr(clientline, "GET / ") != 0) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
// print all the files, use a helper to keep it clean
client.println("<h2>Files:</h2>");
int numTabs;
root.rewindDirectory();
while (true) {
File entry = root.openNextFile();
if (! entry) {
// no more files
client.println("** no more files **");
client.println("<br />");
break;
}
client.print("<a href=\"");
client.print(entry.name());
client.print("\">");
client.print(entry.name());
client.print("</a>");
client.print(" ");
client.print(entry.size(), DEC);
client.print("<br />");
entry.close();
}
} else if (strstr(clientline, "GET /") != 0) {
// this time no space after the /, so a sub-file!
char *filename;
filename = clientline + 5; // look after the "GET /" (5 chars)
// a little trick, look for the " HTTP/1.1" string and
// turn the first character of the substring into a 0 to clear it out.
(strstr(clientline, " HTTP"))[0] = 0;
// print the file we want
Serial.print("filename: ");
Serial.print(filename);
Serial.println(" Opened!");
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/plain");
client.println();
webFile = SD.open(filename);
if (webFile) {
while (webFile.available()) {
client.write(webFile.read());
}
webFile.close();
}
} else {
// everything else is a 404
client.println("HTTP/1.1 404 Not Found");
client.println("Content-Type: text/html");
client.println();
client.println("<h2>File Not Found!</h2>");
}
break;
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
}
Requirements
1. Arduino Mega2560 R3
2. W5100 Ethernet Shield
3. RTC Sensor Shield (designed to stack on Arduino Uno cannot stack on Mega2560)
4. LM35 Temperature Sensor Breakout connect to RTC Sensor Shield A3
Connection
Sketch
/*
* NTPSynchronizedRTCAnalogDataLoggerWithFileDownloadServer.ino
*
* This sketch calls alarm functions at 7:30 am and at 7:30 pm (19:30)
* and sync DS1307, Arduino system time
*
* At startup the system time read from DS1307, then both sync with NTP
*
* Modified by Befun Hung on Oct. 11, 2013 based on NTPSyncronizedAnalogDataLogger.ino
* by adding web interface file download server function,
* so that files can be downloaded from the remote site the data logger installed
*/
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <TimeAlarms.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SD.h>
#define analogSensorStart 3 // sensor connect to A3
#define analogSensorEnd 3 // sensor connect to A3
// Enter a MAC address for your controller bellow.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
byte ip[] = {192, 168, 1, 177};
unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(140, 112, 2, 188); // ntp2.ntu.edu.tw NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// timeZoneOffset = (Time Zone) * 3600L eg. (+8) * 3600L = 28800L for Taipei, Taiwan
const long timeZoneOffset = 28800L;
// sync to NTP server every "ntpSyncTime" seconds, set to 1 hour or more to be reasonable
unsigned long ntpSyncTime = 21600;
// adjust the sync latency with computer NTP client in seconds
unsigned int syncLatency = 2;
// sd card variables
File file; // test file
const uint8_t SD_CS = 4; // SD chip select
String file_name = ""; // file name should not prefix with "prefix_word"
char fn[] = "MMDDHHMM.CSV";
int i=0;
int displayAtSecond = 0;
time_t t;
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
// for list files
File root;
File webFile;
//------------------------------------------------------------------------------
// call back for file timestamps
void dateTime(uint16_t* date, uint16_t* time) {
time_t timeStamp = now();
// return date using FAT_DATE macro to format fields
*date = FAT_DATE(year(timeStamp), month(timeStamp), day(timeStamp));
// return time using FAT_TIME macro to format fields
*time = FAT_TIME(hour(timeStamp), minute(timeStamp), second(timeStamp));
}
//------------------------------------------------------------------------------
void setup()
{
Serial.begin(9600);
Wire.begin();
setSyncProvider(RTC.get); // the function to get the time from the RTC
if (timeStatus() != timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
// set date time callback function
SdFile::dateTimeCallback(dateTime);
// display RTC time
Serial.print(year());
Serial.print('-');
Serial.print(month());
Serial.print('-');
Serial.print(day());
Serial.print(' ');
Serial.print(hour());
Serial.print(':');
Serial.print(minute());
Serial.print(':');
Serial.print(second());
Serial.println(" --- RTC Time");
// create the alarms
Alarm.alarmRepeat(7,30,0, ntpSyncDS1307); // 7:30am every day
Alarm.alarmRepeat(19,30,0, ntpSyncDS1307); // 7:30pm every day
// start Ethernet and UDP
Ethernet.begin(mac, ip);
Udp.begin(localPort);
ntpSyncDS1307();
// process file name string
t = now();
if (month(t) < 10) {
file_name = String(file_name + '0' + String(month(t), DEC));
}
else {
file_name = String(file_name +String(month(t), DEC));
}
if (day(t) < 10) {
file_name = String(file_name + '0' + String(day(t), DEC));
}
else {
file_name = String(file_name +String(day(t), DEC));
}
if (hour(t) < 10) {
file_name = String(file_name + '0' + String(hour(t), DEC));
}
else {
file_name = String(file_name +String(hour(t), DEC));
}
if (minute(t) < 10) {
file_name = String(file_name + '0' + String(minute(t), DEC));
}
else {
file_name = String(file_name +String(minute(t), DEC));
}
file_name = String(file_name + ".CSV");
for (i=0;i<=file_name.length();i++) {
fn[i] = file_name.charAt(i);
}
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
if (!SD.begin(SD_CS)) {
Serial.println("SD failed");
// while(1);
}
// start the web server:
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
root = SD.open("/");
}
void loop(){
webServer();
t = now();
if (displayAtSecond != second(t)) {
analogSensorDataLogger();
displayAtSecond = second(t);
}
Alarm.delay(100); // wait 1/10 second between cycles
}
// functions to be called when an alarm triggers:
void ntpSyncDS1307() {
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a replay is available
delay(1000);
if (Udp.parsePacket()) {
// We've received a packet, read the data from it
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
// the timstamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900)
unsigned long secsSince1900 = highWord << 16 | lowWord;
// now convert NTP time into everyday time:
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800L;
// substract seventy years:
unsigned long epoch = secsSince1900 - seventyYears + timeZoneOffset + syncLatency;
setTime(epoch);
RTC.set(epoch);
// output time and "Sync OK" message every sync
Serial.print(year());
Serial.print('-');
Serial.print(month());
Serial.print('-');
Serial.print(day());
Serial.print(' ');
Serial.print(hour());
Serial.print(':');
Serial.print(minute());
Serial.print(':');
Serial.print(second());
Serial.print(' ');
Serial.println("Sync OK");
}
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address) {
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clodk
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123);
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
void analogSensorDataLogger() {
String data_string = "";
data_string = String(year(t), DEC);
data_string += "/";
if (month(t) < 10) {
data_string = String(data_string + '0' + String(month(t), DEC));
}
else {
data_string = String(data_string +String(month(t), DEC));
}
data_string += "/";
if (day(t) < 10) {
data_string = String(data_string + '0' + String(day(t), DEC));
}
else {
data_string = String(data_string +String(day(t), DEC));
}
data_string += " ";
if (hour(t) < 10) {
data_string = String(data_string + '0' + String(hour(t), DEC));
}
else {
data_string = String(data_string +String(hour(t), DEC));
}
data_string += ":";
if (minute(t) < 10) {
data_string = String(data_string + '0' + String(minute(t), DEC));
}
else {
data_string = String(data_string +String(minute(t), DEC));
}
data_string += ":";
if (second(t) < 10) {
data_string = String(data_string + '0' + String(second(t), DEC));
}
else {
data_string = String(data_string +String(second(t), DEC));
}
data_string += ",";
//read sensor value from A0-A3 and append to the string
for (int analogPin = analogSensorStart; analogPin <= analogSensorEnd; analogPin++)
{
int sensor = analogRead(analogPin);
data_string += String(sensor);
if (analogPin < analogSensorEnd) {
data_string += ",";
}
}
file = SD.open(fn, FILE_WRITE);
if (file) {
file.println(data_string);
file.close();
Serial.println(data_string);
}
else {
Serial.print("error opening ");
Serial.println(fn);
}
}
#define BUFSIZ 100
void webServer()
{
char clientline[BUFSIZ];
int index = 0;
EthernetClient client = server.available();
if (client) {
// an http request ends with a blank line
boolean current_line_is_blank = true;
// reset the input buffer
index = 0;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// If it isn't a new line, add the character to the buffer
if (c != '\n' && c != '\r') {
clientline[index] = c;
index++;
// are we too big for the buffer? start tossing out data
if (index >= BUFSIZ)
index = BUFSIZ -1;
// continue to read more data!
continue;
}
// got a \n or \r new line, which means the string is done
clientline[index] = 0;
// Print it out for debugging
Serial.print("clientline: ");
Serial.println(clientline);
// Look for substring such as a request to get the root file
if (strstr(clientline, "GET / ") != 0) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
// print all the files, use a helper to keep it clean
client.println("<h2>Files:</h2>");
int numTabs;
root.rewindDirectory();
while (true) {
File entry = root.openNextFile();
if (! entry) {
// no more files
client.println("** no more files **");
client.println("<br />");
break;
}
client.print("<a href=\"");
client.print(entry.name());
client.print("\">");
client.print(entry.name());
client.print("</a>");
client.print(" ");
client.print(entry.size(), DEC);
client.print("<br />");
entry.close();
}
} else if (strstr(clientline, "GET /") != 0) {
// this time no space after the /, so a sub-file!
char *filename;
filename = clientline + 5; // look after the "GET /" (5 chars)
// a little trick, look for the " HTTP/1.1" string and
// turn the first character of the substring into a 0 to clear it out.
(strstr(clientline, " HTTP"))[0] = 0;
// print the file we want
Serial.print("filename: ");
Serial.print(filename);
Serial.println(" Opened!");
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/plain");
client.println();
webFile = SD.open(filename);
if (webFile) {
while (webFile.available()) {
client.write(webFile.read());
}
webFile.close();
}
} else {
// everything else is a 404
client.println("HTTP/1.1 404 Not Found");
client.println("Content-Type: text/html");
client.println();
client.println("<h2>File Not Found!</h2>");
}
break;
}
}
// give the web browser time to receive the data
delay(1);
client.stop();
}
}
Labels:
Breakout,
Data logger,
Datalogger,
Download,
DS1307,
File,
Interface,
LM35,
NTP,
Real Time Clock,
RTC,
Sensor,
Server,
sync,
Synchronized,
Temperature,
TimeAlarms,
TimeAlarms.h,
Web
2013/08/21
NTP Server Synchronized DS1307 RTC Analog Data Logger
This sketch combine analog sensor data logger on Aug. 15, 2013 and NTP server synchronized DS1307 RTC using TimeAlarm library on Aug. 17, 2013.
The shetch use fixed IP, so DHCP server is not needed in the local area network.
Because the RTC is synchronized with NTP server, so the data logger keeps the time within 5 seconds. The NTP sync may fail sometimes depending on the network conditions.
Sketch
/*
* NTPSynchronizedAnalogDataLogger.ino
*
* This sketch calls alarm functions at 7:30 am and at 7:30 pm (19:30)
* and sync DS1307, Arduino system time
*
* At startup the system time read from DS1307, then both sync with NTP
*/
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <TimeAlarms.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SD.h>
#define analogSensorStart 3 // sensor connect to A3
#define analogSensorEnd 3 // sensor connect to A3
// Enter a MAC address for your controller bellow.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
byte ip[] = {192, 168, 1, 177};
unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(140, 112, 2, 188); // ntp2.ntu.edu.tw NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// timeZoneOffset = (Time Zone) * 3600L eg. (+8) * 3600L = 28800L for Taipei, Taiwan
const long timeZoneOffset = 28800L;
// sync to NTP server every "ntpSyncTime" seconds, set to 1 hour or more to be reasonable
unsigned long ntpSyncTime = 21600;
// adjust the sync latency with computer NTP client in seconds
unsigned int syncLatency = 2;
// sd card variables
File file; // test file
const uint8_t SD_CS = 4; // SD chip select
String file_name = ""; // file name should not prefix with "prefix_word"
char fn[] = "MMDDHHMM.CSV";
int i=0;
int displayAtSecond = 0;
time_t t;
//------------------------------------------------------------------------------
// call back for file timestamps
void dateTime(uint16_t* date, uint16_t* time) {
time_t timeStamp = now();
// return date using FAT_DATE macro to format fields
*date = FAT_DATE(year(timeStamp), month(timeStamp), day(timeStamp));
// return time using FAT_TIME macro to format fields
*time = FAT_TIME(hour(timeStamp), minute(timeStamp), second(timeStamp));
}
//------------------------------------------------------------------------------
void setup()
{
Serial.begin(9600);
Wire.begin();
setSyncProvider(RTC.get); // the function to get the time from the RTC
if (timeStatus() != timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
// set date time callback function
SdFile::dateTimeCallback(dateTime);
// display RTC time
Serial.print(year());
Serial.print('-');
Serial.print(month());
Serial.print('-');
Serial.print(day());
Serial.print(' ');
Serial.print(hour());
Serial.print(':');
Serial.print(minute());
Serial.print(':');
Serial.print(second());
Serial.println(" --- RTC Time");
// create the alarms
Alarm.alarmRepeat(7,30,0, ntpSyncDS1307); // 7:30am every day
Alarm.alarmRepeat(19,30,0, ntpSyncDS1307); // 7:30pm every day
// start Ethernet and UDP
Ethernet.begin(mac, ip);
Udp.begin(localPort);
// Serial.println("connect to ntp server");
ntpSyncDS1307();
// process file name string
t = now();
if (month(t) < 10) {
file_name = String(file_name + '0' + String(month(t), DEC));
}
else {
file_name = String(file_name +String(month(t), DEC));
}
if (day(t) < 10) {
file_name = String(file_name + '0' + String(day(t), DEC));
}
else {
file_name = String(file_name +String(day(t), DEC));
}
if (hour(t) < 10) {
file_name = String(file_name + '0' + String(hour(t), DEC));
}
else {
file_name = String(file_name +String(hour(t), DEC));
}
if (minute(t) < 10) {
file_name = String(file_name + '0' + String(minute(t), DEC));
}
else {
file_name = String(file_name +String(minute(t), DEC));
}
file_name = String(file_name + ".CSV");
for (i=0;i<=file_name.length();i++) {
fn[i] = file_name.charAt(i);
}
Serial.print("File Name: ");
Serial.println(fn);
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
if (!SD.begin(SD_CS)) {
Serial.println("SD failed");
// while(1);
}
}
void loop(){
t = now();
if (displayAtSecond != second(t)) {
analogSensorDataLogger();
displayAtSecond = second(t);
}
Alarm.delay(100); // wait 1/10 second between cycles
}
// functions to be called when an alarm triggers:
void ntpSyncDS1307() {
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a replay is available
delay(1000);
if (Udp.parsePacket()) {
// We've received a packet, read the data from it
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
// the timstamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900)
unsigned long secsSince1900 = highWord << 16 | lowWord;
// now convert NTP time into everyday time:
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800L;
// substract seventy years:
unsigned long epoch = secsSince1900 - seventyYears + timeZoneOffset + syncLatency;
setTime(epoch);
RTC.set(epoch);
// output time and "Sync OK" message every sync
Serial.print(year());
Serial.print('-');
Serial.print(month());
Serial.print('-');
Serial.print(day());
Serial.print(' ');
Serial.print(hour());
Serial.print(':');
Serial.print(minute());
Serial.print(':');
Serial.print(second());
Serial.print(' ');
Serial.println("Sync OK");
}
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address) {
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clodk
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123);
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
void analogSensorDataLogger() {
String data_string = "";
data_string = String(year(t), DEC);
data_string += "/";
if (month(t) < 10) {
data_string = String(data_string + '0' + String(month(t), DEC));
}
else {
data_string = String(data_string +String(month(t), DEC));
}
data_string += "/";
if (day(t) < 10) {
data_string = String(data_string + '0' + String(day(t), DEC));
}
else {
data_string = String(data_string +String(day(t), DEC));
}
data_string += " ";
if (hour(t) < 10) {
data_string = String(data_string + '0' + String(hour(t), DEC));
}
else {
data_string = String(data_string +String(hour(t), DEC));
}
data_string += ":";
if (minute(t) < 10) {
data_string = String(data_string + '0' + String(minute(t), DEC));
}
else {
data_string = String(data_string +String(minute(t), DEC));
}
data_string += ":";
if (second(t) < 10) {
data_string = String(data_string + '0' + String(second(t), DEC));
}
else {
data_string = String(data_string +String(second(t), DEC));
}
data_string += ",";
//read sensor value from A0-A3 and append to the string
for (int analogPin = analogSensorStart; analogPin <= analogSensorEnd; analogPin++)
{
int sensor = analogRead(analogPin);
data_string += String(sensor);
if (analogPin < analogSensorEnd) {
data_string += ",";
}
}
file = SD.open(fn, FILE_WRITE);
if (file) {
file.println(data_string);
file.close();
Serial.println(data_string);
}
else {
Serial.print("error opening ");
Serial.println(fn);
}
}
Labels:
Analog,
Arduino,
Data,
Datalogger,
DS1307,
Freeduino,
Library,
LM35,
Logger,
MicroSD,
NTP,
Real Time Clock,
RTC,
SD,
sync,
Synchronize,
Temperature,
Time,
TimeAlarms.h
2013/08/17
NTP Server Synchronized DS1307 RTC Using TimeAlarms Library
This sketch calls alarm functions at 7:30 am and at 7:30 pm (19:30) and sync DS1307, Arduino system time. At startup the Arduino system time is synchronized with DS1307. The sketch output time and "Sync OK" message to Arduino serial monitor at every successful synchronization.
A DHCP server is needed.
Requirements
1. Arduino Uno R3
2. W5100 Ethernet Shield
3. RTC Sensor Shield
Schetch
/*
* TimeAlarmNTPSyncRTC.ino
*
* This sketch calls alarm functions at 7:30 am and at 7:30 pm (19:30)
* and sync DS1307, Arduino system time
*
* At startup the time is sync with DS1307
*/
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <TimeAlarms.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
// Enter a MAC address for your controller bellow.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(140, 112, 2, 188); // ntp2.ntu.edu.tw NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// timeZoneOffset = (Time Zone) * 3600L eg. (+8) * 3600L = 28800L for Taipei, Taiwan
const long timeZoneOffset = 28800L;
// sync to NTP server every "ntpSyncTime" seconds, set to 1 hour or more to be reasonable
unsigned long ntpSyncTime = 21600;
// keep track of how long ago we updated the NTP server
// unsigned long ntpLastUpdate = 0;
// adjust the sync latency with computer NTP client in seconds
unsigned int syncLatency = 2;
void setup()
{
Serial.begin(9600);
setSyncProvider(RTC.get); // the function to get the time from the RTC
// create the alarms
Alarm.alarmRepeat(7,30,0, ntpSyncDS1307); // 7:30am every day
Alarm.alarmRepeat(19,30,0, ntpSyncDS1307); // 7:30pm every day
// start Ethernet and UDP
if (Ethernet.begin(mac) == 0) {
for (;;);
}
Udp.begin(localPort);
ntpSyncDS1307();
}
void loop(){
Alarm.delay(100); // wait 1/10 second between cycles
}
// functions to be called when an alarm triggers:
void ntpSyncDS1307() {
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a replay is available
delay(1000);
if (Udp.parsePacket()) {
// We've received a packet, read the data from it
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
// the timstamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900)
unsigned long secsSince1900 = highWord << 16 | lowWord;
// now convert NTP time into everyday time:
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800L;
// substract seventy years:
unsigned long epoch = secsSince1900 - seventyYears + timeZoneOffset + syncLatency;
setTime(epoch);
RTC.set(epoch);
// ntpLastUpdate = now();
// output time and "Sync OK" message every sync
Serial.print(year());
Serial.print('-');
Serial.print(month());
Serial.print('-');
Serial.print(day());
Serial.print(' ');
Serial.print(hour());
Serial.print(':');
Serial.print(minute());
Serial.print(':');
Serial.print(second());
Serial.print(' ');
Serial.println("Sync OK");
}
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address) {
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clodk
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123);
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
A DHCP server is needed.
Requirements
1. Arduino Uno R3
2. W5100 Ethernet Shield
3. RTC Sensor Shield
Schetch
/*
* TimeAlarmNTPSyncRTC.ino
*
* This sketch calls alarm functions at 7:30 am and at 7:30 pm (19:30)
* and sync DS1307, Arduino system time
*
* At startup the time is sync with DS1307
*/
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <TimeAlarms.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
// Enter a MAC address for your controller bellow.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(140, 112, 2, 188); // ntp2.ntu.edu.tw NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// timeZoneOffset = (Time Zone) * 3600L eg. (+8) * 3600L = 28800L for Taipei, Taiwan
const long timeZoneOffset = 28800L;
// sync to NTP server every "ntpSyncTime" seconds, set to 1 hour or more to be reasonable
unsigned long ntpSyncTime = 21600;
// keep track of how long ago we updated the NTP server
// unsigned long ntpLastUpdate = 0;
// adjust the sync latency with computer NTP client in seconds
unsigned int syncLatency = 2;
void setup()
{
Serial.begin(9600);
setSyncProvider(RTC.get); // the function to get the time from the RTC
// create the alarms
Alarm.alarmRepeat(7,30,0, ntpSyncDS1307); // 7:30am every day
Alarm.alarmRepeat(19,30,0, ntpSyncDS1307); // 7:30pm every day
// start Ethernet and UDP
if (Ethernet.begin(mac) == 0) {
for (;;);
}
Udp.begin(localPort);
ntpSyncDS1307();
}
void loop(){
Alarm.delay(100); // wait 1/10 second between cycles
}
// functions to be called when an alarm triggers:
void ntpSyncDS1307() {
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a replay is available
delay(1000);
if (Udp.parsePacket()) {
// We've received a packet, read the data from it
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
// the timstamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, extract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900)
unsigned long secsSince1900 = highWord << 16 | lowWord;
// now convert NTP time into everyday time:
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800L;
// substract seventy years:
unsigned long epoch = secsSince1900 - seventyYears + timeZoneOffset + syncLatency;
setTime(epoch);
RTC.set(epoch);
// ntpLastUpdate = now();
// output time and "Sync OK" message every sync
Serial.print(year());
Serial.print('-');
Serial.print(month());
Serial.print('-');
Serial.print(day());
Serial.print(' ');
Serial.print(hour());
Serial.print(':');
Serial.print(minute());
Serial.print(':');
Serial.print(second());
Serial.print(' ');
Serial.println("Sync OK");
}
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address) {
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clodk
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123);
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
Labels:
DS1307,
LM35,
NTP,
Real Time Clock,
RTC,
sync,
Synchronized,
Temperature,
TimeAlarms,
TimeAlarms.h
2012/06/01
Freeduino/Arduino: Set/Sync Date and Time on DS1307 Real Time Clock Shield
When setting date and time on DS1307 real time clock sensor shield using RTClib.h, there will be some seconds delay between the time on the shield and the standard time, so I need a sketch to adjust the clock on the shield. And here comes the sketch.
The sketch can be used on the Freeduino/Arduino side to manually set or automatically (using program) sync the date and time of DS1307 RTC (real time clock) sensor shield or breakout.
The sketch will check the range of values keyed in including second, minute, hour, date of the month, month, year, and automatically generate day of the week.
Update: The sketch is updated on May 3, 2013 to be more modular, readable and extendable.
Pins Used
Analog pins 4 and 5 are used for I2C protocol implemented by Maxim DS1307.
Serial Monitor Output
Before Pressing <Enter> Key:
After Pressing <Enter> Key:
Updated Sketch
//
// Maurice Ribble
// 4-17-2008
// http://www.glacialwanderer.com/hobbyrobotics
// This code tests the DS1307 Real Time clock on the Arduino board.
// The ds1307 works in binary coded decimal or BCD. You can look up
// bcd in google if you aren't familior with it. There can output
// a square wave, but I don't expose that in this code. See the
// ds1307 for it's full capabilities.
// Revised by Befun Hung to set/sync date and time for DS1307 Real Time Clock on Freeduino/Arduino shield.
// June-01-2012
// Revised by Befun Hung to create terminalSync function to be more modular
// May-03-2013
// http://cheaphousetek.blogspot.com/
// Usage: After uploading to Freeduino/Arduino board, open the serial monitor.
// Input Format: YYYY-MM-DD hh:mm:ss <Enter>
#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
String datetimeIn;
int TimeSet = 0;
int timeArray[19], checkStatus = 1;
int centuryCode = 6; // for year 2000-2099 (Wikipedia: determination of the day of the week)
int monTable[12] = {0,3,3,6,1,4,6,2,5,0,3,5};
int leapmonTable[12] = {6,2,3,6,1,4,6,2,5,0,3,5};
// 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) );
}
// Stops the DS1307, but it has the side effect of setting seconds to 0
// Probably only want to use this for testing
/*void stopDs1307()
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(0x80);
Wire.endTransmission();
}*/
// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour)); // If you want 12 hour am/pm you need to set
// bit 6 (also need to change readDateDs1307)
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}
// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.receive() & 0x7f);
*minute = bcdToDec(Wire.receive());
*hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.receive());
*dayOfMonth = bcdToDec(Wire.receive());
*month = bcdToDec(Wire.receive());
*year = bcdToDec(Wire.receive());
}
void printFormatError() {
Serial.println("Format Error\n");
}
/*
void printValueError() {
Serial.println("Value Error\n");
}
*/
void setup() {
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
Wire.begin();
Serial.begin(9600);
delay(100);
Serial.print("Waiting for setting the date and time now.\n");
Serial.print("Input Format: YYYY-MM-DD HH:MM:SS\n");
// Change these values to what you want to set your clock to.
// You probably only want to set your clock once and then remove
// the setDateDs1307 call.
// second = 45;
// minute = 3;
// hour = 7;
// dayOfWeek = 5;
// dayOfMonth = 17;
// month = 4;
// year = 8;
// setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}
void loop() {
terminalSync();
}
void terminalSync() {
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
if (Serial.available() == 19 ) {
for (int i=0;i<19;i++) {
timeArray[i] = Serial.read(); // Serial.read() read int type ASCII code value
}
// for digits subtract 48 ('0' ASCII code value)
for (int j=0;j<19;j++) {
if (timeArray[j] > 47 && timeArray[j] < 58) {
timeArray[j] -= 48;
}
if (timeArray[j] <= 9) {
Serial.print(timeArray[j]);
}
else {
Serial.print(char(timeArray[j]));
}
}
Serial.println("");
// check for digits range
checkStatus = 1;
if (timeArray[0] != 2) {
printFormatError();
checkStatus = 0;
}
if (timeArray[1] != 0) {
printFormatError();
checkStatus = 0;
}
if (timeArray[2] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[3] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[5] > 1) {
printFormatError();
checkStatus = 0;
}
if (timeArray[6] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[5]*10+timeArray[6] > 12) {
// printValueError();
checkStatus = 0;
}
if (timeArray[8] > 3) {
printFormatError();
checkStatus = 0;
}
if (timeArray[9] > 9) {
printFormatError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 1 ||
timeArray[5]*10+timeArray[6] == 3 ||
timeArray[5]*10+timeArray[6] == 5 ||
timeArray[5]*10+timeArray[6] == 7 ||
timeArray[5]*10+timeArray[6] == 8 ||
timeArray[5]*10+timeArray[6] == 10 ||
timeArray[5]*10+timeArray[6] == 12) && timeArray[8]*10+timeArray[9] > 31) {
// printValueError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 4 ||
timeArray[5]*10+timeArray[6] == 6 ||
timeArray[5]*10+timeArray[6] == 9 ||
timeArray[5]*10+timeArray[6] == 11) && timeArray[8]*10+timeArray[9] > 30) {
// printValueError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 == 0) && timeArray[8]*10+timeArray[9] > 29) {
// printValueError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 != 0) && timeArray[8]*10+timeArray[9] > 28) {
// printValueError();
checkStatus = 0;
}
if (timeArray[11] > 2) {
printFormatError();
checkStatus = 0;
}
if (timeArray[12] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[11]*10+timeArray[12] > 23) {
// printValueError();
checkStatus = 0;
}
if (timeArray[14] > 5) {
printFormatError();
checkStatus = 0;
}
if (timeArray[15] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[14]*10+timeArray[15] > 59) {
// printValueError();
checkStatus = 0;
}
if (timeArray[17] > 5) {
printFormatError();
checkStatus = 0;
}
if (timeArray[18] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[17]*10+timeArray[18] > 59) {
// printValueError();
checkStatus = 0;
}
// Serial.println(checkStatus);
if (checkStatus) {
second = timeArray[17]*10+timeArray[18];
minute = timeArray[14]*10+timeArray[15];
hour = timeArray[11]*10+timeArray[12];
// dayOfWeek = 5;
dayOfMonth = timeArray[8]*10+timeArray[9];
month = timeArray[5]*10+timeArray[6];
year = timeArray[2]*10+timeArray[3];
if ((year % 4) == 0) {
dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + leapmonTable[month-1] + dayOfMonth) % 7;
}
else {
dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + monTable[month-1] + dayOfMonth) % 7;
}
if (dayOfWeek == 0) {
dayOfWeek += 7;
}
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
Serial.print(hour, DEC);
Serial.print(":");
Serial.print(minute, DEC);
Serial.print(":");
Serial.print(second, DEC);
Serial.print(" ");
Serial.print(month, DEC);
Serial.print("/");
Serial.print(dayOfMonth, DEC);
Serial.print("/");
Serial.print(year, DEC);
Serial.print(" Day_of_week:");
Serial.println(dayOfWeek, DEC);
// delay(1000);
}
}
Original Sketch
//
// Maurice Ribble
// 4-17-2008
// http://www.glacialwanderer.com/hobbyrobotics
// This code tests the DS1307 Real Time clock on the Arduino board.
// The ds1307 works in binary coded decimal or BCD. You can look up
// bcd in google if you aren't familior with it. There can output
// a square wave, but I don't expose that in this code. See the
// ds1307 for it's full capabilities.
// Revised by Befun Hung to set/sync date and time for DS1307 Real Time Clock on Freeduino/Arduino shield.
// 1 June 2012
// File Name: SetSyncDateTime.pde
// http://cheaphousetek.blogspot.com/
// Usage: After uploading to Freeduino/Arduino board, open the serial monitor.
// Input Format: YYYY-MM-DD hh:mm:ss <Enter>
// The sketch works on Arduino IDE 0022
#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
String datetimeIn;
int TimeSet = 0;
int timeArray[19], checkStatus = 1;
int centuryCode = 6; // for year 2000-2099 (Wikipedia: determination of the day of the week)
int monTable[12] = {0,3,3,6,1,4,6,2,5,0,3,5};
int leapmonTable[12] = {6,2,3,6,1,4,6,2,5,0,3,5};
// 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) );
}
// Stops the DS1307, but it has the side effect of setting seconds to 0
// Probably only want to use this for testing
/*void stopDs1307()
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(0x80);
Wire.endTransmission();
}*/
// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour)); // If you want 12 hour am/pm you need to set
// bit 6 (also need to change readDateDs1307)
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}
// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.receive() & 0x7f);
*minute = bcdToDec(Wire.receive());
*hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.receive());
*dayOfMonth = bcdToDec(Wire.receive());
*month = bcdToDec(Wire.receive());
*year = bcdToDec(Wire.receive());
}
void printFormatError() {
Serial.println("Format Error\n");
}
/*
void printValueError() {
Serial.println("Value Error\n");
}
*/
void setup() {
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
Wire.begin();
Serial.begin(9600);
delay(100);
Serial.print("Waiting for setting the date and time now.\n");
Serial.print("Input Format: YYYY-MM-DD HH:MM:SS\n");
// Change these values to what you want to set your clock to.
// You probably only want to set your clock once and then remove
// the setDateDs1307 call.
// second = 45;
// minute = 3;
// hour = 7;
// dayOfWeek = 5;
// dayOfMonth = 17;
// month = 4;
// year = 8;
// setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}
void loop() {
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
if (Serial.available() == 19 ) {
for (int i=0;i<19;i++) {
timeArray[i] = Serial.read(); // Serial.read() read int type ASCII code value
}
// for digits subtract 48 ('0' ASCII code value)
for (int j=0;j<19;j++) {
if (timeArray[j] > 47 && timeArray[j] < 58) {
timeArray[j] -= 48;
}
if (timeArray[j] <= 9) {
Serial.print(timeArray[j]);
}
else {
Serial.print(char(timeArray[j]));
}
}
Serial.println("");
// check for digits range
checkStatus = 1;
if (timeArray[0] != 2) {
printFormatError();
checkStatus = 0;
}
if (timeArray[1] != 0) {
printFormatError();
checkStatus = 0;
}
if (timeArray[2] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[3] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[5] > 1) {
printFormatError();
checkStatus = 0;
}
if (timeArray[6] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[5]*10+timeArray[6] > 12) {
// printValueError();
checkStatus = 0;
}
if (timeArray[8] > 3) {
printFormatError();
checkStatus = 0;
}
if (timeArray[9] > 9) {
printFormatError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 1 ||
timeArray[5]*10+timeArray[6] == 3 ||
timeArray[5]*10+timeArray[6] == 5 ||
timeArray[5]*10+timeArray[6] == 7 ||
timeArray[5]*10+timeArray[6] == 8 ||
timeArray[5]*10+timeArray[6] == 10 ||
timeArray[5]*10+timeArray[6] == 12) && timeArray[8]*10+timeArray[9] > 31) {
// printValueError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 4 ||
timeArray[5]*10+timeArray[6] == 6 ||
timeArray[5]*10+timeArray[6] == 9 ||
timeArray[5]*10+timeArray[6] == 11) && timeArray[8]*10+timeArray[9] > 30) {
// printValueError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 == 0) && timeArray[8]*10+timeArray[9] > 29) {
// printValueError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 != 0) && timeArray[8]*10+timeArray[9] > 28) {
// printValueError();
checkStatus = 0;
}
if (timeArray[11] > 2) {
printFormatError();
checkStatus = 0;
}
if (timeArray[12] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[11]*10+timeArray[12] > 23) {
// printValueError();
checkStatus = 0;
}
if (timeArray[14] > 5) {
printFormatError();
checkStatus = 0;
}
if (timeArray[15] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[14]*10+timeArray[15] > 59) {
// printValueError();
checkStatus = 0;
}
if (timeArray[17] > 5) {
printFormatError();
checkStatus = 0;
}
if (timeArray[18] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[17]*10+timeArray[18] > 59) {
// printValueError();
checkStatus = 0;
}
// Serial.println(checkStatus);
if (checkStatus) {
second = timeArray[17]*10+timeArray[18];
minute = timeArray[14]*10+timeArray[15];
hour = timeArray[11]*10+timeArray[12];
// dayOfWeek = 5;
dayOfMonth = timeArray[8]*10+timeArray[9];
month = timeArray[5]*10+timeArray[6];
year = timeArray[2]*10+timeArray[3];
if ((year % 4) == 0) {
dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + leapmonTable[month-1] + dayOfMonth) % 7;
}
else {
dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + monTable[month-1] + dayOfMonth) % 7;
}
if (dayOfWeek == 0) {
dayOfWeek += 7;
}
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
Serial.print(hour, DEC);
Serial.print(":");
Serial.print(minute, DEC);
Serial.print(":");
Serial.print(second, DEC);
Serial.print(" ");
Serial.print(month, DEC);
Serial.print("/");
Serial.print(dayOfMonth, DEC);
Serial.print("/");
Serial.print(year, DEC);
Serial.print(" Day_of_week:");
Serial.println(dayOfWeek, DEC);
// delay(1000);
}
}
The sketch can be used on the Freeduino/Arduino side to manually set or automatically (using program) sync the date and time of DS1307 RTC (real time clock) sensor shield or breakout.
The sketch will check the range of values keyed in including second, minute, hour, date of the month, month, year, and automatically generate day of the week.
Update: The sketch is updated on May 3, 2013 to be more modular, readable and extendable.
Pins Used
Analog pins 4 and 5 are used for I2C protocol implemented by Maxim DS1307.
Serial Monitor Output
Before Pressing <Enter> Key:
After Pressing <Enter> Key:
Updated Sketch
//
// Maurice Ribble
// 4-17-2008
// http://www.glacialwanderer.com/hobbyrobotics
// This code tests the DS1307 Real Time clock on the Arduino board.
// The ds1307 works in binary coded decimal or BCD. You can look up
// bcd in google if you aren't familior with it. There can output
// a square wave, but I don't expose that in this code. See the
// ds1307 for it's full capabilities.
// Revised by Befun Hung to set/sync date and time for DS1307 Real Time Clock on Freeduino/Arduino shield.
// June-01-2012
// Revised by Befun Hung to create terminalSync function to be more modular
// May-03-2013
// http://cheaphousetek.blogspot.com/
// Usage: After uploading to Freeduino/Arduino board, open the serial monitor.
// Input Format: YYYY-MM-DD hh:mm:ss <Enter>
#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
String datetimeIn;
int TimeSet = 0;
int timeArray[19], checkStatus = 1;
int centuryCode = 6; // for year 2000-2099 (Wikipedia: determination of the day of the week)
int monTable[12] = {0,3,3,6,1,4,6,2,5,0,3,5};
int leapmonTable[12] = {6,2,3,6,1,4,6,2,5,0,3,5};
// 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) );
}
// Stops the DS1307, but it has the side effect of setting seconds to 0
// Probably only want to use this for testing
/*void stopDs1307()
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(0x80);
Wire.endTransmission();
}*/
// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour)); // If you want 12 hour am/pm you need to set
// bit 6 (also need to change readDateDs1307)
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}
// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.receive() & 0x7f);
*minute = bcdToDec(Wire.receive());
*hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.receive());
*dayOfMonth = bcdToDec(Wire.receive());
*month = bcdToDec(Wire.receive());
*year = bcdToDec(Wire.receive());
}
void printFormatError() {
Serial.println("Format Error\n");
}
/*
void printValueError() {
Serial.println("Value Error\n");
}
*/
void setup() {
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
Wire.begin();
Serial.begin(9600);
delay(100);
Serial.print("Waiting for setting the date and time now.\n");
Serial.print("Input Format: YYYY-MM-DD HH:MM:SS\n");
// Change these values to what you want to set your clock to.
// You probably only want to set your clock once and then remove
// the setDateDs1307 call.
// second = 45;
// minute = 3;
// hour = 7;
// dayOfWeek = 5;
// dayOfMonth = 17;
// month = 4;
// year = 8;
// setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}
void loop() {
terminalSync();
}
void terminalSync() {
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
if (Serial.available() == 19 ) {
for (int i=0;i<19;i++) {
timeArray[i] = Serial.read(); // Serial.read() read int type ASCII code value
}
// for digits subtract 48 ('0' ASCII code value)
for (int j=0;j<19;j++) {
if (timeArray[j] > 47 && timeArray[j] < 58) {
timeArray[j] -= 48;
}
if (timeArray[j] <= 9) {
Serial.print(timeArray[j]);
}
else {
Serial.print(char(timeArray[j]));
}
}
Serial.println("");
// check for digits range
checkStatus = 1;
if (timeArray[0] != 2) {
printFormatError();
checkStatus = 0;
}
if (timeArray[1] != 0) {
printFormatError();
checkStatus = 0;
}
if (timeArray[2] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[3] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[5] > 1) {
printFormatError();
checkStatus = 0;
}
if (timeArray[6] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[5]*10+timeArray[6] > 12) {
// printValueError();
checkStatus = 0;
}
if (timeArray[8] > 3) {
printFormatError();
checkStatus = 0;
}
if (timeArray[9] > 9) {
printFormatError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 1 ||
timeArray[5]*10+timeArray[6] == 3 ||
timeArray[5]*10+timeArray[6] == 5 ||
timeArray[5]*10+timeArray[6] == 7 ||
timeArray[5]*10+timeArray[6] == 8 ||
timeArray[5]*10+timeArray[6] == 10 ||
timeArray[5]*10+timeArray[6] == 12) && timeArray[8]*10+timeArray[9] > 31) {
// printValueError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 4 ||
timeArray[5]*10+timeArray[6] == 6 ||
timeArray[5]*10+timeArray[6] == 9 ||
timeArray[5]*10+timeArray[6] == 11) && timeArray[8]*10+timeArray[9] > 30) {
// printValueError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 == 0) && timeArray[8]*10+timeArray[9] > 29) {
// printValueError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 != 0) && timeArray[8]*10+timeArray[9] > 28) {
// printValueError();
checkStatus = 0;
}
if (timeArray[11] > 2) {
printFormatError();
checkStatus = 0;
}
if (timeArray[12] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[11]*10+timeArray[12] > 23) {
// printValueError();
checkStatus = 0;
}
if (timeArray[14] > 5) {
printFormatError();
checkStatus = 0;
}
if (timeArray[15] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[14]*10+timeArray[15] > 59) {
// printValueError();
checkStatus = 0;
}
if (timeArray[17] > 5) {
printFormatError();
checkStatus = 0;
}
if (timeArray[18] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[17]*10+timeArray[18] > 59) {
// printValueError();
checkStatus = 0;
}
// Serial.println(checkStatus);
if (checkStatus) {
second = timeArray[17]*10+timeArray[18];
minute = timeArray[14]*10+timeArray[15];
hour = timeArray[11]*10+timeArray[12];
// dayOfWeek = 5;
dayOfMonth = timeArray[8]*10+timeArray[9];
month = timeArray[5]*10+timeArray[6];
year = timeArray[2]*10+timeArray[3];
if ((year % 4) == 0) {
dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + leapmonTable[month-1] + dayOfMonth) % 7;
}
else {
dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + monTable[month-1] + dayOfMonth) % 7;
}
if (dayOfWeek == 0) {
dayOfWeek += 7;
}
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
Serial.print(hour, DEC);
Serial.print(":");
Serial.print(minute, DEC);
Serial.print(":");
Serial.print(second, DEC);
Serial.print(" ");
Serial.print(month, DEC);
Serial.print("/");
Serial.print(dayOfMonth, DEC);
Serial.print("/");
Serial.print(year, DEC);
Serial.print(" Day_of_week:");
Serial.println(dayOfWeek, DEC);
// delay(1000);
}
}
Original Sketch
//
// Maurice Ribble
// 4-17-2008
// http://www.glacialwanderer.com/hobbyrobotics
// This code tests the DS1307 Real Time clock on the Arduino board.
// The ds1307 works in binary coded decimal or BCD. You can look up
// bcd in google if you aren't familior with it. There can output
// a square wave, but I don't expose that in this code. See the
// ds1307 for it's full capabilities.
// Revised by Befun Hung to set/sync date and time for DS1307 Real Time Clock on Freeduino/Arduino shield.
// 1 June 2012
// File Name: SetSyncDateTime.pde
// http://cheaphousetek.blogspot.com/
// Usage: After uploading to Freeduino/Arduino board, open the serial monitor.
// Input Format: YYYY-MM-DD hh:mm:ss <Enter>
// The sketch works on Arduino IDE 0022
#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
String datetimeIn;
int TimeSet = 0;
int timeArray[19], checkStatus = 1;
int centuryCode = 6; // for year 2000-2099 (Wikipedia: determination of the day of the week)
int monTable[12] = {0,3,3,6,1,4,6,2,5,0,3,5};
int leapmonTable[12] = {6,2,3,6,1,4,6,2,5,0,3,5};
// 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) );
}
// Stops the DS1307, but it has the side effect of setting seconds to 0
// Probably only want to use this for testing
/*void stopDs1307()
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(0x80);
Wire.endTransmission();
}*/
// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers
void setDateDs1307(byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock
Wire.send(decToBcd(minute));
Wire.send(decToBcd(hour)); // If you want 12 hour am/pm you need to set
// bit 6 (also need to change readDateDs1307)
Wire.send(decToBcd(dayOfWeek));
Wire.send(decToBcd(dayOfMonth));
Wire.send(decToBcd(month));
Wire.send(decToBcd(year));
Wire.endTransmission();
}
// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.receive() & 0x7f);
*minute = bcdToDec(Wire.receive());
*hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.receive());
*dayOfMonth = bcdToDec(Wire.receive());
*month = bcdToDec(Wire.receive());
*year = bcdToDec(Wire.receive());
}
void printFormatError() {
Serial.println("Format Error\n");
}
/*
void printValueError() {
Serial.println("Value Error\n");
}
*/
void setup() {
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
Wire.begin();
Serial.begin(9600);
delay(100);
Serial.print("Waiting for setting the date and time now.\n");
Serial.print("Input Format: YYYY-MM-DD HH:MM:SS\n");
// Change these values to what you want to set your clock to.
// You probably only want to set your clock once and then remove
// the setDateDs1307 call.
// second = 45;
// minute = 3;
// hour = 7;
// dayOfWeek = 5;
// dayOfMonth = 17;
// month = 4;
// year = 8;
// setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}
void loop() {
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
if (Serial.available() == 19 ) {
for (int i=0;i<19;i++) {
timeArray[i] = Serial.read(); // Serial.read() read int type ASCII code value
}
// for digits subtract 48 ('0' ASCII code value)
for (int j=0;j<19;j++) {
if (timeArray[j] > 47 && timeArray[j] < 58) {
timeArray[j] -= 48;
}
if (timeArray[j] <= 9) {
Serial.print(timeArray[j]);
}
else {
Serial.print(char(timeArray[j]));
}
}
Serial.println("");
// check for digits range
checkStatus = 1;
if (timeArray[0] != 2) {
printFormatError();
checkStatus = 0;
}
if (timeArray[1] != 0) {
printFormatError();
checkStatus = 0;
}
if (timeArray[2] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[3] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[5] > 1) {
printFormatError();
checkStatus = 0;
}
if (timeArray[6] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[5]*10+timeArray[6] > 12) {
// printValueError();
checkStatus = 0;
}
if (timeArray[8] > 3) {
printFormatError();
checkStatus = 0;
}
if (timeArray[9] > 9) {
printFormatError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 1 ||
timeArray[5]*10+timeArray[6] == 3 ||
timeArray[5]*10+timeArray[6] == 5 ||
timeArray[5]*10+timeArray[6] == 7 ||
timeArray[5]*10+timeArray[6] == 8 ||
timeArray[5]*10+timeArray[6] == 10 ||
timeArray[5]*10+timeArray[6] == 12) && timeArray[8]*10+timeArray[9] > 31) {
// printValueError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 4 ||
timeArray[5]*10+timeArray[6] == 6 ||
timeArray[5]*10+timeArray[6] == 9 ||
timeArray[5]*10+timeArray[6] == 11) && timeArray[8]*10+timeArray[9] > 30) {
// printValueError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 == 0) && timeArray[8]*10+timeArray[9] > 29) {
// printValueError();
checkStatus = 0;
}
if ((timeArray[5]*10+timeArray[6] == 2 && year % 4 != 0) && timeArray[8]*10+timeArray[9] > 28) {
// printValueError();
checkStatus = 0;
}
if (timeArray[11] > 2) {
printFormatError();
checkStatus = 0;
}
if (timeArray[12] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[11]*10+timeArray[12] > 23) {
// printValueError();
checkStatus = 0;
}
if (timeArray[14] > 5) {
printFormatError();
checkStatus = 0;
}
if (timeArray[15] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[14]*10+timeArray[15] > 59) {
// printValueError();
checkStatus = 0;
}
if (timeArray[17] > 5) {
printFormatError();
checkStatus = 0;
}
if (timeArray[18] > 9) {
printFormatError();
checkStatus = 0;
}
if (timeArray[17]*10+timeArray[18] > 59) {
// printValueError();
checkStatus = 0;
}
// Serial.println(checkStatus);
if (checkStatus) {
second = timeArray[17]*10+timeArray[18];
minute = timeArray[14]*10+timeArray[15];
hour = timeArray[11]*10+timeArray[12];
// dayOfWeek = 5;
dayOfMonth = timeArray[8]*10+timeArray[9];
month = timeArray[5]*10+timeArray[6];
year = timeArray[2]*10+timeArray[3];
if ((year % 4) == 0) {
dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + leapmonTable[month-1] + dayOfMonth) % 7;
}
else {
dayOfWeek = (centuryCode + year + ((year - (year % 4)) / 4) + monTable[month-1] + dayOfMonth) % 7;
}
if (dayOfWeek == 0) {
dayOfWeek += 7;
}
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
Serial.print(hour, DEC);
Serial.print(":");
Serial.print(minute, DEC);
Serial.print(":");
Serial.print(second, DEC);
Serial.print(" ");
Serial.print(month, DEC);
Serial.print("/");
Serial.print(dayOfMonth, DEC);
Serial.print("/");
Serial.print(year, DEC);
Serial.print(" Day_of_week:");
Serial.println(dayOfWeek, DEC);
// delay(1000);
}
}
Labels:
Arduino,
DS1307,
Freeduino,
Real Time Clock,
real time clock sensor shield,
real time clock shield,
RTC,
rtc sensor shield,
rtc shield,
set,
sync
Subscribe to:
Posts (Atom)



