BMP388 / CJMCU-388 Barometric Pressure Sensor

The BMP388 is a high-precision digital barometric pressure and temperature sensor, offering enhanced accuracy and stability. It supports both I²C and SPI communication, making it ideal for weather monitoring, altitude measurement, and UAV applications.

BMP388 / CJMCU-388 Barometric Pressure Sensor image
BMP388 · I2C / SPI
2modes
I2C · SPI
6pins
Connections
1.65-3.6 V
Supply
±0.08 hPa
Accuracy
-40 to +85 °C
Operating temp
On this page

BMP388 pinout

6 pins · I2C · SPI

The BMP388 supports both I²C and SPI with enhanced precision:

View:
BMP388 / CJMCU-388 Barometric Pressure Sensor pinout
PinTypeDescriptionNotes
VCCPowerPower input3.3V (not 5V tolerant)
GNDPowerGround connection
SDACommunicationI²C data lineConnect to ESP32 GPIO21
SCLCommunicationI²C clock lineConnect to ESP32 GPIO22
CSCommunicationChip select for SPITie to 3.3V (VDDIO) for I²C mode - pulling it low switches the chip to SPI
SDOCommunicationSPI data out / I²C addressGND=0x76, VCC=0x77 for I²C
  • Dual Protocol: Supports both I²C and SPI

  • I²C Address: 0x76 or 0x77 (SDO pin selects)

  • Temperature: -40°C to +85°C, ±0.5°C accuracy

  • Pressure: 300-1250 hPa, ±0.5 hPa accuracy

  • Altitude: ±0.25m precision (excellent for drones)

  • Power: 3.3V ONLY (not 5V tolerant)

  • High Precision: Best in BMP series

  • Low Noise: Improved temperature stability

  • Applications: Drones, UAVs, precision altimeters, weather stations

Wiring the BMP388 to ESP32

5 connections · all required

To interface the BMP388 with an ESP32 using I²C:

BMP388 / CJMCU-388 Barometric Pressure Sensor wiring with ESP32
BMP388 pinESP32 pinPurpose
VCC3.3VPower supply (3.3V only)
GNDGNDGround
SDAGPIO21I²C data line
SCLGPIO22I²C clock line
CS3.3VTie to 3.3V for I²C mode (pulling it low switches the chip to SPI)
  • I²C Address: 0x76 (SDO→GND) or 0x77 (SDO→VCC)

  • Power: 3.3V ONLY - do NOT use 5V

  • High Precision: Best accuracy in BMP series

  • CSB Pin: Must be tied to 3.3V for I²C mode - pulling it low permanently selects SPI until power-off (many breakout boards pull it high already)

  • Drones: Ideal for UAV altitude control

  • Fast: Quick conversion times

BMP388 code examples

5 platforms
Platform:

BMP388 Arduino example

Copy
// Requires library: "Adafruit BMP3XX Library"
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP3XX.h>

Adafruit_BMP3XX bmp;

void setup() {
  Serial.begin(115200);
  // 0x77 is the default address; use 0x76 if SDO is pulled low
  if (!bmp.begin_I2C(0x77)) {
    Serial.println("Could not find a valid BMP388 sensor, check wiring!");
    while (1);
  }
}

void loop() {
  if (!bmp.performReading()) {
    Serial.println("Failed to perform reading");
    return;
  }
  Serial.print("Temperature: ");
  Serial.print(bmp.temperature);
  Serial.println(" *C");

  Serial.print("Pressure: ");
  Serial.print(bmp.pressure / 100.0);
  Serial.println(" hPa");
  delay(2000);
}

This Arduino code initializes the BMP388 sensor using the Adafruit BMP3XX library. It reads temperature and pressure values and prints them to the Serial Monitor every two seconds.

BMP388 ESP-IDF example

Copy
// Requires the Soldered BMP388 driver from the ESP Component Registry:
//   idf.py add-dependency "solderedelectronics/soldered-bmp388-esp-idf-component^1.0.0"

/**
 * @file main.c
 * @brief Basic usage example for the soldered-bmp388-esp-idf-component
 * @author Soldered Electronics
 */

#include <stdio.h>

#include "driver/i2c_master.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "soldered_bmp388.h"

// Adjust to whatever GPIOs the sensor is wired to on your board.
#define I2C_SDA_GPIO 21
#define I2C_SCL_GPIO 22

