Zum Hauptinhalt springen

Read on the data-ready interrupt

What this example shows​

Instead of asking the sensor over and over, the script waits for the BMP585's INT pin. The sensor pulses INT high each time a new reading is ready, an interrupt handler sets a flag, and the main loop then reads and prints the result.

Wire the breakout over I2C as in the Quick Start (SCL on pin 9, SDA on pin 8), and wire the breakout's INT pin to pin 5. Change INT_PIN or the I2C pins to match your board.

The example code​

# FILE: bmp585-dataReadyInterrupt.py
# AUTHOR: Soldered Electronics
# BRIEF: Uses the BMP585's physical interrupt pin to know when a new
# pressure/temperature reading is ready, instead of polling the
# interrupt status register
# WORKS WITH: BMP585 Barometric Pressure Sensor breakout: www.solde.red/333189
# LAST UPDATED: 2026-09-18

from bmp585 import (
BMP585,
BMP5_OK,
BMP5_PULSED,
BMP5_ACTIVE_HIGH,
BMP5_INTR_PUSH_PULL,
BMP5_INT_ASSERTED_DRDY,
)
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 = BMP585(i2c)

if sensor.status != BMP5_OK:
raise Exception("Failed to initialize BMP585: " + sensor.status_string())

print("BMP585 connected!")

# Configure the interrupt pin as push/pull, active high, pulsed
sensor.configure_interrupt(BMP5_PULSED, BMP5_ACTIVE_HIGH, BMP5_INTR_PUSH_PULL, True)

