DARKHalf

ZUNO_BMP280.cpp

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

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×