Qwiic Pressure Sensor (BMP384) Hookup Guide

Pages
Contributors: El Duderino
Favorited Favorite 0

Arduino Examples

Let's take a closer look at a few of the examples included in the SparkFun BMP384 Arduino Library.

Example 1 - Basic Readings I2C

The first example initializes the BMP384 to communicate over I2C with default settings. Open the example by navigating to File Examples > SparkFun BMP384 Arduino Library > Example_1_Basic_ReadingsI2C. Select your Board and Port and click upload. Open the serial monitor after the upload completes with the baud set to 115200 to watch pressure data (in Pascals) print out.

If you have switched to the alternate address, comment/uncomment the line with the correct value:

language:c
uint8_t i2cAddress = BMP384_I2C_ADDRESS_DEFAULT; // 0x77
//uint8_t i2cAddress = BMP384_I2C_ADDRESS_SECONDARY; // 0x76

The code attempts to initialize the sensor with default settings in I2C at the specified address and prints out an error message if it cannot initialize properly:

language:c
while(pressureSensor.beginI2C(i2cAddress) != BMP3_OK)
{
    // Not connected, inform user
    Serial.println("Error: BMP384 not connected, check wiring and I2C address!");

    // Wait a bit to see if connection is established
    delay(1000);
}

After initializing, the main loop polls the BMP384 for pressure and temperature data every second. If polling for data fails, the code will print out an error code for debugging. Try moving the sensor up and down and you should see noticeable differences in pressure readings with just a few inches of movement.

language:c
void loop()
{
    // Get measurements from the sensor
    bmp3_data data = {0};
    int8_t err = pressureSensor.getSensorData(&data);

    // Check whether data was acquired successfully
    if(err == BMP3_OK)
    {
        // Acquisistion succeeded, print temperature and pressure
        Serial.print("Temperature (C): ");
        Serial.print(data.temperature);
        Serial.print("\t\t");
        Serial.print("Pressure (Pa): ");
        Serial.println(data.pressure);
    }
    else
    {
        // Acquisition failed, most likely a communication error (code -2)
        Serial.print("Error getting data from sensor! Error code: ");
        Serial.println(err);
    }

    // Only print every second
    delay(1000);
}

Example 4 - Filtering

Example 4 demonstrates how to set up a low-pass filter for the BMP384 data to smooth out the output. After initializing the sensor, the code creates an case to print error codes returned by API calls and sets the filter coefficient:

language:c
// Variable to track errors returned by API calls
int8_t err = BMP3_OK;

// By default, the filter coefficient is set to 0 (no filtering). We can
// smooth out the measurements by increasing the coefficient
err = pressureSensor.setFilterCoefficient(BMP3_IIR_FILTER_COEFF_127);
if(err)
{
    // Setting coefficient failed, most likely an invalid coefficient (code -3)
    Serial.print("Error setting filter coefficient! Error code: ");
    Serial.println(err);
}

Example 5 - Oversampling

Example 5 shows how to set the oversampling rate on the BMP384 so it performs multiple samples between each measurement to boost resolution and reduce noise. The code sets the oversampling rate to 32x for pressure measurements and 2x for temperature:

language:c
bmp3_odr_filter_settings osrMultipliers =
{
    .press_os = BMP3_OVERSAMPLING_32X,
    .temp_os = BMP3_OVERSAMPLING_2X
};
err = pressureSensor.setOSRMultipliers(osrMultipliers);
if(err)
{
    // Setting OSR failed, most likely an invalid multiplier (code -3)
    Serial.print("Error setting OSR! Error code: ");
    Serial.println(err);
}

Adjusting the oversampling rate requires an adjustment to the output data rate as well. The setOSRMultipliers() function automatically adjusts it and the code polls the sensor to return the data rate in Hz:

language:c
uint8_t odr = 0;
err = pressureSensor.getODRFrequency(&odr);
if(err)
{
    // Interrupt settings failed, most likely a communication error (code -2)
    Serial.print("Error getting ODR! Error code: ");
    Serial.println(err);
}

// The true ODR frequency in Hz is [200 / (2^odr)]
Serial.print("ODR Frequency: ");
Serial.print(200 / pow(2, odr));
Serial.println("Hz");

Example 6 - FIFO Buffer

Reminder We recommend using a microcontroller with plenty of RAM like the RedBoard Artemis as the BMP384 reads the entire FIFO buffer all at once. This causes some microcontrollers like the ATMega328 on the RedBoard or Uno to run out of RAM after just a few samples.

Example 6 demonstrates how to enable, read and flush the FIFO buffer on the BMP384. The example uses the BMP384's interrupt pin to trigger an external interrupt for an attached microcontroller to monitor when the FIFO buffer reaches a specified threshold, in this case the code will trigger when the FIFO buffer has 5 samples stored in it.

The code sets up D2 as the interrupt pin so make sure to connect the Interrupt pin to D2 and ensure your microcontroller supports external interrupts on D2. If it does not, adjust the pin to one that can.

language:c
int interruptPin = 2;

// Flag to know when interrupts occur
volatile bool interruptOccurred = false;

// Create a buffer for FIFO data
// Note - on some systems (eg. Arduino Uno), warnings will be generated
// when numSamples is large (eg. >= 5)
const uint8_t numSamples = 5;
bmp3_data fifoData[numSamples];

The setup initializes the BMP384 on the I2C bus and then sets the FIFO buffer settings:

language:c
bmp3_fifo_settings fifoSettings =
{
    .mode            = BMP3_ENABLE,  // Enable the FIFO buffer
    .stop_on_full_en = BMP3_DISABLE, // Stop writing to FIFO once full, or overwrite oldest data
    .time_en         = BMP3_DISABLE, // Enable sensor time, only 1 frame at end of buffer
    .press_en        = BMP3_ENABLE,  // Enable pressure sensor recording
    .temp_en         = BMP3_ENABLE,  // Enable temperature sensor recording
    .down_sampling   = BMP3_FIFO_NO_SUBSAMPLING, // Set downsampling factor
    .filter_en       = BMP3_DISABLE, // Enable data filtering
    .fwtm_en         = BMP3_ENABLE,  // Trigger interrupt on FIFO watermark
    .ffull_en        = BMP3_DISABLE  // Trigger interrupt on FIFO full
};

Note that the FIFO settings includes the interrupt conditions. In this case, the interrupt is configured to trigger on the FIFO watermark (5 samples) set further down in the code.

After setting everything up, the main loop monitors the FIFO buffer, prints the number of samples currently stored up to when the sample number hits the watermark threshold. Once the number of samples hits the watermark, the interrupt condition triggers and the code prints out the data for each sample stored in the FIFO buffer.