MAXIM DS3231 accurate Real Time Clock Library

Dependents:   20180621_FT813

Fork of DS3231 by remi cormier

ARM_RTC.cpp

Committer:
JackB
Date:
2018-07-23
Revision:
3:1af2ff7cfe26

File content as of revision 3:1af2ff7cfe26:

#include "ARM_RTC.h"

ARM_RTC::ARM_RTC()
{
    setTimeZone(1);
    dayLightSaving = true;
}

bool ARM_RTC::checkTimeLost(void)
{
    return (atoi(getFormatedDateTime("%Y")) <= 2015) ? true : false;
}

// BCD to decimal conversion
int ARM_RTC::bcd2dec(int bcd)
{
    return(((bcd & 0xF0) >> 4) * 10 + (bcd & 0x0F));
}

// decimal to BCD conversion
int ARM_RTC::dec2bcd(int dec)
{
    return((dec / 10) * 16 + (dec % 10));
}

void ARM_RTC::setTimeZone(double TZ)
{
    timeZoneOffset = (uint32_t) (TZ * 3600.0f);
}

double ARM_RTC::getTimeZone(void)
{
    return (double)timeZoneOffset / 3600.0f;
}

void ARM_RTC::setDate(int day, int month, int year)
{
    printf("%d-%d-%d\n", day, month, year);
    // First read
    time_t rawtime;
    struct tm t;
    struct tm * t2;

    time(&rawtime);
    t2 = localtime(&rawtime);

    if (year<100) {
        year+=2000;
    }
    if (year > 1900)
        t.tm_year = year - 1900;    // adjust for tm structure required values
    else
        t.tm_year = year;
    t.tm_mon  = month - 1;        // adjust for tm structure required values
    t.tm_mday = day;
    t.tm_hour = t2->tm_hour;
    t.tm_min  = t2->tm_min;
    t.tm_sec  = t2->tm_sec;

    // Set system date and time
    rawtime = mktime(&t);   // seconds since the Epoch
    set_time(rawtime);

//    time_t t_seconds = time(NULL);
//    char buffer[32];
//    strftime(buffer, 32, "%A %d-%m-%Y %H:%M:%S", localtime(&t_seconds));
//    printf("%s\n", buffer);
}

// set time register
void ARM_RTC::setTime(int hours, int minutes, int seconds)
{
    // First read
    time_t rawtime;
    struct tm t;
    struct tm * t2;

    time(&rawtime);
    t2 = localtime(&rawtime);

    t.tm_hour = hours;
    t.tm_min  = minutes;
    t.tm_sec  = seconds;
    t.tm_year = t2->tm_year;
//    t.tm_year = 2016-1900;
    t.tm_mon  = t2->tm_mon;
    t.tm_mday = t2->tm_mday;
//    t.tm_wday = t2->tm_wday;
//    printf("%d-%d-%d %d:%d:%d\n", t.tm_year, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
    
    // Set system date and time
    rawtime = mktime(&t);   // seconds since the Epoch
    set_time(rawtime);

//    time_t t_seconds = time(NULL);
//    char buffer[32];
//    strftime(buffer, 32, "%A %d-%m-%Y %H:%M:%S", localtime(&t_seconds));
//    printf("%s\n", buffer);
}

void ARM_RTC::setDateTime(int day, int month, int year, int hours, int minutes, int seconds)
{
    // First read
    time_t rawtime;
    struct tm t;
    struct tm * t2;

    time(&rawtime);
    t2 = localtime(&rawtime);

    if (year<100) {
        year+=2000;
    }
    if (year > 1900)
        t.tm_year = year - 1900;    // adjust for tm structure required values
    else
        t.tm_year = year;
    t.tm_mon  = month - 1;        // adjust for tm structure required values
    t.tm_mday = day;

    t.tm_hour = hours;
    t.tm_min  = minutes;
    t.tm_sec  = seconds;

    // Set system date and time
    rawtime = mktime(&t);   // seconds since the Epoch
    set_time(rawtime);

//    time_t t_seconds = time(NULL);
//    char buffer[32];
//    strftime(buffer, 32, "%A %d-%m-%Y %H:%M:%S", localtime(&t_seconds));
//    printf("%s\n", buffer);
}


