Modified to run on Renesas GR Peach board

Dependencies:   EthernetInterface HTTP-Server Webpage mbed-rpc mbed-src

Fork of HTTPServer_echoback by Takuya Urakawa

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Adafruit_BMP085_U.cpp Source File

Adafruit_BMP085_U.cpp

00001 /***************************************************************************
00002   This is a library for the BMP085 pressure sensor
00003 
00004   Designed specifically to work with the Adafruit BMP085 or BMP180 Breakout 
00005   ----> http://www.adafruit.com/products/391
00006   ----> http://www.adafruit.com/products/1603
00007  
00008   These displays use I2C to communicate, 2 pins are required to interface.
00009 
00010   Adafruit invests time and resources providing this open source code,
00011   please support Adafruit andopen-source hardware by purchasing products
00012   from Adafruit!
00013 
00014   Written by Kevin Townsend for Adafruit Industries.  
00015   BSD license, all text above must be included in any redistribution
00016  ***************************************************************************/
00017 
00018 //#include "mbed.h"
00019 //#include "I2C.h"
00020 #include "Adafruit_BMP085_U.h"
00021 
00022 static bmp085_calib_data _bmp085_coeffs;   // Last read accelerometer data will be available here
00023 static uint8_t           _bmp085Mode;
00024 
00025 #define BMP085_USE_DATASHEET_VALS (0) /* Set to 1 for sanity check */
00026 typedef uint8_t byte;
00027 
00028 //extern i2c;
00029 //extern I2C* i2c;
00030 //extern mbed::I2C* i2c;
00031 //extern mbed::I2C* i2c(I2C_SDA, I2C_SCL);
00032 //extern I2C i2c();
00033 //extern i2c(I2C_SDA, I2C_SCL);
00034 //extern int i2c(I2C_SDA, I2C_SCL);
00035 //extern I2C i2c(I2C_SDA, I2C_SCL);        // sda, scl
00036 
00037 /***************************************************************************
00038  PRIVATE FUNCTIONS
00039  ***************************************************************************/
00040 
00041 /**************************************************************************/
00042 /*!
00043     @brief  Writes an 8 bit value over I2C
00044 */
00045 /**************************************************************************/
00046 static void writeCommand(byte reg, byte value)
00047 {
00048     char data_write[2];
00049 
00050     data_write[0] = reg;
00051     data_write[1] = value;
00052     int status = i2c->write(BMP085_ADDRESS, data_write, 2, 0);
00053  
00054 }
00055 
00056 /**************************************************************************/
00057 /*!
00058     @brief  Reads an 8 bit value over I2C
00059 */
00060 /**************************************************************************/
00061 static void read8(byte reg, uint8_t *value)
00062 {
00063     char data_write[2];
00064     char data_read[2];
00065   
00066         // Read register
00067     data_write[0] = reg;
00068     i2c->write(BMP085_ADDRESS, data_write, 1, 1); // no stop
00069     i2c->read(BMP085_ADDRESS, data_read, 2, 0);
00070  
00071 }
00072 
00073 /**************************************************************************/
00074 /*!
00075     @brief  Reads a 16 bit value over I2C
00076 */
00077 /**************************************************************************/
00078 static void read16(byte reg, uint16_t *value)
00079 {
00080     char data_write[2];
00081     char data_read[2];
00082     //uint8_t data_read[2];
00083 
00084     //Sample_RIIC_Read( (uint8_t)BMP085_ADDRESS,reg,1, data_read);
00085     data_write[0] = reg;
00086     i2c->write(BMP085_ADDRESS, data_write, 1, 1); // no stop
00087     i2c->read(BMP085_ADDRESS, data_read, 2, 0);
00088 
00089     *value = (((uint16_t)data_read[0]) << 8) | ((uint16_t)data_read[1]);
00090 
00091 }
00092 
00093 /**************************************************************************/
00094 /*!
00095     @brief  Reads a signed 16 bit value over I2C
00096 */
00097 /**************************************************************************/
00098 static void readS16(byte reg, int16_t *value)
00099 {
00100   uint16_t i;
00101   read16(reg, &i);
00102   *value = (int16_t)i;
00103 }
00104 
00105 /**************************************************************************/
00106 /*!
00107     @brief  Reads the factory-set coefficients
00108 */
00109 /**************************************************************************/
00110 static void readCoefficients(void)
00111 {
00112   #if BMP085_USE_DATASHEET_VALS
00113     _bmp085_coeffs.ac1 = 408;
00114     _bmp085_coeffs.ac2 = -72;
00115     _bmp085_coeffs.ac3 = -14383;
00116     _bmp085_coeffs.ac4 = 32741;
00117     _bmp085_coeffs.ac5 = 32757;
00118     _bmp085_coeffs.ac6 = 23153;
00119     _bmp085_coeffs.b1  = 6190;
00120     _bmp085_coeffs.b2  = 4;
00121     _bmp085_coeffs.mb  = -32768;
00122     _bmp085_coeffs.mc  = -8711;
00123     _bmp085_coeffs.md  = 2868;
00124     _bmp085Mode        = 0;
00125   #else
00126     readS16(BMP085_REGISTER_CAL_AC1, &_bmp085_coeffs.ac1);
00127     readS16(BMP085_REGISTER_CAL_AC2, &_bmp085_coeffs.ac2);
00128     readS16(BMP085_REGISTER_CAL_AC3, &_bmp085_coeffs.ac3);
00129     read16(BMP085_REGISTER_CAL_AC4, &_bmp085_coeffs.ac4);
00130     read16(BMP085_REGISTER_CAL_AC5, &_bmp085_coeffs.ac5);
00131     read16(BMP085_REGISTER_CAL_AC6, &_bmp085_coeffs.ac6);
00132     readS16(BMP085_REGISTER_CAL_B1, &_bmp085_coeffs.b1);
00133     readS16(BMP085_REGISTER_CAL_B2, &_bmp085_coeffs.b2);
00134     readS16(BMP085_REGISTER_CAL_MB, &_bmp085_coeffs.mb);
00135     readS16(BMP085_REGISTER_CAL_MC, &_bmp085_coeffs.mc);
00136     readS16(BMP085_REGISTER_CAL_MD, &_bmp085_coeffs.md);
00137   #endif
00138 }
00139 
00140 /**************************************************************************/
00141 /*!
00142 
00143 */
00144 /**************************************************************************/
00145 static void readRawTemperature(int32_t *temperature)
00146 {
00147   #if BMP085_USE_DATASHEET_VALS
00148     *temperature = 27898;
00149   #else
00150     uint16_t t;
00151     writeCommand(BMP085_REGISTER_CONTROL, BMP085_REGISTER_READTEMPCMD);
00152     wait(5);//delay(5);
00153     read16(BMP085_REGISTER_TEMPDATA, &t);
00154     *temperature = t;
00155   #endif
00156 }
00157 
00158 /**************************************************************************/
00159 /*!
00160 
00161 */
00162 /**************************************************************************/
00163 static void readRawPressure(int32_t *pressure)
00164 {
00165   #if BMP085_USE_DATASHEET_VALS
00166     *pressure = 23843;
00167   #else
00168     uint8_t  p8;
00169     uint16_t p16;
00170     int32_t  p32;
00171 
00172     writeCommand(BMP085_REGISTER_CONTROL, BMP085_REGISTER_READPRESSURECMD + (_bmp085Mode << 6));
00173     switch(_bmp085Mode)
00174     {
00175       case BMP085_MODE_ULTRALOWPOWER:
00176         wait(5);//delay(5);
00177         break;
00178       case BMP085_MODE_STANDARD:
00179         wait(8);//delay(8);
00180         break;
00181       case BMP085_MODE_HIGHRES:
00182         wait(14);//delay(14);
00183         break;
00184       case BMP085_MODE_ULTRAHIGHRES:
00185       default:
00186         wait(26);//delay(26);
00187         break;
00188     }
00189 
00190     read16(BMP085_REGISTER_PRESSUREDATA, &p16);
00191     p32 = (uint32_t)p16 << 8;
00192     read8(BMP085_REGISTER_PRESSUREDATA+2, &p8);
00193     p32 += p8;
00194     p32 >>= (8 - _bmp085Mode);
00195     
00196     *pressure = p32;
00197   #endif
00198 }
00199 
00200 /**************************************************************************/
00201 /*!
00202     @brief  Compute B5 coefficient used in temperature & pressure calcs.
00203 */
00204 /**************************************************************************/
00205 int32_t Adafruit_BMP085_Unified::computeB5(int32_t ut) {
00206   int32_t X1 = (ut - (int32_t)_bmp085_coeffs.ac6) * ((int32_t)_bmp085_coeffs.ac5) >> 15;
00207   int32_t X2 = ((int32_t)_bmp085_coeffs.mc << 11) / (X1+(int32_t)_bmp085_coeffs.md);
00208   return X1 + X2;
00209 }
00210 
00211 
00212 /***************************************************************************
00213  CONSTRUCTOR
00214  ***************************************************************************/
00215  
00216 /**************************************************************************/
00217 /*!
00218     @brief  Instantiates a new Adafruit_BMP085_Unified class
00219 */
00220 /**************************************************************************/
00221 Adafruit_BMP085_Unified::Adafruit_BMP085_Unified(int32_t sensorID) {
00222   _sensorID = sensorID;
00223 }
00224 
00225 /***************************************************************************
00226  PUBLIC FUNCTIONS
00227  ***************************************************************************/
00228  
00229 /**************************************************************************/
00230 /*!
00231     @brief  Setups the HW
00232 */
00233 /**************************************************************************/
00234 bool Adafruit_BMP085_Unified::begin(bmp085_mode_t mode)
00235 {
00236   // Enable I2C
00237   //Wire.begin();
00238 
00239   /* Mode boundary check */
00240   if ((mode > BMP085_MODE_ULTRAHIGHRES) || (mode < 0))
00241   {
00242     mode = BMP085_MODE_ULTRAHIGHRES;
00243   }
00244 
00245   /* Make sure we have the right device */
00246   uint8_t id;
00247   read8(BMP085_REGISTER_CHIPID, &id);
00248   if(id != 0x55)
00249   {
00250     return false;
00251   }
00252 
00253   /* Set the mode indicator */
00254   _bmp085Mode = mode;
00255 
00256   /* Coefficients need to be read once */
00257   readCoefficients();
00258     
00259   return true;
00260 }
00261 
00262 /**************************************************************************/
00263 /*!
00264     @brief  Gets the compensated pressure level in kPa
00265 */
00266 /**************************************************************************/
00267 void Adafruit_BMP085_Unified::getPressure(float *pressure)
00268 {
00269   int32_t  ut = 0, up = 0, compp = 0;
00270   int32_t  x1, x2, b5, b6, x3, b3, p;
00271   uint32_t b4, b7;
00272 
00273   /* Get the raw pressure and temperature values */
00274   readRawTemperature(&ut);
00275   readRawPressure(&up);
00276 
00277   /* Temperature compensation */
00278   b5 = computeB5(ut);
00279 
00280   /* Pressure compensation */
00281   b6 = b5 - 4000;
00282   x1 = (_bmp085_coeffs.b2 * ((b6 * b6) >> 12)) >> 11;
00283   x2 = (_bmp085_coeffs.ac2 * b6) >> 11;
00284   x3 = x1 + x2;
00285   b3 = (((((int32_t) _bmp085_coeffs.ac1) * 4 + x3) << _bmp085Mode) + 2) >> 2;
00286   x1 = (_bmp085_coeffs.ac3 * b6) >> 13;
00287   x2 = (_bmp085_coeffs.b1 * ((b6 * b6) >> 12)) >> 16;
00288   x3 = ((x1 + x2) + 2) >> 2;
00289   b4 = (_bmp085_coeffs.ac4 * (uint32_t) (x3 + 32768)) >> 15;
00290   b7 = ((uint32_t) (up - b3) * (50000 >> _bmp085Mode));
00291 
00292   if (b7 < 0x80000000)
00293   {
00294     p = (b7 << 1) / b4;
00295   }
00296   else
00297   {
00298     p = (b7 / b4) << 1;
00299   }
00300 
00301   x1 = (p >> 8) * (p >> 8);
00302   x1 = (x1 * 3038) >> 16;
00303   x2 = (-7357 * p) >> 16;
00304   compp = p + ((x1 + x2 + 3791) >> 4);
00305 
00306   /* Assign compensated pressure value */
00307   *pressure = compp;
00308 }
00309 
00310 /**************************************************************************/
00311 /*!
00312     @brief  Reads the temperatures in degrees Celsius
00313 */
00314 /**************************************************************************/
00315 void Adafruit_BMP085_Unified::getTemperature(float *temp)
00316 {
00317   int32_t UT, X1, X2, B5;     // following ds convention
00318   float t;
00319 
00320   readRawTemperature(&UT);
00321 
00322   #if BMP085_USE_DATASHEET_VALS
00323     // use datasheet numbers!
00324     UT = 27898;
00325     _bmp085_coeffs.ac6 = 23153;
00326     _bmp085_coeffs.ac5 = 32757;
00327     _bmp085_coeffs.mc = -8711;
00328     _bmp085_coeffs.md = 2868;
00329   #endif
00330 
00331   B5 = computeB5(UT);
00332   t = (B5+8) >> 4;
00333   t /= 10;
00334 
00335   *temp = t;
00336 }
00337 
00338 /**************************************************************************/
00339 /*!
00340     Calculates the altitude (in meters) from the specified atmospheric
00341     pressure (in hPa), and sea-level pressure (in hPa).
00342 
00343     @param  seaLevel      Sea-level pressure in hPa
00344     @param  atmospheric   Atmospheric pressure in hPa
00345 */
00346 /**************************************************************************/
00347 float Adafruit_BMP085_Unified::pressureToAltitude(float seaLevel, float atmospheric)
00348 {
00349   // Equation taken from BMP180 datasheet (page 16):
00350   //  http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf
00351 
00352   // Note that using the equation from wikipedia can give bad results
00353   // at high altitude.  See this thread for more information:
00354   //  http://forums.adafruit.com/viewtopic.php?f=22&t=58064
00355   float y = 0.1903;
00356   float x;
00357   x = atmospheric / seaLevel;
00358   
00359   return 44330.0 * (1.0 - pow(x, y)); // 0.1903));
00360 }
00361 
00362 /**************************************************************************/
00363 /*!
00364     Calculates the altitude (in meters) from the specified atmospheric
00365     pressure (in hPa), and sea-level pressure (in hPa).  Note that this
00366     function just calls the overload of pressureToAltitude which takes
00367     seaLevel and atmospheric pressure--temperature is ignored.  The original
00368     implementation of this function was based on calculations from Wikipedia
00369     which are not accurate at higher altitudes.  To keep compatibility with
00370     old code this function remains with the same interface, but it calls the
00371     more accurate calculation.
00372 
00373     @param  seaLevel      Sea-level pressure in hPa
00374     @param  atmospheric   Atmospheric pressure in hPa
00375     @param  temp          Temperature in degrees Celsius
00376 */
00377 /**************************************************************************/
00378 float Adafruit_BMP085_Unified::pressureToAltitude(float seaLevel, float atmospheric, float temp)
00379 {
00380   return pressureToAltitude(seaLevel, atmospheric);
00381 }
00382 
00383 /**************************************************************************/
00384 /*!
00385     Calculates the pressure at sea level (in hPa) from the specified altitude 
00386     (in meters), and atmospheric pressure (in hPa).  
00387 
00388     @param  altitude      Altitude in meters
00389     @param  atmospheric   Atmospheric pressure in hPa
00390 */
00391 /**************************************************************************/
00392 float Adafruit_BMP085_Unified::seaLevelForAltitude(float altitude, float atmospheric)
00393 {
00394   // Equation taken from BMP180 datasheet (page 17):
00395   //  http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf
00396 
00397   // Note that using the equation from wikipedia can give bad results
00398   // at high altitude.  See this thread for more information:
00399   //  http://forums.adafruit.com/viewtopic.php?f=22&t=58064
00400   
00401   return atmospheric / pow(1.0 - (altitude/44330.0), 5.255);
00402 }
00403 
00404 /**************************************************************************/
00405 /*!
00406     Calculates the pressure at sea level (in hPa) from the specified altitude 
00407     (in meters), and atmospheric pressure (in hPa).  Note that this
00408     function just calls the overload of seaLevelForAltitude which takes
00409     altitude and atmospheric pressure--temperature is ignored.  The original
00410     implementation of this function was based on calculations from Wikipedia
00411     which are not accurate at higher altitudes.  To keep compatibility with
00412     old code this function remains with the same interface, but it calls the
00413     more accurate calculation.
00414 
00415     @param  altitude      Altitude in meters
00416     @param  atmospheric   Atmospheric pressure in hPa
00417     @param  temp          Temperature in degrees Celsius
00418 */
00419 /**************************************************************************/
00420 float Adafruit_BMP085_Unified::seaLevelForAltitude(float altitude, float atmospheric, float temp)
00421 {
00422   return seaLevelForAltitude(altitude, atmospheric);
00423 }
00424 
00425 /**************************************************************************/
00426 /*!
00427     @brief  Provides the sensor_t data for this sensor
00428 */
00429 /**************************************************************************/
00430 void Adafruit_BMP085_Unified::getSensor(sensor_t *sensor)
00431 {
00432   /* Clear the sensor_t object */
00433   memset(sensor, 0, sizeof(sensor_t));
00434 
00435   /* Insert the sensor name in the fixed length char array */
00436   strncpy (sensor->name, "BMP085", sizeof(sensor->name) - 1);
00437   sensor->name[sizeof(sensor->name)- 1] = 0;
00438   sensor->version     = 1;
00439   sensor->sensor_id   = _sensorID;
00440   sensor->type        = SENSOR_TYPE_PRESSURE;
00441   sensor->min_delay   = 0;
00442   sensor->max_value   = 1100.0F;               // 300..1100 hPa
00443   sensor->min_value   = 300.0F;
00444   sensor->resolution  = 0.01F;                // Datasheet states 0.01 hPa resolution
00445 }
00446 
00447 /**************************************************************************/
00448 /*!
00449     @brief  Reads the sensor and returns the data as a sensors_event_t
00450 */
00451 /**************************************************************************/
00452 bool Adafruit_BMP085_Unified::getEvent(sensors_event_t *event)
00453 {
00454   float pressure_kPa;
00455 
00456   /* Clear the event */
00457   memset(event, 0, sizeof(sensors_event_t));
00458 
00459   event->version   = sizeof(sensors_event_t);
00460   event->sensor_id = _sensorID;
00461   event->type      = SENSOR_TYPE_PRESSURE;
00462   event->timestamp = 0;
00463   getPressure(&pressure_kPa);
00464   event->pressure = pressure_kPa / 100.0F;
00465   
00466   return true;
00467 }