// Arduino program freezing if RTC (DS3231) disconnected...?
// https://forum.arduino.cc/t/arduino-program-freezing-if-rtc-ds3231-disconnected/1324240

//
//  RTC freeze demo (DS3231)
//
/*
  #include "DS3231.h"     // initialize RTC
  // #include <Wire.h>

  DS3231 rtc();   // (RTC) Define object

  Time rtc_time;    // (RTC) Define date/time structure for RTC

  void setup()
  {
  Serial.begin(115200);
  Serial.print("A5 = ");
  Serial.print(A5);
  Serial.print(",\t A4 = ");
  Serial.println(A4);
  Serial.print("SCL = ");
  Serial.print(SCL);
  Serial.print(",\t SDA = ");
  Serial.println(SDA);
  rtc.begin();      // Initialize the rtc object

  rtc.setTime(15, 41, 45);
  rtc.setDate(24, 11, 2024);

  Serial.print(" rtc_time: ");
  Serial.println(rtc.getTimeStr(FORMAT_LONG));
  }

  String rtc_time_str;  // using RTC time only

  void loop()
  {
  Serial.println(" --> top of loop()");

  rtc_time_str = rtc.getTimeStr(FORMAT_LONG);

  Serial.println("The current time is " + rtc_time_str);
  Serial.println(" I will unplug an i2c line at 3:42p (15:42:00)");

  delay(1000);
  } */
/*
  DS3231_set.pde
  Eric Ayars
  4/11

  Test of set-time routines for a DS3231 RTC

*/

#include <DS3231.h>
#include <Wire.h>

#define RTC_1Hz_Pin 2

DS3231 myRTC;

bool century = false;
bool h12Flag= false;
bool pmFlag= false;
byte alarmDay, alarmHour, alarmMinute, alarmSecond, alarmBits;
bool alarmDy, alarmH12Flag, alarmPmFlag;

byte year;
byte month;
byte date;
byte dOW;
byte hour;
byte minute;
byte second;

void getDateStuff(byte& year, byte& month, byte& date, byte& dOW,
                  byte& hour, byte& minute, byte& second) {
  // Call this if you notice something coming in on
  // the serial port. The stuff coming in should be in
  // the order YYMMDDwHHMMSS, with an 'x' at the end.
  boolean gotString = false;
  char inChar;
  byte temp1, temp2;
  char inString[20];

  byte j = 0;
  while (!gotString) {
    if (Serial.available()) {
      inChar = Serial.read();
      inString[j] = inChar;
      j += 1;
      if (inChar == 'x') {
        gotString = true;
      }
    }
  }
  Serial.println(inString);
  // Read year first
  temp1 = (byte)inString[0] - 48;
  temp2 = (byte)inString[1] - 48;
  year = temp1 * 10 + temp2;
  // now month
  temp1 = (byte)inString[2] - 48;
  temp2 = (byte)inString[3] - 48;
  month = temp1 * 10 + temp2;
  // now date
  temp1 = (byte)inString[4] - 48;
  temp2 = (byte)inString[5] - 48;
  date = temp1 * 10 + temp2;
  // now Day of Week
  dOW = (byte)inString[6] - 48;
  // now hour
  temp1 = (byte)inString[7] - 48;
  temp2 = (byte)inString[8] - 48;
  hour = temp1 * 10 + temp2;
  // now minute
  temp1 = (byte)inString[9] - 48;
  temp2 = (byte)inString[10] - 48;
  minute = temp1 * 10 + temp2;
  // now second
  temp1 = (byte)inString[11] - 48;
  temp2 = (byte)inString[12] - 48;
  second = temp1 * 10 + temp2;
}

void setup() {
  // Start the serial port
  Serial.begin(115200);

  // Start the I2C interface
  Wire.begin();
  Wire.setWireTimeout(1000); // 1000 µs or 1 ms

  pinMode(LED_BUILTIN, OUTPUT);
  // attachInterrupt(digitalPinToInterrupt(RTC_1Hz_Pin), displayDateTime, RISING);
  attachInterrupt(digitalPinToInterrupt(RTC_1Hz_Pin), displayDateTime, CHANGE);
}

void displayDateTime(void) {
  digitalWrite(LED_BUILTIN, digitalRead(RTC_1Hz_Pin));
}

