Advertisement
DARKHalf

ZUNO_BMP280.cpp

Oct 19th, 2016
315
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.15 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement