@alto777: I'm not enjoying that my (cheap knock-off) modules are not very accurate. I do, however, enjoy the fact that the aging register can be used to calibrate the modules to an accuracy that is much better than the default.
The following code works for getting/setting the aging register of a DS3231M module. I cannot guarantee that this will work with other modules. The RTC module and Wire objects must be initialized and the code does not include any error checking/handling.
#define DS3231_AGING_OFFSET 0x10
int8_t ds3231_get_aging_offset()
{
//Returns the aging offset, defaults to 0
Wire.beginTransmission(DS3231_ADDRESS);
Wire.write(DS3231_AGING_OFFSET);
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 1);
return Wire.read() & 0xFF;
}
void ds3231_set_aging_offset(int8_t offset, bool force_conversion = true)
{
//offset = a value from -127 .. 127
//force_conversion = force the clock to use the value immediately
//Negative values will speed up the module.
//A change of +/- 1 will adjust the time base by 0.12ppm
Wire.beginTransmission(DS3231_ADDRESS);
Wire.write(DS3231_AGING_OFFSET);
Wire.write(offset);
Wire.endTransmission();
if (force_conversion)
{
Wire.beginTransmission(DS3231_ADDRESS);
Wire.write(DS3231_CONTROL);
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 1);
uint8_t ctrl = Wire.read() | (1 << 5);
Wire.beginTransmission(DS3231_ADDRESS);
Wire.write(DS3231_CONTROL);
Wire.write(ctrl);
Wire.endTransmission();
}
}
P.S: The setting code should only be performed when the time of the clock is adjusted due to a battery replacement or alike.