Seeed_BME280.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. #include "Seeed_BME280.h"
  2. bool BME280::init(int i2c_addr) {
  3. uint8_t retry = 0;
  4. uint8_t chip_id = 0;
  5. _devAddr = i2c_addr;
  6. Wire.begin();
  7. while ((retry++ < 5) && (chip_id != 0x60)) {
  8. chip_id = BME280Read8(BME280_REG_CHIPID);
  9. #ifdef BMP280_DEBUG_PRINT
  10. Serial.print("Read chip ID: ");
  11. Serial.println(chip_id);
  12. #endif
  13. delay(100);
  14. }
  15. if (chip_id != 0x60){
  16. Serial.println("Read Chip ID fail!");
  17. return false;
  18. }
  19. dig_T1 = BME280Read16LE(BME280_REG_DIG_T1);
  20. dig_T2 = BME280ReadS16LE(BME280_REG_DIG_T2);
  21. dig_T3 = BME280ReadS16LE(BME280_REG_DIG_T3);
  22. dig_P1 = BME280Read16LE(BME280_REG_DIG_P1);
  23. dig_P2 = BME280ReadS16LE(BME280_REG_DIG_P2);
  24. dig_P3 = BME280ReadS16LE(BME280_REG_DIG_P3);
  25. dig_P4 = BME280ReadS16LE(BME280_REG_DIG_P4);
  26. dig_P5 = BME280ReadS16LE(BME280_REG_DIG_P5);
  27. dig_P6 = BME280ReadS16LE(BME280_REG_DIG_P6);
  28. dig_P7 = BME280ReadS16LE(BME280_REG_DIG_P7);
  29. dig_P8 = BME280ReadS16LE(BME280_REG_DIG_P8);
  30. dig_P9 = BME280ReadS16LE(BME280_REG_DIG_P9);
  31. dig_H1 = BME280Read8(BME280_REG_DIG_H1);
  32. dig_H2 = BME280Read16LE(BME280_REG_DIG_H2);
  33. dig_H3 = BME280Read8(BME280_REG_DIG_H3);
  34. dig_H4 = (BME280Read8(BME280_REG_DIG_H4) << 4) | (0x0F & BME280Read8(BME280_REG_DIG_H4 + 1));
  35. dig_H5 = (BME280Read8(BME280_REG_DIG_H5 + 1) << 4) | (0x0F & BME280Read8(BME280_REG_DIG_H5) >> 4);
  36. dig_H6 = (int8_t)BME280Read8(BME280_REG_DIG_H6);
  37. writeRegister(BME280_REG_CONTROLHUMID, 0x05); //Choose 16X oversampling
  38. writeRegister(BME280_REG_CONTROL, 0xB7); //Choose 16X oversampling
  39. return true;
  40. }
  41. float BME280::getTemperature(void) {
  42. int32_t var1, var2;
  43. int32_t adc_T = BME280Read24(BME280_REG_TEMPDATA);
  44. // Check if the last transport successed
  45. if (!isTransport_OK) {
  46. return 0;
  47. }
  48. adc_T >>= 4;
  49. var1 = (((adc_T >> 3) - ((int32_t)(dig_T1 << 1))) *
  50. ((int32_t)dig_T2)) >> 11;
  51. var2 = (((((adc_T >> 4) - ((int32_t)dig_T1)) *
  52. ((adc_T >> 4) - ((int32_t)dig_T1))) >> 12) *
  53. ((int32_t)dig_T3)) >> 14;
  54. t_fine = var1 + var2;
  55. float T = (t_fine * 5 + 128) >> 8;
  56. return T / 100;
  57. }
  58. float BME280::getPressure(void) {
  59. int64_t var1, var2, p;
  60. // Call getTemperature to get t_fine
  61. getTemperature();
  62. // Check if the last transport successed
  63. if (!isTransport_OK) {
  64. return 0;
  65. }
  66. int32_t adc_P = BME280Read24(BME280_REG_PRESSUREDATA);
  67. adc_P >>= 4;
  68. var1 = ((int64_t)t_fine) - 128000;
  69. var2 = var1 * var1 * (int64_t)dig_P6;
  70. var2 = var2 + ((var1 * (int64_t)dig_P5) << 17);
  71. var2 = var2 + (((int64_t)dig_P4) << 35);
  72. var1 = ((var1 * var1 * (int64_t)dig_P3) >> 8) + ((var1 * (int64_t)dig_P2) << 12);
  73. var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)dig_P1) >> 33;
  74. if (var1 == 0) {
  75. return 0; // avoid exception caused by division by zero
  76. }
  77. p = 1048576 - adc_P;
  78. p = (((p << 31) - var2) * 3125) / var1;
  79. var1 = (((int64_t)dig_P9) * (p >> 13) * (p >> 13)) >> 25;
  80. var2 = (((int64_t)dig_P8) * p) >> 19;
  81. p = ((p + var1 + var2) >> 8) + (((int64_t)dig_P7) << 4);
  82. return (float)(p / 256.0);
  83. }
  84. float BME280::getHumidity(void) {
  85. int32_t v_x1_u32r, adc_H;
  86. // Call getTemperature to get t_fine
  87. getTemperature();
  88. // Check if the last transport successed
  89. if (!isTransport_OK) {
  90. return 0;
  91. }
  92. adc_H = BME280Read16(BME280_REG_HUMIDITYDATA);
  93. v_x1_u32r = (t_fine - ((int32_t)76800));
  94. v_x1_u32r = (
  95. ((((adc_H << 14) - (((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * v_x1_u32r)) +
  96. ((int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)dig_H6)) >> 10) *
  97. (((v_x1_u32r * ((int32_t)dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) *
  98. ((int32_t)dig_H2) + 8192) >> 14));
  99. v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)dig_H1)) >> 4));
  100. v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
  101. v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
  102. v_x1_u32r = v_x1_u32r >> 12;
  103. float h = v_x1_u32r / 1024.0;
  104. return h;
  105. }
  106. float BME280::calcAltitude(float pressure) {
  107. if (!isTransport_OK) {
  108. return 0;
  109. }
  110. float A = pressure / 101325;
  111. float B = 1 / 5.25588;
  112. float C = pow(A, B);
  113. C = 1.0 - C;
  114. C = C / 0.0000225577;
  115. return C;
  116. }
  117. uint8_t BME280::BME280Read8(uint8_t reg) {
  118. Wire.beginTransmission(_devAddr);
  119. Wire.write(reg);
  120. Wire.endTransmission();
  121. Wire.requestFrom(_devAddr, 1);
  122. // return 0 if slave didn't response
  123. if (Wire.available() < 1) {
  124. isTransport_OK = false;
  125. return 0;
  126. } else {
  127. isTransport_OK = true;
  128. }
  129. return Wire.read();
  130. }
  131. uint16_t BME280::BME280Read16(uint8_t reg) {
  132. uint8_t msb, lsb;
  133. Wire.beginTransmission(_devAddr);
  134. Wire.write(reg);
  135. Wire.endTransmission();
  136. Wire.requestFrom(_devAddr, 2);
  137. // return 0 if slave didn't response
  138. if (Wire.available() < 2) {
  139. isTransport_OK = false;
  140. return 0;
  141. } else {
  142. isTransport_OK = true;
  143. }
  144. msb = Wire.read();
  145. lsb = Wire.read();
  146. return (uint16_t) msb << 8 | lsb;
  147. }
  148. uint16_t BME280::BME280Read16LE(uint8_t reg) {
  149. uint16_t data = BME280Read16(reg);
  150. return (data >> 8) | (data << 8);
  151. }
  152. int16_t BME280::BME280ReadS16(uint8_t reg) {
  153. return (int16_t)BME280Read16(reg);
  154. }
  155. int16_t BME280::BME280ReadS16LE(uint8_t reg) {
  156. return (int16_t)BME280Read16LE(reg);
  157. }
  158. uint32_t BME280::BME280Read24(uint8_t reg) {
  159. uint32_t data;
  160. Wire.beginTransmission(_devAddr);
  161. Wire.write(reg);
  162. Wire.endTransmission();
  163. Wire.requestFrom(_devAddr, 3);
  164. // return 0 if slave didn't response
  165. if (Wire.available() < 3) {
  166. isTransport_OK = false;
  167. return 0;
  168. } else if (isTransport_OK == false) {
  169. isTransport_OK = true;
  170. if (!init(_devAddr)) {
  171. #ifdef BMP280_DEBUG_PRINT
  172. Serial.println("Device not connected or broken!");
  173. #endif
  174. }
  175. }
  176. data = Wire.read();
  177. data <<= 8;
  178. data |= Wire.read();
  179. data <<= 8;
  180. data |= Wire.read();
  181. return data;
  182. }
  183. void BME280::writeRegister(uint8_t reg, uint8_t val) {
  184. Wire.beginTransmission(_devAddr); // start transmission to device
  185. Wire.write(reg); // send register address
  186. Wire.write(val); // send value to write
  187. Wire.endTransmission(); // end transmission
  188. }