BME280 - Software Debugging Reference
1. Communication Quick-Start
Device Type: Digital humidity, pressure, and temperature sensor.
Interfaces:
I2C: Up to 3.4 MHz. Slave addresses: 0x76 (SDO pin to GND) or 0x77 (SDO pin to VDDIO).
SPI: 3-wire and 4-wire support, up to 10 MHz. Supports SPI modes '00' (CPOL=0, CPHA=0) and '11' (CPOL=1, CPHA=1).
SPI Address Format: The 7-bit register address is shifted. Bit 7 is the Read/Write bit (0 for Write, 1 for Read). Example: To write to 0xF4, use SPI address 0x74. To read 0xF4, use 0xF4.
I2C Transaction:
Write: [Slave Addr + W] -> [Reg Addr] -> [Data].
Read: [Slave Addr + W] -> [Reg Addr] -> [Repeated Start] -> [Slave Addr + R] -> [Data].
Power-on Timing:
$t_{startup}$ : Max 2 ms after VDD > 1.58V and VDDIO > 0.65V.
After power-up, the device enters Sleep Mode .
Data Consistency: Always use burst reads (starting from 0xF7) to ensure data consistency via internal shadowing.
Address
Name
Size
Reset Value
R/W
Brief Description
0x88 - 0x89
dig_T1
16-bit
Individual
R
Temperature calibration parameter (Unsigned)
0x8A - 0x8B
dig_T2
16-bit
Individual
R
Temperature calibration parameter (Signed)
0x8C - 0x8D
dig_T3
16-bit
Individual
R
Temperature calibration parameter (Signed)
0x8E - 0x8F
dig_P1
16-bit
Individual
R
Pressure calibration parameter (Unsigned)
0x90 - 0x91
dig_P2
16-bit
Individual
R
Pressure calibration parameter (Signed)
0x92 - 0x93
dig_P3
16-bit
Individual
R
Pressure calibration parameter (Signed)
0x94 - 0x95
dig_P4
16-bit
Individual
R
Pressure calibration parameter (Signed)
0x96 - 0x97
dig_P5
16-bit
Individual
R
Pressure calibration parameter (Signed)
0x98 - 0x99
dig_P6
16-bit
Individual
R
Pressure calibration parameter (Signed)
0x9A - 0x9B
dig_P7
16-bit
Individual
R
Pressure calibration parameter (Signed)
0x9C - 0x9D
dig_P8
16-bit
Individual
R
Pressure calibration parameter (Signed)
0x9E - 0x9F
dig_P9
16-bit
Individual
R
Pressure calibration parameter (Signed)
0xA1
dig_H1
8-bit
Individual
R
Humidity calibration parameter (Unsigned)
0xD0
id
8-bit
0x60
R
Chip ID (Fixed at 0x60)
0xE0
reset
8-bit
0x00
W
Soft reset register (Write 0xB6 to trigger)
0xE1 - 0xE2
dig_H2
16-bit
Individual
R
Humidity calibration parameter (Signed)
0xE3
dig_H3
8-bit
Individual
R
Humidity calibration parameter (Unsigned)
0xE4 - 0xE5[3:0]
dig_H4
12-bit
Individual
R
Humidity calibration parameter (Signed)
0xE5[7:4] - 0xE6
dig_H5
12-bit
Individual
R
Humidity calibration parameter (Signed)
0xE7
dig_H6
8-bit
Individual
R
Humidity calibration parameter (Signed)
0xF2
ctrl_hum
8-bit
0x00
R/W
Humidity oversampling settings
0xF3
status
8-bit
0x00
R
Device status (measuring and update flags)
0xF4
ctrl_meas
8-bit
0x00
R/W
Pressure/Temp oversampling and sensor mode
0xF5
config
8-bit
0x00
R/W
Rate, filter, and SPI interface options
0xF7
press_msb
8-bit
0x80
R
Raw pressure MSB [19:12]
0xF8
press_lsb
8-bit
0x00
R
Raw pressure LSB [11:4]
0xF9
press_xlsb
8-bit
0x00
R
Raw pressure XLSB [3:0] (Bits 7:4)
0xFA
temp_msb
8-bit
0x80
R
Raw temperature MSB [19:12]
0xFB
temp_lsb
8-bit
0x00
R
Raw temperature LSB [11:4]
0xFC
temp_xlsb
8-bit
0x00
R
Raw temperature XLSB [3:0] (Bits 7:4)
0xFD
hum_msb
8-bit
0x80
R
Raw humidity MSB [15:8]
0xFE
hum_lsb
8-bit
0x00
R
Raw humidity LSB [7:0]
Bits
Field Name
Reset
R/W
Description
7:3
Reserved
0
R
Reserved
2:0
osrs_h[2:0]
000
R/W
Humidity oversampling: 000: Skipped; 001: x1; 010: x2; 011: x4; 100: x8; 101 or others: x16
Bits
Field Name
Reset
R/W
Description
7:4
Reserved
0
R
Reserved
3
measuring
0
R
1 when conversion is running, 0 when results transferred to data registers
2:1
Reserved
0
R
Reserved
0
im_update
0
R
1 when NVM data is being copied to image registers
Bits
Field Name
Reset
R/W
Description
7:5
osrs_t[2:0]
000
R/W
Temperature oversampling: 000: Skipped; 001: x1; 010: x2; 011: x4; 100: x8; 101 or others: x16
4:2
osrs_p[2:0]
000
R/W
Pressure oversampling: 000: Skipped; 001: x1; 010: x2; 011: x4; 100: x8; 101 or others: x16
1:0
mode[1:0]
00
R/W
Sensor mode: 00: Sleep; 01 or 10: Forced; 11: Normal
Bits
Field Name
Reset
R/W
Description
7:5
t_sb[2:0]
000
R/W
Standby time (Normal mode): 000: 0.5ms; 001: 62.5ms; 010: 125ms; 011: 250ms; 100: 500ms; 101: 1000ms; 110: 10ms; 111: 20ms
4:2
filter[2:0]
000
R/W
IIR filter coefficient: 000: Off; 001: 2; 010: 4; 011: 8; 100 or others: 16
1
Reserved
0
R
Reserved
0
spi3w_en
0
R/W
1: Enables 3-wire SPI interface
Data Registers (0xF7 - 0xFE)
Pressure (0xF7-0xF9): 20-bit unsigned. press_msb << 12 | press_lsb << 4 | press_xlsb >> 4.
Temperature (0xFA-0xFC): 20-bit unsigned. temp_msb << 12 | temp_lsb << 4 | temp_xlsb >> 4.
Humidity (0xFD-0xFE): 16-bit unsigned. hum_msb << 8 | hum_lsb.
4. Operating Procedures & Data Conversion
Soft Reset: Write 0xB6 to 0xE0. Wait 2ms.
Read Calibration: Read registers 0x88-0xA1 and 0xE1-0xE7 to store trimming parameters.
Configure Humidity: Write ctrl_hum (0xF2). Note: This write only takes effect after a subsequent write to ctrl_meas.
Configure Mode/Oversampling: Write ctrl_meas (0xF4).
Configure Filter/Standby: Write config (0xF5).
Measurement (Forced Mode)
Write mode = 01 to ctrl_meas (0xF4).
Poll status (0xF3) bit 3 (measuring) until it returns to 0.
Burst read 0xF7 through 0xFE.
Data Conversion (32-bit Integer)
The variable t_fine is calculated during temperature compensation and required for pressure and humidity.
Temperature (°C):
// Returns temperature in DegC, resolution is 0.01 DegC. Output "5123" = 51.23°C.
BME280_S32_t var1 , var2 , T ;
var1 = ((((adc_T >> 3 ) - ((BME280_S32_t )dig_T1 << 1 ))) * ((BME280_S32_t )dig_T2 )) >> 11 ;
var2 = (((((adc_T >> 4 ) - ((BME280_S32_t )dig_T1 )) * ((adc_T >> 4 ) - ((BME280_S32_t )dig_T1 ))) >> 12 ) * ((BME280_S32_t )dig_T3 )) >> 14 ;
t_fine = var1 + var2 ;
T = (t_fine * 5 + 128 ) >> 8 ;
Pressure (Pa):
(Uses 64-bit integer for high accuracy)
// Returns pressure in Pa as Q24.8 format (24 integer bits and 8 fractional bits).
// Output "24674867" = 24674867/256 = 96386.2 Pa
BME280_S64_t var1 , var2 , p ;
var1 = ((BME280_S64_t )t_fine ) - 128000 ;
var2 = var1 * var1 * (BME280_S64_t )dig_P6 ;
var2 = var2 + ((var1 * (BME280_S64_t )dig_P5 ) << 17 );
var2 = var2 + (((BME280_S64_t )dig_P4 ) << 35 );
var1 = ((var1 * var1 * (BME280_S64_t )dig_P3 ) >> 8 ) + ((var1 * (BME280_S64_t )dig_P2 ) << 12 );
var1 = (((((BME280_S64_t )1 ) << 47 ) + var1 )) * ((BME280_S64_t )dig_P1 ) >> 33 ;
if (var1 == 0 ) return 0 ; // Avoid div by zero
p = 1048576 - adc_P ;
p = (((p << 31 ) - var2 ) * 3125 ) / var1 ;
var1 = (((BME280_S64_t )dig_P9 ) * (p >> 13 ) * (p >> 13 )) >> 25 ;
var2 = (((BME280_S64_t )dig_P8 ) * p ) >> 19 ;
p = ((p + var1 + var2 ) >> 8 ) + ((BME280_S64_t )dig_P7 << 4 );
return (BME280_U32_t )p ;
Humidity (%RH):
// Returns humidity in %RH as Q22.10 format. Output "47445" = 46.333 %RH
BME280_S32_t v_x1_u32r ;
v_x1_u32r = (t_fine - ((BME280_S32_t )76800 ));
v_x1_u32r = (((((adc_H << 14 ) - (((BME280_S32_t )dig_H4 ) << 20 ) - (((BME280_S32_t )dig_H5 ) * v_x1_u32r )) + ((BME280_S32_t )16384 )) >> 15 ) * (((((v_x1_u32r * ((BME280_S32_t )dig_H6 )) >> 10 ) * ((v_x1_u32r * ((BME280_S32_t )dig_H3 )) >> 11 ) + ((BME280_S32_t )32768 ))) >> 10 ) + ((BME280_S32_t )2097152 )) * ((BME280_S32_t )dig_H2 ) + 8192 ) >> 14 );
v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15 ) * (v_x1_u32r >> 15 )) >> 7 ) * ((BME280_S32_t )dig_H1 )) >> 4 ));
v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r );
v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r );
return (BME280_U32_t )(v_x1_u32r >> 12 );
Register Update Order: Changes to ctrl_hum (0xF2) only apply after a write to ctrl_meas (0xF4).
SPI Mode Lock: If CSB is not high during power-on, the device may lock into SPI mode and ignore I2C.
Shadowing Trap: If you read registers individually (not burst), the MSB and LSB might come from different measurement cycles. Always burst read 0xF7 to 0xFE.
IIR Filter Reset: Writing to the filter bits in config (0xF5) resets the IIR filter memory.
Status Flags:
measuring == 1: Conversion is in progress.
im_update == 1: NVM copy in progress. Do not write to configuration registers during this time.
Invalid Data: Raw values of 0x80000 (Pressure/Temp) or 0x8000 (Humidity) indicate the measurement was skipped or is not yet ready.
Bus Recovery: If the I2C bus hangs, toggle the VDD line or perform a soft reset by writing 0xB6 to 0xE0 (if the bus is still responsive).