Skip to content

Conversation

@mkrzewic
Copy link
Contributor

@mkrzewic mkrzewic commented Nov 7, 2020

These are mostly minor additions (useful to me, might be to others as well) with the exception of commit cd2d2b6 which changes the signature of millisToWaitForConversion to return an unsigned int - it fixes a compiler warning in the common case of comparison to millis().


// returns number of milliseconds to wait till conversion is complete (based on IC datasheet)
int16_t DallasTemperature::millisToWaitForConversion(uint8_t bitResolution) {
uint16_t DallasTemperature::millisToWaitForConversion(uint8_t bitResolution) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good one, this fixes mixed signed / unsigned math.
Are there argument to use uint32_t instead of uint16_t?

  • millis() and micros() return uint32_t (most timing code I know use 32 bit)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed, millis() returns a 32 bit unsigned (on Arduino at least) so there might be an argument to use that consistently, in this case the function return space would fit in 8 bit, so one might even consider that :) I went with keeping the spirit of the lib and did not opt for changing the layout :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am 100% OK with 16 bit unsigned as 32 bit is indeed not needed, given the range of possible values.
(solved)

}

// convert from Celsius to raw
uint16_t DallasTemperature::celsiusToRaw(float celsius) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
Interesting function, ==> for storage / communication data reduction.

Why do you discard the decimal part?
For the integer part an int8_t would be sufficient (from storage point of view)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When opting for working internally without floating point math (with raw temperatures) one also needs something to convert values on the input which usually are entered in degrees... that is my use case.
The decimal part that is discarded is at most 1/128 of a degree (since that happens after the multiplication), well below the resolution of these sensors, no reason to sacrifice performance and complicate life with proper rounding I think...

Copy link
Contributor Author

@mkrzewic mkrzewic Nov 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for storing the result we need (50+125)*128 = 23040 values = minimum of 15 bits, so we're good with int16_t :) (was unsigned by mistake, fixed in last commit)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I understand the idea better now,

  • please add a few lines (like above) to explain the mapping you make.
  • can you add an example sketch that is showing the use of the function. E.g. one that shows and checks the conversion in two ways, in pseudocode, or one that calculates the average based upon raw values (or both).
for (x = -50 to 125) celsiusToRaw(rawtoCelsius(x)) == x
  • The raw value -127 is used for DEVICE_DISCONNECTED_C so it can (will) occur. Your algorithm has no problem with it, just to be sure you know it can happen. You might need to check it especially and possibly map all non valid values to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks for the comments. I added an explanation.
In order to add a range checking something more would need to be added. The existing value of -127 signals a hardware condition, semantically it is then not a good choice to signal an out of range condition. So we could add another sentinel value to signify that. BUT: it will complicate life and introduce the need for caller to check for yet another value.
I would propose to leave it as is (for this function), since there is no technical reason to do impose that limit: if the user wishes to do operations on temperature values outside of the sensor's range then the user should be allowed to do so, I think there might be legitimate use cases here (e.g. set a thermostat temp to 200C to make sure it stays on at max power or so).
I can make a note of this in the code, if it is not evident enough:)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think it is OK so, and we will see if it generates questions or happy faces in time :)

@RobTillaart
Copy link
Contributor

RobTillaart commented Nov 8, 2020

@milesburton
Looks good to me to be merged - maybe squash the individual commits into one.

@mkrzewic
Thanks!

usual scenario is it is compared to millis() and the like
Add a stateful millisTowaitForConversion (class knows the resolution)

Make millisToWaitForConversion(uint8_t) static

Add celsiusToRaw

Return signed int from celsiusToRaw

Add a description to celsiusToRaw
@milesburton milesburton merged commit 798cfc2 into milesburton:master Dec 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants