This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Beginner's questions on interpreting temperature data from nRF51822

I am using a function to read the die temperature data from nRF51822 as follows:

static uint32_t temperature_data_get(void)
{
    int32_t temp;
    uint32_t err_code;
    
    err_code = sd_temp_get(&temp);
    APP_ERROR_CHECK(err_code);
    
    temp = (temp / 4) * 100;
    
    int8_t exponent = -2;
    return ((exponent & 0xFF) << 24) | (temp & 0x00FFFFFF);
}

It seems to output a single-precison floating point number. I read the data from Nordic Master Control Panel Android app. The data is 0xFE000DAC (after byte order inversion because of the endianess), and is interpreted as 35.00 degree C. However, I have difficulty in getting this result after doing the single-precision floating point number conversion according to en.wikipedia.org/.../Single-precision_floating-point_format and steve.hollasch.net/.../ieeefloat.html . I actually get a negative number as a result of two's complement. Can anyone please advise?

  • Where did you get the idea that uint32_t has any relation to a single bit floating point number? It's not, it's a 32bit value packed with descriptive but fairly pointless data. Since you have the code right there you can see exactly what it is however. Where did that code come from?

    The bottom 24 bits are the read temperature value (which is in .25C increments) divided by 4 and multiplied by 100. So that's just ( temperature X 100 ). Except it isn't, because the division is in parantheses, done first and it's integer division so that neatly throws away 2 bits of the precision you started with.

    eg if the temperature was 0.75, the sd_temp() function would return 3 (3 x .25 == .75) and the line

    temp = ( temp / 4 ) * 100;
    

    would then convert that not to 75 (temperature X 100) but actually to 0. Doing the multiplication first and then the division would at least get that bit right, or even .. just multiplying by 25.

    It then packs a fixed -2 base 10 exponent in the MSB of the result, which I assume is supposed to tell the recipient to apply a 2 decimal point shift (decimal point, not binary point) shift to the result.

    If you start with the result you have. The upper fixed bits are 0xFE which are -2, you know they're -2 because they were fixed to -2 but even if you didn't 0xFE is 2's complement of 2. The lower bits are 0xDAC which is 3,500 (your temperature X 100, apart from the loss of 2 bits) and indeed shifting the decimal point 2 places left (-2) gives you 35.

    Perhaps sending values in a pseudo base-10-floating-point-32-bit format is some kind of convention, if it is it's not one I've seen. I wouldn't bother myself unless whatever was on the other end wanted specifically that, I'd just send the reading and divide by 4, in floating point, on the recipient end which probably has floating point numbers.

  • Thanks so much! It is a very helpful answer.

  • That code is one of the Nordic examples in GitHub and I was wondering what was being achieved until I read this. Thanks.

Related