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().
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 BMP585Creates 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
| Type | Name | Description |
|---|---|---|
I2C | i2c | A 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. |
int | address | I2C 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 strDescribes 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 NoneSets 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
| Type | Name | Description |
|---|---|---|
int | mode | BMP5_PULSED or BMP5_LATCHED. The example uses pulsed. |
int | pol | BMP5_ACTIVE_LOW or BMP5_ACTIVE_HIGH. The example uses active high, so the pin rises on an event. |
int | drive | BMP5_INTR_PUSH_PULL or BMP5_INTR_OPEN_DRAIN. |
bool | enable | True 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 NoneChooses which events drive the INT pin. Call configure_interrupt() first. The result goes to sensor.status.
ReturnsNothing; check sensor.status.
Parameters
| Type | Name | Description |
|---|---|---|
bool | data_ready | A new pressure and temperature reading is ready. The example passes True. |
bool | fifo_full | The FIFO buffer is full. False by default. |
bool | fifo_threshold | The FIFO watermark is reached. False by default. |
bool | pressure_oor | Pressure is out of range. False by default. |
sensor.get_interrupt_status()returns int or NoneReads 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 intReads 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 I2CFrom 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
| Type | Name | Description |
|---|---|---|
int | id | The I2C peripheral. The example uses 0. |
Pin | scl | The pin used for SCL. The example uses Pin(9). |
Pin | sda | The pin used for SDA. The example uses Pin(8). |
int | freq | Maximum 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. |
int | timeout | Longest 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 PinFrom 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
| Type | Name | Description |
|---|---|---|
int | id | The pin number. Which numbers are allowed depends on your board. |
int | mode | Pin.IN for an input, as used for INT_PIN. Left out for the I2C pins. |
int | pull | None, Pin.PULL_UP or Pin.PULL_DOWN. The example leaves it out. |
int | value, drive, alt | Output 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 objectFrom machine. Calls handler when the trigger event happens on an input pin.
ReturnsThe interrupt's callback object; the example does not use it.
Parameters
| Type | Name | Description |
|---|---|---|
| function | handler | The function to call. It takes exactly one argument, the Pin. The example passes int_callback. |
int | trigger | The event: Pin.IRQ_RISING, Pin.IRQ_FALLING, Pin.IRQ_LOW_LEVEL or Pin.IRQ_HIGH_LEVEL. The example uses Pin.IRQ_RISING. |
| keyword | priority, wake, hard | Interrupt 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.