user54800: I am trying to communicate with AT30TS75A-MA8M-T with below code, the problem is converting the 16 bit output to float so I can read temp:
Base on data sheet

I suppose to remove first 5 bit in order to read correctly but I am not converting it correctly.
Ex: (0b001001001100000 AND 0 b0111111111100000) = 0b1001001100000
0b1001001100000 >> 5 = 0b10010011 = 147
    void Atemp::begin()
{

    Wire.begin();

    // Check if sensor temp sensor is avilable

    // if (mySensor.beginI2C() == false)
    // {
    //     data[9] = 5; // Error Code
    // }
    // Set registor for two decimal
    Wire.beginTransmission(_i2cAddress);
    Wire.write(1);
    Wire.write(0b01100000);
    Wire.endTransmission();
}

void Atemp::read()
{
    Wire.beginTransmission(_i2cAddress);
    Wire.write(0);
    result = Wire.endTransmission();
    // result is 0-4
    if (result != 0)
    {
        data[9] = 5; // Error Code
    }

    result = Wire.requestFrom(_i2cAddress, (uint8_t)2);
    if (result != 2)
    {
        data[9] = 5; // Error Code
    }
    else
    {
        uint8_t part1 = Wire.read();
        uint8_t part2 = Wire.read();
        
        data[7] = part1;
         data[8] = part2;
        int16_t rawval = (part1 << 8 | part2) ;
        // rawval >>= 6;
        float temp = rawval / 256.0f;
        floatconv(temp);
    }
}


user4143: You need to do two things:

Right-shift the data to align it to the right of the variable, and
Multiply it by the value of one bit.

When right shifting be sure to do it in a signed data type so that C will sign extend the value and retain any negativeness to the value.
So taking the 12-bit examples from the datasheet you right shift 4 bits, so
SDDDDDDDDDDD0000

becomes
SSSSSDDDDDDDDDDD

(where S is the sign bit and D is a valid data bit, and 0 is padding)
Then simply multiply the value by 0.0625 to get the actual temperature.
In code that might look like:
int16_t rawval = part1 << 8 | part2;
rawval >>= 4; // Do this in the int16_t to preserve the sign
float temperature = rawval * 0.0625;

For different resolutions right shift by different amounts and multiply by the appropriate single-bit value for that resolution (hint: 11 bit is double the value of 12 bit, 10 bit is double the value of 11 bit, etc).

user7508: Just a complement to Majenko's answer. The temperature register is set
in such a way that you can interpret it in the same way irrespective of
the selected resolution:
int16_t rawval = part1 << 8 | part2;
float temperature = rawval * (1/256.0);


54800: <p>I am trying to communicate with AT30TS75A-MA8M-T with below code, the problem is converting the 16 bit output to float so I can read temp:</p>
<p>Base on <a href="https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8839-DTS-AT30TS75A-Datasheet.pdf" rel="nofollow noreferrer">data sheet</a>
<a href="https://i.stack.imgur.com/bGVzS.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bGVzS.png" alt="enter image description here" /></a>
I suppose to remove first 5 bit in order to read correctly but I am not converting it correctly.</p>
<p>Ex: (0b001001001100000 AND 0 b0111111111100000) = 0b1001001100000
0b1001001100000 &gt;&gt; 5 = 0b10010011 = 147</p>
<pre><code>    void Atemp::begin()
{

    Wire.begin();

    // Check if sensor temp sensor is avilable

    // if (mySensor.beginI2C() == false)
    // {
    //     data[9] = 5; // Error Code
    // }
    // Set registor for two decimal
    Wire.beginTransmission(_i2cAddress);
    Wire.write(1);
    Wire.write(0b01100000);
    Wire.endTransmission();
}

void Atemp::read()
{
    Wire.beginTransmission(_i2cAddress);
    Wire.write(0);
    result = Wire.endTransmission();
    // result is 0-4
    if (result != 0)
    {
        data[9] = 5; // Error Code
    }

    result = Wire.requestFrom(_i2cAddress, (uint8_t)2);
    if (result != 2)
    {
        data[9] = 5; // Error Code
    }
    else
    {
        uint8_t part1 = Wire.read();
        uint8_t part2 = Wire.read();
        
        data[7] = part1;
         data[8] = part2;
        int16_t rawval = (part1 &lt;&lt; 8 | part2) ;
        // rawval &gt;&gt;= 6;
        float temp = rawval / 256.0f;
        floatconv(temp);
    }
}
</code></pre>
 4143: <p>You need to do two things:</p>
<ol>
<li>Right-shift the data to align it to the right of the variable, and</li>
<li>Multiply it by the value of one bit.</li>
</ol>
<p>When right shifting be sure to do it in a <em>signed</em> data type so that C will <em>sign extend</em> the value and retain any negativeness to the value.</p>
<p>So taking the 12-bit examples from the datasheet you right shift 4 bits, so</p>
<pre><code>SDDDDDDDDDDD0000
</code></pre>
<p>becomes</p>
<pre><code>SSSSSDDDDDDDDDDD
</code></pre>
<p>(where S is the sign bit and D is a valid data bit, and 0 is padding)</p>
<p>Then simply multiply the value by 0.0625 to get the actual temperature.</p>
<p>In code that might look like:</p>
<pre class="lang-cpp prettyprint-override"><code>int16_t rawval = part1 &lt;&lt; 8 | part2;
rawval &gt;&gt;= 4; // Do this in the int16_t to preserve the sign
float temperature = rawval * 0.0625;
</code></pre>
<p>For different resolutions right shift by different amounts and multiply by the appropriate single-bit value for that resolution (hint: 11 bit is double the value of 12 bit, 10 bit is double the value of 11 bit, etc).</p>
 7508: <p>Just a complement to Majenko's answer. The temperature register is set
in such a way that you can interpret it in the same way irrespective of
the selected resolution:</p>
<pre class="lang-cpp prettyprint-override"><code>int16_t rawval = part1 &lt;&lt; 8 | part2;
float temperature = rawval * (1/256.0);
</code></pre>
