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 controller reads the data when it sees the pulse, instead of asking over I2C.

Besides Qwiic or the I2C header pins, wire the breakout's INT pin to digital pin 2 on your controller, or change interruptPin in the sketch to the pin you use. The pin has to support interrupts.

INT is a 1.8 V signal straight from the sensor. The controller pin has to read 1.8 V as a logic high.

The example code​

Select Board
dataReadyInterrupt.ino
/**
**************************************************
*
* @file dataReadyInterrupt.ino
*
* @brief Example showing how to use the BMM350's physical interrupt
* pin to know when a new magnetometer reading is ready,
* instead of polling the interrupt status register
*
* @link solde.red/333359 : Soldered BMM350 Geomagnetic Sensor breakout
*
* @authors Soldered Electronics
***************************************************/
#include <BMM350-SOLDERED.h>

// Create an instance of the BMM350 sensor
Soldered_BMM350 magSensor;

// Pin connected to the sensor's INT pin, change to match your wiring
int interruptPin = 2;

// Flag to know when an interrupt occurs
volatile bool interruptOccurred = false;

void bmm350InterruptHandler()
{
interruptOccurred = true;
}

void setup()
{
// Initialize serial for output
Serial.begin(115200);
Serial.println("BMM350 Example - Data Ready Interrupt");

// Initialize I2C bus
Wire.begin();

// Check if sensor is connected and initialize it.
// Address is optional, defaults to 0x14 (ADSEL tied low on this breakout)
while (magSensor.begin() != BMM350_OK)
{
Serial.println("Error: BMM350 not connected, check wiring and I2C address!");
delay(1000);
}

Serial.println("BMM350 connected!");

// Configure the interrupt pin as push/pull, active high, pulsed and
// mapped to the physical pin
magSensor.configureInterrupt(BMM350_PULSED, BMM350_ACTIVE_HIGH, BMM350_INTR_PUSH_PULL, true);

// Enable the data-ready interrupt
magSensor.enableInterrupt(true);

// Attach the interrupt handler to the microcontroller pin wired to INT
attachInterrupt(digitalPinToInterrupt(interruptPin), bmm350InterruptHandler, RISING);
}

void loop()
{
if (interruptOccurred)
{
interruptOccurred = false;

if (magSensor.getSensorData() == BMM350_OK)
{
Serial.print("X: ");
Serial.print(magSensor.magX, 2);
Serial.print(" uT\t");
Serial.print("Y: ");
Serial.print(magSensor.magY, 2);
Serial.print(" uT\t");
Serial.print("Z: ");
Serial.print(magSensor.magZ, 2);
Serial.println(" uT");
}
}
}

This example also uses attachInterrupt() and digitalPinToInterrupt() (Arduino reference), which come with the Arduino core and are not part of the BMM350 library, as do Wire, Serial and delay(). delay() pauses the sketch for the number of milliseconds you give it: delay(1000) waits one second between connection attempts.

Expected result, at 115200 baud:

Serial MonitorAutoscrollShow timestampNewline115200 baud
Message (Enter to send message to the board)
BMM350 Example - Data Ready Interrupt
BMM350 connected!

After these two lines comes one line for every interrupt: X:, Y: and Z:, each in uT with two decimals, separated by tabs. begin() sets the sensor to 100 Hz, so a new reading is ready about every 10 ms.

Functions used​

Soldered_BMM350()returns Soldered_BMM350

Constructor. Creates the sensor object; nothing is sent to the sensor until begin().

ReturnsThe sensor object.

int8_t begin(uint8_t address = 0x14, TwoWire &wirePort = Wire)returns int8_t

Initializes the sensor over I2C, then sets a 100 Hz output data rate with 4-sample averaging, enables the X, Y and Z axes and starts normal mode.

ReturnsBMM350_OK (0) on success, an error code otherwise.

Parameters

TypeNameDescription
uint8_taddressI2C address. Defaults to 0x14; use 0x15 when JP5 is moved.
TwoWire &wirePortI2C bus to use. Defaults to Wire.
int8_t configureInterrupt(enum bmm350_intr_latch latching, enum bmm350_intr_polarity polarity, enum bmm350_intr_drive drive, bool mapToPin)returns int8_t

Configures how the sensor's INT pin behaves. It does not enable the interrupt itself; call enableInterrupt() for that.

ReturnsBMM350_OK (0) on success, an error code otherwise.

Parameters

TypeNameDescription
enum bmm350_intr_latchlatchingBMM350_PULSED or BMM350_LATCHED.
enum bmm350_intr_polaritypolarityBMM350_ACTIVE_LOW or BMM350_ACTIVE_HIGH.
enum bmm350_intr_drivedriveBMM350_INTR_OPEN_DRAIN or BMM350_INTR_PUSH_PULL.
boolmapToPintrue to route the data-ready interrupt to the INT pin, false to remove it.
int8_t enableInterrupt(bool enable)returns int8_t

Enables or disables the data-ready interrupt.

ReturnsBMM350_OK (0) on success, an error code otherwise.

Parameters

TypeNameDescription
boolenabletrue to enable, false to disable.
int8_t getSensorData()returns int8_t

Reads compensated magnetometer and temperature data and stores them in the magX, magY and magZ members (µT) and the temperature member (°C).

ReturnsBMM350_OK (0) on success, an error code otherwise.

Putting it together​

configureInterrupt() sets INT to a pulsed, active-high, push-pull output and routes the data-ready interrupt to it, and enableInterrupt(true) turns the interrupt on. attachInterrupt() then calls bmm350InterruptHandler() on each rising edge of INT. The handler only sets a flag; loop() sees the flag, clears it, and reads the data with getSensorData().