ujjval rathod
Published

Grove Pressure/Altitude sensor Bosch BMP390

BMP390 is a sensor with inbuilt pressure and temperature measurement capabilities. The sensor has ultra-high resolution for altitude

IntermediateWork in progressOver 4 days209
Grove Pressure/Altitude sensor Bosch BMP390

Things used in this project

Hardware components

Seeed Studio Grove BMP390 sensor
×1
Wio Terminal
Seeed Studio Wio Terminal
×1

Software apps and online services

Arduino IDE
Arduino IDE
Seeed Studio Seeed fusion services

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Code

Untitled file

Arduino
#include "BMP390.h"

BMP390 bmp;

void setup() {
  // put your setup code here, to run once:
  Wire.begin();
  Serial.begin(9600);
  bmp.begin();

}

void loop() {
  // put your main code here, to run repeatedly:

  Serial.println("\n");
  
  uint8_t temp;
  float temprature, pressure, heightm;

  byte vals[5];

  bmp.begin();

  bmp.readi2cbytes(DATA_0, 6, vals);

  
  temp = bmp.readbyte(0x00);
  
  //Serial.println(temp, HEX);

  temp = bmp.readbyte(0x01);
  //Serial.println(temp, HEX);

  temprature = bmp.measureTemp();
  Serial.print("Temprature in C ");
  Serial.print(temprature);
  Serial.println();

  pressure = bmp.measurePress();
  Serial.print("Pressure in hp ");
  Serial.println(pressure);

  heightm = bmp.calculateAltitude(temprature, pressure);
  Serial.print("Altitude in meters ");
  Serial.print(heightm);
  Serial.println();

  Serial.println("\n");
  Serial.println("_____________________");
  Serial.println("_____________________");

  
  delay(1000);
}

Untitled file

Arduino
#include "BMP390.h"

BMP390::BMP390(void){}

BMP390::~BMP390(void){}

/*
 * Start the sensor by setting IIR filter cofficient to 63
 * ODR select to 200 hz  
 * 
  
*/

void BMP390::begin()
{
  uint8_t tp= 0x00;
  tp = (coff_63 << 1);
  
  writebyte(CONFIG, 0x0C);
  
  writebyte(ODR, 0x01);
  
 // writebyte(OSR, 0x24);

  writebyte(PWR_CTRL, 0x33);

  writebyte(FIFO_CONFIG_1, 0x1F); 
}

double BMP390::calculateAltitude(double temprature, double pressure)
{
  float height = ((pow(1013.25/(pressure/100), (1/5.257)) - 1)) * (temprature + 273.15)/0.0065;
  
  return height;
}

double BMP390::measureTemp()
{

  struct coffvals vals;
  struct pars par;
  
  double partial_data1, partial_data2;
  double t_lin;

  uint32_t utemp;
  byte tvals[5];
  readi2cbytes(DATA_0, 6, tvals);

  utemp = (tvals[5] << 16 | tvals[4] << 8 | tvals[3]);
  
  
  //readcoffs(vals, par);

  byte coffs[4];
  readi2cbytes(NVM_PAR_T1, 5, coffs);

  vals.t1 = ((coffs[1]<< 8) | coffs[0]);
  vals.t2 = ((coffs[3]<< 8) | coffs[2]);
  vals.t3 =  coffs[4];

  par.par_t1 = (double)(vals.t1 * 256);
  par.par_t2 = (double)(vals.t2 / 1073741424.0);
  par.par_t3 = (double)(vals.t3 / 281474976700000.0);

  partial_data1 = (double) (utemp - par.par_t1);
  
  partial_data2 = (double) (partial_data1 * par.par_t2);
  
  t_lin = partial_data2 + (partial_data1 * partial_data1)*par.par_t3;

  return t_lin;
}

