Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No return value when failing to talk to the RTC #13

Open
YHatahet opened this issue Apr 22, 2019 · 2 comments
Open

No return value when failing to talk to the RTC #13

YHatahet opened this issue Apr 22, 2019 · 2 comments

Comments

@YHatahet
Copy link

YHatahet commented Apr 22, 2019

If the arduino boots up and the RTC is not connected, it will not return error values for some parameters such as date and time.

A simple fix is to add the following lines of code in every method:

if (!Wire.available())
{
    return 99; // Some obvious error value
}

For example in the getSecond() method:

byte DS3231::getSecond() {
    Wire.beginTransmission(CLOCK_ADDRESS);
    Wire.write(0x00);
    Wire.endTransmission();
    Wire.requestFrom(CLOCK_ADDRESS, 1);

        if (!Wire.available())
        {
            return 99; // Some obvious error value
        }

    return bcdToDec(Wire.read());
}
@IowaDave
Copy link
Collaborator

@awickert , @YHatahet Yes, the "Get" and "Set" functions generally do not report I2C communications errors. There might be one that does; if so I have forgotten which one.

What would steps should we take so that code writers may verify communications with the DS3231? I can think of three approaches:

Approach #1.

Add a new function, byte DS3231::responsive(). It would perform a "get" on some register, then return Wire.available() . Comment: this would provide an overarching mechanism to detect the status of a DS3231 I2C connection. Programs could use it thus:

if (myRTC.responsive()) {
   // make connection-critical calls to the DS3231
}

Approach #2

Individually add a test for Wire.available() to each and all functions that use I2C, return some suitable value as an error indicator in lieu of the anticipated value, and instruct Library users to consider testing for the error values in their code.

Comment: this approach would be more work for both the developers and the users compared to approach #1. Also, the error codes would add considerable complexity to the RTClib::now() function.

Approach #3

Overload the functions that use I2C. Supply alternative versions that add a reference to boolean variable where an error indication can be placed. Example:

byte DS3231::getSecond( bool& i2cResponsive) {
	_Wire.beginTransmission(CLOCK_ADDRESS);
	_Wire.write(0x00);
	_Wire.endTransmission();

	_Wire.requestFrom(CLOCK_ADDRESS, 1);
        i2cResponsive = Wire.available() ? true : false;
	return bcdToDec(_Wire.read());
}

Comment: approach #3 would be more work for developers and documentation writers. However -- a Good Thing -- it would be just as easy for program writers as approach #1. And it would avoid having to revise RTClib::now(). See the example below.

bool i2cAvailable

byte foo = getSecond(i2cAvailable);
if (i2cAvailable) {
   uint32_t timeNow = RTClib::now();
}

Approach #3 looks like the most thorough anbd user-friendly alternative to me. It's just going to be a lot of work.

At the time of writing, mid-September 2022, I have some non-tech projects to finish. I would be glad to put either approach #1 or #3 on my ToDo list for later this year, if you would kindly indicate which approach you would prefer.

@IowaDave
Copy link
Collaborator

Hmm... Markdown transformed my numbering of approaches in that previous post. It turned the numbers into links for unrelated content. When you read it, please disregard the links.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants