user80781: Anyone can help me decode the temperature of the M117 chip from mysentech.com?
I tried things, but I get a constant raw value of 0xFFFF, which becomes 1 once 2's complemented is applied.
The chip shows up at the expected address (TEMP_SENSOR_ADDRESS is 0x45) during a scan operation of the I2C bus.

    // Start I2C Transmission
    Wire.beginTransmission(TEMP_SENSOR_ADDRESS);
    // Select data register
    Wire.write(0x00);
    // Stop I2C Transmission
    Wire.endTransmission();
    delay(300);

    // == Request for the raw temp 2 bytes
    Wire.requestFrom(TEMP_SENSOR_ADDRESS, 2);
    const size_t count = Wire.available();
    log("%d bytes available", count);
    
    if (count!=2) {
        *ready = false;
        warn("I2c temp is not available");
    }
    else {
        *ready = true;
        // Get the raw data as the 16-bit big endian (MSB-LSB)
        byte data0 = Wire.read();
        byte data1 = Wire.read();
        const uint16_t raw = data0<<8 | data1;
        const int sign = raw>>15 == 1 ? -1 : 1;
        
        // Get the raw temperature as a 2's complement of the 16-bit (MSB-LSB) value
        const int16_t c2Raw = ~raw + 1;
            
        // Apply scale and offset
        temperature = sign * float(c2Raw)/256.0 + 40;
        log("raw: %04x (%d) | Raw 2's complement  %04x (%d) | temperature: %f°C", 
            raw, raw, 
            c2Raw, c2Raw, 
            temperature
        );
    }

[UPDATE | SEPT. 2nd 2022]
Following the discussion I had with @jsoleta, my current code is as follows. But still getting FFFF AC. AC being the correct CRC for FFFF.
Coud it be the result of a wiring issue of the component on our custom PCB?
The logs:
b5725|—|  Thermometer: Command: Writing to register command 0xCC44
b5725|—|  Thermometer: Command byte 0: cc
b5725|—|  Thermometer: Command byte 1: 44
b5725|—|  Thermometer: Command: register transmitted 2 bytes
b5725|—|  Thermometer: 3 bytes available
b5725|—|  Thermometer: Actually read 3 bytes: ff ff ac
b5725|—|  Thermometer:  CRC matched: computed: ac == read: ac
b5725|—|  Thermometer: raw: ffff (65535) | Raw 2's complement  0001 (1) | temperature: 39.996094°C
b5725|—|  Thermometer: raw: ffff (65535) | temperature: 39.996094°C
b5725|—|  Thermometer: Transmitting board temperature 40.0°C over the RS-485 bus (raw is 799 - 0x031f)

The updated code:
loat I2cThermometer :: readTemperature(bool *ready) {
    float temperature = 0;
  
    log("Command: Writing to register command 0xCC44");
    // Start I2C Transmission
    Wire.beginTransmission(TEMP_SENSOR_ADDRESS);
    
    // Select data register 0x00, config 0x01

    const uint16_t command = 
        0xcc44  // Wait for temperature measurement
        //0xf32d    // Read status
        //0x611d    // Measurement result set alarm
    ;
    byte * data = (byte*)&command;
    Wire.write(data[1]); log("Command byte 0: %02x", data[1]);
    Wire.write(data[0]); log("Command byte 1: %02x", data[0]);


    // Stop I2C Transmission
    const auto readCount = Wire.endTransmission();
    log("Command: register transmitted %d bytes", readCount);
    delay(15);
    // == Request for the raw temp 2 bytes + CRC
    Wire.requestFrom(TEMP_SENSOR_ADDRESS, 3);   // 2-byte data + 1-byte CRC
    const size_t count = Wire.available();
    log("%d bytes available", count);
    

    if (count!=3) {
        *ready = false;
        warn("No temp data is not available");
    }
    else {
        *ready = true;


            // Get the raw data as the 16-bit big endian (MSB-LSB)
            byte data[3];
            const size_t r = Wire.readBytes(data, sizeof data);
            log("Actually read %d bytes: %02x %02x %02x", r, data[0], data[1], data[2]);
            const byte crc = MY_CRC8(data, 2);
            if (crc != data[2]) {
                warn("CRC mismatch: computed: %02x != read: %02x", crc, data[2]);
            }
            else {
                success("CRC matched: computed: %02x == read: %02x", crc, data[2]);
            }
            const uint16_t raw = *(uint16_t*)data;
            
            const int sign = raw>>15 == 1 ? -1 : 1;

            // Get the raw temperature as a 2's complement of the 16-bit big engdian (MSB-LSB)
            const int16_t c2Raw = ~raw + 1;
            
            // Apply scale and offset
            temperature = sign * float(c2Raw)/256.0 + 40;
            #if LOG_LEVEL >= LOG_LEVEL_DEBUG
            log("raw: %04x (%d) | Raw 2's complement  %04x (%d) | temperature: %f°C", 
                raw, raw, 
                c2Raw, c2Raw, 
                temperature
            );
            #endif
        

        #if LOG_LEVEL >= LOG_LEVEL_DEBUG
        log("raw: %04x (%d) | temperature: %f°C", 
            raw, raw, 
            temperature
        );
        #endif
        
        writeBoardTemperatureMessage(temperature);
    }


    if (!(*ready)) {
        #if LOG_LEVEL >= LOG_LEVEL_INFO
        log("Temperature is not ready %d°C", temperature);
        #endif
        return temperature;
    }
        
    #if LOG_LEVEL >= LOG_LEVEL_INFO
    log("Temperature is %d°C", temperature);
    #endif

    return temperature;
}



