Il Bosch BME280 è un sensore ambientale digitale che misura la temperatura ambiente, l'umidità relativa e la pressione barometrica. Fornisce letture calibrate e compensate e comunica in genere con i microcontrollori tramite I2C o SPI, per una facile integrazione nei progetti Arduino/ESP32.
| Pin | Segnale | Descrizione |
|---|---|---|
VCC |
power | Power input for the BME280 breakout; connect to the module's supported supply voltage. |
GND |
ground | Ground reference for power and I2C/SPI signals. |
SCL |
SCL | I2C clock line, or SPI serial clock when using SPI mode. |
SDA |
SDA | I2C data line, or SPI MOSI data input when using SPI mode. |
CSB |
chip-select | SPI chip-select input; keep high to use I2C mode. |
SDO |
MISO | SPI MISO data output, or I2C address-select pin. |
| Da | A | Filo |
|---|---|---|
board:5V |
x1:VCC |
red |
board:GND |
x1:GND |
black |
board:A5 |
x1:SCL |
green |
board:A4 |
x1:SDA |
blue |
board:5V |
x1:CSB |
red |
board:5V |
x1:SDO |
red |
Questo esempio è stato scritto e verificato in compilazione per arduino-uno. Codey Online lo adatta a qualsiasi altra scheda supportata.
#include <Wire.h>
const int BME280_ADDR = 0x76;
// BME280 registers
const uint8_t REG_CALIB_START = 0x88;
const uint8_t REG_ID = 0xD0;
const uint8_t REG_RESET = 0xE0;
const uint8_t REG_CTRL_HUM = 0xF2;
const uint8_t REG_STATUS = 0xF3;
const uint8_t REG_CTRL_MEAS = 0xF4;
const uint8_t REG_CONFIG = 0xF5;
const uint8_t REG_PRESS_MSB = 0xF7;
struct CalibrationData {
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;
uint8_t dig_H1;
int16_t dig_H2;
uint8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;
};
CalibrationData calib;
int32_t t_fine = 0;
void write8(uint8_t reg, uint8_t value) {
Wire.beginTransmission(BME280_ADDR);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
uint8_t read8(uint8_t reg) {
Wire.beginTransmission(BME280_ADDR);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(BME280_ADDR, (uint8_t)1);
return Wire.available() ? Wire.read() : 0;
}
void readBytes(uint8_t reg, uint8_t *buf, uint8_t len) {
Wire.beginTransmission(BME280_ADDR);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(BME280_ADDR, len);
for (uint8_t i = 0; i < len && Wire.available(); i++) {
buf[i] = Wire.read();
}
}
bool initBME280() {
uint8_t id = read8(REG_ID);
if (id != 0x60) return false;
write8(REG_RESET, 0xB6);
delay(10);
uint8_t calib1[26];
readBytes(REG_CALIB_START, calib1, 26);
calib.dig_T1 = (uint16_t)(calib1[1] << 8 | calib1[0]);
calib.dig_T2 = (int16_t)(calib1[3] << 8 | calib1[2]);
calib.dig_T3 = (int16_t)(calib1[5] << 8 | calib1[4]);
calib.dig_P1 = (uint16_t)(calib1[7] << 8 | calib1[6]);
calib.dig_P2 = (int16_t)(calib1[9] << 8 | calib1[8]);
calib.dig_P3 = (int16_t)(calib1[11] << 8 | calib1[10]);
calib.dig_P4 = (int16_t)(calib1[13] << 8 | calib1[12]);
calib.dig_P5 = (int16_t)(calib1[15] << 8 | calib1[14]);
calib.dig_P6 = (int16_t)(calib1[17] << 8 | calib1[16]);
calib.dig_P7 = (int16_t)(calib1[19] << 8 | calib1[18]);
calib.dig_P8 = (int16_t)(calib1[21] << 8 | calib1[20]);
calib.dig_P9 = (int16_t)(calib1[23] << 8 | calib1[22]);
calib.dig_H1 = calib1[25];
uint8_t calib2[7];
readBytes(0xE1, calib2, 7);
calib.dig_H2 = (int16_t)(calib2[1] << 8 | calib2[0]);
calib.dig_H3 = calib2[2];
calib.dig_H4 = (int16_t)((calib2[3] << 4) | (calib2[4] & 0x0F));
calib.dig_H5 = (int16_t)((calib2[5] << 4) | (calib2[4] >> 4));
calib.dig_H6 = (int8_t)calib2[6];
// Humidity oversampling x1, temperature oversampling x1, pressure oversampling x1, normal mode
write8(REG_CTRL_HUM, 0x01);
write8(REG_CTRL_MEAS, 0x27);
// Standby 1000 ms, filter off
write8(REG_CONFIG, 0xA0);
return true;
}
int32_t readTemperatureRaw() {
uint8_t data[8];
readBytes(REG_PRESS_MSB, data, 8);
int32_t adc_T = ((int32_t)data[3] << 12) | ((int32_t)data[4] << 4) | (data[5] >> 4);
return adc_T;
}
int32_t readPressureRaw() {
uint8_t data[8];
readBytes(REG_PRESS_MSB, data, 8);
int32_t adc_P = ((int32_t)data[0] << 12) | ((int32_t)data[1] << 4) | (data[2] >> 4);
return adc_P;
}
int32_t readHumidityRaw() {
uint8_t data[8];
readBytes(REG_PRESS_MSB, data, 8);
int32_t adc_H = ((int32_t)data[6] << 8) | data[7];
return adc_H;
}
float compensateTemperature(int32_t adc_T) {
int32_t var1 = ((((adc_T >> 3) - ((int32_t)calib.dig_T1 << 1))) * ((int32_t)calib.dig_T2)) >> 11;
int32_t var2 = (((((adc_T >> 4) - ((int32_t)calib.dig_T1)) * ((adc_T >> 4) - ((int32_t)calib.dig_T1))) >> 12) * ((int32_t)calib.dig_T3)) >> 14;
t_fine = var1 + var2;
float T = (t_fine * 5 + 128) >> 8;
return T / 100.0f;
}
float compensatePressure(int32_t adc_P) {
int64_t var1 = ((int64_t)t_fine) - 128000;
int64_t var2 = var1 * var1 * (int64_t)calib.dig_P6;
var2 = var2 + ((var1 * (int64_t)calib.dig_P5) << 17);
var2 = var2 + (((int64_t)calib.dig_P4) << 35);
var1 = ((var1 * var1 * (int64_t)calib.dig_P3) >> 8) + ((var1 * (int64_t)calib.dig_P2) << 12);
var1 = (((((int64_t)1) << 47) + var1) * (int64_t)calib.dig_P1) >> 33;
if (var1 == 0) return 0;
int64_t p = 1048576 - adc_P;
p = (((p << 31) - var2) * 3125) / var1;
var1 = ((int64_t)calib.dig_P9 * (p >> 13) * (p >> 13)) >> 25;
var2 = ((int64_t)calib.dig_P8 * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((int64_t)calib.dig_P7) << 4);
return p / 256.0f;
}
float compensateHumidity(int32_t adc_H) {
int32_t v_x1_u32r = t_fine - 76800;
v_x1_u32r = (((((adc_H << 14) - (((int32_t)calib.dig_H4) << 20) - (((int32_t)calib.dig_H5) * v_x1_u32r)) + 16384) >> 15) * (((((((v_x1_u32r * ((int32_t)calib.dig_H6)) >> 10) * (((v_x1_u32r * ((int32_t)calib.dig_H3)) >> 11) + 32768)) >> 10) + 2097152) * ((int32_t)calib.dig_H2) + 8192) >> 14));
v_x1_u32r = v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)calib.dig_H1)) >> 4);
if (v_x1_u32r < 0) v_x1_u32r = 0;
if (v_x1_u32r > 419430400) v_x1_u32r = 419430400;
return (v_x1_u32r >> 12) / 1024.0f;
}
void setup() {
Serial.begin(115200);
while (!Serial) {}
Wire.begin();
Serial.println("BME280 canonical example");
if (!initBME280()) {
Serial.println("BME280 not found. Check wiring and that CSB is tied high for I2C mode.");
while (1) {
delay(1000);
}
}
Serial.println("BME280 initialized.");
}
void loop() {
int32_t rawT = readTemperatureRaw();
int32_t rawP = readPressureRaw();
int32_t rawH = readHumidityRaw();
float temperature = compensateTemperature(rawT);
float pressurePa = compensatePressure(rawP);
float humidity = compensateHumidity(rawH);
Serial.print("Temperature: ");
Serial.print(temperature, 2);
Serial.print(" °C, Humidity: ");
Serial.print(humidity, 2);
Serial.print(" %, Pressure: ");
Serial.print(pressurePa / 100.0f, 2);
Serial.println(" hPa");
delay(2000);
}
Descrivi cosa vuoi realizzare. Codey Online scrive il codice, disegna lo schema di collegamento, lo compila e programma la tua scheda direttamente dal browser.
Inizia gratis