-
Notifications
You must be signed in to change notification settings - Fork 709
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
RTC_DS3231.cpp getTemperature() doesn't provide for negative temps #287
Comments
Indeed you are right. This method will fail to correctly read a negative temperature.
This won't work either. It would, if the temperature was encoded using the sign–magnitude representation. However, according to the datasheet of the DS3231, “The temperature is encoded in two’s complement format.” (link mine). I would instead try this: float RTC_DS3231::getTemperature() {
uint8_t buffer[2] = {DS3231_TEMPERATUREREG, 0};
i2c_dev->write_then_read(buffer, 1, buffer, 2);
int16_t temp = uint16_t(buffer[0]) << 8 | buffer[1];
return temp * (1 / 256.0);
} Some notes:
Could you give a try to this implementation? |
I'm not an experienced coder so I am glad there are folks like you to take me to school. I did stupidly assume sign-magnitude representation. I did some reseach and your suggestion not only appears correct but is far more elegant. I'll try it when I get home. Thank you!! |
I have copied the code into my RTC_DS3231.cpp and it runs flawless :) It shows negative temperatures low to -27.00°C. Lower my medical ice spray cant cool down. |
RTC_DS3231::getTemperature() assumes the temperature register stores a positive integer whereas, according to the datasheet,[1] it is a signed number in two’s complement format. Fix the method by transferring this register into a signed 16-bit integer. As the CPU uses two’s complement natively, no further conversion is needed other than scaling by a factor (1/256.0). Fixes adafruit#287. [1] https://www.analog.com/media/en/technical-documentation/data-sheets/DS3231.pdf#page=15
I believe as written, the DS3231 method for getting the temperature does not look at the MSB of the high byte to determine if the temperature is positive or negative. I would recommend something like this for the update:
float RTC_DS3231::getTemperature() {
uint8_t buffer[2] = {DS3231_TEMPERATUREREG, 0};
float temperatureDegC;
i2c_dev->write_then_read(buffer, 1, buffer, 2);
temperatureDegC = (float)buffer[0] + (float)(buffer[1] >> 6) * 0.25f;
if (buffer[0] & 0x80) {
temperatureDegC *= -1.0f;
}
return temperatureDegC;
}
The text was updated successfully, but these errors were encountered: