For years my approach to a misbehaving serial bus was to stare at the code, change one thing, and reflash. It works, eventually, in the way that hitting a stuck machine works eventually. This week I finally gave up and clipped a cheap eight-channel logic analyser onto the I2C lines, the sort that costs about a tenner and pretends to be a Saleae. With sigrok and PulseView in front of me, I could see the bus instead of imagining it.
The problem was obvious within a minute. The sensor was acking its address fine, but my read was issuing a stop and a fresh start where it should have done a repeated start, so I was getting the previous register's value back, one read behind. No amount of squinting at the datasheet had shown me that, because the datasheet describes what should happen and the analyser shows what does.
I feel slightly daft for not buying one years ago. The whole class of "is it the wiring, the timing, or my code" question just evaporates when you can watch the SDA line do its thing. Decode the protocol, read the bytes off the screen, compare to what you meant to send. Cheapest debugging upgrade I've made in ages, and it lives in the drawer next to the multimeter now where it belongs.