diff --git a/DS1307RTC/DS1307RTC.cpp b/DS1307RTC/DS1307RTC.cpp new file mode 100644 index 0000000..2c16a8a --- /dev/null +++ b/DS1307RTC/DS1307RTC.cpp @@ -0,0 +1,218 @@ +/* + * DS1307RTC.h - library for DS1307 RTC + + Copyright (c) Michael Margolis 2009 + This library is intended to be uses with Arduino Time library functions + + The library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + 30 Dec 2009 - Initial release + 5 Sep 2011 updated for Arduino 1.0 + */ + + +#if defined (__AVR_ATtiny84__) || defined(__AVR_ATtiny85__) || (__AVR_ATtiny2313__) +#include +#define Wire TinyWireM +#else +#include +#endif +#include "DS1307RTC.h" + +#define DS1307_CTRL_ID 0x68 + +DS1307RTC::DS1307RTC() +{ + Wire.begin(); +} + +// PUBLIC FUNCTIONS +time_t DS1307RTC::get() // Aquire data from buffer and convert to time_t +{ + tmElements_t tm; + if (read(tm) == false) return 0; + return(makeTime(tm)); +} + +bool DS1307RTC::set(time_t t) +{ + tmElements_t tm; + breakTime(t, tm); + return write(tm); +} + +// Aquire data from the RTC chip in BCD format +bool DS1307RTC::read(tmElements_t &tm) +{ + uint8_t sec; + Wire.beginTransmission(DS1307_CTRL_ID); +#if ARDUINO >= 100 + Wire.write((uint8_t)0x00); +#else + Wire.send(0x00); +#endif + if (Wire.endTransmission() != 0) { + exists = false; + return false; + } + exists = true; + + // request the 7 data fields (secs, min, hr, dow, date, mth, yr) + Wire.requestFrom(DS1307_CTRL_ID, tmNbrFields); + if (Wire.available() < tmNbrFields) return false; +#if ARDUINO >= 100 + sec = Wire.read(); + tm.Second = bcd2dec(sec & 0x7f); + tm.Minute = bcd2dec(Wire.read() ); + tm.Hour = bcd2dec(Wire.read() & 0x3f); // mask assumes 24hr clock + tm.Wday = bcd2dec(Wire.read() ); + tm.Day = bcd2dec(Wire.read() ); + tm.Month = bcd2dec(Wire.read() ); + tm.Year = y2kYearToTm((bcd2dec(Wire.read()))); +#else + sec = Wire.receive(); + tm.Second = bcd2dec(sec & 0x7f); + tm.Minute = bcd2dec(Wire.receive() ); + tm.Hour = bcd2dec(Wire.receive() & 0x3f); // mask assumes 24hr clock + tm.Wday = bcd2dec(Wire.receive() ); + tm.Day = bcd2dec(Wire.receive() ); + tm.Month = bcd2dec(Wire.receive() ); + tm.Year = y2kYearToTm((bcd2dec(Wire.receive()))); +#endif + if (sec & 0x80) return false; // clock is halted + return true; +} + +bool DS1307RTC::write(tmElements_t &tm) +{ + // To eliminate any potential race conditions, + // stop the clock before writing the values, + // then restart it after. + Wire.beginTransmission(DS1307_CTRL_ID); +#if ARDUINO >= 100 + Wire.write((uint8_t)0x00); // reset register pointer + Wire.write((uint8_t)0x80); // Stop the clock. The seconds will be written last + Wire.write(dec2bcd(tm.Minute)); + Wire.write(dec2bcd(tm.Hour)); // sets 24 hour format + Wire.write(dec2bcd(tm.Wday)); + Wire.write(dec2bcd(tm.Day)); + Wire.write(dec2bcd(tm.Month)); + Wire.write(dec2bcd(tmYearToY2k(tm.Year))); +#else + Wire.send(0x00); // reset register pointer + Wire.send(0x80); // Stop the clock. The seconds will be written last + Wire.send(dec2bcd(tm.Minute)); + Wire.send(dec2bcd(tm.Hour)); // sets 24 hour format + Wire.send(dec2bcd(tm.Wday)); + Wire.send(dec2bcd(tm.Day)); + Wire.send(dec2bcd(tm.Month)); + Wire.send(dec2bcd(tmYearToY2k(tm.Year))); +#endif + if (Wire.endTransmission() != 0) { + exists = false; + return false; + } + exists = true; + + // Now go back and set the seconds, starting the clock back up as a side effect + Wire.beginTransmission(DS1307_CTRL_ID); +#if ARDUINO >= 100 + Wire.write((uint8_t)0x00); // reset register pointer + Wire.write(dec2bcd(tm.Second)); // write the seconds, with the stop bit clear to restart +#else + Wire.send(0x00); // reset register pointer + Wire.send(dec2bcd(tm.Second)); // write the seconds, with the stop bit clear to restart +#endif + if (Wire.endTransmission() != 0) { + exists = false; + return false; + } + exists = true; + return true; +} + +unsigned char DS1307RTC::isRunning() +{ + Wire.beginTransmission(DS1307_CTRL_ID); +#if ARDUINO >= 100 + Wire.write((uint8_t)0x00); +#else + Wire.send(0x00); +#endif + Wire.endTransmission(); + + // Just fetch the seconds register and check the top bit + Wire.requestFrom(DS1307_CTRL_ID, 1); +#if ARDUINO >= 100 + return !(Wire.read() & 0x80); +#else + return !(Wire.receive() & 0x80); +#endif +} + +void DS1307RTC::setCalibration(char calValue) +{ + unsigned char calReg = abs(calValue) & 0x1f; + if (calValue >= 0) calReg |= 0x20; // S bit is positive to speed up the clock + Wire.beginTransmission(DS1307_CTRL_ID); +#if ARDUINO >= 100 + Wire.write((uint8_t)0x07); // Point to calibration register + Wire.write(calReg); +#else + Wire.send(0x07); // Point to calibration register + Wire.send(calReg); +#endif + Wire.endTransmission(); +} + +char DS1307RTC::getCalibration() +{ + Wire.beginTransmission(DS1307_CTRL_ID); +#if ARDUINO >= 100 + Wire.write((uint8_t)0x07); +#else + Wire.send(0x07); +#endif + Wire.endTransmission(); + + Wire.requestFrom(DS1307_CTRL_ID, 1); +#if ARDUINO >= 100 + unsigned char calReg = Wire.read(); +#else + unsigned char calReg = Wire.receive(); +#endif + char out = calReg & 0x1f; + if (!(calReg & 0x20)) out = -out; // S bit clear means a negative value + return out; +} + +// PRIVATE FUNCTIONS + +// Convert Decimal to Binary Coded Decimal (BCD) +uint8_t DS1307RTC::dec2bcd(uint8_t num) +{ + return ((num/10 * 16) + (num % 10)); +} + +// Convert Binary Coded Decimal (BCD) to Decimal +uint8_t DS1307RTC::bcd2dec(uint8_t num) +{ + return ((num/16 * 10) + (num % 16)); +} + +bool DS1307RTC::exists = false; + +DS1307RTC RTC = DS1307RTC(); // create an instance for the user + diff --git a/DS1307RTC/DS1307RTC.h b/DS1307RTC/DS1307RTC.h new file mode 100644 index 0000000..82c95b1 --- /dev/null +++ b/DS1307RTC/DS1307RTC.h @@ -0,0 +1,40 @@ +/* + * DS1307RTC.h - library for DS1307 RTC + * This library is intended to be uses with Arduino Time library functions + */ + +#ifndef DS1307RTC_h +#define DS1307RTC_h + +#include + +// library interface description +class DS1307RTC +{ + // user-accessible "public" interface + public: + DS1307RTC(); + static time_t get(); + static bool set(time_t t); + static bool read(tmElements_t &tm); + static bool write(tmElements_t &tm); + static bool chipPresent() { return exists; } + static unsigned char isRunning(); + static void setCalibration(char calValue); + static char getCalibration(); + + private: + static bool exists; + static uint8_t dec2bcd(uint8_t num); + static uint8_t bcd2dec(uint8_t num); +}; + +#ifdef RTC +#undef RTC // workaround for Arduino Due, which defines "RTC"... +#endif + +extern DS1307RTC RTC; + +#endif + + diff --git a/DS1307RTC/examples/ReadTest/ReadTest.ino b/DS1307RTC/examples/ReadTest/ReadTest.ino new file mode 100644 index 0000000..02f331c --- /dev/null +++ b/DS1307RTC/examples/ReadTest/ReadTest.ino @@ -0,0 +1,49 @@ +#include +#include +#include + +void setup() { + Serial.begin(9600); + while (!Serial) ; // wait for serial + delay(200); + Serial.println("DS1307RTC Read Test"); + Serial.println("-------------------"); +} + +void loop() { + tmElements_t tm; + + if (RTC.read(tm)) { + Serial.print("Ok, Time = "); + print2digits(tm.Hour); + Serial.write(':'); + print2digits(tm.Minute); + Serial.write(':'); + print2digits(tm.Second); + Serial.print(", Date (D/M/Y) = "); + Serial.print(tm.Day); + Serial.write('/'); + Serial.print(tm.Month); + Serial.write('/'); + Serial.print(tmYearToCalendar(tm.Year)); + Serial.println(); + } else { + if (RTC.chipPresent()) { + Serial.println("The DS1307 is stopped. Please run the SetTime"); + Serial.println("example to initialize the time and begin running."); + Serial.println(); + } else { + Serial.println("DS1307 read error! Please check the circuitry."); + Serial.println(); + } + delay(9000); + } + delay(1000); +} + +void print2digits(int number) { + if (number >= 0 && number < 10) { + Serial.write('0'); + } + Serial.print(number); +} diff --git a/DS1307RTC/examples/SetTime/SetTime.ino b/DS1307RTC/examples/SetTime/SetTime.ino new file mode 100644 index 0000000..336c2c5 --- /dev/null +++ b/DS1307RTC/examples/SetTime/SetTime.ino @@ -0,0 +1,75 @@ +#include +#include +#include + +const char *monthName[12] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +tmElements_t tm; + +void setup() { + bool parse=false; + bool config=false; + + // get the date and time the compiler was run + if (getDate(__DATE__) && getTime(__TIME__)) { + parse = true; + // and configure the RTC with this info + if (RTC.write(tm)) { + config = true; + } + } + + Serial.begin(9600); + while (!Serial) ; // wait for Arduino Serial Monitor + delay(200); + if (parse && config) { + Serial.print("DS1307 configured Time="); + Serial.print(__TIME__); + Serial.print(", Date="); + Serial.println(__DATE__); + } else if (parse) { + Serial.println("DS1307 Communication Error :-{"); + Serial.println("Please check your circuitry"); + } else { + Serial.print("Could not parse info from the compiler, Time=\""); + Serial.print(__TIME__); + Serial.print("\", Date=\""); + Serial.print(__DATE__); + Serial.println("\""); + } +} + +void loop() { +} + +bool getTime(const char *str) +{ + int Hour, Min, Sec; + + if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false; + tm.Hour = Hour; + tm.Minute = Min; + tm.Second = Sec; + return true; +} + +bool getDate(const char *str) +{ + char Month[12]; + int Day, Year; + uint8_t monthIndex; + + if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false; + for (monthIndex = 0; monthIndex < 12; monthIndex++) { + if (strcmp(Month, monthName[monthIndex]) == 0) break; + } + if (monthIndex >= 12) return false; + tm.Day = Day; + tm.Month = monthIndex + 1; + tm.Year = CalendarYrToTm(Year); + return true; +} + diff --git a/DS1307RTC/keywords.txt b/DS1307RTC/keywords.txt new file mode 100644 index 0000000..2fe86ca --- /dev/null +++ b/DS1307RTC/keywords.txt @@ -0,0 +1,23 @@ +####################################### +# Syntax Coloring Map For DS1307RTC +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +get KEYWORD2 +set KEYWORD2 +read KEYWORD2 +write KEYWORD2 +chipPresent KEYWORD2 +####################################### +# Instances (KEYWORD2) +####################################### +RTC KEYWORD2 +####################################### +# Constants (LITERAL1) +####################################### diff --git a/DS1307RTC/library.json b/DS1307RTC/library.json new file mode 100644 index 0000000..23da3d7 --- /dev/null +++ b/DS1307RTC/library.json @@ -0,0 +1,12 @@ +{ + "name": "DS1307RTC", + "keywords": "i2c, rtc, time, clock", + "description": "DS1307 RTC (Real-Time-Clock)", + "repository": + { + "type": "git", + "url": "https://github.com/PaulStoffregen/DS1307RTC.git" + }, + "frameworks": "arduino", + "platforms": "atmelavr" +} diff --git a/DS1307RTC/library.properties b/DS1307RTC/library.properties new file mode 100644 index 0000000..f39b262 --- /dev/null +++ b/DS1307RTC/library.properties @@ -0,0 +1,10 @@ +name=DS1307RTC +version=1.4 +author=Michael Margolis +maintainer=Paul Stoffregen +sentence=Use a DS1307 Real Time Clock chip with the Time library +paragraph= +category=Timing +url=http://playground.arduino.cc/code/time +architectures=* + diff --git a/DS1307RTC/readme.txt b/DS1307RTC/readme.txt new file mode 100644 index 0000000..5978295 --- /dev/null +++ b/DS1307RTC/readme.txt @@ -0,0 +1,7 @@ +Readme file for DS1307RTC Library + +The DS1307RTC library is provided to demonstrate the Arduino Time library. + +See the TimeRTC example sketches privided with the Time library download for usage + + diff --git a/README.md b/README.md index 37269bc..dc4fd1a 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -twobuttonstimer scetch for Arduino \ No newline at end of file +twobuttonstimer scetch for Arduino using DS1307RTC \ No newline at end of file diff --git a/timetoserial.py b/timetoserial.py deleted file mode 100644 index fd89e41..0000000 --- a/timetoserial.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python - -# https://forum.arduino.cc/index.php?topic=92457.msg2803014#msg2803014 - -import time -import serial.tools.list_ports -import serial -import signal # For trapping ctrl-c or SIGINT -import sys # For exiting program with exit code - -def SIGINT_handler(signal, frame): - print('Quitting program!') - ser.close() - sys.exit(0) - -signal.signal(signal.SIGINT, SIGINT_handler) - -port_names=[] -a=serial.tools.list_ports.comports() -for w in a: - port_names.append(w.device) - -port_names.sort() -print('\nDetected the following serial ports:\nDon\'t choose /dev/ttyAMA0.') -i=0 -for w in port_names: - print('%d) %s' %(i,w)) - i=i+1 -total_ports=i # now i= total ports - -user_port_selection=input('\nSelect port: (0,1,2...)') -if (int(user_port_selection)>=total_ports): - exit(1) # port selection out of range - -ser=serial.Serial(port=port_names[int(user_port_selection)],baudrate=9600,timeout=1) - -# ser=serial.Serial("COM1",baudrate=9600,timeout=10) -while(1): - mycmd=ser.read() - if (len(mycmd)>0): -# 10800 is GMT+3 - epoch='T' + str(int(time.time()) + 10800) + '\n' - ser.write((epoch).encode()) - print (str(epoch)) diff --git a/twobuttonstimer.ino b/twobuttonstimer.ino index b01c5d4..6333939 100644 --- a/twobuttonstimer.ino +++ b/twobuttonstimer.ino @@ -1,116 +1,84 @@ -/* +/* * based on: - * - * TimeSerial.pde - * example code illustrating Time library set through serial port messages. - * - * Messages consist of the letter T followed by ten digit time (as seconds since Jan 1 1970) - * you can send the text on the next line using Serial Monitor to set the clock to noon Jan 1 2013 - * T1357041600 - * - * A Processing example sketch to automatically send the messages is included in the download - * On Linux, you can use "date +T%s\n > /dev/ttyACM0" (UTC time zone) - */ - -#include + * TimeRTC.pde + * example code illustrating Time library with Real Time Clock. + * + */ -#define TIME_HEADER "T" // Header tag for serial time sync message -#define TIME_REQUEST 7 // ASCII bell character requests a time sync message +#include +#include +#include // a basic DS1307 library that returns time as a time_t + +int led = 13; +int indicator = 0; void setup() { - Serial.begin(9600); - while (!Serial) ; // Needed for Leonardo only pinMode(8, OUTPUT); pinMode(9, OUTPUT); - pinMode(10, OUTPUT); - pinMode(13, OUTPUT); - setSyncProvider( requestSync); //set function to call when sync required - Serial.println("Waiting for sync message"); + pinMode(led, OUTPUT); + Serial.begin(9600); + while (!Serial) ; // wait until Arduino Serial Monitor opens + 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"); } -void loop(){ - if (Serial.available()) { - processSyncMessage(); - } - if (timeStatus()!= timeNotSet) { - digitalClockDisplay(); - } +void loop() +{ if (timeStatus() == timeSet) { - digitalWrite(13, HIGH); // LED on if synced + checkTime(); } else { - digitalWrite(13, LOW); // LED off if needs refresh + // fast blinking indicate that time is not set or RTC is not plugged + int i; + for (i = 1; i <= 50; i++) + { + digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level) + delay(50); // wait for a second + digitalWrite(led, LOW); // turn the LED off by making the voltage LOW + delay(50); // wait for a second + } } - checkTime(); - delay(10000); + delay(1000); } void checkTime(){ - if ((hour()==6) && (minute()==1)) { + if ((hour()==6 || hour()==7 ) && (indicator==0)) { pressSTART(); } - if ((hour()==8) && (minute()==41)) { + if ((hour()==8) && (minute()==1)) { pressSTOP(); } - if ((hour()==15) && (minute()==1)) { + if ((hour()==12 || hour()==13 ) && (indicator==0)) { pressSTART(); } - if ((hour()==17) && (minute()==31)) { + if ((hour()==14) && (minute()==1)) { + pressSTOP(); + } + if ((hour()==17) && (indicator==0)) { + pressSTART(); + } + if ((hour()==18) && (minute()==25)) { pressSTOP(); } } void pressSTOP(){ - digitalWrite(8, HIGH); // turn the LED on (HIGH is the voltage level) - delay(500); // wait for a second - digitalWrite(8, LOW); // turn the LED off by making the voltage LOW + digitalWrite(led, LOW); // turn the LED off by making the voltage LOW + indicator = 0; + digitalWrite(8, HIGH); + delay(500); + digitalWrite(8, LOW); delay(61000); } void pressSTART(){ - digitalWrite(9, HIGH); // turn the LED on (HIGH is the voltage level) - delay(500); // wait for a second - digitalWrite(9, LOW); // turn the LED off by making the voltage LOW + digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level) + indicator = 1; + digitalWrite(9, HIGH); + delay(500); + digitalWrite(9, LOW); delay(61000); } -void digitalClockDisplay(){ - // digital clock display of the time - Serial.print(hour()); - printDigits(minute()); - printDigits(second()); - Serial.print(" "); - Serial.print(day()); - Serial.print(" "); - Serial.print(month()); - Serial.print(" "); - Serial.print(year()); - Serial.println(); -} - -void printDigits(int digits){ - // utility function for digital clock display: prints preceding colon and leading 0 - Serial.print(":"); - if(digits < 10) - Serial.print('0'); - Serial.print(digits); -} - - -void processSyncMessage() { - unsigned long pctime; - const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 - - if(Serial.find(TIME_HEADER)) { - pctime = Serial.parseInt(); - if( pctime >= DEFAULT_TIME) { // check the integer is a valid time (greater than Jan 1 2013) - setTime(pctime); // Sync Arduino clock to the time received on the serial port - } - } -} - -time_t requestSync() -{ - Serial.write(TIME_REQUEST); - return 0; // the time will be sent later in response to serial mesg -} -