// read the date and time registers and set system clock
void ARM_RTC::setSystemClock(void)
{
//    int dayOfWeek, day, month, year, hours, minutes, seconds;
//    readDateTime(&dayOfWeek, &day, &month, &year, &hours, &minutes, &seconds);

//    getDateTime(&t);

//    time_t secondsEpoch = mktime(&t);   // seconds since the Epoch
    // Get weekday
//    t = *localtime(&secondsEpoch);
//    set_time(secondsEpoch);
}

void ARM_RTC::readDateTime(void)
{
    // First read
    time_t rawtime;
    struct tm t;
    struct tm * t2;
    time(&rawtime);
    t2 = localtime(&rawtime);

//    time(&secondsEpoch);
//    t = localtime(&secondsEpoch);
}

void ARM_RTC::getDateTime(struct tm *t)
{
    time(&secondsEpoch);
    t = localtime(&secondsEpoch);
}

void ARM_RTC::setDateTime(struct tm *time)
{
    secondsEpoch = mktime(time);   // seconds since the Epoch
    set_time(secondsEpoch);
}

void ARM_RTC::setDateTimeSecsSince1900(uint32_t secsSince1900)
{
    setDateTimeSecsSince1970(secsSince1900 - NTP_OFFSET);
}

void ARM_RTC::setDateTimeSecsSince1970(uint32_t secsSince1970)
{
    set_time(secsSince1970);
}

// read the date and time registers and return secondsEpoch
uint32_t ARM_RTC::getDateTimeSecsSince1970(void)
{
    return (mktime(&t) - timeZoneOffset);   // seconds since the Epoch
}

// read the date and time registers and return secondsEpoch
time_t ARM_RTC::getDateTimeSecsSince1970TZ(void)
{
    return mktime(&t);   // seconds since the Epoch
}

int ARM_RTC::getDayOfWeek(int mday, int month, int year)   // y > 1752, 1 <= m <= 12
{
    t.tm_year = year - 1900;    // adjust for tm structure required values
    t.tm_mon  = month - 1;        // adjust for tm structure required values
    t.tm_mday = mday;
    t.tm_hour = 0;
    t.tm_min = 0;
    t.tm_sec = 0;
    time_t secondsEpoch = mktime(&t);   // seconds since the Epoch
    t = *localtime(&secondsEpoch);
    return t.tm_wday;                   // (0=Sunday, 6=Saturday)
    
//    static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
//    year -= month < 3;
//    return ((year + year/4 - year/100 + year/400 + t[month-1] + mday) % 7) + 1; // 01 - 07, 01 = Sunday
}

char * ARM_RTC::getDayOfWeekName(void)   // y > 1752, 1 <= m <= 12
{
    time_t secondsEpoch = mktime(&t);   // seconds since the Epoch
    t = *localtime(&secondsEpoch);
    strftime(buffer, 32, "%a", localtime(&secondsEpoch));
    return buffer;
}

// char *buffer;
// buffer = ARM_RTC.getFormatedDateTime("%A %d-%m-%Y %H:%M:%S");
// TFT.gotoxy(0,7);
// TFT.printf("Date: %s\n", buffer);
char * ARM_RTC::getFormatedDateTime(char *format)
{
    time_t t_seconds = time(NULL);
    strftime(buffer, 40, format, localtime(&t_seconds));
    return buffer;
}

