Library 37- BMP180 pressure sensor for STM32F4

BMP180 is a digital pressure sensor, with builtin temperature sensor. Its range is between 300 and 1100 hPa (0.3 to 1.1Bar). In relating to the sea level, this is +9000 to -500 meters.

Sensor works with I2C communication at 100kHz.

If you want sensor from ebay, here is one link.

Sensor is quite bad created, because if you want to read pressure, you first need to read current temperature for pressure calculation. To read temperature you have to wait at least 4.5ms. After that, you first have to read temperature and then you can start with pressure measurement. Time for pressure measurement depends on mode you select. After pressure is measured, you can read uncompensated data from device. This is because device has one register for control temperature and pressure, and also one register for data. So both, temperature and  pressure can not be measured at same time.

This takes about at least 10ms for every stuff to be done. At the end a lot of calculations are needed to get valid pressure from device.

Because veeery long time for STM32F4, I split things into several functions, to start temp, read temp, start pressure, read pressure, etc.

I have also added possibility, that you calculate pressure right above the sea from known pressure at known altitude.

Sequency for reading useful data is:

  • Start temperature measurement
    • Wait 4.5ms at least
  • Read temperature
  • Start pressure measurement
    • Delay depends on measurement mode you select
  • Read pressure
  • Use pressure data

Library

Features

  • Read BMP180 temperature sensor
  • Read BMP180 pressure sensor
  • Calculate sea level pressure at from given know pressure and altitude
    • If you are at ex 1000meters and there si pressure 98000Pascals, then you can calculate pressure at sea level from this values

Dependencies

  • CMSIS
    • STM32F4xx
    • STM32F4xx RCC
    • STM32F4xx GPIO
    • STM32F4xx I2C
  • TM
    • TM I2C
    • defines.h
BMP180 STM32F4 Description
SCL PA8 I2C3 Serial clock
SDA PC9 I2C3 Serial data

You can change I2C settings. Open defines.h file, copy lines below and edit them.

Like I said on beginning, different modes for reading pressure can be used. Modes differ in number of samples, conversion time and noise. You select your mode each time you start pressure measurement. For temperature, there is no possible to select mode.

Mode Internal number of samples Conversion time [us] RMS noise [Pascals] RMS noise [meters]
Ultra Low Power 1 4500 6 0.5
Standard 2 7500 5 0.4
High Resolution 4 13500 4 0.3
Ultra High Resolution 8 25500 3 0.25

Functions and enumerations

Example

Example below takes measurements from device and sends data to USART1, TX pin on PB6 at 115200 bauds. You should get result something like on image below.

BMP180 pressure sensor USART result

BMP180 pressure sensor USART result



Project is available at my Github account.

Icon
TM STM32F4 BMP180 Library