double BMP390::measurePress()
{
  double pressure;
  
  struct coffvals vals;
  struct pars par;
  double t_lin;

  t_lin = measureTemp();

  double partial_data1, partial_data2, partial_data3, partial_data4, partial_out1, partial_out2;
  
  byte coffs[15];

  readi2cbytes(NVM_PAR_P1, 16, coffs);

  vals.p1 = ((coffs[1]<<8) | coffs[0]);
  vals.p2 = ((coffs[3]<<8) | coffs[2]);
  vals.p3 =  coffs[4];
  
  vals.p4 = coffs[5];
  vals.p5 = ((coffs[7]<<8) | coffs[6]);
  vals.p6 = ((coffs[9]<<8) | coffs[8]);
  
  vals.p7 = coffs[10];
  vals.p8 = coffs[11];
  vals.p9 = ((coffs[13]<<8) | coffs[12]);
  vals.p10 = coffs[14];
  vals.p11 = coffs[15];

  par.par_p1 = (double)((vals.p1 - 16384.0) / 1048576.0);
  par.par_p2 = (double)((vals.p2 - 16384.0)/ 536870912.0);
  par.par_p3 = (double)(vals.p3/4294967296.0);
  par.par_p4 = (double)(vals.p4/137438953472.0);
  par.par_p5 = (double)(vals.p5 * 8.0);
  par.par_p6 = (double)(vals.p6/64.0);
  par.par_p7 = (double)(vals.p7/256.0);
  par.par_p8 = (double)(vals.p8/32768.0);
  par.par_p9 = (double)(vals.p9/281474976710656.0);
  par.par_p10 = (double)(vals.p10/281474976710656.0);
  par.par_p11 = (double)(vals.p11/3689348814741910300.0);

  partial_data1 = (double)(par.par_p6 * t_lin);
  partial_data2 = (double)(par.par_p7 * t_lin * t_lin);
  partial_data3 = (double)(par.par_p8 * t_lin * t_lin * t_lin);

  partial_out1 = (double)(par.par_p5 + partial_data1 + partial_data2 + partial_data3);
  
  partial_data1 = (double)(par.par_p2 * t_lin);
  partial_data2 = (double)(par.par_p3 * t_lin * t_lin);
  partial_data3 = (double)(par.par_p4 * t_lin * t_lin * t_lin);

  uint32_t upres;
  byte ttvals[5];
  readi2cbytes(DATA_0, 6, ttvals);

  upres = (ttvals[2]<<16 | ttvals[1]<<8 | ttvals[0]);

  partial_out2 = (double)upres * (par.par_p1 + partial_data1 + partial_data2 + partial_data3);

  partial_data1 = (double)upres * (double)upres;
  partial_data2 = (double)(par.par_p9 + (par.par_p10 * t_lin));
  
  partial_data3 = (double)(partial_data1 * partial_data2);
  partial_data4 = (double)(partial_data3 + ((double) (upres) * (double)(upres)*(double)(upres))*par.par_p11);

  pressure = partial_out1 + partial_out2 + partial_data4;

  return pressure;
}

void BMP390::enableforcemode(){
  writebyte(PWR_CTRL, 0x23);  
}

uint8_t BMP390::readchipid()
{
   uint8_t id;
   id = readbyte(CHIP_ID);
   return id;
}

uint8_t BMP390::readrevid(){
   uint8_t id;
   id = readbyte(REV_ID);
   return id;  
}

void BMP390::readcoffs(struct coffvals vals, struct pars par)
{
  
  byte coffs[21];
  readi2cbytes(NVM_PAR_T1, 21, coffs);

  vals.t1 = (coffs[1]<< 8) | coffs[0];
  vals.t2 = (coffs[3]<< 8) | coffs[2];
  vals.t3 =  coffs[4];

  vals.p1 = (coffs[6]<< 8) | coffs[5];
  vals.p2 = (coffs[8]<< 8) | coffs[7];
  vals.p3 = coffs[9];

  vals.p4 = coffs[10];
  vals.p5 = (coffs[12]<< 8) | coffs[11];
  vals.p6 = (coffs[14]<< 8) | coffs[13];

  vals.p7 = coffs[15];
  vals.p8 = coffs[16];
  vals.p9 = (coffs[18]<< 8) | coffs[17];

  vals.p10 = coffs[19];
  vals.p11 = coffs[20];  

  par.par_t1 = (double) (vals.t1 * 256);
  par.par_t2 = (double) (vals.t2 / 1073741824.0);
  par.par_t3 = (double) (vals.t3 / 281474976700000.0);
   
}


byte BMP390::readbyte(byte reg)
{
  Wire.beginTransmission(BMP_ADDRESS);
  Wire.write(reg);
  Wire.endTransmission();
  Wire.requestFrom(BMP_ADDRESS, 1);
  return Wire.read();  
}

void BMP390::readi2cbytes(uint8_t reg, int count, uint8_t temp[]) 
{
  Wire.beginTransmission(BMP_ADDRESS);
  Wire.write(reg);
  Wire.endTransmission();
  Wire.requestFrom(BMP_ADDRESS, count);

  for(int i=0; i<count; i++){
    temp[i] = Wire.read();    
    }
} 
  
void BMP390::writebyte(byte reg, uint8_t val)
{
  Wire.beginTransmission(BMP_ADDRESS);
  Wire.write(reg);
  Wire.write(val);
  Wire.endTransmission();  
}

Untitled file

Arduino
#ifndef _BMP390_H
#define _BMP390_H

#include "Arduino.h"
#include "BMP390REG.h"
#include <Wire.h>

/*Filter selection from range 1 to 127. Zero is bypass-mode*/
typedef enum
{
  coff_0 = 0b000,
  coff_1 = 0b001,
  coff_3 = 0b010,
  coff_7 = 0b011,
  coff_15 = 0b100,
  coff_31 = 0b101,
  coff_63 = 0b110,
  coff_127 = 0b111,
  
}iir_filter_coff;

