I bought a BMP280 and it looks like this:
How can I connect BMP280 to Arduino Uno? I tried the following examples on the web, but they didn't work. I used this library, connecting the PINS in this way:
VCC -> 3.3V
GND -> GND
SCL -> 13
SDA -> 12
SDO -> 11
But the sensor did not initialize.
2 Answers 2
Eventually as reported here, it worked using this pinout:
VCC --> 3.3V
GND --> GND
SCK --> A5
SDI --> A4
And this code:
#include <Wire.h>
#define BME280_ADDRESS 0x76
unsigned long int hum_raw,temp_raw,pres_raw;
signed long int t_fine;
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
int8_t dig_H1;
int16_t dig_H2;
int8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;
void setup()
{
uint8_t osrs_t = 1; //Temperature oversampling x 1
uint8_t osrs_p = 1; //Pressure oversampling x 1
uint8_t osrs_h = 1; //Humidity oversampling x 1
uint8_t mode = 3; //Normal mode
uint8_t t_sb = 5; //Tstandby 1000ms
uint8_t filter = 0; //Filter off
uint8_t spi3w_en = 0; //3-wire SPI Disable
uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
uint8_t config_reg = (t_sb << 5) | (filter << 2) | spi3w_en;
uint8_t ctrl_hum_reg = osrs_h;
Serial.begin(9600);
Wire.begin();
writeReg(0xF2,ctrl_hum_reg);
writeReg(0xF4,ctrl_meas_reg);
writeReg(0xF5,config_reg);
readTrim(); //
}
void loop()
{
double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
signed long int temp_cal;
unsigned long int press_cal,hum_cal;
readData();
temp_cal = calibration_T(temp_raw);
press_cal = calibration_P(pres_raw);
hum_cal = calibration_H(hum_raw);
temp_act = (double)temp_cal / 100.0;
press_act = (double)press_cal / 100.0;
hum_act = (double)hum_cal / 1024.0;
Serial.print("TEMP : ");
Serial.print(temp_act);
Serial.print(" DegC PRESS : ");
Serial.print(press_act);
Serial.print(" hPa HUM : ");
Serial.print(hum_act);
Serial.println(" %");
delay(1000);
}
void readTrim()
{
uint8_t data[32],i=0; // Fix 2014年04月06日
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0x88);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,24); // Fix 2014年04月06日
while(Wire.available()){
data[i] = Wire.read();
i++;
}
Wire.beginTransmission(BME280_ADDRESS); // Add 2014年04月06日
Wire.write(0xA1); // Add 2014年04月06日
Wire.endTransmission(); // Add 2014年04月06日
Wire.requestFrom(BME280_ADDRESS,1); // Add 2014年04月06日
data[i] = Wire.read(); // Add 2014年04月06日
i++; // Add 2014年04月06日
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xE1);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,7); // Fix 2014年04月06日
while(Wire.available()){
data[i] = Wire.read();
i++;
}
dig_T1 = (data[1] << 8) | data[0];
dig_T2 = (data[3] << 8) | data[2];
dig_T3 = (data[5] << 8) | data[4];
dig_P1 = (data[7] << 8) | data[6];
dig_P2 = (data[9] << 8) | data[8];
dig_P3 = (data[11]<< 8) | data[10];
dig_P4 = (data[13]<< 8) | data[12];
dig_P5 = (data[15]<< 8) | data[14];
dig_P6 = (data[17]<< 8) | data[16];
dig_P7 = (data[19]<< 8) | data[18];
dig_P8 = (data[21]<< 8) | data[20];
dig_P9 = (data[23]<< 8) | data[22];
dig_H1 = data[24];
dig_H2 = (data[26]<< 8) | data[25];
dig_H3 = data[27];
dig_H4 = (data[28]<< 4) | (0x0F & data[29]);
dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F); // Fix 2014年04月06日
dig_H6 = data[31]; // Fix 2014年04月06日
}
void writeReg(uint8_t reg_address, uint8_t data)
{
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(reg_address);
Wire.write(data);
Wire.endTransmission();
}
void readData()
{
int i = 0;
uint32_t data[8];
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xF7);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,8);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
hum_raw = (data[6] << 8) | data[7];
}
signed long int calibration_T(signed long int adc_T)
{
signed long int var1, var2, T;
var1 = ((((adc_T >> 3) - ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T>>4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
unsigned long int calibration_P(signed long int adc_P)
{
signed long int var1, var2;
unsigned long int P;
var1 = (((signed long int)t_fine)>>1) - (signed long int)64000;
var2 = (((var1>>2) * (var1>>2)) >> 11) * ((signed long int)dig_P6);
var2 = var2 + ((var1*((signed long int)dig_P5))<<1);
var2 = (var2>>2)+(((signed long int)dig_P4)<<16);
var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long int)dig_P2) * var1)>>1))>>18;
var1 = ((((32768+var1))*((signed long int)dig_P1))>>15);
if (var1 == 0)
{
return 0;
}
P = (((unsigned long int)(((signed long int)1048576)-adc_P)-(var2>>12)))*3125;
if(P<0x80000000)
{
P = (P << 1) / ((unsigned long int) var1);
}
else
{
P = (P / (unsigned long int)var1) * 2;
}
var1 = (((signed long int)dig_P9) * ((signed long int)(((P>>3) * (P>>3))>>13)))>>12;
var2 = (((signed long int)(P>>2)) * ((signed long int)dig_P8))>>13;
P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4));
return P;
}
unsigned long int calibration_H(signed long int adc_H)
{
signed long int v_x1;
v_x1 = (t_fine - ((signed long int)76800));
v_x1 = (((((adc_H << 14) -(((signed long int)dig_H4) << 20) - (((signed long int)dig_H5) * v_x1)) +
((signed long int)16384)) >> 15) * (((((((v_x1 * ((signed long int)dig_H6)) >> 10) *
(((v_x1 * ((signed long int)dig_H3)) >> 11) + ((signed long int) 32768))) >> 10) + (( signed long int)2097152)) *
((signed long int) dig_H2) + 8192) >> 14));
v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((signed long int)dig_H1)) >> 4));
v_x1 = (v_x1 < 0 ? 0 : v_x1);
v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
return (unsigned long int)(v_x1 >> 12);
}
Actually, BMP280 doesn't monitor relative humidity so you can delete the part related to the humidity control.
#include <Wire.h>
#define BME280_ADDRESS 0x76
unsigned long int temp_raw,pres_raw;
signed long int t_fine;
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
void setup()
{
uint8_t osrs_t = 1; //Temperature oversampling x 1
uint8_t osrs_p = 1; //Pressure oversampling x 1
uint8_t mode = 3; //Normal mode
uint8_t t_sb = 5; //Tstandby 1000ms
uint8_t filter = 0; //Filter off
uint8_t spi3w_en = 0; //3-wire SPI Disable
uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
uint8_t config_reg = (t_sb << 5) | (filter << 2) | spi3w_en;
Serial.begin(9600);
Wire.begin();
writeReg(0xF4,ctrl_meas_reg);
writeReg(0xF5,config_reg);
readTrim(); //
}
void loop()
{
double temp_act = 0.0, press_act = 0.0;
signed long int temp_cal;
unsigned long int press_cal;
readData();
temp_cal = calibration_T(temp_raw);
press_cal = calibration_P(pres_raw);
temp_act = (double)temp_cal / 100.0;
press_act = (double)press_cal / 100.0;
Serial.print("TEMP : ");
Serial.print(temp_act);
Serial.print(" DegC PRESS : ");
Serial.println(press_act);
delay(1000);
}
void readTrim()
{
uint8_t data[32],i=0; // Fix 2014年04月06日
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0x88);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,24); // Fix 2014年04月06日
while(Wire.available()){
data[i] = Wire.read();
i++;
}
Wire.beginTransmission(BME280_ADDRESS); // Add 2014年04月06日
Wire.write(0xA1); // Add 2014年04月06日
Wire.endTransmission(); // Add 2014年04月06日
Wire.requestFrom(BME280_ADDRESS,1); // Add 2014年04月06日
data[i] = Wire.read(); // Add 2014年04月06日
i++; // Add 2014年04月06日
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xE1);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,7); // Fix 2014年04月06日
while(Wire.available()){
data[i] = Wire.read();
i++;
}
dig_T1 = (data[1] << 8) | data[0];
dig_T2 = (data[3] << 8) | data[2];
dig_T3 = (data[5] << 8) | data[4];
dig_P1 = (data[7] << 8) | data[6];
dig_P2 = (data[9] << 8) | data[8];
dig_P3 = (data[11]<< 8) | data[10];
dig_P4 = (data[13]<< 8) | data[12];
dig_P5 = (data[15]<< 8) | data[14];
dig_P6 = (data[17]<< 8) | data[16];
dig_P7 = (data[19]<< 8) | data[18];
dig_P8 = (data[21]<< 8) | data[20];
dig_P9 = (data[23]<< 8) | data[22];
}
void writeReg(uint8_t reg_address, uint8_t data)
{
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(reg_address);
Wire.write(data);
Wire.endTransmission();
}
void readData()
{
int i = 0;
uint32_t data[8];
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xF7);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,8);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
}
signed long int calibration_T(signed long int adc_T)
{
signed long int var1, var2, T;
var1 = ((((adc_T >> 3) - ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T>>4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
unsigned long int calibration_P(signed long int adc_P)
{
signed long int var1, var2;
unsigned long int P;
var1 = (((signed long int)t_fine)>>1) - (signed long int)64000;
var2 = (((var1>>2) * (var1>>2)) >> 11) * ((signed long int)dig_P6);
var2 = var2 + ((var1*((signed long int)dig_P5))<<1);
var2 = (var2>>2)+(((signed long int)dig_P4)<<16);
var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long int)dig_P2) * var1)>>1))>>18;
var1 = ((((32768+var1))*((signed long int)dig_P1))>>15);
if (var1 == 0)
{
return 0;
}
P = (((unsigned long int)(((signed long int)1048576)-adc_P)-(var2>>12)))*3125;
if(P<0x80000000)
{
P = (P << 1) / ((unsigned long int) var1);
}
else
{
P = (P / (unsigned long int)var1) * 2;
}
var1 = (((signed long int)dig_P9) * ((signed long int)(((P>>3) * (P>>3))>>13)))>>12;
var2 = (((signed long int)(P>>2)) * ((signed long int)dig_P8))>>13;
P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4));
return P;
}
The BMP280 is a sensor that can be used at 3.3V, but not at 5V. The datasheet tells that the interface pins may be maximum 3.6V (when the sensor is powered with 3.3V). That means you may not connect the sensor to an Arduino Uno. Not to the SPI interface and not to the I2C interface. The sensor might already be damaged. This is not a joke. When sensor is still working, the results might be noisy or the values could drift too much.
The easiest solution is a level shifter module for I2C. Another option is to add two extra pullup resistors of 10k from SDA to 3.3V and from SCL to 3.3V and connect the SDA and SCL directly to the Arduino Uno. It will not be reliable, but with some luck it will work. You need some luck, because it will not be okay according to the datasheet of the ATmega328P.
You could also buy a 3.3V Arduino board (Arduino Due, Arduino Zero, Arduino M0, and so on), or buy a BMP280 module that is compatible with 3.3V and 5V signals: Adafruit BMP280
-
Thanks for the answer, but I am wiring it at 3.3 V so where is the problem?G M– G M2017年03月02日 16:24:40 +00:00Commented Mar 2, 2017 at 16:24
-
1I was talking about the signals of the SPI bus and I2C bus. Even the I2C bus is not fully compatible with a 3.3V sensor. The internal pullup resistors are enabled and the Arduino Uno requires 3.5V for a reliable high level at SDA and SCL according to the datasheet of the ATmega328P. The internal 50k pullup resistors together with the 10k pullup resistors on the module make a voltage at SDA and SCL of 3.58V. That is enough for a high level of the ATmega328P and it won't damage the sensor. But that is pure luck. It changes if you add something to the I2C bus.Jot– Jot2017年03月03日 07:17:11 +00:00Commented Mar 3, 2017 at 7:17