RTC_DS3231: correctly handle negative temperatures #303
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
As reported in issue #287, the method
RTC_DS3231::getTemperature()
fails on negative temperatures. This is because the conversion from raw bytes to afloat
-typed temperature assumes the value is always positive, wheres the datasheet specifies it is stored as a signed, two's complement integer.This pull request fixes the method by changing the conversion code to this:
Some points worth noting:
Casting
buffer[0]
to an unsigned type is meant to avoid signed integer overflow, which is undefined behavior in C++.Assigning the result to a signed integer makes numbers with the most significant bit set be interpreted as negative. There is no extra work to do, as all current processors use two’s complement representation internally.
Multiplying by
1 / 256.0
(rather than1 / 4.0
) obviates the need for the 6-bit shift. Also,1 / 256.0
being a compile-time constant, there is no division performed at run-time (which would be expensive).This code also reduces the number of floating-point operations to only two (int-to-float conversion and multiplication), v.s. four in the original code (two int-to-float conversions, one multiplication and one addition).
Tested down to −27.00°C by @i440bx.
Fixes #287.