Seeed_BMP280.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include "Seeed_BMP280.h"
  2. // #define BMP280_DEBUG_PRINT
  3. bool BMP280::init(int i2c_addr) {
  4. uint8_t chip_id = 0;
  5. uint8_t retry = 0;
  6. _devAddr = i2c_addr;
  7. Wire.begin();
  8. while ((retry++ < 5) && (chip_id != 0x58)) {
  9. chip_id = bmp280Read8(BMP280_REG_CHIPID);
  10. #ifdef BMP280_DEBUG_PRINT
  11. Serial.print("Read chip ID: ");
  12. Serial.println(chip_id);
  13. #endif
  14. delay(100);
  15. }
  16. dig_T1 = bmp280Read16LE(BMP280_REG_DIG_T1);
  17. dig_T2 = bmp280ReadS16LE(BMP280_REG_DIG_T2);
  18. dig_T3 = bmp280ReadS16LE(BMP280_REG_DIG_T3);
  19. dig_P1 = bmp280Read16LE(BMP280_REG_DIG_P1);
  20. dig_P2 = bmp280ReadS16LE(BMP280_REG_DIG_P2);
  21. dig_P3 = bmp280ReadS16LE(BMP280_REG_DIG_P3);
  22. dig_P4 = bmp280ReadS16LE(BMP280_REG_DIG_P4);
  23. dig_P5 = bmp280ReadS16LE(BMP280_REG_DIG_P5);
  24. dig_P6 = bmp280ReadS16LE(BMP280_REG_DIG_P6);
  25. dig_P7 = bmp280ReadS16LE(BMP280_REG_DIG_P7);
  26. dig_P8 = bmp280ReadS16LE(BMP280_REG_DIG_P8);
  27. dig_P9 = bmp280ReadS16LE(BMP280_REG_DIG_P9);
  28. writeRegister(BMP280_REG_CONTROL, 0x3F);
  29. return true;
  30. }
  31. float BMP280::getTemperature(void) {
  32. int32_t var1, var2;
  33. int32_t adc_T = bmp280Read24(BMP280_REG_TEMPDATA);
  34. // Check if the last transport successed
  35. if (!isTransport_OK) {
  36. return 0;
  37. }
  38. adc_T >>= 4;
  39. var1 = (((adc_T >> 3) - ((int32_t)(dig_T1 << 1))) *
  40. ((int32_t)dig_T2)) >> 11;
  41. var2 = (((((adc_T >> 4) - ((int32_t)dig_T1)) *
  42. ((adc_T >> 4) - ((int32_t)dig_T1))) >> 12) *
  43. ((int32_t)dig_T3)) >> 14;
  44. t_fine = var1 + var2;
  45. float T = (t_fine * 5 + 128) >> 8;
  46. return T / 100;
  47. }
  48. uint32_t BMP280::getPressure(void) {
  49. int64_t var1, var2, p;
  50. // Call getTemperature to get t_fine
  51. getTemperature();
  52. // Check if the last transport successed
  53. if (!isTransport_OK) {
  54. return 0;
  55. }
  56. int32_t adc_P = bmp280Read24(BMP280_REG_PRESSUREDATA);
  57. adc_P >>= 4;
  58. var1 = ((int64_t)t_fine) - 128000;
  59. var2 = var1 * var1 * (int64_t)dig_P6;
  60. var2 = var2 + ((var1 * (int64_t)dig_P5) << 17);
  61. var2 = var2 + (((int64_t)dig_P4) << 35);
  62. var1 = ((var1 * var1 * (int64_t)dig_P3) >> 8) + ((var1 * (int64_t)dig_P2) << 12);
  63. var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)dig_P1) >> 33;
  64. if (var1 == 0) {
  65. return 0; // avoid exception caused by division by zero
  66. }
  67. p = 1048576 - adc_P;
  68. p = (((p << 31) - var2) * 3125) / var1;
  69. var1 = (((int64_t)dig_P9) * (p >> 13) * (p >> 13)) >> 25;
  70. var2 = (((int64_t)dig_P8) * p) >> 19;
  71. p = ((p + var1 + var2) >> 8) + (((int64_t)dig_P7) << 4);
  72. return (uint32_t)p / 256;
  73. }
  74. float BMP280::calcAltitude(float p0, float p1, float t) {
  75. float C;
  76. C = (p0 / p1);
  77. C = pow(C, (1 / 5.25588)) - 1.0;
  78. C = (C * (t + 273.15)) / 0.0065;
  79. return C;
  80. }
  81. float BMP280::calcAltitude(float p0) {
  82. if (!isTransport_OK) {
  83. return 0;
  84. }
  85. float t = getTemperature();
  86. float p1 = getPressure();
  87. return calcAltitude(p0, p1, t);
  88. }
  89. uint8_t BMP280::bmp280Read8(uint8_t reg) {
  90. Wire.beginTransmission(_devAddr);
  91. Wire.write(reg);
  92. Wire.endTransmission();
  93. Wire.requestFrom(_devAddr, 1);
  94. // return 0 if slave didn't response
  95. if (Wire.available() < 1) {
  96. isTransport_OK = false;
  97. return 0;
  98. } else if (isTransport_OK == false) {
  99. isTransport_OK = true;
  100. }
  101. return Wire.read();
  102. }
  103. uint16_t BMP280::bmp280Read16(uint8_t reg) {
  104. uint8_t msb, lsb;
  105. Wire.beginTransmission(_devAddr);
  106. Wire.write(reg);
  107. Wire.endTransmission();
  108. Wire.requestFrom(_devAddr, 2);
  109. // return 0 if slave didn't response
  110. if (Wire.available() < 2) {
  111. isTransport_OK = false;
  112. return 0;
  113. } else {
  114. isTransport_OK = true;
  115. }
  116. msb = Wire.read();
  117. lsb = Wire.read();
  118. return (uint16_t) msb << 8 | lsb;
  119. }
  120. uint16_t BMP280::bmp280Read16LE(uint8_t reg) {
  121. uint16_t data = bmp280Read16(reg);
  122. return (data >> 8) | (data << 8);
  123. }
  124. int16_t BMP280::bmp280ReadS16(uint8_t reg) {
  125. return (int16_t)bmp280Read16(reg);
  126. }
  127. int16_t BMP280::bmp280ReadS16LE(uint8_t reg) {
  128. return (int16_t)bmp280Read16LE(reg);
  129. }
  130. uint32_t BMP280::bmp280Read24(uint8_t reg) {
  131. uint32_t data;
  132. Wire.beginTransmission(_devAddr);
  133. Wire.write(reg);
  134. Wire.endTransmission();
  135. Wire.requestFrom(_devAddr, 3);
  136. // return 0 if slave didn't response
  137. if (Wire.available() < 3) {
  138. isTransport_OK = false;
  139. return 0;
  140. } else if (isTransport_OK == false) {
  141. isTransport_OK = true;
  142. if (!init(_devAddr)) {
  143. #ifdef BMP280_DEBUG_PRINT
  144. Serial.println("Device not connected or broken!");
  145. #endif
  146. }
  147. }
  148. data = Wire.read();
  149. data <<= 8;
  150. data |= Wire.read();
  151. data <<= 8;
  152. data |= Wire.read();
  153. return data;
  154. }
  155. void BMP280::writeRegister(uint8_t reg, uint8_t val) {
  156. Wire.beginTransmission(_devAddr); // start transmission to device
  157. Wire.write(reg); // send register address
  158. Wire.write(val); // send value to write
  159. Wire.endTransmission(); // end transmission
  160. }