|
| 1 | +# BME280 MicroPython Driver |
| 2 | + |
| 3 | +MicroPython driver for the **Bosch BME280** combined pressure, humidity, and temperature sensor. |
| 4 | + |
| 5 | +This driver provides a simple API to read **pressure**, **humidity**, and **temperature** over **I2C**. |
| 6 | + |
| 7 | +The BME280 is a high-precision environmental sensor suitable for applications such as: |
| 8 | + |
| 9 | +* weather monitoring |
| 10 | +* indoor air quality |
| 11 | +* altimetry support |
| 12 | +* environmental sensing |
| 13 | + |
| 14 | +--- |
| 15 | + |
| 16 | +## Features |
| 17 | + |
| 18 | +* I2C communication |
| 19 | +* device identification |
| 20 | +* pressure measurement (hPa) |
| 21 | +* temperature measurement (C) |
| 22 | +* relative humidity measurement (%RH) |
| 23 | +* one-shot acquisition (forced mode) |
| 24 | +* continuous measurement mode (normal mode) |
| 25 | +* configurable oversampling (temperature, pressure, humidity) |
| 26 | +* configurable IIR filter |
| 27 | +* configurable standby time |
| 28 | +* data-ready status helpers |
| 29 | +* sleep mode (power off) |
| 30 | +* soft reset and full reset with recalibration |
| 31 | + |
| 32 | +--- |
| 33 | + |
| 34 | +## Sensor Overview |
| 35 | + |
| 36 | +| Feature | Value | |
| 37 | +| ---------------------- | ----------------------- | |
| 38 | +| Pressure range | 300 hPa - 1100 hPa | |
| 39 | +| Pressure resolution | 0.18 Pa (20-bit ADC) | |
| 40 | +| Temperature range | -40 C to +85 C | |
| 41 | +| Temperature resolution | 0.01 C | |
| 42 | +| Humidity range | 0 - 100 %RH | |
| 43 | +| Humidity resolution | 0.008 %RH (16-bit ADC) | |
| 44 | +| Interface | I2C / SPI | |
| 45 | +| Chip ID | 0x60 | |
| 46 | + |
| 47 | +--- |
| 48 | + |
| 49 | +## I2C Address |
| 50 | + |
| 51 | +The sensor can use two I2C addresses depending on the **SDO pin**: |
| 52 | + |
| 53 | +| SDO | Address | |
| 54 | +| ------ | ------- | |
| 55 | +| GND | `0x76` | |
| 56 | +| VDDIO | `0x77` | |
| 57 | + |
| 58 | +The default address used by the driver is **0x76**. |
| 59 | + |
| 60 | +--- |
| 61 | + |
| 62 | +## Basic Usage |
| 63 | + |
| 64 | +```python |
| 65 | +from machine import I2C |
| 66 | +from time import sleep |
| 67 | +from bme280 import BME280 |
| 68 | + |
| 69 | +i2c = I2C(1) |
| 70 | + |
| 71 | +sensor = BME280(i2c) |
| 72 | + |
| 73 | +while True: |
| 74 | + temperature, pressure, humidity = sensor.read_one_shot() |
| 75 | + |
| 76 | + print("T:", temperature, "C") |
| 77 | + print("P:", pressure, "hPa") |
| 78 | + print("H:", humidity, "%RH") |
| 79 | + print() |
| 80 | + |
| 81 | + sleep(1) |
| 82 | +``` |
| 83 | + |
| 84 | +--- |
| 85 | + |
| 86 | +## API Reference |
| 87 | + |
| 88 | +## Initialization |
| 89 | + |
| 90 | +```python |
| 91 | +sensor = BME280(i2c) |
| 92 | +``` |
| 93 | + |
| 94 | +Optional custom address: |
| 95 | + |
| 96 | +```python |
| 97 | +sensor = BME280(i2c, address=0x77) |
| 98 | +``` |
| 99 | + |
| 100 | +The constructor verifies the chip ID, waits for NVM calibration data to be ready, reads factory trimming parameters, and applies a default configuration (1x oversampling, sleep mode). |
| 101 | + |
| 102 | +--- |
| 103 | + |
| 104 | +## Measurements |
| 105 | + |
| 106 | +### Read all channels |
| 107 | + |
| 108 | +```python |
| 109 | +temperature, pressure, humidity = sensor.read() |
| 110 | +``` |
| 111 | + |
| 112 | +Returns a tuple of `(temperature_c, pressure_hpa, humidity_rh)`. |
| 113 | + |
| 114 | +--- |
| 115 | + |
| 116 | +### Temperature |
| 117 | + |
| 118 | +```python |
| 119 | +sensor.temperature() |
| 120 | +``` |
| 121 | + |
| 122 | +Returns the temperature in **degrees Celsius**. |
| 123 | + |
| 124 | +--- |
| 125 | + |
| 126 | +### Pressure |
| 127 | + |
| 128 | +```python |
| 129 | +sensor.pressure_hpa() |
| 130 | +``` |
| 131 | + |
| 132 | +Returns the pressure in **hPa**. |
| 133 | + |
| 134 | +--- |
| 135 | + |
| 136 | +### Humidity |
| 137 | + |
| 138 | +```python |
| 139 | +sensor.humidity() |
| 140 | +``` |
| 141 | + |
| 142 | +Returns the relative humidity in **%RH**. |
| 143 | + |
| 144 | +--- |
| 145 | + |
| 146 | +### One-shot measurement |
| 147 | + |
| 148 | +```python |
| 149 | +temperature, pressure, humidity = sensor.read_one_shot() |
| 150 | +``` |
| 151 | + |
| 152 | +Triggers a forced measurement, waits for completion, and returns all three channels. |
| 153 | + |
| 154 | +--- |
| 155 | + |
| 156 | +### Trigger forced measurement |
| 157 | + |
| 158 | +```python |
| 159 | +sensor.trigger_one_shot() |
| 160 | +``` |
| 161 | + |
| 162 | +Triggers a single forced measurement. Poll `data_ready()` for completion, then read values with `temperature()`, `pressure_hpa()`, `humidity()`, or `read()`. |
| 163 | + |
| 164 | +--- |
| 165 | + |
| 166 | +## Data-Ready Status |
| 167 | + |
| 168 | +```python |
| 169 | +sensor.data_ready() # True when all channels are ready |
| 170 | +sensor.temperature_ready() # True when temperature is ready |
| 171 | +sensor.pressure_ready() # True when pressure is ready |
| 172 | +sensor.humidity_ready() # True when humidity is ready |
| 173 | +``` |
| 174 | + |
| 175 | +--- |
| 176 | + |
| 177 | +## Configuration |
| 178 | + |
| 179 | +### Oversampling |
| 180 | + |
| 181 | +```python |
| 182 | +from bme280.const import OSRS_X2, OSRS_X4, OSRS_X16 |
| 183 | + |
| 184 | +sensor.set_oversampling(temperature=OSRS_X2, pressure=OSRS_X16, humidity=OSRS_X4) |
| 185 | +``` |
| 186 | + |
| 187 | +Available constants: `OSRS_SKIP`, `OSRS_X1`, `OSRS_X2`, `OSRS_X4`, `OSRS_X8`, `OSRS_X16`. |
| 188 | + |
| 189 | +Pass `None` to keep the current setting for a channel. |
| 190 | + |
| 191 | +--- |
| 192 | + |
| 193 | +### IIR Filter |
| 194 | + |
| 195 | +```python |
| 196 | +from bme280.const import FILTER_4 |
| 197 | + |
| 198 | +sensor.set_iir_filter(FILTER_4) |
| 199 | +``` |
| 200 | + |
| 201 | +Available constants: `FILTER_OFF`, `FILTER_2`, `FILTER_4`, `FILTER_8`, `FILTER_16`. |
| 202 | + |
| 203 | +--- |
| 204 | + |
| 205 | +### Standby Time |
| 206 | + |
| 207 | +```python |
| 208 | +from bme280.const import STANDBY_500_MS |
| 209 | + |
| 210 | +sensor.set_standby(STANDBY_500_MS) |
| 211 | +``` |
| 212 | + |
| 213 | +Available constants: `STANDBY_0_5_MS`, `STANDBY_62_5_MS`, `STANDBY_125_MS`, `STANDBY_250_MS`, `STANDBY_500_MS`, `STANDBY_1000_MS`. |
| 214 | + |
| 215 | +--- |
| 216 | + |
| 217 | +## Modes |
| 218 | + |
| 219 | +### Sleep mode |
| 220 | + |
| 221 | +```python |
| 222 | +sensor.power_off() # enter sleep mode, stop measurements |
| 223 | +sensor.power_on() # enter normal mode, continuous measurements |
| 224 | +``` |
| 225 | + |
| 226 | +--- |
| 227 | + |
| 228 | +### Continuous mode |
| 229 | + |
| 230 | +```python |
| 231 | +from bme280.const import STANDBY_125_MS |
| 232 | + |
| 233 | +sensor.set_continuous(standby=STANDBY_125_MS) |
| 234 | +``` |
| 235 | + |
| 236 | +Enters normal mode with the specified standby time between measurements. If `standby` is `None`, the current standby setting is kept. |
| 237 | + |
| 238 | +--- |
| 239 | + |
| 240 | +## Device Management |
| 241 | + |
| 242 | +### Device ID |
| 243 | + |
| 244 | +```python |
| 245 | +sensor.device_id() # returns 0x60 |
| 246 | +``` |
| 247 | + |
| 248 | +--- |
| 249 | + |
| 250 | +### Soft Reset |
| 251 | + |
| 252 | +```python |
| 253 | +sensor.soft_reset() |
| 254 | +``` |
| 255 | + |
| 256 | +Sends the reset command and waits for NVM reload. |
| 257 | + |
| 258 | +--- |
| 259 | + |
| 260 | +### Full Reset |
| 261 | + |
| 262 | +```python |
| 263 | +sensor.reset() |
| 264 | +``` |
| 265 | + |
| 266 | +Performs a soft reset, re-reads calibration data, and re-applies default configuration. |
| 267 | + |
| 268 | +--- |
| 269 | + |
| 270 | +## Examples |
| 271 | + |
| 272 | +| Example | Description | |
| 273 | +| -------------------- | -------------------------------------------------- | |
| 274 | +| `basic_reader.py` | Read temperature, pressure, and humidity | |
| 275 | +| `weather_station.py` | Continuous logging with altitude computation | |
| 276 | + |
| 277 | +--- |
| 278 | + |
| 279 | +## Comparison with other MicroPython BME280 drivers |
| 280 | + |
| 281 | +| Feature | **STeaMi** | **robert-hh** | **Adafruit** | **neliogodoi** | **Pimoroni** | **RandomNerd** | |
| 282 | +|---|---|---|---|---|---|---| |
| 283 | +| I2C | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
| 284 | +| SPI | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | |
| 285 | +| Sleep mode | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | |
| 286 | +| Forced mode | ✅ | ✅ | ✅ | ⚠️ Implicit | ❌ | ❌ | |
| 287 | +| Normal mode | ✅ | ✅ | ✅ | ❌ | ⚠️ Fixed | ❌ | |
| 288 | +| Oversampling (per channel) | ✅ | ✅ | ✅ | ✅ | ⚠️ Fixed x16 | ⚠️ Constants only | |
| 289 | +| IIR filter | ✅ | ❌ | ✅ | ✅ | ⚠️ Fixed x16 | ❌ | |
| 290 | +| Standby time | ✅ | ❌ | ✅ | ❌ | ⚠️ Fixed 500ms | ❌ | |
| 291 | +| Altitude | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | |
| 292 | +| Sea-level pressure | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | |
| 293 | +| Dew point | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | |
| 294 | +| Soft reset | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | |
| 295 | +| Full reset + recalibration | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | |
| 296 | +| power_off / power_on | ✅ | ❌ | ⚠️ Via mode | ❌ | ❌ | ❌ | |
| 297 | +| data_ready | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | |
| 298 | +| read_one_shot | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | |
| 299 | +| set_continuous | ✅ | ❌ | ⚠️ Via mode | ❌ | ❌ | ❌ | |
| 300 | +| Integer compensation | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | |
| 301 | +| Measurement time estimate | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | |
| 302 | +| Multi-unit temperature | ❌ | ❌ | ❌ | ✅ C/F/K | ❌ | ❌ | |
| 303 | +| BMP280 compatibility | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | |
| 304 | +| Dedicated exceptions | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | |
| 305 | +| Mock test suite | ✅ (39) | ❌ | ❌ | ❌ | ❌ | ❌ | |
| 306 | +| Hardware test suite | ✅ (6) | ❌ | ❌ | ❌ | ❌ | ❌ | |
| 307 | + |
| 308 | +Reference implementations: |
| 309 | + |
| 310 | +* [robert-hh/BME280](https://github.com/robert-hh/BME280) — integer compensation, altitude, dew point |
| 311 | +* [Adafruit CircuitPython BME280](https://github.com/adafruit/Adafruit_CircuitPython_BME280) — I2C + SPI, basic/advanced split |
| 312 | +* [neliogodoi/MicroPython-BME280](https://github.com/neliogodoi/MicroPython-BME280) — configurable oversampling and IIR |
| 313 | +* [Pimoroni envirobit](https://github.com/pimoroni/micropython-envirobit) — Micro:bit driver, BMP280 alias |
| 314 | +* [RandomNerdTutorials](https://randomnerdtutorials.com/micropython-bme280-esp32-esp8266/) — ESP32/ESP8266 tutorial |
| 315 | + |
| 316 | +--- |
| 317 | + |
| 318 | +## References |
| 319 | + |
| 320 | +* [BME280 Datasheet](https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf) |
0 commit comments