#include "MCP7940_ADI.h" #include // Serial Monitor Cheat Cheat for setting time and alarms // SETTING TIME // format set a to 1 if 12hr mode, then b to 1 if PM, otherwise set to 00 for 24hr mode // Thh:mm:22 ab mm/dd/yr w // Example for setting time to 3:41:00PM 2/4/17 SAT ////T03:41:00 11 02/04/17 7 // SETTING ALARM // abc = alarm mask, like 001=Minutes alarm // d = AM/PM, 1=PM w=weekday // A0hh:mm:ss abc d mm/dd w // Example for setting alarm for 12:13PM on Sunday 2/4 // A012:13:00 111 1 02/04 1 // defines #define RTCADDR B1101111 // page11 datasheet #define RTCSEC 0x00 #define RTCMIN 0x01 #define RTCHOUR 0x02 #define RTCWKDAY 0x03 #define RTCDATE 0x04 #define RTCMTH 0x05 #define RTCYEAR 0x06 #define CONTROL 0x07 #define OSCTRIM 0x08 #define ALM0SEC 0x0A #define ALM0MIN 0x0B #define ALM0HOUR 0x0C #define ALM0WKDAY 0x0D #define ALM0DATE 0x0E #define ALM0MTH 0x0F #define ALM1SEC 0x11 #define ALM1MIN 0x12 #define ALM1HOUR 0x13 #define ALM1WKDAY 0x14 #define ALM1DATE 0x15 #define ALM1MTH 0x16 #define PWRDNMIN 0x18 #define PWRDNHOUR 0x19 #define PWRDNDATE 0x1A #define PWRDNMTH 0x1B #define PWRUPMIN 0x1C #define PWRUPHOUR 0x1D #define PWRUPDATE 0x1E #define PWRUPMTH 0x1F // variables used here byte rtcSeconds, rtcMinutes, rtcHours; byte rtcWeekDay, rtcDay, rtcMonth, rtcYear; boolean rtc12hrMode, rtcPM, rtcOscRunning, rtcPowerFail, rtcVbatEn; String weekDay[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}; boolean mfpPinTriggered = false; void rtcInit() { // RTC Initialize int i; // sets up I2C at 100kHz Wire.setClock(100000); Wire.begin(); Wire.beginTransmission(RTCADDR); Wire.write(CONTROL); Wire.write(0x00); // clear out the entire control register // was 0x41 Wire.endTransmission(); Wire.beginTransmission(RTCADDR); Wire.write(RTCWKDAY); Wire.endTransmission(); Wire.requestFrom(RTCADDR, 1); delay(1); byte rtcWeekdayRegister = Wire.read(); rtcWeekdayRegister |= 0x08; // enable Battery backup Wire.beginTransmission(RTCADDR); Wire.write(RTCWKDAY); Wire.write(rtcWeekdayRegister); Wire.endTransmission(); Wire.beginTransmission(RTCADDR); Wire.write(RTCSEC); Wire.endTransmission(); Wire.requestFrom(RTCADDR, 1); delay(1); byte rtcSecondRegister = Wire.read(); // read out seconds rtcSecondRegister |= 0x80; // flip the start bit to ON Wire.beginTransmission(RTCADDR); Wire.write(RTCSEC); Wire.write(rtcSecondRegister); // write it back in... now the RTC is running Wire.endTransmission(); // read time out of rtc Wire.beginTransmission(RTCADDR); Wire.write(RTCSEC); Wire.endTransmission(); Wire.requestFrom(RTCADDR, 7); // pull out all timekeeping registers delay(1); // little delay } uint32_t getEpochRtc(void) { uint32_t ep; Wire.beginTransmission(RTCADDR); Wire.write(RTCSEC); Wire.endTransmission(); Wire.requestFrom(RTCADDR, 7); // pull out all timekeeping registers delay(1); // little delay // now read each byte in and clear off bits we don't need, hence the AND operations rtcSeconds = Wire.read() & 0x7F; rtcMinutes = Wire.read() & 0x7F; rtcHours = Wire.read() & 0x7F; rtcWeekDay = Wire.read() & 0x3F; rtcDay = Wire.read() & 0x3F; rtcMonth = Wire.read() & 0x3F; rtcYear = Wire.read(); // now format the data, combine lower and upper parts of byte to give decimal number rtcSeconds = (rtcSeconds >> 4) * 10 + (rtcSeconds & 0x0F); rtcMinutes = (rtcMinutes >> 4) * 10 + (rtcMinutes & 0x0F); if ((rtcHours >> 6) == 1) // check for 12hr mode rtc12hrMode = true; else rtc12hrMode = false; // 12hr check and formatting of Hours if (rtc12hrMode) { // 12 hr mode so get PM/AM if ((rtcHours >> 5) & 0x01 == 1) rtcPM = true; else rtcPM = false; rtcHours = ((rtcHours >> 4) & 0x01) * 10 + (rtcHours & 0x0F); // only up to 12 } else { // 24hr mode rtcPM = false; rtcHours = ((rtcHours >> 4) & 0x03) * 10 + (rtcHours & 0x0F); // uses both Tens digits, '23' } // weekday register has some other bits in it, that are pulled out here if ((rtcWeekDay >> 5) & 0x01 == 1) rtcOscRunning = true; // good thing to check to make sure the RTC is running else rtcOscRunning = false; if ((rtcWeekDay >> 4) & 0x01 == 1) rtcPowerFail = true; // if the power fail bit is set, we can then go pull the timestamp for when it happened else rtcPowerFail = false; if ((rtcWeekDay >> 3) & 0x01 == 1) // check to make sure the battery backup is enabled rtcVbatEn = true; else rtcVbatEn = false; rtcWeekDay = rtcWeekDay & 0x07; // only the bottom 3 bits for the actual weekday value // more formatting bytes into decimal numbers rtcDay = (rtcDay >> 4) * 10 + (rtcDay & 0x0F); rtcMonth = ((rtcMonth >> 4) & 0x01) * 10 + (rtcMonth & 0x0F); rtcYear = (rtcYear >> 4) * 10 + (rtcYear & 0x0F); dt.Second = rtcSeconds; dt.Minute = rtcMinutes; dt.Hour = rtcHours; dt.Wday = rtcWeekDay; dt.Day = rtcDay; dt.Month = rtcMonth; dt.Year = rtcYear; // dt.Year += 30; //from 1970. not 2000 dt.Year += 30; ep = makeTime(dt); // dt.Year -= 30; if (VB) { Serial.print("Epoch Created: "); Serial.println(ep); // print everything out Serial.print(rtcHours); Serial.print(":"); Serial.print(rtcMinutes); Serial.print(":"); Serial.print(rtcSeconds); if (rtc12hrMode == true && rtcPM == true) Serial.print(" PM "); else if (rtc12hrMode == true && rtcPM == false) Serial.print(" AM "); if (rtc12hrMode == false) Serial.print(" 24hr "); if (rtcWeekDay > 0) if (rtcWeekDay < 8) { // Serial.print("WeekDay="); // Serial.print(rtcWeekDay); Serial.print(weekDay[rtcWeekDay - 1]); Serial.print(" "); Serial.print(rtcMonth); Serial.print("/"); Serial.print(rtcDay); Serial.print("/"); Serial.print(rtcYear); Serial.println(""); } } return (ep); } /* void checkAlarm() { if (mfpPinTriggered == true) { Serial.println("MFP Triggered"); mfpPinTriggered = false; Wire.beginTransmission(RTCADDR);//Enable Alarm0 Wire.write(ALM0WKDAY); Wire.endTransmission(); Wire.requestFrom(RTCADDR, 1); delay(1); byte alarm0Check = Wire.read(); Serial.println(alarm0Check, BIN); if (((alarm0Check >> 3) & 0x01) == 1) Serial.println("Alarm0 Triggered"); else Serial.println("Alarm0 False Alarm"); } } */ void setEpochRtc(uint32_t ep) { tmElements_t et; parms.write(69, ep); // just to monitor last rtc set Serial.print("Setting RTC with Epoch: "); Serial.println(ep); // breakTime off by 30 years breakTime(ep, et); et.Year -= 30; // let's go change the time: // first stop the clock: Wire.beginTransmission(RTCADDR); Wire.write(RTCSEC); Wire.write(0x00); Wire.endTransmission(); getEpochRtc(); // rtcGetTime();//go grab the time again just to make sure the osc stopped if (rtcOscRunning == false) { // oscillator stopped, we're good Serial.println("RTC has stopped - Changing Time"); Wire.beginTransmission(RTCADDR); // set the time/date Wire.write(RTCSEC); Wire.write(((et.Second / 10) << 4) + (et.Second % 10)); Wire.write(((et.Minute / 10) << 4) + (et.Minute % 10)); Wire.write(((et.Hour / 10) << 4) + (et.Hour % 10)); Wire.write(et.Wday + 8); Wire.write(((et.Day / 10) << 4) + (et.Day % 10)); Wire.write(((et.Month / 10) << 4) + (et.Month % 10)); Wire.write(((et.Year / 10) << 4) + (et.Year % 10)); // two digit year Wire.endTransmission(); Wire.beginTransmission(RTCADDR); // start back up Wire.write(RTCSEC); Wire.endTransmission(); Wire.requestFrom(RTCADDR, 1); delay(1); byte rtcSecondRegister = Wire.read(); rtcSecondRegister |= 0x80; // start bit! Wire.beginTransmission(RTCADDR); Wire.write(RTCSEC); Wire.write(rtcSecondRegister); Wire.endTransmission(); Wire.beginTransmission(RTCADDR); // Enable Alarm0 Wire.write(CONTROL); Wire.endTransmission(); Wire.requestFrom(RTCADDR, 1); delay(1); byte rtcControlRegister = Wire.read(); rtcControlRegister |= 0x10; // enable alm0 Wire.beginTransmission(RTCADDR); Wire.write(CONTROL); Wire.write(rtcControlRegister); Wire.endTransmission(); } Serial.println(" --RTC set finished"); } String makeTimeStr(void) { getEpochRtc(); return (String(dt.Year - 30) + "-" + String(dt.Month) + "-" + String(dt.Day) + "-" + String(dt.Hour) + "-" + String(dt.Minute) + "-" + String(dt.Second)); } void toggleMFP(void) { Wire.beginTransmission(RTCADDR); Wire.write(CONTROL); Wire.write(0x80); Wire.endTransmission(); delay(250); Wire.beginTransmission(RTCADDR); Wire.write(CONTROL); Wire.write(0x00); Wire.endTransmission(); }