# Only assert the pin on a new data-ready reading
sensor.set_interrupt_source(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 is not None and (status & BMP5_INT_ASSERTED_DRDY):
if sensor.get_sensor_data() == BMP5_OK:
print(
"Pressure: {:.2f} Pa\tTemperature: {:.2f} degC".format(
sensor.data.pressure, sensor.data.temperature
)
)
else:
print("Failed to read sensor data:", sensor.status_string())

🔗Open the complete example

Examples/bmp585-dataReadyInterrupt.py at commit 098c1e2

→

Expected result:

This output was taken with the unmodified example, I2C at the 400 kHz default, on a Qwiic cable of about 10 cm. On longer cables or a busier bus, set freq=100000 in I2C().

ShellMicroPython
BMP585 connected!
Pressure: 101317.85 Pa Temperature: 23.44 degC
Pressure: 101315.81 Pa Temperature: 23.44 degC
Pressure: 101317.21 Pa Temperature: 23.44 degC
Pressure: 101319.61 Pa Temperature: 23.43 degC

One line arrives per data-ready interrupt: the pressure in pascals and the temperature in °C, each with two decimals. If BMP585 connected! appears but no readings follow, the board is not seeing INT: check that wire and INT_PIN.

Functions used​

BMP585(i2c=None, address=BMP5_I2C_ADDR_SEC)returns BMP585

Creates the sensor object and starts the sensor: a soft reset, a chip ID and NVM check, then temperature oversampling 64x, pressure oversampling 4x, 50 Hz with pressure enabled, and NORMAL mode. It raises an exception when the sensor cannot be reached. Every other method stores its result in sensor.status instead of raising.

ReturnsThe sensor object.

Parameters

TypeNameDescription
I2Ci2cA ready machine.I2C object. When left out, the module checks uname().sysname: on the esp32 and esp8266 ports, and on one Soldered board firmware it names, it uses I2C(0, scl=Pin(22), sda=Pin(21)); on any other port it raises Board not recognized, enter I2C pins manually.
intaddressI2C address. BMP5_I2C_ADDR_SEC (0x47) by default; pass BMP5_I2C_ADDR_PRIM (0x46) when the ADDRESS jumper (JP3) is moved, after importing it with from bmp585 import BMP5_I2C_ADDR_PRIM.
sensor.status_string()returns str

Describes the current sensor.status code, such as Communication failure.

ReturnsThe description, or an empty string when the status is BMP5_OK.

sensor.configure_interrupt(mode, pol, drive, enable)returns None

Sets how the INT pin behaves and turns it on or off. It first disables all interrupt sources and clears pending status. It does not choose which event drives the pin; set_interrupt_source() does that. The result goes to sensor.status.

ReturnsNothing; check sensor.status.

Parameters

TypeNameDescription
intmodeBMP5_PULSED or BMP5_LATCHED. The example uses pulsed.
intpolBMP5_ACTIVE_LOW or BMP5_ACTIVE_HIGH. The example uses active high, so the pin rises on an event.
intdriveBMP5_INTR_PUSH_PULL or BMP5_INTR_OPEN_DRAIN.
boolenableTrue to enable the INT pin, False to disable it.
sensor.set_interrupt_source(data_ready, fifo_full=False, fifo_threshold=False, pressure_oor=False)returns None

Chooses which events drive the INT pin. Call configure_interrupt() first. The result goes to sensor.status.

ReturnsNothing; check sensor.status.

Parameters

TypeNameDescription
booldata_readyA new pressure and temperature reading is ready. The example passes True.
boolfifo_fullThe FIFO buffer is full. False by default.
boolfifo_thresholdThe FIFO watermark is reached. False by default.
boolpressure_oorPressure is out of range. False by default.
sensor.get_interrupt_status()returns int or None

Reads the sensor's interrupt status bits over I2C.

ReturnsA bitmask of BMP5_INT_ASSERTED_* flags (BMP5_INT_ASSERTED_DRDY is data ready), or None on a bus error.

sensor.get_sensor_data()returns int

Reads a new measurement into sensor.data: sensor.data.pressure in Pa and sensor.data.temperature in °C.

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

This example also uses I2C and Pin from MicroPython's machine module, which is not part of the BMP585 library and comes with MicroPython itself.

I2C(id, *, scl, sda, freq=400000, timeout=50000)returns I2C

From machine. Creates the I2C bus object that is passed to BMP585(). Which bus IDs and pins are allowed depends on your board.

ReturnsThe I2C bus object.

Parameters

TypeNameDescription
intidThe I2C peripheral. The example uses 0.
PinsclThe pin used for SCL. The example uses Pin(9).
PinsdaThe pin used for SDA. The example uses Pin(8).
intfreqMaximum SCL frequency in Hz, 400000 by default. The example leaves it out, so the bus is set to 400 kHz. On longer cables or a busier bus, pass freq=100000.
inttimeoutLongest time allowed for an I2C transaction, in microseconds; 50000 by default. Some ports do not accept it. The example leaves it out.
Pin(id, mode=-1, pull=-1, *, value=None, drive=0, alt=-1)returns Pin

From machine. Gives access to one GPIO pin. The example uses it for the I2C pins and to read INT as an input. Settings you leave out keep their previous state.

ReturnsThe pin object.

Parameters

TypeNameDescription
intidThe pin number. Which numbers are allowed depends on your board.
intmodePin.IN for an input, as used for INT_PIN. Left out for the I2C pins.
intpullNone, Pin.PULL_UP or Pin.PULL_DOWN. The example leaves it out.
intvalue, drive, altOutput value, drive strength and alternate function; not used by the example.
interrupt_pin.irq(handler=None, trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, *, priority=1, wake=None, hard=False)returns callback object

From machine. Calls handler when the trigger event happens on an input pin.

ReturnsThe interrupt's callback object; the example does not use it.

Parameters

TypeNameDescription
functionhandlerThe function to call. It takes exactly one argument, the Pin. The example passes int_callback.
inttriggerThe event: Pin.IRQ_RISING, Pin.IRQ_FALLING, Pin.IRQ_LOW_LEVEL or Pin.IRQ_HIGH_LEVEL. The example uses Pin.IRQ_RISING.
keywordpriority, wake, hardInterrupt priority, wake-from-sleep source and hard interrupt; not used by the example.

Putting it together​

After the sensor starts, configure_interrupt() makes INT a push-pull, active-high pulse and set_interrupt_source(True) lets only the data-ready event drive it. Pin.irq() from MicroPython's machine module calls int_callback() on each rising edge, and the callback only sets data_ready. The loop then confirms the data-ready bit with get_interrupt_status() before reading, so the I2C traffic stays out of the interrupt handler.