Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 4

/////////////////////////////////////////////////////////

cpp/////////////////////////////////////////
#include "mbed.h"
#include "BME280.h"

BME280::BME280(PinName sda, PinName scl, char slave_adr)


:
i2c_p(new I2C(sda, scl)),
i2c(*i2c_p),
address(slave_adr),
t_fine(0)
{
initialize();
}

BME280::~BME280()
{
if (NULL != i2c_p)
delete i2c_p;
}

void BME280::initialize()
{
char cmd[18];

cmd[0] = 0xf2; // ctrl_hum Consultar Table 18: Memory map


cmd[1] = 0x01; // Humidity oversampling x1 Table 20: register settings osrs_h
i2c.write(address, cmd, 2);

cmd[0] = 0xf4; // ctrl_meas Table 18: Memory map


cmd[1] = 0x27; // Base 2= 1(oversampling �1_pressure)001(oversampling
�1_temperature)11 (Normal mode)
i2c.write(address, cmd, 2);

cmd[0] = 0xf5; // config


cmd[1] = 0xa0; // Bsae 2= 101(1000 t_standby)000(Filter off)00(SPI Off)
i2c.write(address, cmd, 2);

cmd[0] = 0x88; // read dig_T regs Table 16: Compensation parameter storage,
naming and data type
i2c.write(address, cmd, 1);
i2c.read(address, cmd, 6);

dig_T1 = (cmd[1] << 8) | cmd[0]; // Corrimiento de 8 bits por la tabla 16


dig_T2 = (cmd[3] << 8) | cmd[2];
dig_T3 = (cmd[5] << 8) | cmd[4];

cmd[0] = 0x8E; // read dig_P regs Table 16: Compensation parameter storage,
naming and data type
i2c.write(address, cmd, 1);
i2c.read(address, cmd, 18);

dig_P1 = (cmd[ 1] << 8) | cmd[ 0];// Corrimieto de 8 bits por la tabla


dig_P2 = (cmd[ 3] << 8) | cmd[ 2];
dig_P3 = (cmd[ 5] << 8) | cmd[ 4];
dig_P4 = (cmd[ 7] << 8) | cmd[ 6];
dig_P5 = (cmd[ 9] << 8) | cmd[ 8];
dig_P6 = (cmd[11] << 8) | cmd[10];
dig_P7 = (cmd[13] << 8) | cmd[12];
dig_P8 = (cmd[15] << 8) | cmd[14];
dig_P9 = (cmd[17] << 8) | cmd[16];

cmd[0] = 0xA1; // read dig_H regs Table 16: Compensation parameter storage,
naming and data type
i2c.write(address, cmd, 1);
i2c.read(address, cmd, 1);

cmd[1] = 0xE1; // read dig_H regs Table 16: Compensation parameter storage,
naming and data type
i2c.write(address, &cmd[1], 1);
i2c.read(address, &cmd[1], 7);

dig_H1 = cmd[0];
dig_H2 = (cmd[2] << 8) | cmd[1];
dig_H3 = cmd[3];
dig_H4 = (cmd[4] << 4) | (cmd[5] & 0x0f);
dig_H5 = (cmd[6] << 4) | ((cmd[5]>>4) & 0x0f);
dig_H6 = cmd[7];

