The Fridge Insists It Is 255°C
The fridge insists it is 255°C
In one line
The two bytes a sensor sends are not yet a temperature. You can trust the number only when you can explain its byte order, sign, and unit.
Why this was needed
A refrigerator insists it is at 255°C. You cannot conclude right away that it is really overheating, and you cannot dismiss it as a display bug either. This story is a synthetic fault scenario. First you reproduce the raw bytes, the conversion convention, and the output unit separately. The exercise is about finding the boundary where the wrong value was created; it is not a process for designing real refrigerator controls or safety devices.
Start with the basics of C functions, pointers, and structs. The function does not put its whole result into one return value. The return value reports success, and the temperature is written through an output pointer. If an old value is still there after a failure, that does not mean this call succeeded. The caller must treat the status code and the value together.
How it works
In this TMP102 temperature register conversion, the upper byte arrives first. Normal mode is 12-bit and extended mode is 13-bit two's complement, and one count is 0.0625°C. Bit 0 of the second byte tells the two modes apart. For the exact layout, check Tables 6-8 and 6-9 of the official datasheet.
In the lab you use integer micro-degrees Celsius instead of floating point. 1°C is 1,000,000 and one count is 62,500. If you drop the fractional part and then change the unit, small negative and fractional values disappear. Get the count exactly first, and convert the unit last.
In normal mode, 0x19 0x00 is 25°C and 0xff 0xf0 is -0.0625°C. Displaying 0xff directly as an unsigned temperature of 255 is an example of confusing a byte with a physical quantity. If the sign bit of a 12-bit number is set, subtract 4096 from the count read as a positive integer. Extended mode changes this width. The reason to restore the sign explicitly, rather than rely on right-shifting a negative number, is to reduce differences between C implementations.
In this task, an input with a reserved bit set is rejected with SENSOR_FORMAT and the output is left untouched. This is the valid-input policy of this task, not a general rule for every sensor. First read the function declarations and the status enum in the header sensor.h. The main function is supplied by the checker, so your submission file implements only the two functions.
Convert by hand and form a hypothesis about the code
The following table is a worked example computed from the conversion convention, not a measurement. First work out the count on paper, then compare it with the last column. The micro-degrees column holds unit-bearing integers, with the thousands separators omitted.
| Two bytes | Mode | Count after sign restoration | Micro-degrees Celsius |
|---|---|---|---|
| 0x19 0x00 | Normal | 400 | 25000000 |
| 0x0a 0x10 | Normal | 161 | 10062500 |
| 0xff 0x50 | Normal | -11 | -687500 |
| 0xff 0xf0 | Normal | -1 | -62500 |
| 0x4b 0x01 | Extended | 2400 | 150000000 |
Let's work through the third row. Combining the bytes gives 0xff50; dropping the low four bits leaves 0xff5, which is 4085. This value is at or above the 12-bit sign boundary 2048, so 4085−4096=−11. Multiplying by 62,500 gives −687,500, which is −0.6875°C. If you read only the first byte, or divide down to integer degrees Celsius first, this small negative value disappears. In the fifth row, the low bit 0 is 1, so you must drop three bits. If you check only the mode bit and leave the shift width unchanged, the same bytes are interpreted as a different temperature.
In C, sign restoration is a convention that includes the data type the arithmetic runs in. The shifted non-negative count is at most 8191, so it fits in int32_t. In that range, move it into a signed variable first and then subtract 4096 or 8192, and you create the negative number explicitly. Conversely, if you subtract while still unsigned, the result wraps back to a large positive number. Do not rely on converting that result to signed later. The absolute value of a finished count is at most 4096, so the product with 62,500 also stays within the int32_t range. The habit that matters is checking the range both in the intermediate calculation and in the final storage.
Now build a counterexample. If you read 0x0a 0x10 from the table in reverse, you get 0x100a, which also violates the reserved-bit policy for normal mode in this task. On the other hand, 0x00 0x00 does not change when you reverse the order. So a test that "0 came out" and a test that "the order is right" are not the same. Write down why you chose each normal input, together with the defect that input cannot distinguish.
What it looks like in the field
A reproduction report records not only the number on the screen but also the raw bytes, the mode, and the output unit. Code with the wrong byte order is accidentally correct for some values. If you test only 0, code that swaps the order and correct code cannot be told apart. That is why you split the cases into positive, zero, small negative, boundary, and reserved-bit inputs.
The numbers a format can represent also differ from the physical operating range. Even if the 150°C calculation in the extended encoding is correct, it does not guarantee that a real TMP102 operates at that temperature. Fine resolution likewise does not mean the measurement is that accurate.
What to check next
The quiz that follows checks the order of calculation and counterexamples. After that you read about the failure and timing contracts and move on to the cumulative C lab of the last module. In steps 1–3 of the lab you implement sensor_decode and check, in turn, the whole positive range, the whole negative range, the two modes, and error inputs. Fix compiler warnings first, and do not hardcode just a few values from the table.