Sensor Multi-Byte Reads: Avoid Combining Two Different Conversion Results

Read a sensor result using the device’s documented snapshot mechanism. A sequence of individually successful byte reads can combine different conversion generations into a value that never existed. A repeated START preserves bus transaction framing; it does not independently promise that the sensor freezes its result registers.

Applicability: the concrete example is Bosch BME280 normal-mode readout, using the official PDF retrieved on 14 October 2026. Its cover identifies revision 1.24, February 2024, document BST-BME280-DS001-24, while interior footers retain revision 1.23, January 2022. The cited readout clauses were checked in this mixed-label document. The procedure concerns conversion-generation consistency, not compensation accuracy or I2C electrical qualification.

Two synthetic BME280-format generations combine into an invalid mixed value when read separately; a complete protected burst preserves one generation.
The constructed byte values illustrate a failure model. Correct BME280 burst shadowing is the protection, not a claim that protected reads tear.

1. Define the atomic unit the application needs

Decide whether the consumer needs one complete numeric field, a temperature/pressure pair, or the complete temperature/pressure/humidity result set. A guarantee that protects two bytes of one channel may not protect every channel in a scan. Read the sensor’s exact latching or shadow-register rule.

The BME280 data-readout section specifies a burst from 0xF7 through 0xFE for pressure, temperature, and humidity. Its normal-mode shadowing protects consistency when all data registers are read in one burst. Independent read commands can mix measurements.

Keep the raw result set together through decoding and compensation. Do not let separate application tasks update temperature and pressure fields in a shared object at unrelated times, recreating a torn snapshot after the bus transfer was coherent.

2. Make the tearing failure concrete

Use an explicitly synthetic twenty-bit pressure fixture. Generation A is 0x12FF0, represented by register bytes 12 FF 00. Generation B is 0x13010, represented by 13 01 00, with the low nibble of the third register unused for this extraction.

If software reads the first byte from A, then a conversion update occurs before separate reads obtain the remaining bytes from B, it assembles 12 01 00. Applying the twenty-bit extraction gives 0x12010, which is neither A nor B. The numerical result can remain plausible enough to evade simple range checks.

This fixture demonstrates a possible failure of independently read, changing registers. It does not claim that a correctly executed BME280 protected burst tears. The point is to make the driver test fail when its bus wrapper accidentally splits the intended snapshot into independent operations.

3. Verify the actual burst boundary

For the selected BME280 behavior, an I2C STOP or SPI CSB rising edge ends the burst and allows shadowed results to replace the visible data registers. A wrapper that reads one field, ends the transfer, and then reads another field creates an update opportunity even if each individual operation is valid.

Trace the complete request through the public API, adapter, and controller. For an I2C implementation, a single register-selector phase followed by the required consecutive receive bytes is different from a loop that calls a one-register helper eight times. Inspect the wire or the lowest meaningful transfer trace rather than judging by the application function’s name.

The Linux v6.12 I2C userspace interface provides combined-message operations where the adapter supports them. That capability helps express the transaction, but the sensor datasheet supplies the data-consistency guarantee. Neither an API name nor a repeated START substitutes for the device rule.

4. Choose only supported coherence mechanisms

Documented mechanism Implementation decision Boundary to verify
Complete-burst shadowing Read the entire protected register set in one burst. Which transaction event releases the shadowed update?
Explicit latch or snapshot command Latch, read the defined set, then release as specified. Does the latch cover all needed channels and survive errors?
Conversion-stop or triggered mode Read after confirmed completion while no new update can occur. Who may start the next conversion?
Documented sequence/retry protocol Verify generation before and after reading. What wrap and update-rate assumptions make the retry valid?

These are alternatives to look for in a target manual, not features claimed for every sensor. Do not invent a high-low-high retry algorithm merely because it works for one counter peripheral. Arbitrary sensor values can move in both directions, and equal high bytes do not prove an unchanged generation.

5. Test updates at every vulnerable boundary

Build a register-model test that switches between the two synthetic generations immediately after each byte position. An intentionally unprotected per-register implementation should reveal mixed values; the modeled protected burst should return only a complete A or complete B snapshot.

Vary transaction boundaries as well as byte values. Test an early STOP, a wrapper-imposed transfer split, a short read, and a failed middle operation. Reject incomplete snapshots rather than publishing a partially refreshed structure with old bytes left in place.

Test the application handoff separately. Decode into a private result object, attach its configuration and generation context, then publish the complete object under the application’s synchronization contract. A consumer must not observe half of the previous result and half of the new result.

6. Separate coherence from freshness

A coherent snapshot can still be old. In a continuously converting sensor, repeated reads may legitimately return the same generation, while slow consumers may miss intermediate generations. Define freshness and loss behavior separately from the requirement that a single reported result is internally consistent.

For physical validation, capture the bus while conversions run at the intended rate and compare the actual burst with the datasheet. Use a controlled input change only within the sensor’s operating conditions. A smooth environmental signal is a weak tearing test because adjacent conversions may share most bits.

No register-model program or sensor capture was executed for this article. The release artifact is the protected-register-set definition, transaction-boundary trace, changing-generation fixture, and whole-result publication rule. Acceptance means each delivered measurement is one coherent generation, with separate evidence for its age and any missed conversions.

Similar Posts