float BME280::ReadTemperature()
{
uint32_t adc_T;
float T;
char cmd[4];

cmd[0] = 0xfa; // temp_msb Table 18: Memory map


i2c.write(address, cmd, 1);
i2c.read(address, &cmd[1], 3);
//Table 30: Register 0xFA � 0xFC �temp�
T = (cmd[1] << 12) | (cmd[2] << 4) | (cmd[3] >> 4);// corrimiento en 12, 4 y 4
bits segunla abla 30
int32_t temp;

// consulte parte 4.2.3 Compensation formulas: Apartado de formulas


temp = (((((adc_T >> 3) - (dig_T1 << 1))) * dig_T2) >> 11) + ((((((adc_T >> 4)
- dig_T1) * ((adc_T >> 4) - dig_T1)) >> 12) * dig_T3) >> 14);
t_fine = temp; // t_fine carries fine temperature as global value
temp = (temp * 5 + 128) >> 8;
T= (float)temp;
return T/100; // Returns temperature in DegC, resolution is 0.01 DegC. Output
value of �5123� equals 51.23 DegC.

float BME280::ReadPressure()
{
uint32_t p;
float pressf;
char cmd[4];

cmd[0] = 0xf7; // press_msb


i2c.write(address, cmd, 1);
i2c.read(address, &cmd[1], 3);

p = (cmd[1] << 12) | (cmd[2] << 4) | (cmd[3] >> 4);

int32_t var1, var2;


uint32_t press;

var1 = (t_fine >> 1) - 64000;


var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * dig_P6;
var2 = var2 + ((var1 * dig_P5) << 1);
var2 = (var2 >> 2) + (dig_P4 << 16);
var1 = (((dig_P3 * (((var1 >> 2)*(var1 >> 2)) >> 13)) >> 3) + ((dig_P2 * var1)
>> 1)) >> 18;
var1 = ((32768 + var1) * dig_P1) >> 15;
if (var1 == 0) {
return 0; // avoid exception caused by division by zero

}
press = (((1048576 - p) - (var2 >> 12))) * 3125;
if(press < 0x80000000) {
press = (press << 1) / var1;
} else {
press = (press / var1) * 2;
}
var1 = ((int32_t)dig_P9 * ((int32_t)(((press >> 3) * (press >> 3)) >> 13))) >>
12;
var2 = (((int32_t)(press >> 2)) * (int32_t)dig_P8) >> 13;
press = (press + ((var1 + var2 + dig_P7) >> 4));

pressf = (float)press;
return (pressf/256); //// Output value of �24674867� represents 24674867/256 =
96386.2 Pa = 963.862 hPa
}

float BME280::ReadHumidity()
{
uint32_t hum_raw;
float humf;
char cmd[4];

cmd[0] = 0xfd; // hum_msb


i2c.write(address, cmd, 1);
i2c.read(address, &cmd[1], 2);

hum_raw = (cmd[1] << 8) | cmd[2];

int32_t v_x1;

v_x1 = t_fine - 76800;


v_x1 = (((((hum_raw << 14) -(((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) *
v_x1)) + ((int32_t)16384)) >> 15) * (((((((v_x1 * (int32_t)dig_H6) >> 10) *
(((v_x1 * ((int32_t)dig_H3)) >> 11) +
32768)) >> 10) + 2097152) *
(int32_t)dig_H2 + 8192) >> 14));
v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * (int32_t)dig_H1) >>
4));
v_x1 = (v_x1 < 0 ? 0 : v_x1);
v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);

humf = (float)(v_x1 >> 12);

return (humf/1024);
// Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format (22
integer and 10 fractional bits).
// Output value of �47445� represents 47445/1024 = 46.333 %RH
}
////////////////////////////////////////////////////h//////////////////////////////
//////////////////////////////////

#ifndef MBED_BME280_H
#define MBED_BME280_H

#include "mbed.h"

#define DEFAULT_SLAVE_ADDRESS (0x76 << 1)

class BME280
{
public:
BME280(PinName sda, PinName sck, char slave_adr = DEFAULT_SLAVE_ADDRESS);
virtual ~BME280();
void initialize(void);
float ReadTemperature(void);
float ReadPressure(void);
float ReadHumidity(void);

private:
I2C &i2c;
I2C *i2c_p;
char address;
uint16_t dig_T1;
int16_t dig_T2, dig_T3;
uint16_t dig_P1;
int16_t dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9;
uint16_t dig_H1, dig_H3;
int16_t dig_H2, dig_H4, dig_H5, dig_H6;
int32_t t_fine;

};

#endif // MBED_BME280_H

You might also like