sleemanj / DS3231_Simple

An Arduino Library for EASY communication with DS3231 I2C RTC Clock and Atmel AT24C32 I2C EEPROM commonly found on the same board. Implements setting, getting the time/date, setting, checking and clearing alarms, and dead-easy circular-buffered logging of data with timestamp.
MIT License
82 stars 25 forks source link

"read only" mode for checkAlarms #22

Closed histefanhere closed 3 years ago

histefanhere commented 3 years ago

Hello!

Your library is awesome because it provides a lot of functionality with interacting with the alarms of the DS3231, many libraries don't offer as much control.

In my use case I have the SQW pin controlling a power subsystem which is what provides power to the Arduino, and I need to check if the Arduino was turned on via an alarm or manually by calling checkAlarms. However, doing this also clears the alarms immediately after meaning the SQW pin floats, power to the arduino is cut and everything fails.

The checkAlarms function should have a "read only" mode where it doesn't change anything on the clock, just as the name implies "check" on the alarms. This means any fired alarms would stay on until you set a new alarm time and call checkAlarms() again but this time letting it write to the chip and letting the alarms re-prime properly.

It's a fairly simple and intuitive change that can accomplish this

histefanhere commented 3 years ago

There's another element to this too... in the begin() method the alarms are disabled (and control bytes cleared?) which is also a problem for my setup as it also prematurely cuts the power to the arduino. I'm not sure if there's any standard for begin functions but could it be possible to pass a parameter to begin that would disable these from executing? It seems a strange thing to do anyway, disable and reset features of the chip before it's even turned on and used by scripts, we're effectively losing information about it.

sleemanj commented 3 years ago

Merged your PR.

As for the rest, I'd suggest something like the below, if you test and submit a pull request. Arguably the reset might also want to reset the time.

.h

void begin( uint8_t beginWithReset = true );
void DS3231_Simple::reset();

.cpp

void DS3231_Simple::begin(uint8_t beginWithReset)
{  
  Wire.begin();

  if(beginWithReset)
  {
    reset();
  }
}

void DS3231_Simple::reset()
{
  // Setup the clock to make sure that it is running, that the oscillator and 
  // square wave are disabled, and that alarm interrupts are disabled
  rtc_i2c_write_byte(0xE, 0b00000000);
  disableAlarms();
}