Advertisement
Guest User

Untitled

a guest
Apr 8th, 2015
321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.75 KB | None | 0 0
  1. #include "bmp.h"
  2. #include "i2c_rw.h"
  3. #include "tools.h"
  4. #include <iostream>
  5. #include <iomanip>
  6. #include <exception>
  7.  
  8. #define BMP180_READ_ADDRESS 0x77
  9. #define BMP180_WRITE_ADDRESS 0x77
  10.  
  11. #define BMP085_REG_CALIBRATION_DATA_ADDR 0xAA
  12. #define BMP085_REG_CHIPID       0xD0
  13. #define BMP085_REG_VERSION      0xD1
  14. #define BMP085_CMD_CONTROL      0xf4
  15. #define BMP085_REG_TEMPDATA     0xf6
  16. #define BMP085_REG_PRESDATA     0xf6
  17. #define BMP085_CMD_READTEMP     0x2e
  18. #define BMP085_CMD_READPRES     0x34
  19. #define BMP085_CMD_SOFTRESET    0xE0
  20.  
  21. static char chipId  = 0;
  22. static char version = 0;
  23. // dafault values here are from datasheet for diagnostic purposes
  24. static int16_t  ac1 = 408,
  25.                 ac2 = -72,
  26.                 ac3 = -14383;
  27. static uint16_t ac4 = 32741,
  28.                 ac5 = 32757,
  29.                 ac6 = 23153;
  30. static int16_t  b1  = 6190,
  31.                 b2  = 4,
  32.                 mb  = -32768,
  33.                 mc  = -8711,
  34.                 md  = 2868;
  35.  
  36. void cleanup_bmp()
  37. {
  38.  
  39. }
  40.  
  41. void init_bmp()
  42. {
  43.     try
  44.     {
  45.         bcm2835_i2c_setSlaveAddress(BMP180_READ_ADDRESS);
  46.         // get id/version
  47.         chipId  =  i2c_reg_get8(BMP085_REG_CHIPID);
  48.         version =  i2c_reg_get8(BMP085_REG_VERSION);
  49.  
  50. #ifndef BMP_DIAGNOSTIC
  51.         // get calibration data
  52.         ac1 = i2c_reg_get16(BMP085_REG_CALIBRATION_DATA_ADDR);
  53.         ac2 = i2c_reg_get16(BMP085_REG_CALIBRATION_DATA_ADDR + 2);
  54.         ac3 = i2c_reg_get16(BMP085_REG_CALIBRATION_DATA_ADDR + 4);
  55.         ac4 = i2c_reg_get16(BMP085_REG_CALIBRATION_DATA_ADDR + 6);
  56.         ac5 = i2c_reg_get16(BMP085_REG_CALIBRATION_DATA_ADDR + 8);
  57.         ac6 = i2c_reg_get16(BMP085_REG_CALIBRATION_DATA_ADDR + 10);
  58.          b1 = i2c_reg_get16(BMP085_REG_CALIBRATION_DATA_ADDR + 12);
  59.          b2 = i2c_reg_get16(BMP085_REG_CALIBRATION_DATA_ADDR + 14);
  60.          mb = i2c_reg_get16(BMP085_REG_CALIBRATION_DATA_ADDR + 16);
  61.          mc = i2c_reg_get16(BMP085_REG_CALIBRATION_DATA_ADDR + 18);
  62.          md = i2c_reg_get16(BMP085_REG_CALIBRATION_DATA_ADDR + 20);
  63. #endif // BMP_DIAGNOSTIC
  64.  
  65.         i2c_reg_set8(BMP085_CMD_SOFTRESET, 0xB6);
  66.     }
  67.     catch(const std::system_error& err)
  68.     {
  69.         std::cout << "bmp180: " << err.what() << " : ";
  70.         switch (err.code().value())
  71.         {
  72.             case BCM2835_I2C_REASON_ERROR_NACK: std::cout << "Received a NACK"; break;
  73.             case BCM2835_I2C_REASON_ERROR_CLKT: std::cout << "Received Clock Stretch Timeout"; break;
  74.             case BCM2835_I2C_REASON_ERROR_DATA: std::cout << "Not all data is sent / received"; break;
  75.             default: std::cout << "Unknown error"; break;
  76.         }
  77.         std::cout << std::endl;
  78.     }
  79. }
  80.  
  81. void poll_bmp(uint8_t oversampling)
  82. {
  83. #ifdef BMP_DIAGNOSTIC
  84.     oversampling = BMP085_ULTRALOWPOWER;
  85. #endif
  86.  
  87.     try
  88.     {
  89.         int32_t b3, b5, b6, x1, x2, x3, p;
  90.         uint32_t b4, b7;
  91.         uint16_t tempRawData = 27898;
  92.         int32_t presRawData = 23843;
  93.  
  94.         // get raw temperature
  95.         bcm2835_i2c_setSlaveAddress(BMP180_WRITE_ADDRESS);
  96.         i2c_reg_set8(BMP085_CMD_CONTROL, BMP085_CMD_READTEMP);
  97.  
  98.         rpi_delay(5);
  99.  
  100. #ifndef BMP_DIAGNOSTIC
  101. //        tempRawData = i2c_reg_get16(BMP085_REG_TEMPDATA);
  102.  
  103.         char tempReadBuf[2];
  104.         i2c_read_reg(BMP085_REG_TEMPDATA, tempReadBuf, sizeof(tempReadBuf));
  105.         tempRawData = (int)tempReadBuf[0] << 8 | (int)tempReadBuf[1];
  106. #endif // BMP_DIAGNOSTIC
  107.  
  108.         // get raw pressure
  109.         i2c_reg_set8(BMP085_CMD_CONTROL, BMP085_CMD_READPRES + (oversampling << 6));
  110.         rpi_delay(2 + (3 << oversampling));
  111.  
  112. #ifndef BMP_DIAGNOSTIC
  113. //        presRawData =  i2c_reg_get16(BMP085_REG_PRESDATA);
  114. //        presRawData <<= 8;
  115. //        presRawData |= (int8_t)i2c_reg_get8(BMP085_REG_PRESDATA+2);
  116.  
  117.         char presReadBuf[3];
  118.         i2c_read_reg(BMP085_REG_PRESDATA, presReadBuf, sizeof(presReadBuf));
  119.         presRawData = (int)presReadBuf[0] << 16 | (int)presReadBuf[1] << 8 | (int)presReadBuf[2];
  120.  
  121.         presRawData >>= (8-oversampling);
  122. #endif // BMP_DIAGNOSTIC
  123.  
  124.         // calculate real temp / press
  125.         x1 = ((int)tempRawData - (int)ac6) * ((int)ac5) >> 15;
  126.         if (x1 == -md)
  127.             throw std::runtime_error("invalid data");
  128.         x2 = ((int)mc << 11) / (x1+md);
  129.         b5 = x1 + x2;
  130.  
  131.         b6 = b5 - 4000;
  132.  
  133.         x1 = (b2 *  (b6 * b6)>>12 ) >> 11;
  134.         x2 = (ac2 * b6) >> 11;
  135.         x3 = x1 + x2;
  136.         b3 = ((((int)ac1*4 + x3) << oversampling) + 2) / 4;
  137.  
  138.         x1 = (ac3 * b6) >> 13;
  139.         x2 = (b1 * ((b6 * b6) >> 12)) >> 16;
  140.         x3 = ((x1 + x2) + 2) >> 2;
  141.         b4 = (ac4 * (uint32_t)(x3 + 32768)) >> 15;
  142.         if (b4 == 0)
  143.             throw std::runtime_error ("invalid data");
  144.  
  145.         b7 = ((uint32_t)(presRawData - b3) * ( 50000UL >> oversampling ));
  146.  
  147.         if (b7 < 0x80000000)
  148.         {
  149.             p = (b7 * 2) / b4;
  150.         }
  151.         else
  152.         {
  153.             p = (b7 / b4) * 2;
  154.         }
  155.         x1 = (p >> 8) * (p >> 8);
  156.         x1 = (x1 * 3038) >> 16;
  157.         x2 = (-7357 * p) >> 16;
  158.  
  159.         int32_t pres = p + ((x1 + x2 + 3791)>>4);
  160.         int16_t temp = (b5 + 8) >> 4 ;
  161.  
  162.         std::cout << "bcm085: t=" << std::fixed << std::setprecision(1) << temp/10.0
  163.                          <<  " p=" << std::fixed << std::setprecision(1) << pres
  164.                    << std::endl;
  165.  
  166. #ifdef DEBUG_BMP
  167.         std::cout << "chipid: " << (int)chipId
  168.                    << " version: " << (int)version
  169.                    << std::hex
  170.                    << " Calibration data: "
  171.                    << " ac1=" << std::setw(4) << ac1 << " ac2=" << std::setw(4) << ac2
  172.                    << " ac3=" << std::setw(4) << ac3 << " ac4=" << std::setw(4) << ac4
  173.                    << " ac5=" << std::setw(4) << ac5 << " ac6=" << std::setw(4) << ac6
  174.                    << "  b1=" << std::setw(4) <<  b1 << "  b2=" << std::setw(4) << b2
  175.                    << "  mb=" << std::setw(4) <<  mb << "  mc=" << std::setw(4) << mc
  176.                    << "  md=" << std::setw(4) << md
  177.                    << " Raw data: "
  178.                    << " rt=" << std::setw(4) << tempRawData
  179.                    << " rp=" << std::setw(6) << presRawData
  180.                    << std::dec
  181.                    << std::endl;
  182. #endif // DEBUG_BMP
  183.     }
  184.     catch(const std::system_error& err)
  185.     {
  186.         std::cout << "bmp180: " << err.what() << " : ";
  187.         switch (err.code().value())
  188.         {
  189.             case BCM2835_I2C_REASON_ERROR_NACK: std::cout << "Received a NACK"; break;
  190.             case BCM2835_I2C_REASON_ERROR_CLKT: std::cout << "Received Clock Stretch Timeout"; break;
  191.             case BCM2835_I2C_REASON_ERROR_DATA: std::cout << "Not all data is sent / received"; break;
  192.             default: std::cout << "Unknown error"; break;
  193.         }
  194.         std::cout << std::endl;
  195.     }
  196. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement