Data-ready interrupt
What this example showsโ
Reading the field only when the BMM350 says a new measurement is ready. The
sensor pulses its INT pin for every new reading, and your board reads the
data when it sees the pulse.
The example creates I2C bus 0 with SCL on GPIO 9 and SDA on GPIO 8, and expects
the breakout's INT pin on GPIO 5 (INT_PIN). Change these pins to the ones
you wired.
INT is a 1.8 V signal straight from the sensor. The pin on your board has to
read 1.8 V as a logic high.
The example codeโ
# FILE: bmm350-dataReadyInterrupt.py
# AUTHOR: Soldered Electronics
# BRIEF: Uses the BMM350's physical interrupt pin to know when a new
# magnetometer reading is ready, instead of polling the interrupt
# status register
# WORKS WITH: BMM350 Geomagnetic Sensor breakout: www.solde.red/333359
# LAST UPDATED: 2026-09-22
from bmm350 import BMM350, BMM350_OK, BMM350_PULSED, BMM350_ACTIVE_HIGH, BMM350_INTR_PUSH_PULL
from machine import I2C, Pin
# Hardware setup: connect the breakout board's INT pin to INT_PIN below
INT_PIN = 5
data_ready = False
def int_callback(pin):
global data_ready
data_ready = True
# Change these to match how your board wires I2C
i2c = I2C(0, scl=Pin(9), sda=Pin(8))
sensor = BMM350(i2c)
if sensor.status != BMM350_OK:
raise Exception("Failed to initialize BMM350: " + sensor.status_string())
print("BMM350 connected!")
# Configure the interrupt pin as push/pull, active high, pulsed and mapped
# to the physical pin
sensor.configure_interrupt(BMM350_PULSED, BMM350_ACTIVE_HIGH, BMM350_INTR_PUSH_PULL, True)
# Enable the data-ready interrupt
sensor.enable_interrupt(True)
interrupt_pin = Pin(INT_PIN, Pin.IN)
interrupt_pin.irq(trigger=Pin.IRQ_RISING, handler=int_callback)
while True:
if data_ready:
data_ready = False
status = sensor.get_interrupt_status()
if status:
if sensor.get_sensor_data() == BMM350_OK:
print(
"X: {:.2f} uT\tY: {:.2f} uT\tZ: {:.2f} uT".format(
sensor.data.mag_x, sensor.data.mag_y, sensor.data.mag_z
)
)
else:
print("Failed to read sensor data:", sensor.status_string())
๐Open the complete example
bmm350-dataReadyInterrupt.py at commit 0995e8d
This example also uses machine.I2C
(MicroPython reference)
and machine.Pin with Pin.irq()
(MicroPython reference),
which come with the MicroPython firmware and are not part of the bmm350
module.
Expected result: BMM350 connected!, then one line for every interrupt: X:,
Y: and Z:, each in uT with two decimals, separated by tabs.
BMM350 connected!
X: 12.47 uT Y: -23.81 uT Z: -38.92 uT
X: 12.52 uT Y: -23.74 uT Z: -38.85 uT
X: 12.39 uT Y: -23.90 uT Z: -39.03 uT
X: 12.58 uT Y: -23.69 uT Z: -38.88 uT
Functions usedโ
BMM350(i2c=None, address=BMM350_I2C_ADSEL_SET_LOW)returns BMM350Constructor. Resets the sensor, checks its chip ID, loads its calibration data, sets 100 Hz with 4-sample averaging, enables all axes and starts normal mode. Raises an exception when the sensor does not answer or another chip answers. Without an i2c object it uses I2C(0, scl=Pin(22), sda=Pin(21)) when the firmware reports itself as esp32, esp8266 or one Soldered board's own firmware name, and raises an exception on any other board.
ReturnsThe sensor object.
Parameters
| Type | Name | Description |
|---|---|---|
I2C | i2c | An initialized machine.I2C object. Optional only on the boards the module detects (see the constructor above). |
int | address | I2C address. BMM350_I2C_ADSEL_SET_LOW (0x14, the default) or BMM350_I2C_ADSEL_SET_HIGH (0x15). |
configure_interrupt(latching, polarity, drive, map_to_pin)returns NoneConfigures how the sensor's INT pin behaves. It does not enable the interrupt itself; call enable_interrupt() for that.
ReturnsThe result is stored in sensor.status.
Parameters
| Type | Name | Description |
|---|---|---|
int | latching | BMM350_PULSED or BMM350_LATCHED. |
int | polarity | BMM350_ACTIVE_LOW or BMM350_ACTIVE_HIGH. |
int | drive | BMM350_INTR_OPEN_DRAIN or BMM350_INTR_PUSH_PULL. |
bool | map_to_pin | True to route the data-ready interrupt to the INT pin, False to remove it. |
enable_interrupt(enable)returns NoneEnables or disables the data-ready interrupt.
ReturnsThe result is stored in sensor.status.
Parameters
| Type | Name | Description |
|---|---|---|
bool | enable | True to enable, False to disable. |
get_interrupt_status()returns intReads the data-ready interrupt status.
Returns1 when new data is ready, 0 when not, None on an I2C error.
get_sensor_data()returns intReads a new compensated measurement into sensor.data.mag_x, sensor.data.mag_y and sensor.data.mag_z (ยตT) and sensor.data.temperature (ยฐC).
ReturnsBMM350_OK (0) on success, an error code otherwise.
status_string()returns strDescribes the current sensor.status code.
ReturnsThe description, or an empty string when the status is BMM350_OK.
Putting it togetherโ
configure_interrupt() sets INT to a pulsed, active-high, push-pull output
and routes the data-ready interrupt to it, and enable_interrupt(True) turns
the interrupt on. Pin.irq() calls int_callback() on each rising edge of
INT, and the callback only sets a flag. The loop sees the flag, checks
get_interrupt_status(), and reads the data with get_sensor_data().