void loop() {

  // If something is coming in on the serial line, it's
  // a time correction so set the clock accordingly.
  if (Serial.available()) {
    getDateStuff(year, month, date, dOW, hour, minute, second);

    myRTC.setClockMode(false);  // set to 24h
    //setClockMode(true); // set to 12h

    myRTC.setYear(year);
    myRTC.setMonth(month);
    myRTC.setDate(date);
    myRTC.setDoW(dOW);
    myRTC.setHour(hour);
    myRTC.setMinute(minute);
    myRTC.setSecond(second);

    // Test of alarm functions
    // set A1 to one minute past the time we just set the clock
    // on current day of week.
    myRTC.setA1Time(dOW, hour, minute + 1, second, 0x0, true,
                    false, false);
    // set A2 to two minutes past, on current day of month.
    myRTC.setA2Time(date, hour, minute + 2, 0x0, false, false,
                    false);
    // Turn on both alarms, with external interrupt
    myRTC.turnOnAlarm(1);
    myRTC.turnOnAlarm(2);

  }


  // send what's going on to the serial monitor.

  // Start with the year
  Serial.print("2");
  if (century) {			// Won't need this for 89 years.
    Serial.print("1");
  } else {
    Serial.print("0");
  }
  Serial.print(myRTC.getYear(), DEC);
  Serial.print(' ');

  // then the month
  Serial.print(myRTC.getMonth(century), DEC);
  Serial.print(" ");

  // then the date
  Serial.print(myRTC.getDate(), DEC);
  Serial.print(" ");

  // and the day of the week
  Serial.print(myRTC.getDoW(), DEC);
  Serial.print(" ");

  // Finally the hour, minute, and second
  Serial.print(myRTC.getHour(h12Flag, pmFlag), DEC);
  Serial.print(" ");
  Serial.print(myRTC.getMinute(), DEC);
  Serial.print(" ");
  Serial.print(myRTC.getSecond(), DEC);

  // Add AM/PM indicator
  if (h12Flag) {
    if (pmFlag) {
      Serial.print(" PM ");
    } else {
      Serial.print(" AM ");
    }
  } else {
    Serial.print(" 24h ");
  }

  // Display the temperature
  Serial.print("T=");
  Serial.print(myRTC.getTemperature(), 2);

  // Tell whether the time is (likely to be) valid
  if (myRTC.oscillatorCheck()) {
    Serial.print(" O+");
  } else {
    Serial.print(" O-");
  }

  // Indicate whether an alarm went off
  if (myRTC.checkIfAlarm(1)) {
    Serial.print(" A1!");
  }

  if (myRTC.checkIfAlarm(2)) {
    Serial.print(" A2!");
  }

  // New line on display
  Serial.println();

  // Display Alarm 1 information
  Serial.print("Alarm 1: ");
  myRTC.getA1Time(alarmDay, alarmHour, alarmMinute, alarmSecond, alarmBits, alarmDy, alarmH12Flag, alarmPmFlag);
  Serial.print(alarmDay, DEC);
  if (alarmDy) {
    Serial.print(" DoW");
  } else {
    Serial.print(" Date");
  }
  Serial.print(' ');
  Serial.print(alarmHour, DEC);
  Serial.print(' ');
  Serial.print(alarmMinute, DEC);
  Serial.print(' ');
  Serial.print(alarmSecond, DEC);
  Serial.print(' ');
  if (alarmH12Flag) {
    if (alarmPmFlag) {
      Serial.print("pm ");
    } else {
      Serial.print("am ");
    }
  }
  if (myRTC.checkAlarmEnabled(1)) {
    Serial.print("enabled");
  }
  Serial.println();

  // Display Alarm 2 information
  Serial.print("Alarm 2: ");
  myRTC.getA2Time(alarmDay, alarmHour, alarmMinute, alarmBits, alarmDy, alarmH12Flag, alarmPmFlag);
  Serial.print(alarmDay, DEC);
  if (alarmDy) {
    Serial.print(" DoW");
  } else {
    Serial.print(" Date");
  }
  Serial.print(" ");
  Serial.print(alarmHour, DEC);
  Serial.print(" ");
  Serial.print(alarmMinute, DEC);
  Serial.print(" ");
  if (alarmH12Flag) {
    if (alarmPmFlag) {
      Serial.print("pm");
    } else {
      Serial.print("am");
    }
  }
  if (myRTC.checkAlarmEnabled(2)) {
    Serial.print("enabled");
  }

  // display alarm bits
  Serial.println();
  Serial.print("Alarm bits: ");
  Serial.println(alarmBits, BIN);

  Serial.println();
  delay(1000);
}
GND5VSDASCLSQWRTCDS1307+