user70020: 
WARNING: I have no way to test/verify the parts of this that directly apply to your chip.

Issue conversion command
This device does not appear to follow the common write-register-address followed by read-register-value scheme. Instead, it seems in order for the device to  sample and convert temperature at all you must first issue  a command to perform the conversion. You're not doing that, so that seems to be the principal problem. You're reading whatever the value is prior to every having asked for a conversion an the datasheet says indicates this is indeterminate. So 0xFFFF is plausible and unremarkable for a value you'd get not having already requested conversion.
Issuing the conversion command (again, I'm not able to test this):
void request_temperature_conversion() {
  Wire.beginTransmission(TEMP_SENSOR_ADDRESS);
  Wire.write(0xCC);
  Wire.write(0x44);
  const auto check_me = Wire.endTransmission();
  delay(15); // Ensure a completed conversion.
}

Read result
To read the result of value of the most recent conversion:
uint16_t read_u16_temperature() {
  const auto read_count = Wire.requestFrom(
    TEMP_SENSOR_ADDRESS,
    3 // the actual transaction includes an 8-bit as well as 16-bit sample
  );
  uint8_t temp_payload[2];  // 2 because i'm going to ignore the CRC.
  Wire.read(temp_payload, sizeof temp_payload);

  return uint16_t(temp_payload[0]) << 8 | temp_payload[1];
}

int16_t read_s16_temperature() {
  int16_t r;
  const uint16_t u = read_u16_temperature();
  memcpy(&r, &u, sizeof r);
  return r;
}

Together
Again, I can't really test this.
request_temperature_conversion();
temperature = 
  sign
  * float(read_s16_temperature()) / 256
  + 40;

You probably can and should avoid the use of the floating point type.  If you're logging this data and transmitting this data to somewhere else to be logged, you may be better off transmitting/storing the raw values which can be (re)interpreted later rather than having different versions of your sketch potentially affecting how a calculation is done on the values.
Manufacturer's documentation
The website you have linked to has a datasheet in Chinese. You may get some use out of you machine translate it to English (or whatever). Google Drive is capable of this. Probably more useful are the archives of sample code intended for STM32.  That's where all the information came from, including crucially the use of 0xCC44 command to prompt conversion. The 15ms delay is also lifted from what I read in the STM32 sample code in the rar archive from the site; I didn't put much thought into its significance or how the part behaves if you don't wait long enough. You should read through it, because there's more about configuring the chip, the CRC, etc.


80781: <p>Anyone can help me decode the temperature of <a href="https://www-mysentech-com.translate.goog/productinfo/535226.html?_x_tr_sch=http&amp;_x_tr_sl=zh-CN&amp;_x_tr_tl=en&amp;_x_tr_hl=en&amp;_x_tr_pto=sc" rel="nofollow noreferrer">the M117 chip from mysentech.com</a>?</p>
<p>I tried things, but I get a constant raw value of 0xFFFF, which becomes 1 once 2's complemented is applied.</p>
<p>The chip shows up at the expected address (TEMP_SENSOR_ADDRESS is 0x45) during a scan operation of the I2C bus.</p>
<pre class="lang-cpp prettyprint-override"><code>
    // Start I2C Transmission
    Wire.beginTransmission(TEMP_SENSOR_ADDRESS);
    // Select data register
    Wire.write(0x00);
    // Stop I2C Transmission
    Wire.endTransmission();
    delay(300);

    // == Request for the raw temp 2 bytes
    Wire.requestFrom(TEMP_SENSOR_ADDRESS, 2);
    const size_t count = Wire.available();
    log(&quot;%d bytes available&quot;, count);
    
    if (count!=2) {
        *ready = false;
        warn(&quot;I2c temp is not available&quot;);
    }
    else {
        *ready = true;
        // Get the raw data as the 16-bit big endian (MSB-LSB)
        byte data0 = Wire.read();
        byte data1 = Wire.read();
        const uint16_t raw = data0&lt;&lt;8 | data1;
        const int sign = raw&gt;&gt;15 == 1 ? -1 : 1;
        
        // Get the raw temperature as a 2's complement of the 16-bit (MSB-LSB) value
        const int16_t c2Raw = ~raw + 1;
            
        // Apply scale and offset
        temperature = sign * float(c2Raw)/256.0 + 40;
        log(&quot;raw: %04x (%d) | Raw 2's complement  %04x (%d) | temperature: %f°C&quot;, 
            raw, raw, 
            c2Raw, c2Raw, 
            temperature
        );
    }
</code></pre>
<p><strong>[UPDATE | SEPT. 2nd 2022]</strong>
Following the discussion I had with @jsoleta, my current code is as follows. But still getting FFFF AC. AC being the correct CRC for FFFF.
Coud it be the result of a wiring issue of the component on our custom PCB?</p>
<p>The logs:</p>
<pre><code>b5725|—|  Thermometer: Command: Writing to register command 0xCC44
b5725|—|  Thermometer: Command byte 0: cc
b5725|—|  Thermometer: Command byte 1: 44
b5725|—|  Thermometer: Command: register transmitted 2 bytes
b5725|—|  Thermometer: 3 bytes available
b5725|—|  Thermometer: Actually read 3 bytes: ff ff ac
b5725|—|  Thermometer:  CRC matched: computed: ac == read: ac
b5725|—|  Thermometer: raw: ffff (65535) | Raw 2's complement  0001 (1) | temperature: 39.996094°C
b5725|—|  Thermometer: raw: ffff (65535) | temperature: 39.996094°C
b5725|—|  Thermometer: Transmitting board temperature 40.0°C over the RS-485 bus (raw is 799 - 0x031f)
</code></pre>
<p>The updated code:</p>
<pre class="lang-cpp prettyprint-override"><code>loat I2cThermometer :: readTemperature(bool *ready) {
    float temperature = 0;
  
    log(&quot;Command: Writing to register command 0xCC44&quot;);
    // Start I2C Transmission
    Wire.beginTransmission(TEMP_SENSOR_ADDRESS);
    
    // Select data register 0x00, config 0x01

    const uint16_t command = 
        0xcc44  // Wait for temperature measurement
        //0xf32d    // Read status
        //0x611d    // Measurement result set alarm
    ;
    byte * data = (byte*)&amp;command;
    Wire.write(data[1]); log(&quot;Command byte 0: %02x&quot;, data[1]);
    Wire.write(data[0]); log(&quot;Command byte 1: %02x&quot;, data[0]);


    // Stop I2C Transmission
    const auto readCount = Wire.endTransmission();
    log(&quot;Command: register transmitted %d bytes&quot;, readCount);
    delay(15);
    // == Request for the raw temp 2 bytes + CRC
    Wire.requestFrom(TEMP_SENSOR_ADDRESS, 3);   // 2-byte data + 1-byte CRC
    const size_t count = Wire.available();
    log(&quot;%d bytes available&quot;, count);
    

    if (count!=3) {
        *ready = false;
        warn(&quot;No temp data is not available&quot;);
    }
    else {
        *ready = true;


            // Get the raw data as the 16-bit big endian (MSB-LSB)
            byte data[3];
            const size_t r = Wire.readBytes(data, sizeof data);
            log(&quot;Actually read %d bytes: %02x %02x %02x&quot;, r, data[0], data[1], data[2]);
            const byte crc = MY_CRC8(data, 2);
            if (crc != data[2]) {
                warn(&quot;CRC mismatch: computed: %02x != read: %02x&quot;, crc, data[2]);
            }
            else {
                success(&quot;CRC matched: computed: %02x == read: %02x&quot;, crc, data[2]);
            }
            const uint16_t raw = *(uint16_t*)data;
            
            const int sign = raw&gt;&gt;15 == 1 ? -1 : 1;

            // Get the raw temperature as a 2's complement of the 16-bit big engdian (MSB-LSB)
            const int16_t c2Raw = ~raw + 1;
            
            // Apply scale and offset
            temperature = sign * float(c2Raw)/256.0 + 40;
            #if LOG_LEVEL &gt;= LOG_LEVEL_DEBUG
            log(&quot;raw: %04x (%d) | Raw 2's complement  %04x (%d) | temperature: %f°C&quot;, 
                raw, raw, 
                c2Raw, c2Raw, 
                temperature
            );
            #endif
        

        #if LOG_LEVEL &gt;= LOG_LEVEL_DEBUG
        log(&quot;raw: %04x (%d) | temperature: %f°C&quot;, 
            raw, raw, 
            temperature
        );
        #endif
        
        writeBoardTemperatureMessage(temperature);
    }


    if (!(*ready)) {
        #if LOG_LEVEL &gt;= LOG_LEVEL_INFO
        log(&quot;Temperature is not ready %d°C&quot;, temperature);
        #endif
        return temperature;
    }
        
    #if LOG_LEVEL &gt;= LOG_LEVEL_INFO
    log(&quot;Temperature is %d°C&quot;, temperature);
    #endif

    return temperature;
}

</code></pre>
 70020: <blockquote>
<p>WARNING: I have no way to test/verify the parts of this that directly apply to your chip.</p>
</blockquote>
<h2>Issue conversion command</h2>
<p>This device does not appear to follow the common write-register-address followed by read-register-value scheme. <strong>Instead, it seems in order for the device to  sample and convert temperature at all you must first issue  a command to perform the conversion. You're not doing that, so that seems to be the principal problem.</strong> You're reading whatever the value is prior to every having asked for a conversion an the datasheet says indicates this is indeterminate. So 0xFFFF is plausible and unremarkable for a value you'd get not having already requested conversion.</p>
<p>Issuing the conversion command (again, I'm not able to test this):</p>
<pre class="lang-cpp prettyprint-override"><code>void request_temperature_conversion() {
  Wire.beginTransmission(TEMP_SENSOR_ADDRESS);
  Wire.write(0xCC);
  Wire.write(0x44);
  const auto check_me = Wire.endTransmission();
  delay(15); // Ensure a completed conversion.
}
</code></pre>
<h2>Read result</h2>
<p>To read the result of value of the most recent conversion:</p>
<pre class="lang-cpp prettyprint-override"><code>uint16_t read_u16_temperature() {
  const auto read_count = Wire.requestFrom(
    TEMP_SENSOR_ADDRESS,
    3 // the actual transaction includes an 8-bit as well as 16-bit sample
  );
  uint8_t temp_payload[2];  // 2 because i'm going to ignore the CRC.
  Wire.read(temp_payload, sizeof temp_payload);

  return uint16_t(temp_payload[0]) &lt;&lt; 8 | temp_payload[1];
}

int16_t read_s16_temperature() {
  int16_t r;
  const uint16_t u = read_u16_temperature();
  memcpy(&amp;r, &amp;u, sizeof r);
  return r;
}
</code></pre>
<h2>Together</h2>
<p>Again, I can't really test this.</p>
<pre class="lang-cpp prettyprint-override"><code>request_temperature_conversion();
temperature = 
  sign
  * float(read_s16_temperature()) / 256
  + 40;
</code></pre>
<p>You probably can and should avoid the use of the floating point type.  If you're logging this data and transmitting this data to somewhere else to be logged, you may be better off transmitting/storing the raw values which can be (re)interpreted later rather than having different versions of your sketch potentially affecting how a calculation is done on the values.</p>
<h2>Manufacturer's documentation</h2>
<p>The website you have linked to has a datasheet in Chinese. You may get some use out of you machine translate it to English (or whatever). Google Drive is capable of this. Probably more useful are the archives of sample code intended for STM32.  That's where all the information came from, including crucially the use of <code>0xCC44</code> command to prompt conversion. The 15ms delay is also lifted from what I read in the STM32 sample code in the rar archive from the site; I didn't put much thought into its significance or how the part behaves if you don't wait long enough. You should read through it, because there's more about configuring the chip, the CRC, etc.</p>
<p><a href="https://i.stack.imgur.com/Do8zN.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Do8zN.png" alt="Chip Maker's download center showing filenames M117 M117B Digital Temperature Chip Product Manual-Minyuan 202206.pdf, M117B_IIC_Samplecode_stm32-MY202203.rar, M117_MTS01_IIC_Samplecode_stm32-MY202202.rar" /></a></p>
