Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
BME280.cpp@3:87add4547c4e, 2020-12-18 (annotated)
- Committer:
- pierreprovent
- Date:
- Fri Dec 18 17:25:46 2020 +0000
- Revision:
- 3:87add4547c4e
- Parent:
- 2:6ff57cf56fe1
sans modif
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| pierreprovent | 1:5d994dea50ef | 1 | #include "mbed.h" |
| pierreprovent | 1:5d994dea50ef | 2 | #include "BME280.h" |
| pierreprovent | 1:5d994dea50ef | 3 | |
| pierreprovent | 1:5d994dea50ef | 4 | BME280::BME280(PinName sda, PinName scl):i2c(sda, scl) |
| pierreprovent | 1:5d994dea50ef | 5 | { |
| pierreprovent | 1:5d994dea50ef | 6 | init(); |
| pierreprovent | 1:5d994dea50ef | 7 | read_calibration_data() ; |
| pierreprovent | 1:5d994dea50ef | 8 | } |
| pierreprovent | 1:5d994dea50ef | 9 | |
| pierreprovent | 1:5d994dea50ef | 10 | void BME280::init() |
| pierreprovent | 1:5d994dea50ef | 11 | { |
| pierreprovent | 1:5d994dea50ef | 12 | // Configuration de la mesure de température, pression et humidité |
| pierreprovent | 1:5d994dea50ef | 13 | // Mode ""normal" pour des mesures régulières et précises de P, T, H. |
| pierreprovent | 1:5d994dea50ef | 14 | // T et P filtrées par IIR et suréchantillonnage |
| pierreprovent | 1:5d994dea50ef | 15 | // Choix d'un mode "indoor navigation" p 17-18 doc constructeur |
| pierreprovent | 1:5d994dea50ef | 16 | // Registres : ctrl_hum osrs_h[2:0] = 001 oversampling humidity x1 |
| pierreprovent | 1:5d994dea50ef | 17 | // ctrl_hum = 00000 001 |
| pierreprovent | 1:5d994dea50ef | 18 | // ctrl_meas osrs_t[2:0] = 010 oversampling temperature x2 |
| pierreprovent | 1:5d994dea50ef | 19 | // ctrl_meas osrs_p[2:0] = 101 oversampling pressure x16 |
| pierreprovent | 1:5d994dea50ef | 20 | // ctrl_meas mode[1:0] = 11 Normal mode |
| pierreprovent | 1:5d994dea50ef | 21 | // ctrl_meas = 010 101 11 |
| pierreprovent | 1:5d994dea50ef | 22 | // config t_sb[2:0] = 000 t_standby 0.5 ms |
| pierreprovent | 1:5d994dea50ef | 23 | // config filter[2:0] = 100 filtre IIR à 16 coefficients |
| pierreprovent | 1:5d994dea50ef | 24 | // config = 000 100 00 |
| pierreprovent | 1:5d994dea50ef | 25 | data_write[0] = BME280_CTRL_HUM_ADDR ; |
| pierreprovent | 3:87add4547c4e | 26 | data_write[1] = ??????????? ; |
| pierreprovent | 1:5d994dea50ef | 27 | i2c.write(BME280_ADDRESS, data_write, 2); |
| pierreprovent | 1:5d994dea50ef | 28 | data_write[0] = BME280_CTRL_MEAS_ADDR ; |
| pierreprovent | 3:87add4547c4e | 29 | data_write[1] = ?????????? ; |
| pierreprovent | 1:5d994dea50ef | 30 | i2c.write(BME280_ADDRESS, data_write, 2); |
| pierreprovent | 1:5d994dea50ef | 31 | data_write[0] = BME280_CONFIG_ADDR ; |
| pierreprovent | 3:87add4547c4e | 32 | data_write[1] = ??????????? ; |
| pierreprovent | 1:5d994dea50ef | 33 | i2c.write(BME280_ADDRESS, data_write, 2); |
| pierreprovent | 1:5d994dea50ef | 34 | } |
| pierreprovent | 1:5d994dea50ef | 35 | |
| pierreprovent | 1:5d994dea50ef | 36 | void BME280::read_calibration_data() |
| pierreprovent | 1:5d994dea50ef | 37 | { |
| pierreprovent | 1:5d994dea50ef | 38 | //Lecture des données de calibration de température et de pression du capteur |
| pierreprovent | 1:5d994dea50ef | 39 | // 3 mots de 16 bits pour la température |
| pierreprovent | 1:5d994dea50ef | 40 | // 9 mots de 16 bits pour la pression |
| pierreprovent | 1:5d994dea50ef | 41 | // p 22-23 |
| pierreprovent | 1:5d994dea50ef | 42 | // Démarre la lecture à partir de l'adresse BME280_REG_DIG_T1 0x88 |
| pierreprovent | 1:5d994dea50ef | 43 | // Jusqu'à l'adresse BME280_REG_DIG_P9 0x9E |
| pierreprovent | 1:5d994dea50ef | 44 | // Lecture des 24 octets en une seule fois |
| pierreprovent | 1:5d994dea50ef | 45 | // 8 bits LSB en premier dans data_read[0], 8 bits MSB en second dans data_read[1] ; |
| pierreprovent | 1:5d994dea50ef | 46 | // Et lecture de 2 octets supplémentaires, adresse 0xA0 et 0xA1 |
| pierreprovent | 1:5d994dea50ef | 47 | // 0xA1 contient une donnée de calibration pour l'humidité |
| pierreprovent | 1:5d994dea50ef | 48 | // Les 7 autres octets de calibration d'humidité seront lus après de l'adresse 0xE1 à 0xE7 |
| pierreprovent | 1:5d994dea50ef | 49 | |
| pierreprovent | 1:5d994dea50ef | 50 | data_write[0] = BME280_REG_DIG_T1 ; |
| pierreprovent | 1:5d994dea50ef | 51 | i2c.write(BME280_ADDRESS, data_write, 1); |
| pierreprovent | 1:5d994dea50ef | 52 | i2c.read(BME280_ADDRESS, data_read, 26); |
| pierreprovent | 1:5d994dea50ef | 53 | |
| pierreprovent | 1:5d994dea50ef | 54 | dig_T1 = (uint16_t) ( (uint16_t) (data_read[1] << 8) | (uint16_t) data_read[0] ) ; |
| pierreprovent | 1:5d994dea50ef | 55 | dig_T2 = (int16_t) ( (int16_t) (data_read[3] << 8) | (int16_t) data_read[2] ) ; |
| pierreprovent | 1:5d994dea50ef | 56 | dig_T3 = (int16_t) ( (int16_t) (data_read[5] << 8) | (int16_t) data_read[4] ) ; |
| pierreprovent | 1:5d994dea50ef | 57 | dig_P1 = (uint16_t) ( (uint16_t) (data_read[7] << 8) | (uint16_t) data_read[6] ) ; |
| pierreprovent | 1:5d994dea50ef | 58 | dig_P2 = (int16_t) ( (int16_t) (data_read[9] << 8) | (int16_t) data_read[8] ) ; |
| pierreprovent | 1:5d994dea50ef | 59 | dig_P3 = (int16_t) ( (int16_t) (data_read[11] << 8) | (int16_t) data_read[10] ) ; |
| pierreprovent | 1:5d994dea50ef | 60 | dig_P4 = (int16_t) ( (int16_t) (data_read[13] << 8) | (int16_t) data_read[12] ) ; |
| pierreprovent | 1:5d994dea50ef | 61 | dig_P5 = (int16_t) ( (int16_t) (data_read[15] << 8) | (int16_t) data_read[14] ) ; |
| pierreprovent | 1:5d994dea50ef | 62 | dig_P6 = (int16_t) ( (int16_t) (data_read[17] << 8) | (int16_t) data_read[16] ) ; |
| pierreprovent | 1:5d994dea50ef | 63 | dig_P7 = (int16_t) ( (int16_t) (data_read[19] << 8) | (int16_t) data_read[18] ) ; |
| pierreprovent | 1:5d994dea50ef | 64 | dig_P8 = (int16_t) ( (int16_t) (data_read[21] << 8) | (int16_t) data_read[20] ) ; |
| pierreprovent | 1:5d994dea50ef | 65 | dig_P9 = (int16_t) ( (int16_t) (data_read[23] << 8) | (int16_t) data_read[22] ) ; |
| pierreprovent | 1:5d994dea50ef | 66 | dig_H1 = (uint8_t) data_read[25] ; |
| pierreprovent | 1:5d994dea50ef | 67 | |
| pierreprovent | 1:5d994dea50ef | 68 | //Lecture des données de calibration d'humidité |
| pierreprovent | 1:5d994dea50ef | 69 | // 7 octets de l'adresse 0xE1 à 0xE7 |
| pierreprovent | 1:5d994dea50ef | 70 | data_write[0] = BME280_REG_DIG_H2 ; |
| pierreprovent | 1:5d994dea50ef | 71 | i2c.write(BME280_ADDRESS, data_write, 1); |
| pierreprovent | 1:5d994dea50ef | 72 | i2c.read(BME280_ADDRESS, data_read, 7); |
| pierreprovent | 1:5d994dea50ef | 73 | |
| pierreprovent | 1:5d994dea50ef | 74 | dig_H2 = (int16_t) ( (int16_t) (data_read[1] << 8) | (int16_t) data_read[0] ) ; |
| pierreprovent | 1:5d994dea50ef | 75 | dig_H3 = (uint8_t) data_read[2] ; |
| pierreprovent | 1:5d994dea50ef | 76 | dig_H4 = (int16_t) ( (int16_t) (data_read[4] & 0x0F) | (int16_t) data_read[3] *16 ) ; |
| pierreprovent | 1:5d994dea50ef | 77 | dig_H5 = (int16_t) ( ((int16_t) data_read[5] * 16 | (int16_t) data_read[4]) >> 4 ) ; |
| pierreprovent | 1:5d994dea50ef | 78 | dig_H6 = (int8_t) data_read[6] ; |
| pierreprovent | 1:5d994dea50ef | 79 | } |
| pierreprovent | 1:5d994dea50ef | 80 | |
| pierreprovent | 1:5d994dea50ef | 81 | double BME280::temperature() |
| pierreprovent | 1:5d994dea50ef | 82 | { |
| pierreprovent | 1:5d994dea50ef | 83 | double temperature ; // Température en double précision |
| pierreprovent | 1:5d994dea50ef | 84 | int32_t temp_32bits; |
| pierreprovent | 1:5d994dea50ef | 85 | |
| pierreprovent | 1:5d994dea50ef | 86 | data_write[0] = BME280_REG_TEMPDATA ; |
| pierreprovent | 1:5d994dea50ef | 87 | i2c.write(BME280_ADDRESS, data_write, 1); |
| pierreprovent | 1:5d994dea50ef | 88 | i2c.read(BME280_ADDRESS, data_read, 3); |
| pierreprovent | 1:5d994dea50ef | 89 | temp_32bits = (int32_t) ( ((int32_t) data_read[0] << 12 | (int32_t) data_read[1] << 4 | (int16_t) data_read[2] >> 4) ) ; |
| pierreprovent | 1:5d994dea50ef | 90 | var1 = (((double) temp_32bits) / 16384.0 - ((double) dig_T1) / 1024.0) * ((double)dig_T2) ; |
| pierreprovent | 1:5d994dea50ef | 91 | var2 = ((((double) temp_32bits) / 131072.0 - ((double) dig_T1) / 8192.0) * |
| pierreprovent | 1:5d994dea50ef | 92 | (((double) temp_32bits) / 131072.0 - ((double) dig_T1) / 8192.0)) * |
| pierreprovent | 1:5d994dea50ef | 93 | ((double) dig_T3); |
| pierreprovent | 1:5d994dea50ef | 94 | temperature = ((var1 + var2) / 5120.0); |
| pierreprovent | 1:5d994dea50ef | 95 | t_fine = (int32_t) (var1 + var2); |
| pierreprovent | 1:5d994dea50ef | 96 | return temperature ; |
| pierreprovent | 1:5d994dea50ef | 97 | } |
| pierreprovent | 1:5d994dea50ef | 98 | |
| pierreprovent | 1:5d994dea50ef | 99 | double BME280::pression() |
| pierreprovent | 1:5d994dea50ef | 100 | { |
| pierreprovent | 1:5d994dea50ef | 101 | double pression ; // Pression en double precision |
| pierreprovent | 1:5d994dea50ef | 102 | int32_t press_32bits; |
| pierreprovent | 1:5d994dea50ef | 103 | |
| pierreprovent | 1:5d994dea50ef | 104 | data_write[0] = BME280_REG_PRESSUREDATA ; |
| pierreprovent | 1:5d994dea50ef | 105 | i2c.write(BME280_ADDRESS, data_write, 1); |
| pierreprovent | 1:5d994dea50ef | 106 | i2c.read(BME280_ADDRESS, data_read, 3); |
| pierreprovent | 1:5d994dea50ef | 107 | press_32bits = (int32_t) ( ((int32_t) data_read[0] << 12 | (int32_t) data_read[1] << 4 | (int16_t) data_read[2] >> 4) ) ; |
| pierreprovent | 1:5d994dea50ef | 108 | var1 = ((double) t_fine / 2.0) - 64000.0; |
| pierreprovent | 1:5d994dea50ef | 109 | var2 = var1 * var1 * ((double) dig_P6) / 32768.0; |
| pierreprovent | 1:5d994dea50ef | 110 | var2 = var2 + var1 * ((double) dig_P5) * 2.0; |
| pierreprovent | 1:5d994dea50ef | 111 | var2 = (var2 / 4.0) + (((double) dig_P4) * 65536.0); |
| pierreprovent | 1:5d994dea50ef | 112 | var1 = (((double) dig_P3) * var1 * var1 / 524288.0 + ((double) dig_P2) * var1) / |
| pierreprovent | 1:5d994dea50ef | 113 | 524288.0; |
| pierreprovent | 1:5d994dea50ef | 114 | var1 = (1.0 + var1 / 32768.0) * ((double) dig_P1); |
| pierreprovent | 1:5d994dea50ef | 115 | if (var1 == 0.0) |
| pierreprovent | 1:5d994dea50ef | 116 | return 0; // avoid exception caused by division by zero |
| pierreprovent | 1:5d994dea50ef | 117 | pression = 1048576.0 - (double)press_32bits ; |
| pierreprovent | 1:5d994dea50ef | 118 | pression = (pression-(var2/4096.0))* 6250.0/var1; |
| pierreprovent | 1:5d994dea50ef | 119 | var1 = ((double) dig_P9) * pression * pression / 2147483648.0; |
| pierreprovent | 1:5d994dea50ef | 120 | var2 = pression * ((double) dig_P8) / 32768.0; |
| pierreprovent | 1:5d994dea50ef | 121 | pression = pression + (var1 + var2 + ((double) dig_P7)) / 16.0; |
| pierreprovent | 1:5d994dea50ef | 122 | return pression ; |
| pierreprovent | 1:5d994dea50ef | 123 | } |
| pierreprovent | 1:5d994dea50ef | 124 | |
| pierreprovent | 1:5d994dea50ef | 125 | double BME280::humidite() |
| pierreprovent | 1:5d994dea50ef | 126 | { |
| pierreprovent | 1:5d994dea50ef | 127 | double humidite ; // Humidite en double precision |
| pierreprovent | 1:5d994dea50ef | 128 | int32_t hum_32bits; |
| pierreprovent | 1:5d994dea50ef | 129 | data_write[0] = BME280_REG_HUMDATA ; |
| pierreprovent | 1:5d994dea50ef | 130 | i2c.write(BME280_ADDRESS, data_write, 1); |
| pierreprovent | 1:5d994dea50ef | 131 | i2c.read(BME280_ADDRESS, data_read, 2); |
| pierreprovent | 1:5d994dea50ef | 132 | hum_32bits = (int32_t) ( ((int32_t) data_read[0] << 8 | (int32_t) data_read[1] ) ) ; |
| pierreprovent | 1:5d994dea50ef | 133 | humidite = (double)t_fine - 76800.0; |
| pierreprovent | 1:5d994dea50ef | 134 | humidite = (hum_32bits - (((double)dig_H4) * 64.0 + ((double)dig_H5) / 16384.0 * humidite)) * |
| pierreprovent | 1:5d994dea50ef | 135 | (((double)dig_H2) / 65536.0 * (1.0 + ((double)dig_H6) / 67108864.0 * humidite * |
| pierreprovent | 1:5d994dea50ef | 136 | (1.0 + ((double)dig_H3) / 67108864.0 * humidite))); |
| pierreprovent | 1:5d994dea50ef | 137 | humidite = humidite * (1.0 - ((double)dig_H1) * humidite / 524288.0); |
| pierreprovent | 1:5d994dea50ef | 138 | if (humidite > 100.0) |
| pierreprovent | 1:5d994dea50ef | 139 | humidite = 100.0; |
| pierreprovent | 1:5d994dea50ef | 140 | else if (humidite < 0.0) |
| pierreprovent | 1:5d994dea50ef | 141 | humidite = 0.0; |
| pierreprovent | 1:5d994dea50ef | 142 | return humidite; |
| pierreprovent | 1:5d994dea50ef | 143 | } |