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.
Diff: BME280.cpp
- Revision:
- 6:f94ffb546799
- Parent:
- 5:c1f1647004c4
- Child:
- 7:d94871acb463
--- a/BME280.cpp Sat Mar 11 04:21:14 2017 +0000
+++ b/BME280.cpp Sat Dec 29 05:49:55 2018 +0000
@@ -27,6 +27,15 @@
* THE SOFTWARE.
*/
+/*
+ * Modified by Kenji Arai / JH1PJL
+ *
+ * http://www.page.sannet.ne.jp/kenjia/index.html
+ * http://mbed.org/users/kenjiArai/
+ * Created: November 21st, 2018
+ * Revised: December 29th, 2018
+ */
+
#include "mbed.h"
#include "BME280.h"
@@ -59,13 +68,32 @@
void BME280::initialize()
{
char cmd[18];
-
+ uint8_t id;
+
+ wait_ms(2);
+ id = getID();
+ if (id != 0x60){
+ if (address == DEFAULT_SLAVE_ADDRESS){
+ address = DEFAULT_SLAVE_ADDRESS;
+ } else if (address == ANOTHER_SLAVE_ADDRESS){
+ address = DEFAULT_SLAVE_ADDRESS;
+ }
+ id = getID();
+ if (id != 0x60){
+ cmd[0] = 0xe0; // reset addr
+ cmd[1] = 0xb6; // reset command
+ i2c.write(address, cmd, 2);
+ wait_ms(2);
+ }
+ }
+
cmd[0] = 0xf2; // ctrl_hum
cmd[1] = 0x01; // Humidity oversampling x1
i2c.write(address, cmd, 2);
cmd[0] = 0xf4; // ctrl_meas
- cmd[1] = 0x27; // Temparature oversampling x1, Pressure oversampling x1, Normal mode
+ // Temparature oversampling x1, Pressure oversampling x1, Normal mode
+ cmd[1] = 0x27;
i2c.write(address, cmd, 2);
cmd[0] = 0xf5; // config
@@ -96,7 +124,10 @@
dig_P8 = (cmd[15] << 8) | cmd[14];
dig_P9 = (cmd[17] << 8) | cmd[16];
- DEBUG_PRINT("dig_P = 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", dig_P1, dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9);
+ DEBUG_PRINT(
+ "dig_P = 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
+ dig_P1, dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9
+ );
cmd[0] = 0xA1; // read dig_H regs
i2c.write(address, cmd, 1);
@@ -112,7 +143,9 @@
dig_H5 = (cmd[6] << 4) | ((cmd[5]>>4) & 0x0f);
dig_H6 = cmd[7];
- DEBUG_PRINT("dig_H = 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", dig_H1, dig_H2, dig_H3, dig_H4, dig_H5, dig_H6);
+ DEBUG_PRINT("dig_H = 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
+ dig_H1, dig_H2, dig_H3, dig_H4, dig_H5, dig_H6
+ );
}
float BME280::getTemperature()
@@ -120,7 +153,10 @@
uint32_t temp_raw;
float tempf;
char cmd[4];
-
+
+ if(check_chip() == false){
+ return 100.0f;
+ }
cmd[0] = 0xfa; // temp_msb
i2c.write(address, cmd, 1);
i2c.read(address, &cmd[1], 3);
@@ -131,7 +167,8 @@
temp =
(((((temp_raw >> 3) - (dig_T1 << 1))) * dig_T2) >> 11) +
- ((((((temp_raw >> 4) - dig_T1) * ((temp_raw >> 4) - dig_T1)) >> 12) * dig_T3) >> 14);
+ ((((((temp_raw >> 4) - dig_T1) * ((temp_raw >> 4) - dig_T1)) >> 12)
+ * dig_T3) >> 14);
t_fine = temp;
temp = (temp * 5 + 128) >> 8;
@@ -145,7 +182,11 @@
uint32_t press_raw;
float pressf;
char cmd[4];
-
+
+ if(check_chip() == false){
+ return 2000.0f;
+ }
+
cmd[0] = 0xf7; // press_msb
i2c.write(address, cmd, 1);
i2c.read(address, &cmd[1], 3);
@@ -159,7 +200,8 @@
var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * dig_P6;
var2 = var2 + ((var1 * dig_P5) << 1);
var2 = (var2 >> 2) + (dig_P4 << 16);
- var1 = (((dig_P3 * (((var1 >> 2)*(var1 >> 2)) >> 13)) >> 3) + ((dig_P2 * var1) >> 1)) >> 18;
+ var1 = (((dig_P3 * (((var1 >> 2)*(var1 >> 2)) >> 13)) >> 3)
+ + ((dig_P2 * var1) >> 1)) >> 18;
var1 = ((32768 + var1) * dig_P1) >> 15;
if (var1 == 0) {
return 0;
@@ -170,7 +212,8 @@
} else {
press = (press / var1) * 2;
}
- var1 = ((int32_t)dig_P9 * ((int32_t)(((press >> 3) * (press >> 3)) >> 13))) >> 12;
+ var1 = ((int32_t)dig_P9 * ((int32_t)(((press >> 3)
+ * (press >> 3)) >> 13))) >> 12;
var2 = (((int32_t)(press >> 2)) * (int32_t)dig_P8) >> 13;
press = (press + ((var1 + var2 + dig_P7) >> 4));
@@ -184,6 +227,10 @@
float humf;
char cmd[4];
+ if(check_chip() == false){
+ return 0.0f;
+ }
+
cmd[0] = 0xfd; // hum_msb
i2c.write(address, cmd, 1);
i2c.read(address, &cmd[1], 2);
@@ -193,11 +240,13 @@
int32_t v_x1;
v_x1 = t_fine - 76800;
- v_x1 = (((((hum_raw << 14) -(((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * v_x1)) +
- ((int32_t)16384)) >> 15) * (((((((v_x1 * (int32_t)dig_H6) >> 10) *
- (((v_x1 * ((int32_t)dig_H3)) >> 11) + 32768)) >> 10) + 2097152) *
- (int32_t)dig_H2 + 8192) >> 14));
- v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * (int32_t)dig_H1) >> 4));
+ v_x1 = (((((hum_raw << 14) -(((int32_t)dig_H4) << 20)
+ - (((int32_t)dig_H5) * v_x1)) + ((int32_t)16384)) >> 15)
+ * (((((((v_x1 * (int32_t)dig_H6) >> 10)
+ * (((v_x1 * ((int32_t)dig_H3)) >> 11) + 32768)) >> 10) + 2097152)
+ * (int32_t)dig_H2 + 8192) >> 14));
+ v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7)
+ * (int32_t)dig_H1) >> 4));
v_x1 = (v_x1 < 0 ? 0 : v_x1);
v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
@@ -205,3 +254,171 @@
return (humf/1024.0f);
}
+
+//------------------------------------------------------------------------------
+// Added functions by JH1PJL
+//------------------------------------------------------------------------------
+// Read chip ID
+uint8_t BME280::getID(void)
+{
+ char cmd[4];
+
+ cmd[0] = 0xd0; // ID addr
+ i2c.write(address, cmd, 1, true);
+ i2c.read(address, cmd, 2, false);
+ return cmd[0];
+}
+
+bool BME280::check_chip(void)
+{
+ uint8_t id;
+
+ id = getID();
+ if (id != 0x60){
+ if (address == DEFAULT_SLAVE_ADDRESS){
+ address = DEFAULT_SLAVE_ADDRESS;
+ } else if (address == ANOTHER_SLAVE_ADDRESS){
+ address = DEFAULT_SLAVE_ADDRESS;
+ }
+ id = getID();
+ if (id != 0x60){
+ return resetChip_by_sw();
+ }
+ }
+ return true;
+}
+
+// Reset the chip by software
+bool BME280::resetChip_by_sw(void)
+{
+ uint8_t id;
+ char cmd[4];
+
+ if (address == DEFAULT_SLAVE_ADDRESS){
+ ;
+ } else if (address == ANOTHER_SLAVE_ADDRESS){
+ ;
+ } else {
+ address = DEFAULT_SLAVE_ADDRESS;
+ }
+ // 1st try
+ cmd[0] = 0xe0; // reset addr
+ cmd[1] = 0xb6; // reset command
+ i2c.write(address, cmd, 2);
+ wait_ms(2);
+ id = getID();
+ if (id == 0x60){
+ initialize();
+ return true;
+ }
+ // 2nd retry (reset again and read again)
+ cmd[0] = 0xe0; // reset addr
+ cmd[1] = 0xb6; // reset command
+ i2c.write(address, cmd, 2);
+ wait_ms(2);
+ id = getID();
+ if (id == 0x60){
+ initialize();
+ return true;
+ }
+ // 3rd retry (reaset again and another chip addr)
+ if (address == DEFAULT_SLAVE_ADDRESS){
+ address = DEFAULT_SLAVE_ADDRESS;
+ } else if (address == ANOTHER_SLAVE_ADDRESS){
+ address = DEFAULT_SLAVE_ADDRESS;
+ } else {
+ return false;
+ }
+ cmd[0] = 0xe0; // reset addr
+ cmd[1] = 0xb6; // reset command
+ i2c.write(address, cmd, 2);
+ wait_ms(2);
+ id = getID();
+ if (id == 0x60){
+ initialize();
+ return true;
+ }
+ return false;
+}
+
+// Get compensated data
+void BME280::getAll_compensated_data(BME280_Data_TypeDef *dt) {
+ uint32_t raw_data;
+ char cmd[8];
+
+ // Temperatue
+ cmd[0] = 0xfa; // temp_msb
+ i2c.write(address, cmd, 1);
+ i2c.read(address, &cmd[1], 3);
+ raw_data = (cmd[1] << 12) | (cmd[2] << 4) | (cmd[3] >> 4);
+ double var1, var2;
+ var1 = ((( double)raw_data) / 16384.0 - ((double)dig_T1) / 1024.0) *
+ ((double)dig_T2);
+ var2 = ((((double)raw_data) / 131072.0 - ((double)dig_T1) / 8192.0) *
+ (((double)raw_data) / 131072.0 - ((double)dig_T1) / 8192.0))
+ * ((double)dig_T3);
+ int32_t t_fine = (int32_t)(var1 + var2);
+ dt->temperatue = (var1 + var2) / 5120.0;
+ // Pressue
+ cmd[0] = 0xf7; // press_msb
+ i2c.write(address, cmd, 1);
+ i2c.read(address, &cmd[1], 3);
+ raw_data = (cmd[1] << 12) | (cmd[2] << 4) | (cmd[3] >> 4);
+ double p;
+ var1 = ((double)t_fine / 2.0) - 64000.0;
+ var2 = var1 * var1 * ((double)dig_P6) / 32768.0;
+ var2 = var2 + var1 * ((double)dig_P5) * 2.0;
+ var2 = (var2 / 4.0)+(((double)dig_P4) * 65536.0);
+ var1 = (((double)dig_P3) * var1 * var1 / 524288.0 +
+ ((double)dig_P2) * var1) / 524288.0;
+ var1 = (1.0 + var1 / 32768.0)*((double)dig_P1);
+ if (var1 == 0.0) {
+ dt->pressue = 0.0;
+ return; //avoid exception caused by division by zero
+ }
+ p = 1048576.0 - (double)raw_data;
+ p = (p - (var2 / 4096.0)) * 6250.0 / var1;
+ var1 = ((double)dig_P9) * p * p / 2147483648.0;
+ var2 = p * ((double)dig_P8) / 32768.0;
+ p = p + (var1 + var2 + ((double)dig_P7)) / 16.0;
+ dt->pressue = p / 100.0;
+ // Humidity
+ cmd[0] = 0xfd; // hum_msb
+ i2c.write(address, cmd, 1);
+ i2c.read(address, &cmd[1], 2);
+ raw_data = (cmd[1] << 8) | cmd[2];
+ double var_H;
+ var_H = (((double)t_fine) - 76800.0);
+ var_H = (raw_data - (((double)dig_H4) * 64.0 +
+ ((double)dig_H5) / 16384.0 * var_H)) *
+ (((double)dig_H2) / 65536.0 * (1.0 +
+ ((double)dig_H6) / 67108864.0 * var_H *
+ (1.0 + ((double)dig_H3) / 67108864.0 * var_H)));
+ var_H = var_H * (1.0 - ((double)dig_H1) * var_H / 524288.0);
+ if (var_H > 100.0) {
+ var_H = 100.0;
+ } else if (var_H < 0.0) {
+ var_H = 0.0;
+ }
+ dt->humidity = var_H;
+}
+
+#if 0
+double calcAltitude(float pressure,float temperature)
+{
+ // Equation taken from BMP180 datasheet (page 16):
+ // http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf
+
+
+ // Note that using the equation from wikipedia can give bad results
+ // at high altitude. See this thread for more information:
+ // http://forums.adafruit.com/viewtopic.php?f=22&t=58064
+ /*
+ double altitude = (temperature + 273.15)
+ * (pow(MEAN_SEA_LEVEL_PRESSURE/pressure, 0.190294957)-1.0) / 0.0065;
+ */
+ double altitude =
+ 44330.0 * (1.0 - pow(pressure / MEAN_SEA_LEVEL_PRESSURE, 0.190294957));
+ return altitude;
+}
+#endif
\ No newline at end of file