typedef enum
{
  x1 = 0b000,
  x2 = 0b001,
  x4 = 0b010,
  x8 = 0b011,
  x16 = 0b100,
  x32 = 0b101,  
}osr_tp_vals;

typedef enum 
{
 temp_en = 0b1,
 pres_en = 0b1,

 temp_dis = 0b0,
 pres_dis = 0b0,

 sleep_mode = 0b00,
 forced_mode = 0b01,
 forced_mode2 = 0b10,
 normal_mode = 0b11,
 
}power_control;

struct coffvals
{
  uint16_t t1;
  uint16_t t2;
  int8_t   t3;
  
  int16_t p1;
  int16_t p2;
  int8_t   p3;
  
  int8_t   p4;
  uint16_t p5;
  uint16_t p6;
  
  int8_t   p7;
  int8_t   p8;
  int16_t  p9;
  int8_t   p10;
  int8_t   p11;  
};

struct pars
{ 
  double par_t1;
  double par_t2;
  double par_t3;

  double par_p1;
  double par_p2;
  double par_p3;
  double par_p4;
  double par_p5;
  double par_p6;
  double par_p7;
  double par_p8;
  double par_p9;
  double par_p10;
  double par_p11;
 
};


typedef enum
{
  odr_200 = 0x00,
  odr_100 = 0x01,
  odr_50 = 0x02,
  odr_25 = 0x03,
  odr_12p5 = 0x04,
  odr_6p25 = 0x05,
  odr_3p1 = 0x06,
  odr_1p5 = 0x07,
  odr_0p78 = 0x08,
  odr_0p39 = 0x09,
  odr_0p2 = 0x0A,
  odr_0p1 = 0x0B,
  odr_0p05 = 0x0C,
  odr_0p02 = 0x0D,
  odr_0p01 = 0x0E,
  odr_0p006 = 0x0F,
  odr_0p003 = 0x10,
  odr_0p0015 = 0x11,
  
}odr_sel;

class BMP390
{
  public:
  BMP390();
  ~BMP390();
  byte readbyte(byte reg);
  void readi2cbytes(uint8_t reg, int count, uint8_t temp[]);
  void writebyte(byte reg, uint8_t val);
  uint8_t readchipid();
  void begin();
  uint8_t readrevid();

  void setMode(String mode);
  double measurePress();
  double measureTemp();

  void readcoffs(struct coffvals vals, struct pars par);

  void enableforcemode();
  double calculateAltitude(double temprature, double pressure);
  
  
};
#endif

BMP390REG.h

Arduino
#ifndef _BMP390REG_H
#define _BMP390REG_H

#define BMP_ADDRESS                     0x77

#define CHIP_ID                         0x00
#define REV_ID                          0x01

#define ERR_REG                         0x02
#define STATUS                          0x03

#define DATA_0                          0x04
#define DATA_1                          0x05
#define DATA_2                          0x06

#define DATA_3                          0x07
#define DATA_4                          0x08
#define DATA_5                          0x09

#define   SENSORTIME_0                  0x0C
#define   SENSORTIME_1                  0x0D
#define   SENSORTIME_2                  0x0E

#define   EVENT                         0x10

#define   INT_STATUS                    0x11

#define   FIFO_LENGTH_0                 0x12
#define   FIFO_LENGTH_1                 0x13
#define   FIFO_DATA                     0x14

#define   FIFO_WTM0                     0x15
#define   FIFO_WTM1                     0x16

#define   FIFO_CONFIG_1                 0x17
#define   FIFO_CONFIG_2                 0x18

#define   INT_CTRL                      0x19
#define   IF_CONFIG                     0x1A

#define   PWR_CTRL                     0x1B

#define   OSR                           0x1C
#define   ODR                           0x1D
#define   CONFIG                        0x1F

#define   CMD                           0x7E

#define   NVM_PAR_T1                   0x31
#define   NVM_PAR_T1H                  0x32
#define   NVM_PAR_T2                   0x33
#define   NVM_PAR_T1H                  0x34
#define   NVM_PAR_T3                   0x35

#define   NVM_PAR_P1                   0x36
#define   NVM_PAR_P1H                  0x37
#define   NVM_PAR_P2                   0x38
#define   NVM_PAR_P1H                  0x39
#define   NVM_PAR_P3                   0x3A
#define   NVM_PAR_P4                   0x3B
#define   NVM_PAR_P5                   0x3C
#define   NVM_PAR_P5H                  0x3D
#define   NVM_PAR_P6                   0x3E
#define   NVM_PAR_P6H                  0x3F
#define   NVM_PAR_P7                   0x40
#define   NVM_PAR_P8                   0x41
#define   NVM_PAR_P9                   0x42
#define   NVM_PAR_P9H                  0x43
#define   NVM_PAR_P10                  0x44
#define   NVM_PAR_P11                  0x45

#endif

Credits

ujjval rathod

ujjval rathod

9 projects • 19 followers
Thanks to Seeed Studios.

Comments