I am using a Microchip MCP9808 I2C temperature sensor (https://learn.adafruit.com/adafruit-mcp9808-precision-i2c-temperature-sensor-guide/overview).

I'm having problems being able to calculate the temperature using the values I'm reading from the sensor.

The temperature is 13 bits wide. According to the datasheet, I need to send two read commands, the first read to return the upper byte and the second read will return the lower byte. 3 of the remaining bits are used to indicate temperature alarms, and 1 bit is used to indicate the sign of the reading (positive or negative).

I'm able to read the two bytes, by using the sample code from the datasheet as a starting point. However, the values I'm getting from it are incorrect. I'm also unable to get negative temperatures, so I think my code has something wrong with it.

I'm using a USB->I2C adaptor, and I've written a C# implementation of the datasheet sample code to calculate the temperature.

enter image description here

And then my code (which apart from some extra necessary castings due to the way C# handles data types) I think is identical.

    public static double CalculateAmbientTemperature(byte upperByte, byte lowerByte)
        const byte ALERT_MASK_VALUE = 0x1F;
        const byte CLEAR_SIGN_MASK = 0x0F;

        double temperature = 0.00;

        upperByte = (byte)(upperByte & ALERT_MASK_VALUE);

        // Ambient temperature less than 0 degrees
        if((upperByte & (byte)(upperByte & 0x10)) == 0x10)
            upperByte = (byte)(upperByte & CLEAR_SIGN_MASK);
            temperature = 256.0 - ((double)upperByte * 16.0 + (double)lowerByte / 16.0);
            temperature = ((double)upperByte * 16.0 + (double)lowerByte / 16.0);

        return temperature;

So to test the code, I've been sending the bytes: START_BIT 0x3E (the address) 0x05 (the address of the temperature register) This tells the sensor to point the register pointer at the temperature register, so that when I send the two read commands, it reads from that register.

And when I read the data back, I'm getting 0xC1 0x24. When I pass these values to the function, I'm getting 17.0625 degrees C. Bearing in mind, I'm holding an ice cube on the sensor. (Currently don't have a more precise way). So basically, my calculation is faulty but I don't know where to begin with fixing it.

Any help would be appreciated.

(EDIT: To check I'm able to read the chip correctly, I read the Manufacturer ID register and get back the expected 0x54)

  • \$\begingroup\$ Your CLEAR_SIGN_MASK looks incorrect. It should be 0x1F \$\endgroup\$
    – Eugene Sh.
    Commented Dec 16, 2014 at 22:37
  • \$\begingroup\$ Oh, come on. There's always a better way. Crush some ice, make an ice/water slurry in a bowl, put your sensor in a plastic bag, immerse it in the ice/water mixture, and give it time to come to equilibrium. You'll be very near zero. \$\endgroup\$ Commented Dec 16, 2014 at 22:38
  • \$\begingroup\$ @EugeneSh. How so? The datasheet says 0x0F? \$\endgroup\$
    – user9993
    Commented Dec 16, 2014 at 22:40
  • \$\begingroup\$ @user9993 Sorry, missed one bit. Disregard :) \$\endgroup\$
    – Eugene Sh.
    Commented Dec 16, 2014 at 22:42
  • 1
    \$\begingroup\$ I manually calculate those values as 18.25 degrees. But then, I got the order of precedence right in my calculation. Tip: don't work in double till right at the end. Keep it as integers. \$\endgroup\$
    – Majenko
    Commented Dec 16, 2014 at 22:43

1 Answer 1


I've run into this problem myself recently. The error originates from the manufacturer's datasheet. When the 'negative' flag is set the proper computation is:

temp -= 256;  // correct!

instead of

temp = 256 - temp;  // incorrect! But this is the example in the datasheet!

Here are a couple examples of control code for the MCP9808 on Github:



  • \$\begingroup\$ Thanks for the edits. Also: I've submitted a documentation bug report to Microchip. We'll see how they respond. \$\endgroup\$
    – Freshness
    Commented Jul 8, 2016 at 15:06
  • \$\begingroup\$ Did they ever respond? @Freshness \$\endgroup\$
    – user9993
    Commented Jun 21, 2017 at 10:02
  • \$\begingroup\$ No, they did not. I git a survey request about a year later and scored them pretty low, but no acknowledgement and no change in documentation. \$\endgroup\$
    – Freshness
    Commented Jul 7, 2017 at 8:35
  • \$\begingroup\$ How annoying! @Freshness \$\endgroup\$
    – user9993
    Commented Jul 7, 2017 at 9:04
  • \$\begingroup\$ I have used the calculation from datasheet, and it gives correct values. Your modified equation gives false results. \$\endgroup\$ Commented Sep 24, 2017 at 18:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.