3 releases

new 0.1.2 Feb 11, 2026
0.1.1 Feb 7, 2026
0.1.0 Feb 7, 2026

#1879 in Embedded development

MIT/Apache

63KB
960 lines

BMP38x-ya  

crates.io License Documentation

A Rust crate for Bosch Sensortec BMP38x and BMP390 air pressure sensor (-ya = Yet Another)

fix https://github.com/marvinrobot42/bmp38x-ya.git

The Bosch Sensortec BMP 384 (388) and 390 air pressure and temperature sensor with I2C interface.

Most I2C API functions are implemented.

Features

  • uses embedded-hal version 1.0.x
  • no_std embedded compatible
  • async support included as a feature, default is sync or blocking
  • designed for embedded use (ESP32-C3, -C6 and -S3 and Raspberry Pi)
  • ESP32 RISC V and Raspberry Pi examples included
  • most BMP384 IO functions implemented
  • configurable interrupt pin function
  • FIFO functions with configuration and easier "frame" based reads
  • includes sealevel equivalent air pressure calculation when altitude is provided

Notes

Developed using Sparkfun BMP384 (QWIIC) model: https://www.sparkfun.com/sparkfun-pressure-sensor-bmp384-qwiic.html

It is recommended to enable both temperature and pressure measurements so that the air pressure can be accurate compensated (as it requires current temperature). This is a BMP3xx compensation algorthim design, not this driver.

Recent version history

  • 0.1.0 Initial release
  • 0.1.1 Fixed docs link
  • 0.1.2 Updated docs

Usage


Add the dependency to Cargo.toml.

[dependencies.bmp38x-ya]
version = "0.1"
  1. Create a hardward specific I²C driver interface and a Delay object
  2. Create an BMP38x struct with the I²C interface and a delay object as parameters
  3. Initialize the BMP38x instance
  4. Create a new Bmp3Configuration using either the handy const builder or initial the struct's properties as required
  • then call set_bmp3_configuration(new_bmp3Configuration)
  1. Optional: create a new InterruptPinControl instance and set its properties as required and call set_interrupt_pin_config fn
  2. Optional: create a new Fifo_Config instance and set its properties as required call set_fifo_config
  3. call get_status() and if (status.get_temp_ready() && status.get_press_ready())
  • then call ither read_measurements or read_measurements_with_altitude fn

Simple Example

A more complete example is in the repository examples path


use anyhow::Result;  // add dependency for this
use bmp38x_ya::{BMP38x, constants::DeviceAddress, data::{Bmp3Configuration, PowerMode, SensorFrameEnum}};
use log::{info, error};

...


fn main() -> Result<()> {

  ...as per your hardware hal, below is ESP32-C3 - C6 style

  let peripherals = Peripherals::take().unwrap();
  let pins = peripherals.pins;
  let sda = pins.gpio6; // esp32-c3  has pins.gpio0 , check your board schematic
  let scl = pins.gpio7; // esp32-c3  haspins.gpio1, check your board schematic
  let i2c = peripherals.i2c0;
  let config = I2cConfig::new().baudrate(400.kHz().into());
  let i2c_bus = I2cDriver::new(i2c, sda, scl, &config)?;

  let mut delay: Delay = Default::default();   // your hardware delay from use ...
  let mut sensor = BMP38x::new(i2c_dev,DeviceAddress::Secondary as u8, &mut delay);  // note the secondary I2C address
  sensor.init_device().unwrap();
  info!("BMP38x init_device done");
  let new_config = const {
        Bmp3Configuration::builder()
            .power_mode(PowerMode::Normal)  //  *** very important to get measurements
            .temperature_enable(true)
            .pressure_enable(true)
            .over_sampling_temp(Over_Sampling::ULTRA_LOW_POWER) // ultra_low ok
            .over_sampling_press(Over_Sampling::HIGH_RESOLUTION)// standard ok
            .iir_filter_coef(FilterCoef::COEF_15) // CORF_15 ok
            .output_data_rate(Odr::ODR_12P5)  // ODR_50 ok,  ODR_12P5 for slower rate testing fifo operation
            .build()
    };
    sensor.set_bmp3_configuration(new_config).unwrap();
    let config = sensor.get_bmp3_configuration().unwrap();  // optional just to see that set config worked
    info!("new Bmp3Configuration = {:?}", config);

  FreeRtos::delay_ms(250);  // or your sleep function here

  loop {
    let status = sensor.get_status().unwrap();
    info!(" bmp38x status is  {:?}", status);
    if (status.get_temp_ready() && status.get_press_ready()) {
      let sensor_measurements = sensor.read_measurements_with_altitude(383.5).unwrap();  // using 383.5 m of altitude for sealevel equivalent pressure
      // alternative call sensor.read_measurements().unwrape; if sealevel pressure not needed
      info!(" sensor measurements = {:?}", sensor_measurements);
    } else {
            log::info!("  bmp38x sensor data not ready!");
    }
    FreeRtos::delay_ms(10000);
  }

}
    

For async set bmp38x-ya dependency features = ["async"] and Bmp38x::new method requires async I2C and delay

parameters. Default features is sync (blocking)

License


You are free to copy, modify, and distribute this application with attribution under the terms of either

at your option.

This project is not affiliated with nor endorsed in any way by Silicon Labs or Adafruit.

Dependencies

~1.3–2MB
~41K SLoC