bmp280.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*
  2. BMP280.cpp
  3. Bosch BMP280 pressure sensor library for the Arduino microcontroller.
  4. This library uses I2C connection.
  5. Uses floating-point equations from BMP280 datasheet.
  6. modified by mhafuzul islam
  7. version 1.01 16/9/2014 initial version
  8. Our example code uses the "pizza-eating" license. You can do anything
  9. you like with this code. No really, anything. If you find it useful,
  10. buy me italian pizza someday.
  11. */
  12. #include "BMP280.h"
  13. #include <Wire.h>
  14. #include <stdio.h>
  15. #include <math.h>
  16. BMP280::BMP280()
  17. {
  18. //do nothing
  19. }
  20. /*
  21. * Initialize library and coefficient for measurements
  22. */
  23. char BMP280::begin(int sdaPin, int sclPin)
  24. {
  25. Wire.begin(sdaPin,sclPin);
  26. return (readCalibration());
  27. }
  28. char BMP280::begin()
  29. {
  30. // Start up the Arduino's "wire" (I2C) library:
  31. Wire.begin();
  32. return (readCalibration());
  33. }
  34. // The BMP280 includes factory calibration data stored on the device.
  35. // Each device has different numbers, these must be retrieved and
  36. // used in the calculations when taking measurements.
  37. // Retrieve calibration data from device:
  38. char BMP280::readCalibration() {
  39. if (
  40. readUInt(0x88, dig_T1) &&
  41. readInt(0x8A, dig_T2) &&
  42. readInt(0x8C, dig_T3) &&
  43. readUInt(0x8E, dig_P1) &&
  44. readInt(0x90, dig_P2) &&
  45. readInt(0x92, dig_P3) &&
  46. readInt(0x94, dig_P4) &&
  47. readInt(0x96, dig_P5) &&
  48. readInt(0x98, dig_P6) &&
  49. readInt(0x9A, dig_P7) &&
  50. readInt(0x9C, dig_P8) &&
  51. readInt(0x9E, dig_P9)){
  52. #ifdef _debugSerial
  53. Serial.print("dig_T1="); Serial.println(dig_T1,2);
  54. Serial.print("dig_T2="); Serial.println(dig_T2,2);
  55. Serial.print("dig_T3="); Serial.println(dig_T3,2);
  56. Serial.print("dig_P1="); Serial.println(dig_P1,2);
  57. Serial.print("dig_P2="); Serial.println(dig_P2,2);
  58. Serial.print("dig_P3="); Serial.println(dig_P3,2);
  59. Serial.print("dig_P4="); Serial.println(dig_P4,2);
  60. Serial.print("dig_P5="); Serial.println(dig_P5,2);
  61. Serial.print("dig_P6="); Serial.println(dig_P6,2);
  62. Serial.print("dig_P7="); Serial.println(dig_P7,2);
  63. Serial.print("dig_P8="); Serial.println(dig_P8,2);
  64. Serial.print("dig_P9="); Serial.println(dig_P9,2);
  65. #endif
  66. #ifdef _debugTestData
  67. dig_T1 = 27504.0;
  68. dig_T2 = 26435.0;
  69. dig_T3 = -1000.0;
  70. dig_P1 = 36477.0;
  71. dig_P2 = -10685.0;
  72. dig_P3 = 3024.0;
  73. dig_P4 = 2855.0;
  74. dig_P5 = 140.0;
  75. dig_P6 = -7.0;
  76. dig_P7 = 15500.0;
  77. dig_P8 = -14600.0;
  78. dig_P9 = 6000.0;
  79. Serial.print("dig_T1="); Serial.println(dig_T1,2);
  80. Serial.print("dig_T2="); Serial.println(dig_T2,2);
  81. Serial.print("dig_T3="); Serial.println(dig_T3,2);
  82. Serial.print("dig_P1="); Serial.println(dig_P1,2);
  83. Serial.print("dig_P2="); Serial.println(dig_P2,2);
  84. Serial.print("dig_P3="); Serial.println(dig_P3,2);
  85. Serial.print("dig_P4="); Serial.println(dig_P4,2);
  86. Serial.print("dig_P5="); Serial.println(dig_P5,2);
  87. Serial.print("dig_P6="); Serial.println(dig_P6,2);
  88. Serial.print("dig_P7="); Serial.println(dig_P7,2);
  89. Serial.print("dig_P8="); Serial.println(dig_P8,2);
  90. Serial.print("dig_P9="); Serial.println(dig_P9,2);
  91. #endif
  92. return (1);
  93. }
  94. else
  95. return (0);
  96. }
  97. /*
  98. ** Read a signed integer (two bytes) from device
  99. ** @param : address = register to start reading (plus subsequent register)
  100. ** @param : value = external variable to store data (function modifies value)
  101. */
  102. char BMP280::readInt(char address, double &value)
  103. {
  104. unsigned char data[2]; //char is 4bit,1byte
  105. data[0] = address;
  106. if (readBytes(data,2))
  107. {
  108. value = (double)(int16_t)(((unsigned int)data[1]<<8)|(unsigned int)data[0]); //
  109. return(1);
  110. }
  111. value = 0;
  112. return(0);
  113. }
  114. /*
  115. ** Read an unsigned integer (two bytes) from device
  116. ** @param : address = register to start reading (plus subsequent register)
  117. ** @param : value = external variable to store data (function modifies value)
  118. */
  119. char BMP280::readUInt(char address, double &value)
  120. {
  121. unsigned char data[2]; //4bit
  122. data[0] = address;
  123. if (readBytes(data,2))
  124. {
  125. value = (double)(unsigned int)(((unsigned int)data[1]<<8)|(unsigned int)data[0]);
  126. return(1);
  127. }
  128. value = 0;
  129. return(0);
  130. }
  131. /*
  132. ** Read an array of bytes from device
  133. ** @param : value = external array to hold data. Put starting register in values[0].
  134. ** @param : length = number of bytes to read
  135. */
  136. char BMP280::readBytes(unsigned char *values, char length)
  137. {
  138. char x;
  139. Wire.beginTransmission(BMP280_ADDR);
  140. Wire.write(values[0]);
  141. error = Wire.endTransmission();
  142. if (error == 0)
  143. {
  144. Wire.requestFrom(BMP280_ADDR,length);
  145. while(Wire.available() != length) ; // wait until bytes are ready
  146. for(x=0;x<length;x++)
  147. {
  148. values[x] = Wire.read();
  149. }
  150. return(1);
  151. }
  152. return(0);
  153. }
  154. /*
  155. ** Write an array of bytes to device
  156. ** @param : values = external array of data to write. Put starting register in values[0].
  157. ** @param : length = number of bytes to write
  158. */
  159. char BMP280::writeBytes(unsigned char *values, char length)
  160. {
  161. Wire.beginTransmission(BMP280_ADDR);
  162. Wire.write(values,length);
  163. error = Wire.endTransmission();
  164. if (error == 0)
  165. return(1);
  166. else
  167. return(0);
  168. }
  169. short BMP280::getOversampling(void)
  170. {
  171. return oversampling;
  172. }
  173. char BMP280::setOversampling(short oss)
  174. {
  175. oversampling = oss;
  176. return (1);
  177. }
  178. /*
  179. ** Begin a measurement cycle.
  180. ** Oversampling: 0 to 4, higher numbers are slower, higher-res outputs.
  181. ** @returns : delay in ms to wait, or 0 if I2C error.
  182. */
  183. char BMP280::startMeasurment(void)
  184. {
  185. unsigned char data[2], result, delay;
  186. data[0] = BMP280_REG_CONTROL;
  187. switch (oversampling)
  188. {
  189. case 0:
  190. data[1] = BMP280_COMMAND_PRESSURE0;
  191. oversampling_t = 1;
  192. delay = 8;
  193. break;
  194. case 1:
  195. data[1] = BMP280_COMMAND_PRESSURE1;
  196. oversampling_t = 1;
  197. delay = 10;
  198. break;
  199. case 2:
  200. data[1] = BMP280_COMMAND_PRESSURE2;
  201. oversampling_t = 1;
  202. delay = 15;
  203. break;
  204. case 3:
  205. data[1] = BMP280_COMMAND_PRESSURE3;
  206. oversampling_t = 1;
  207. delay = 24;
  208. break;
  209. case 4:
  210. data[1] = BMP280_COMMAND_PRESSURE4;
  211. oversampling_t = 1;
  212. delay = 45;
  213. break;
  214. case 16:
  215. data[1] = BMP280_COMMAND_OVERSAMPLING_MAX;
  216. oversampling_t = 1;
  217. delay = 80; //I cannot find any data about timings in datasheet for x16 pressure and x16 temeprature oversampling
  218. break; //I guess this is enough time (maybe it can be even smaller ~60ms)
  219. default:
  220. data[1] = BMP280_COMMAND_PRESSURE0;
  221. delay = 9;
  222. break;
  223. }
  224. result = writeBytes(data, 2);
  225. if (result) // good write?
  226. return(delay); // return the delay in ms (rounded up) to wait before retrieving data
  227. else
  228. return(0); // or return 0 if there was a problem communicating with the BMP
  229. }
  230. /*
  231. ** Get the uncalibrated pressure and temperature value.
  232. ** @param : uP = stores the uncalibrated pressure value.(20bit)
  233. ** @param : uT = stores the uncalibrated temperature value.(20bit)
  234. */
  235. char BMP280::getUnPT(double &uP, double &uT)
  236. {
  237. unsigned char data[6];
  238. char result;
  239. data[0] = BMP280_REG_RESULT_PRESSURE; //0xF7
  240. result = readBytes(data, 6); // 0xF7; xF8, 0xF9, 0xFA, 0xFB, 0xFC
  241. if (result) // good read
  242. {
  243. double factor = pow(2, 4);
  244. uP = (double)(data[0] *4096 + data[1]*16 + data[2]/16) ; //20bit UP
  245. uT = (double)(data[3]*4096 + data[4]*16 + data[5]/16) ; //20bit UT
  246. #ifdef _debugSerial
  247. Serial.print(uT);
  248. Serial.print(" ");
  249. Serial.println(uP);
  250. #endif
  251. #ifdef _debugTestData
  252. uT = 519888.0;
  253. uP = 415148.0;
  254. Serial.print(uT);
  255. Serial.print(" ");
  256. Serial.println(uP);
  257. #endif
  258. }
  259. return(result);
  260. }
  261. /*
  262. ** Retrieve temperature and pressure.
  263. ** @param : T = stores the temperature value in degC.
  264. ** @param : P = stores the pressure value in mBar.
  265. */
  266. char BMP280::getTemperatureAndPressure(double &T,double &P)
  267. {
  268. double uT ;
  269. double uP;
  270. char result = getUnPT(uP,uT);
  271. if(result!=0){
  272. // calculate the temperature
  273. result = calcTemperature(T,uT);
  274. if(result){
  275. // calculate the pressure
  276. result = calcPressure(P,uP);
  277. if(result)return (1);
  278. else error = 3 ; // pressure error ;
  279. return (9);
  280. }else
  281. error = 2; // temperature error ;
  282. }
  283. else
  284. error = 1;
  285. return (9);
  286. }
  287. /*
  288. ** temperature calculation
  289. ** @param : T = stores the temperature value after calculation.
  290. ** @param : uT = the uncalibrated temperature value.
  291. */
  292. char BMP280::calcTemperature(double &T, double &adc_T)
  293. //
  294. {
  295. //Serial.print("adc_T = "); Serial.println(adc_T,DEC);
  296. double var1 = (adc_T/16384.0 - dig_T1/1024.0)*dig_T2;
  297. double var2 = ((adc_T/131072.0 - dig_T1/8192.0)*(adc_T/131072.0 - dig_T1/8192.0))*dig_T3;
  298. t_fine = var1+var2;
  299. T = (var1+var2)/5120.0;
  300. #ifdef _debugSerial
  301. Serial.print(var1);
  302. Serial.print(" ");
  303. Serial.print(var2);
  304. Serial.print(" ");
  305. Serial.print(t_fine);
  306. Serial.print(" ");
  307. Serial.println(T);
  308. #endif
  309. if(T>100 || T <-100)return 0;
  310. return (1);
  311. }
  312. /*
  313. ** Pressure calculation from uncalibrated pressure value.
  314. ** @param : P = stores the pressure value.
  315. ** @param : uP = uncalibrated pressure value.
  316. */
  317. char BMP280::calcPressure(double &P,double uP)
  318. {
  319. //char result;
  320. double var1 , var2 ;
  321. var1 = (t_fine/2.0) - 64000.0;
  322. #ifdef _debugSerial
  323. Serial.print("var1 = ");Serial.println(var1,2);
  324. #endif
  325. var2 = var1 * (var1 * dig_P6/32768.0); //not overflow
  326. #ifdef _debugSerial
  327. Serial.print("var2 = ");Serial.println(var2,2);
  328. #endif
  329. var2 = var2 + (var1 * dig_P5 * 2.0); //overflow
  330. #ifdef _debugSerial
  331. Serial.print("var2 = ");Serial.println(var2,2);
  332. #endif
  333. var2 = (var2/4.0)+((dig_P4)*65536.0);
  334. #ifdef _debugSerial
  335. Serial.print("var2 = ");Serial.println(var2,2);
  336. #endif
  337. var1 = (dig_P3 * var1 * var1/524288.0 + dig_P2 * var1) / 524288.0;
  338. #ifdef _debugSerial
  339. Serial.print("var1 = ");Serial.println(var1,2);
  340. #endif
  341. var1 = (1.0 + var1/32768.0) * dig_P1;
  342. #ifdef _debugSerial
  343. Serial.print("var1 = ");Serial.println(var1,2);
  344. #endif
  345. P = 1048576.0- uP;
  346. #ifdef _debugSerial
  347. Serial.print("p = ");Serial.println(p,2);
  348. #endif
  349. P = (P-(var2/4096.0))*6250.0/var1 ; //overflow
  350. #ifdef _debugSerial
  351. Serial.print("p = ");Serial.println(p,2);
  352. #endif
  353. var1 = dig_P9*P*P/2147483648.0; //overflow
  354. #ifdef _debugSerial
  355. Serial.print("var1 = ");Serial.println(var1,2);
  356. #endif
  357. var2 = P*dig_P8/32768.0;
  358. #ifdef _debugSerial
  359. Serial.print("var2 = ");Serial.println(var2,2);
  360. #endif
  361. P = P + (var1+var2+dig_P7)/16.0;
  362. #ifdef _debugSerial
  363. Serial.print("p = ");Serial.println(p,2);
  364. #endif
  365. P = P/100.0 ;
  366. if(P>1200.0 || P < 800.0)return (0);
  367. return (1);
  368. }
  369. double BMP280::sealevel(double P, double A)
  370. // Given a pressure P (mb) taken at a specific altitude (meters),
  371. // return the equivalent pressure (mb) at sea level.
  372. // This produces pressure readings that can be used for weather measurements.
  373. {
  374. return(P/pow(1-(A/44330.0),5.255));
  375. }
  376. double BMP280::altitude(double P, double P0)
  377. // Given a pressure measurement P (mb) and the pressure at a baseline P0 (mb),
  378. // return altitude (meters) above baseline.
  379. {
  380. return(44330.0*(1-pow(P/P0,1/5.255)));
  381. }
  382. char BMP280::getError(void)
  383. // If any library command fails, you can retrieve an extended
  384. // error code using this command. Errors are from the wire library:
  385. // 0 = Success
  386. // 1 = Data too long to fit in transmit buffer
  387. // 2 = Received NACK on transmit of address
  388. // 3 = Received NACK on transmit of data
  389. // 4 = Other error
  390. {
  391. return(error);
  392. }