tilz0R

Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • Klaus Liebler

    Hi Tilen,

    thank you for this wonderful library! I adapted it to my environment (using CubeMX-HAL) and was able to get connected to the BMP180 and to read out the calibration values. However, it I try to read out the temperature value “UT”, I always get the value 2560 (0x0a00). Even If I make the sensor warmer, the value doesn’t change. Between giving the start command and reading out the value, the program waits sufficient time (100msecs). Do you have any hints?

    Thank you for your help!

    Klaus

    • Klaus Liebler

      Hi Tilen,
      I solved this issue – it was a hardware problem. Thx!

      Klaus

  • Pingback: Fix Uvision Error 65 Windows XP, Vista, 7, 8 [Solved]()

  • Andy

    Tilen,

  • Andy

    Pertaining to the below post:

    Here’s the result of the following code:

    TM_I2C_Init(BMP180_I2C, BMP180_I2C_PINSPACK, BMP180_I2C_SPEED);
    while (1) {

    TM_I2C_Start(I2C3, 0xEE, 0, 1);
    TM_I2C_WriteData(I2C3, 0xF4);
    TM_I2C_WriteData(I2C3, 0x2E);
    TM_I2C_Stop(I2C3);

    Delayms(1);

    }

    • Sorry Andy,

      I think I don’t understand what you wanna told me here.

      • Andy

        The SDA should should show F4 after the ACK for the h77, but it just stays high. I drew in red what I expected to see on the logic analyzer (excuse my artistic abilities). Any idea why my board is not proceeding to the next byte?

        • Try to use TM_I2C_Write(I2C3, 0xEE, 0xF4, 0x2E); if it will work for you.

          • Andy

            No joy. Same result.

            However, when I change TM_I2C_TIMEOUT to 250 (instead of 20000) and try the following code, it appears to be working shown with attached picture (any idea why?):

            TM_I2C_Start(I2C3, 0xEE, 0, 0);
            TM_I2C_ReadAck(I2C3);
            TM_I2C_WriteData(I2C3, 0xF4);
            TM_I2C_ReadAck(I2C3);
            TM_I2C_WriteData(I2C3, 0x2E);
            TM_I2C_Stop(I2C3);

          • Andy

            Able to read temp at 100 Hz with TM_I2C_TIMEOUT 250 and the following code (picture is the output from the analyzer):

            while (1) {

            TM_I2C_Start(I2C3, 0xEE, 0, 0);
            TM_I2C_ReadAck(I2C3);
            TM_I2C_WriteData(I2C3, 0xF4);
            TM_I2C_ReadAck(I2C3);
            TM_I2C_WriteData(I2C3, 0x2E);
            TM_I2C_ReadAck(I2C3);
            TM_I2C_ReadNack(I2C3);
            TM_I2C_Stop(I2C3);

            TM_I2C_Start(I2C3, 0xEE, 0, 1);
            TM_I2C_ReadAck(I2C3);
            TM_I2C_WriteData(I2C3, 0xF6);
            TM_I2C_ReadNack(I2C3);
            TM_I2C_Stop(I2C3);

            TM_I2C_Start(I2C3, 0xEE, 1, 0);
            TM_I2C_ReadAck(I2C3);
            TM_I2C_ReadAck(I2C3);
            TM_I2C_ReadNack(I2C3);
            TM_I2C_Stop(I2C3);

            Delayms(10);
            }

            Thanks anyway Tilen.

  • Mohammad Kamel

    Hi tilen
    thanks for this great sample
    i did what you said in this toutorial but i have outputs witch are not shown correctly
    but i dont khow how to fix it i khow the code is correct and work but i dont khow where is my problem
    what should i do???
    thanks alot

  • Christian Julius

    Tilen,
    when I ran this software in Debug Mode, the value is exactly like the same on my Arduino barometer (975 at the moment). When I ran it in Release mode, I get 200mBar less (507). Very strange…..

    • Christian Julius

      Absolut correct…. in Debug Mode (slower than Release)

      • Christian Julius

        Ok, got it! The delay has to be 12ms at least, better 15ms for stable results.

        • Your optimization settings are different in debug and release modes.

          • Christian Julius

            Nevertheless, the required delay must be larger than estimated in your text. It works fine now and the RTC is trimmed better than untrimmed.

          • Delay values are from datasheet.

          • Christian Julius

            Well, in the 80s we call it “Little computer people” when things don’t function as expected or documented in data sheets… in my Arduino project 10ms are delayed in source code and it works for more than two years now as a good indicator.

  • Christian Julius

    Strange thing:

    I have to read out the temperature first, to get a valid pressure result. I wanted to split the functions, but
    when I read the pressure, he value is very false.

    Normally float BMP180_readPressure should look like this:

    float BMP180_ReadPressure(){
    /* Start pressure conversion at ultra high resolution */
    TM_BMP180_StartPressure(&BMP180, TM_BMP180_Oversampling_HighResolution);
    Delay(BMP180.Delay);
    /* Read pressure value */
    TM_BMP180_ReadPressure(&BMP180);
    double pressure_normal = (double)BMP180.Pressure / 100;
    float foo = pressure_normal / pow(1-(0.0065 * HOEHE_ORT) / 288.15, 5.255);
    return foo;
    }

    Is is necessary to read T out first and then P ?

    http://pastebin.com/cMm8wR5q

    • Christian Julius

      Yeah, it seems, that T and P can only be read out one after each other: