add DS1307RTC support

This commit is contained in:
ivan 2017-07-26 14:23:09 +03:00
parent e8cedd2725
commit 636e9bdfa6
11 changed files with 487 additions and 129 deletions

218
DS1307RTC/DS1307RTC.cpp Normal file
View File

@ -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 <TinyWireM.h>
#define Wire TinyWireM
#else
#include <Wire.h>
#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

40
DS1307RTC/DS1307RTC.h Normal file
View File

@ -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 <TimeLib.h>
// 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

View File

@ -0,0 +1,49 @@
#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
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);
}

View File

@ -0,0 +1,75 @@
#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
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;
}

23
DS1307RTC/keywords.txt Normal file
View File

@ -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)
#######################################

12
DS1307RTC/library.json Normal file
View File

@ -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"
}

View File

@ -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=*

7
DS1307RTC/readme.txt Normal file
View File

@ -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

View File

@ -1 +1 @@
twobuttonstimer scetch for Arduino
twobuttonstimer scetch for Arduino using DS1307RTC

View File

@ -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))

View File

@ -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 <TimeLib.h>
* 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 <TimeLib.h>
#include <Wire.h>
#include <DS1307RTC.h> // 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
}