Ok, it took me a bit to figure out what what going on here. The good news is it’s mostly just a case of misleading nomenclature and needing to use the ambient offset, I believe
First: setXThreshold(5) is not 5 mT — it’s a raw register code
The // mT comment in the example is misleading. Per the datasheet and the library’s own doc comments, X_THR_CONFIG is an 8-bit, 2’s complement X axis threshold code for limit check, with a range of +/-128, and the threshold value in mT is calculated as (40(1+X_Y_RANGE)/128)*X_THR_CONFIG. Github descriptons With the default X_Y_RANGE (0 → ±40 mT range) and a code of 5, that works out to: (40 × 1 / 128) × 5 ≈ 1.56 mT
So setXThreshold(5) is actually setting a threshold around 1.5 mT, not 5 mT — the example comment just states the units it’s trying to represent (mT) without doing the conversion for you. If you want a specific real-world mT threshold, you need to invert that formula yourself: code = round(desired_mT * 128 / (40*(1+range))).
Second: setMagDir() doesn’t set magnetic pole direction — it flips which side of the threshold triggers
That function writes the bit documented as: the direction of threshold check, ignored when THR_HYST > 001b — 0x0 sets interrupt for field above the threshold, 0x1 sets interrupt for field below the threshold (SENSOR_CONFIG_2, bit 5). Link to reference. So:
setMagDir(false) (default) → interrupt fires when the field goes below the threshold → that’s exactly why you only saw negative values under ~-3 mT triggering it.
setMagDir(true) → interrupt fires when the field goes above the threshold → and now everything above -3 mT triggers, which is also exactly what you saw.
It has nothing to do with “which pole of the magnet”, it’s purely above-vs-below comparison direction. The name setMagDir makes it sound like polarity/orientation, but functionally it’s a threshold-comparison-direction toggle situation
If you want the interrupt to behave the way most people expect (“fire when field magnitude exceeds X mT in either direction from a calibrated zero”), you’ll want to first zero out the ambient offset (there’s an offset register/config for this), then compute your threshold code from the mT formula above, and treat setMagDir purely as “above vs. below,” picking whichever matches your use case.