void app_main(void)
{
    i2c_master_bus_config_t bus_cfg = {
        .i2c_port = -1,
        .sda_io_num = I2C_SDA_GPIO,
        .scl_io_num = I2C_SCL_GPIO,
        .clk_source = I2C_CLK_SRC_DEFAULT,
        .glitch_ignore_cnt = 7,
        .flags.enable_internal_pullup = true,
    };

    i2c_master_bus_handle_t bus;
    ESP_ERROR_CHECK(i2c_new_master_bus(&bus_cfg, &bus));

    bmp388_t bmp388;
    esp_err_t err = bmp388_init(&bmp388, bus);

    if (err != ESP_OK) {
        printf("bmp388_init failed: %s\n", esp_err_to_name(err));
        return;
    }

    while (1) {
        float temperature, pressure;
        err = bmp388_read(&bmp388, &temperature, &pressure);

        if (err == ESP_OK) {
            printf("temperature: %.2f C, pressure: %.2f Pa\n", temperature, pressure);
        } else {
            printf("bmp388_read failed: %s\n", esp_err_to_name(err));
        }

        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

ESP-IDF ships no BMP388 driver of its own, so this example uses the Soldered BMP388 driver (plain I2C from the ESP Component Registry - it works with any BMP388 breakout, not just Soldered's). Install it into your project first with idf.py add-dependency "solderedelectronics/soldered-bmp388-esp-idf-component^1.0.0", then build as usual.

The driver uses ESP-IDF's modern i2c_master API: the code creates an I2C master bus, hands it to bmp388_init(), and then reads compensated values with bmp388_read(), which returns temperature in Celsius and pressure in Pascal. The default configuration samples continuously; see the component's bmp388_configure() for oversampling and output-data-rate options.

BMP388 ESPHome example

Copy
i2c:
  sda: GPIO21
  scl: GPIO22

sensor:
  - platform: bmp3xx_i2c
    temperature:
      name: "BMP388 Temperature"
    pressure:
      name: "BMP388 Pressure"
    address: 0x76

Since ESPHome 2024.6 the Bosch BMP3xx platform is split by bus - bmp3xx_i2c covers the BMP388 and BMP390 on the default I2C pins (address 0x77, or 0x76 with SDO low).

BMP388 PlatformIO example

Copy
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
    adafruit/Adafruit BMP3XX Library @ ^2.1.6
    adafruit/Adafruit Unified Sensor @ ^1.1.15
src/main.cppCopy
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP3XX.h>

Adafruit_BMP3XX bmp;

void setup() {
  Serial.begin(115200);
  // 0x77 is the default address; use 0x76 if SDO is pulled low
  if (!bmp.begin_I2C(0x77)) {
    Serial.println("Could not find a valid BMP388 sensor, check wiring!");
    while (1);
  }
}

void loop() {
  if (!bmp.performReading()) {
    Serial.println("Failed to perform reading");
    return;
  }
  Serial.print("Temperature: ");
  Serial.print(bmp.temperature);
  Serial.println(" *C");

  Serial.print("Pressure: ");
  Serial.print(bmp.pressure / 100.0);
  Serial.println(" hPa");
  delay(2000);
}

This PlatformIO code integrates the BMP388 sensor to read temperature and pressure values, printing them every two seconds.

BMP388 MicroPython example

Copy
# Requires driver: bmp388.py (and bmp388_constants.py) from
# https://github.com/SolderedElectronics/Soldered-BMP388-MicroPython-Library
# Copy both to the board: mpremote cp bmp388.py bmp388_constants.py :
from machine import Pin, I2C
from bmp388 import BMP388
import time

i2c = I2C(0, scl=Pin(22), sda=Pin(21))
bmp = BMP388(i2c)

bmp.setSeaLevelPressure(1013.25)  # for altitude readings
bmp.startNormalConversion()       # continuous measurement mode

while True:
    temperature, pressure, altitude = bmp.getMeasurements()
    if temperature is not None:
        print("Temperature: {:.2f} C".format(temperature))
        print("Pressure: {:.2f} hPa".format(pressure))
        print("Altitude: {:.1f} m".format(altitude))
    time.sleep(2)

The example uses Soldered's maintained BMP388 MicroPython library - copy both bmp388.py and bmp388_constants.py to the board. startNormalConversion() puts the sensor in continuous mode and getMeasurements() returns compensated temperature, pressure and altitude (derived from the sea-level pressure you set). Default address 0x77; pass address=0x76 if SDO is low.

BMP388 specifications

From the datasheet
Interface
I²C (up to 3.4 MHz) / SPI (up to 10 MHz)
Pressure Range
300 hPa to 1250 hPa
Temperature Range
-40°C to +85°C
Operating Voltage
1.65V to 3.6V
Resolution
0.03 hPa
Accuracy
±0.08 hPa
Power Consumption
3.4 µA at 1 Hz
Output
Temperature and Pressure (Digital)
Package Dimensions
2.0 mm × 2.0 mm × 0.75 mm
Weight
0.5 g

About the BMP388

The BMP388 is Bosch’s high-precision follow-up to the BMP280 line, trading the older chip’s ±1 hPa accuracy for ±0.08 hPa and a lower-noise front end - accurate enough to resolve a few centimeters of altitude change. Bosch marketed it specifically for drone and UAV altitude hold, and it became a common barometer choice on open-source flight controllers. Unlike most Bosch breakouts it needs a clean 3.3 V supply - it is not 5V tolerant.

Bosch has since discontinued the BMP388 itself - distributor listings show it obsolete since 2021 - in favor of the BMP390, a pin-compatible successor that runs the same driver code with only a chip-ID check to update. If you are sourcing new stock, do not be surprised to find BMP390 silicon under a BMP388-labeled breakout; most designs will not notice the difference.

For projects that do not need drone-grade altitude resolution, the older BMP280 is cheaper and accurate enough for weather stations and general altitude logging, and BME280 adds humidity if you want all three measurements from one part.

BMP388 troubleshooting

3 common issues

Library Not Found Error

Issue: The Arduino IDE cannot find the required BMP388 library.

Solution: Ensure that you have installed the Adafruit BMP3XX library from the Arduino Library Manager. Restart the Arduino IDE after installation.

Sensor Initialization Failure

Issue: The BMP388 sensor fails to initialize, and the error message Could not find a valid BMP388 sensor appears.

Solution: Check the wiring connections and ensure the sensor receives 3.3V power. Use an I²C scanner to detect the sensor's address.

Incorrect Pressure Readings

Issue: The sensor outputs incorrect pressure values, leading to inaccurate altitude measurements.

Solution: Verify that the reference sea-level pressure value is set correctly and recalibrate the sensor if needed.

Resources