bool ARM_RTC::getSummerTime(void)
{
    getDateTime(&t);

    time_t secondsEpoch = mktime(&t);   // seconds since the Epoch
    t = *localtime(&secondsEpoch);
    strftime(buffer, 32, "%j", localtime(&secondsEpoch));
    int dayOfYearC = atoi(buffer);

    strftime(buffer, 32, "%Y", localtime(&secondsEpoch));
    int year = atoi(buffer);

    int index  = (year - 2011) * 5;
    if (index < 0)
        index = 0;
    if (index > 440)                    // (2099 - 2011) * 5 = 440
        index = 440;
    
    int monthS = atoi(SummerTime[index+1]);
    int dayS   = atoi(SummerTime[index+2]);

    t.tm_mon   = monthS - 1;            // adjust for tm structure required values
    t.tm_mday  = dayS;
    secondsEpoch = mktime(&t);   // seconds since the Epoch
    t = *localtime(&secondsEpoch);
    strftime(buffer, 32, "%j", localtime(&secondsEpoch));
    int dayOfYearS = atoi(buffer);

    int monthE = atoi(SummerTime[index+3]);
    int dayE   = atoi(SummerTime[index+4]);

    t.tm_mon   = monthE - 1;            // adjust for tm structure required values
    t.tm_mday  = dayE;
    secondsEpoch = mktime(&t);   // seconds since the Epoch
    t = *localtime(&secondsEpoch);
    strftime(buffer, 32, "%j", localtime(&secondsEpoch));
    int dayOfYearE = atoi(buffer);

    return ((dayOfYearC >= dayOfYearS) && (dayOfYearC < dayOfYearE)) ? true : false;
}

int ARM_RTC::dayOfYearC(void)
{
    getDateTime(&t);

    time_t secondsEpoch = mktime(&t);   // seconds since the Epoch
    strftime(buffer, 32, "%j", localtime(&secondsEpoch));
    return atoi(buffer);
}

char * ARM_RTC::getSunRise(void)
{
    return (char*) SunRise[dayOfYearC()];
}

char * ARM_RTC::getSunSet(void)
{
    return (char*) SunSet[dayOfYearC()];
}

char * ARM_RTC::getDayLength(void)
{
    return (char*) DayLength[dayOfYearC()];
}

int ARM_RTC::getSunRiseMinute(void)
{
    int doy = dayOfYearC();
    int h = atoi(substr((char*)SunRise[doy], 0, 2));
    int m = atoi(substr((char*)SunRise[doy], 3, 2));
    return h * 60 + m;
}

int ARM_RTC::getSunSetMinute(void)
{
    int doy = dayOfYearC();
    int h = atoi(substr((char*)SunSet[doy], 0, 2));
    int m = atoi(substr((char*)SunSet[doy], 3, 2));
    return h * 60 + m;
}

bool ARM_RTC::checkSunRise(void)
{
    int dayOfWeek, mday, month, year, hours, minutes, seconds;
//    readDateTime(&dayOfWeek, &mday, &month, &year, &hours, &minutes, &seconds);

//    t.tm_year = year - 1900;    // adjust for tm structure required values
//    t.tm_mon  = month - 1;        // adjust for tm structure required values
//    t.tm_mday = mday;
//    t.tm_hour = 0;
//    t.tm_min  = 0;
//    t.tm_sec  = 0;

    int absMinute     = t.tm_hour * 60 + t.tm_min;
    int SunRiseMinute = getSunRiseMinute();
    int SunSetMinute  = getSunSetMinute();

    return ((absMinute >= SunRiseMinute) && (absMinute < SunSetMinute)) ? true : false;
}

void ARM_RTC::substr(char *s, char *d, int pos, int len)
{
    char *t;
    s = s+pos;
    t = s+len;
    while (s != t) {
        *d=*s;
        s++;
        d++;
    }
    *d='\0';
}

char * ARM_RTC::substr(char *s, int pos, int len)
{
    char *t;
    char *d;
    d = buffer;
    s = s+pos;
    t = s+len;
    while (s != t) {
        *d=*s;
        s++;
        d++;
    }
    *d='\0';
    return buffer;
}