#include <SPI.h>
const int cs=10; //chip select on DUO
//const int RunLED=3; // on-board run LED
//
static const uint8_t daysInMonth[] = {
31,28,31,30,31,30,31,31,30,31,30,31 };
#define SECONDS_FROM_1970_TO_2000 946684800
#define SECONDS_PER_DAY 86400L
byte hh,mm,ss,d,m;
int yOff;
// SPI DS3234 Clock Source #2 (4 MHz) <-------<<<<<
int DS3234[7]; // added for DS3234 time date array
//DS3234[0] sec
//DS3234[1] min
//DS3234[2] hr
//DS3234[3] null
//DS3234[4] day
//DS3234[5] mon
//DS3234[6] yr
byte DS3234_Hour;
byte DS3234_Minute;
byte DS3234_Second;
byte DS3234_DOW; // null not used
byte DS3234_Day;
byte DS3234_Month;
int DS3234_Year;
unsigned long DS3234_Unix_Local;
unsigned long DS3234_Unix_GMT;
void setup() {
// pinMode(RunLED,OUTPUT);
// digitalWrite(RunLED, LOW);
// digitalWrite(cs, HIGH);
// set the cs as an output:
pinMode(cs,OUTPUT); // chip select
Serial.begin(57600);
// init time / date array
DS3234[0] = 0; // sec
DS3234[1] = 0; // min
DS3234[2] = 0; // hr
DS3234[3] = 0; // null
DS3234[4] = 0; // day
DS3234[5] = 0; // mon
DS3234[6] = 0; // yr
RTC_init();
//------------------------ Set DS3234 Time Date----------------------------------------------
// month(1-12), day(1-31), year(0-99), hour --> military time(0-23), minute(0-59), second(0-59)
SetTimeDate(4,25,13,15,44,0); // <-------------<<<<< works - comment out after use!!!!
//-------------------------------------------------------------------------------------------
}
void loop() {
//Serial.println(ReadTimeDate());
print_DS3234_time_date();
print_clock_source();
//while(1){}
//digitalWrite(RunLED, LOW);
//delay(500);
//digitalWrite(RunLED, HIGH);
//delay(500);
}
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
int RTC_init(){
pinMode(cs,OUTPUT); // chip select
// start the SPI library:
SPI.begin();
//------------------------------------------------------------------------------------------------------------------
// Use one SPI clock setting - DS3234 max is 4 MHz but there are other timing variables requirements.
//SPI.setClockDivider(SPI_CLOCK_DIV2); //
SPI.setClockDivider(SPI_CLOCK_DIV4); // 16 MHz / 4 = 4 Mhz <-- Default Teensy 2 SPI ?
//SPI.setClockDivider(SPI_CLOCK_DIV8); //
//SPI.setClockDivider(SPI_CLOCK_DIV16); //
//SPI.setClockDivider(SPI_CLOCK_DIV32); //
//SPI.setClockDivider(SPI_CLOCK_DIV64); // <---- works only on SeeedStudio 328P Arduino with IO shield max
//SPI.setClockDivider(SPI_CLOCK_DIV128); // <----- works only on SeeedStudio 328P Arduino with IO shield
//-------------------------------------------------------------------------------------------------------------------
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE3); // both mode 1 & 3 should work on the T2 (mode 1 or mode 3 works on the SeeedStudio 328P Arduino)
//set control register
digitalWrite(cs, LOW);
SPI.transfer(0x8E);
SPI.transfer(0x60); //60= disable Osciallator and Battery SQ wave @1hz, temp compensation, Alarms disable
digitalWrite(cs, HIGH);
delay(10);
}
//-------------------------------------------------------------------
int SetTimeDate(int mo, int d, int y, int h, int mi, int s){
int TimeDate [7]={s,mi,h,0,d,mo,y};
for(int i=0; i<=6;i++){
delayMicroseconds(100);
if(i==3)
i++;
int b= TimeDate[i]/10;
int a= TimeDate[i]-b*10;
if(i==2){
if (b==2)
b=B00000010;
else if (b==1)
b=B00000001;
}
TimeDate[i]= a+(b<<4);
digitalWrite(cs, LOW);
SPI.transfer(i+0x80);
SPI.transfer(TimeDate[i]);
digitalWrite(cs, HIGH);
}
}
//---------------------------------------------------------------------
String ReadTimeDate(){ // string
String temp;
int TimeDate [7]; //second,minute,hour,null,day,month,year
for(int i=0; i<=6;i++){
if(i==3)
i++;
digitalWrite(cs, LOW);
SPI.transfer(i+0x00);
unsigned int n = SPI.transfer(0x00);
digitalWrite(cs, HIGH);
int a=n & B00001111;
if(i==2){
int b=(n & B00110000)>>4; //24 hour mode
if(b==B00000010)
b=20;
else if(b==B00000001)
b=10;
TimeDate[i]=a+b;
}
else if(i==4){
int b=(n & B00110000)>>4;
TimeDate[i]=a+b*10;
}
else if(i==5){
int b=(n & B00010000)>>4;
TimeDate[i]=a+b*10;
}
else if(i==6){
int b=(n & B11110000)>>4;
TimeDate[i]=a+b*10;
}
else{
int b=(n & B01110000)>>4;
TimeDate[i]=a+b*10;
}
}
temp.concat(TimeDate[4]);
temp.concat("/") ;
temp.concat(TimeDate[5]);
temp.concat("/") ;
temp.concat(TimeDate[6]);
temp.concat(" ") ;
temp.concat(TimeDate[2]);
temp.concat(":") ;
temp.concat(TimeDate[1]);
temp.concat(":") ;
temp.concat(TimeDate[0]);
return(temp);
}
//------------------------------------------------------------------------------
//Taken from Sparfun sample (amended to return values and not a string)
//Parameter you pass must be a correctly initialized 7 or more int array
void ReadTimeArray(int* TimeDate){
//int TimeDate [7]; //second,minute,hour,null,day,month,year
for(int i=0; i<=6;i++){
if(i==3)
i++;
digitalWrite(cs, LOW);
delay(10);
SPI.transfer(i+0x00);
unsigned int n = SPI.transfer(0x00);
digitalWrite(cs, HIGH);
delay(10);
int a=n & B00001111;
if(i==2){
int b=(n & B00110000)>>4; //24 hour mode
if(b==B00000010)
b=20;
else if(b==B00000001)
b=10;
*(TimeDate +i)=a+b;
}
else if(i==4){
int b=(n & B00110000)>>4;
*(TimeDate +i)=a+b*10;
}
else if(i==5){
int b=(n & B00010000)>>4;
*(TimeDate +i)=a+b*10;
}
else if(i==6){
int b=(n & B11110000)>>4;
*(TimeDate +i)=a+b*10;
}
else{
int b=(n & B01110000)>>4;
*(TimeDate +i)=a+b*10;
}
}
}
//-----------------------------------------------
void print_DS3234_time_date(void){
ReadTimeArray(DS3234); // array
Serial.print("Time = ");
Serial.print(DS3234[2],DEC); //hr
Serial.print(":");
Serial.print(DS3234[1],DEC); // min
Serial.print(":");
Serial.println(DS3234[0],DEC); //sec
Serial.print("Date = ");
Serial.print(DS3234[5],DEC); //mon
Serial.print("/");
Serial.print(DS3234[4],DEC); //day
Serial.print("/");
Serial.println(DS3234[6] + 2000,DEC); //yr
Serial.println();
}
//----------------------------------------------
void read_DS3234_T_D(void){
int DST_TZ = -5;
ReadTimeArray(DS3234); // array
// move variables from array to Global variables
DS3234_Second = DS3234[0]; // sec
DS3234_Minute = DS3234[1]; // min
DS3234_Hour = DS3234[2]; // hr
DS3234_Day = DS3234[4]; // day
DS3234_Month = DS3234[5]; // mon
DS3234_Year = DS3234[6]; // yr
// compute unix time GMT
ss = DS3234[0]; // sec
mm = DS3234[1]; // min
hh = DS3234[2]; // hr
d = DS3234[4]; // day
m = DS3234[5]; // mon
yOff = DS3234[6]; // yr <----<<<<<
//DS3234_Unix_GMT = unixtime(); // computes RTC local time in seconds
DS3234_Unix_Local = unixtime();
if (DST_TZ == -4){
DS3234_Unix_GMT = DS3234_Unix_Local + 14400; // -4 hrs EDT
}
if (DST_TZ == -5){
DS3234_Unix_GMT = DS3234_Unix_Local + 18000; // -5 hrs EST
}
}
//-----------------------------------------------------------------
void print_clock_source(void){
read_DS3234_T_D(); // reads and computes DS3234 time values
Serial.println("------------------");
Serial.println("DS3234 Time and Date");
Serial.print( DS3234_Hour,DEC);
Serial.print(":");
Serial.print( DS3234_Minute,DEC);
Serial.print(":");
Serial.println(DS3234_Second,DEC);
Serial.print(DS3234_Month,DEC);
Serial.print("-");
Serial.print(DS3234_Day,DEC);
Serial.print("-");
Serial.println(DS3234_Year + 2000,DEC); //+2000
Serial.print("DS3234 Unix GMT secs = ");
Serial.println(DS3234_Unix_GMT,DEC);
Serial.print("DS3234 Unix Local secs = ");
Serial.println(DS3234_Unix_Local,DEC);
Serial.println("------------------");
}
//-----------------------------------------------
void unix_time_2_Date_Time(unsigned long t){
byte hh,mm,ss,d,m;
uint8_t daysPerMonth;
int yOff;
static const uint8_t daysInMonth[] = {
31,28,31,30,31,30,31,31,30,31,30,31 };
t -= SECONDS_FROM_1970_TO_2000; // bring to 2000 timestamp from 1970
ss = t % 60;
t /= 60;
mm = t % 60;
t /= 60;
hh = t % 24;
uint16_t days = t / 24;
uint8_t leap;
for (yOff = 0; ; ++yOff)
{
leap = yOff % 4 == 0;
if (days < 365U + leap)
break;
days -= 365 + leap;
}
for (m = 1; ; ++m)
{
daysPerMonth = daysInMonth[+ m - 1];
if (leap && m == 2)
++daysPerMonth;
if (days < daysPerMonth)
break;
days -= daysPerMonth;
}
d = days + 1;
Serial.println("------------------");
Serial.println("Converted Unix time to Time and Date");
Serial.print(hh,DEC);
Serial.print(":");
Serial.print(mm,DEC);
Serial.print(":");
Serial.println(ss,DEC);
Serial.print(m,DEC);
Serial.print("-");
Serial.print(d,DEC);
Serial.print("-");
Serial.println(yOff,DEC);
Serial.println("------------------");
}
//-------------------------------------------
uint8_t dayOfWeek(void)
{
uint16_t day = date2days(yOff, m, d);
return (day + 6) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6
}
//------------------------------------------
static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s)
{
return ((days * 24L + h) * 60 + m) * 60 + s;
}
//------------------------------------------
// number of days since 2000/01/01, valid for 2001..2099
static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d)
{
if (y >= 2000)
y -= 2000;
uint16_t days = d;
for (uint8_t i = 1; i < m; ++i)
//days += pgm_read_byte(daysInMonth + i - 1);
days += daysInMonth[ + i - 1];
if (m > 2 && y % 4 == 0)
++days;
return days + 365 * y + (y + 3) / 4 - 1;
}
//-----------------------------------------------
uint32_t unixtime(void)
{
uint32_t t;
uint16_t days = date2days(yOff, m, d);
t = time2long(days, hh, mm, ss);
t += SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000
return t;
}
//----------------------------------------------------------