Skip to main content

Basic readings

What this example shows​

Reading the compensated magnetic field on all three axes, in µT, and the sensor's temperature, in a loop about every 100 ms. This is the module's simplest example and the one the Quick Start uses.

The example creates I2C bus 0 with SCL on GPIO 9 and SDA on GPIO 8. Change these pins to the ones you wired.

The example code​

# FILE: bmm350-basicReadings.py
# AUTHOR: Soldered Electronics
# BRIEF: Reads compensated magnetometer and temperature data from the BMM350
# sensor over I2C
# WORKS WITH: BMM350 Geomagnetic Sensor breakout: www.solde.red/333359
# LAST UPDATED: 2026-09-22

from bmm350 import BMM350, BMM350_OK
from machine import I2C, Pin
import time

# 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!")

while True:
if sensor.get_sensor_data() == BMM350_OK:
print(
"X: {:.2f} uT\tY: {:.2f} uT\tZ: {:.2f} uT\tTemperature: {:.2f} degC".format(
sensor.data.mag_x, sensor.data.mag_y, sensor.data.mag_z, sensor.data.temperature
)
)
else:
print("Failed to read sensor data:", sensor.status_string())

time.sleep_ms(100)

🔗Open the complete example

bmm350-basicReadings.py at commit 0995e8d

→

This example also uses machine.I2C (MicroPython reference), machine.Pin (MicroPython reference) and time.sleep_ms() (MicroPython reference), which come with the MicroPython firmware and are not part of the bmm350 module. time.sleep_ms() pauses the program for the given number of milliseconds: time.sleep_ms(100) at the end of the loop sets the pace of about one reading every 100 ms.

Expected result: BMM350 connected!, then one line per reading, about every 100 ms: X:, Y: and Z:, each in uT with two decimals, then Temperature: in degC, separated by tabs.

ShellMicroPython
BMM350 connected!
X: 12.84 uT Y: -23.51 uT Z: -38.27 uT Temperature: 24.62 degC
X: 12.91 uT Y: -23.47 uT Z: -38.32 uT Temperature: 24.62 degC
X: 12.79 uT Y: -23.56 uT Z: -38.21 uT Temperature: 24.64 degC
X: 12.88 uT Y: -23.49 uT Z: -38.30 uT Temperature: 24.64 degC

If a read fails, the line reads Failed to read sensor data: and the reason instead.

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).
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​

The constructor already raises an exception when the sensor cannot be reached, so the sensor.status check after it is a second guard. Each pass of the loop calls get_sensor_data() and prints the three axes and the temperature from sensor.data when it returns BMM350_OK.

For a board with JP5 moved to 0x15, create the sensor with BMM350(i2c, address=BMM350_I2C_ADSEL_SET_HIGH) and import that constant from bmm350.