Skip to main content

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.

ShellMicroPython
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 BMM350

Constructor. 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

TypeNameDescription
I2Ci2cAn initialized machine.I2C object. Optional only on the boards the module detects (see the constructor above).
intaddressI2C 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 None

Configures 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

TypeNameDescription
intlatchingBMM350_PULSED or BMM350_LATCHED.
intpolarityBMM350_ACTIVE_LOW or BMM350_ACTIVE_HIGH.
intdriveBMM350_INTR_OPEN_DRAIN or BMM350_INTR_PUSH_PULL.
boolmap_to_pinTrue to route the data-ready interrupt to the INT pin, False to remove it.
enable_interrupt(enable)returns None

Enables or disables the data-ready interrupt.

ReturnsThe result is stored in sensor.status.

Parameters

TypeNameDescription
boolenableTrue to enable, False to disable.
get_interrupt_status()returns int

Reads the data-ready interrupt status.

Returns1 when new data is ready, 0 when not, None on an I2C error.

get_sensor_data()returns int

Reads 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 str

Describes 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().