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