This is a mbed 5.2 Release

Dependencies:   USBDevice

Fork of mbed-os-test by Jerry Bradshaw

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BMP280.cpp Source File

BMP280.cpp

00001 /*******************************************************************************
00002  * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included
00012  * in all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017  * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018  * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020  * OTHER DEALINGS IN THE SOFTWARE.
00021  *
00022  * Except as contained in this notice, the name of Maxim Integrated
00023  * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024  * Products, Inc. Branding Policy.
00025  *
00026  * The mere transfer of this software does not imply any licenses
00027  * of trade secrets, proprietary technology, copyrights, patents,
00028  * trademarks, maskwork rights, or any other form of intellectual
00029  * property whatsoever. Maxim Integrated Products, Inc. retains all
00030  * ownership rights.
00031  *******************************************************************************
00032  */
00033 
00034 
00035 #include "mbed.h"
00036 #include "BMP280.h"
00037 
00038 //******************************************************************************
00039 BMP280::BMP280(PinName sda, PinName scl, int slaveAddress) : 
00040         slaveAddress(slaveAddress) {
00041   i2c = new I2C(sda, scl);
00042   isOwner = true;
00043 }
00044 //******************************************************************************
00045 BMP280::BMP280(I2C *i2c, int slaveAddress) : 
00046         slaveAddress(slaveAddress) {
00047   this->i2c = i2c;
00048   isOwner = false;
00049 
00050   i2c->frequency(100000);
00051   loggingEnabled = 0;
00052   loggingSampleRate = 5;
00053 }
00054 //******************************************************************************
00055 BMP280::~BMP280(void) {
00056   if (isOwner == true) {
00057     delete i2c;
00058   }
00059 }
00060 
00061 //******************************************************************************
00062 int BMP280::init(BMP280::bmp280_osrs_P_t Osrs_p, BMP280::bmp280_osrs_T_t Osrs_t,
00063                  BMP280::bmp280_FILT_t Filter, BMP280::bmp280_MODE_t Mode,
00064                  BMP280::bmp280_TSB_t T_sb)
00065 
00066 {
00067   char reg;
00068   char raw_Tn[6];
00069   char raw_Pn[20];
00070 
00071   // Read all the temp coeffecients from the BMP280 memory. It will be used in
00072   // calculation
00073   reg = 0x88;
00074   if (reg_read(reg, raw_Tn, 6) != 0) {
00075     return -1;
00076   }
00077 
00078   dig_T1 = (((uint16_t)raw_Tn[1]) << 8) | raw_Tn[0];
00079   dig_T2 = (((int16_t)raw_Tn[3]) << 8) | raw_Tn[2];
00080   dig_T3 = (((int16_t)raw_Tn[5]) << 8) | raw_Tn[4];
00081 
00082   // Read all the press coeffecients from the BMP280 memory. It will be used in
00083   // calculation
00084   reg = 0x8E;
00085   if (reg_read(reg, raw_Pn, 20) != 0) {
00086     return -1;
00087   }
00088 
00089   dig_P1 = (((uint16_t)raw_Pn[1]) << 8) | raw_Pn[0];
00090   dig_P2 = (((int16_t)raw_Pn[3]) << 8) | raw_Pn[2];
00091   dig_P3 = (((int16_t)raw_Pn[5]) << 8) | raw_Pn[4];
00092   dig_P4 = (((int16_t)raw_Pn[7]) << 8) | raw_Pn[6];
00093   dig_P5 = (((int16_t)raw_Pn[9]) << 8) | raw_Pn[8];
00094   dig_P6 = (((int16_t)raw_Pn[11]) << 8) | raw_Pn[10];
00095   dig_P7 = (((int16_t)raw_Pn[13]) << 8) | raw_Pn[12];
00096   dig_P8 = (((int16_t)raw_Pn[15]) << 8) | raw_Pn[14];
00097   dig_P9 = (((int16_t)raw_Pn[17]) << 8) | raw_Pn[16];
00098 
00099 
00100   wait(1.0 / 10.0);
00101 
00102   /****/
00103   if (reg_read(BMP280_CTRL_MEAS, &bmp280_ctrl_meas.all, 1) != 0) {
00104     return -1;
00105   }
00106 
00107   bmp280_ctrl_meas.bit.osrs_p = Osrs_p;
00108   bmp280_ctrl_meas.bit.osrs_t = Osrs_t;
00109 
00110   bmp280_ctrl_meas.bit.mode = Mode;
00111 
00112   if (reg_write(BMP280_CTRL_MEAS, bmp280_ctrl_meas.all) != 0) {
00113     return -1;
00114   }
00115 
00116   /****/
00117 
00118   if (reg_read(BMP280_CONFIG, &bmp280_config.all, 1) != 0) {
00119     return -1;
00120   }
00121 
00122   bmp280_config.bit.filter = Filter;
00123 
00124   if (Mode == 0b11) {
00125     bmp280_config.bit.t_sb = T_sb;
00126   }
00127 
00128   if (reg_write(BMP280_CONFIG, bmp280_config.all) != 0) {
00129     return -1;
00130   }
00131 
00132   return 0;
00133 }
00134 
00135 //******************************************************************************
00136 float BMP280::ToFahrenheit(float temperature) {
00137   return temperature * 9 / 5 + 32;
00138 }
00139 
00140 //******************************************************************************
00141 int BMP280::ReadCompDataRaw2(char *bmp280_rawData) {
00142   int i;
00143   char data[6];
00144   float temp;
00145   float pressure;
00146   int iPressure;
00147   char str[32];
00148   ReadCompDataRaw(data);
00149   ToFloat(data, &temp, &pressure);
00150   iPressure = (int)pressure;
00151   sprintf(str, "%d  ", iPressure);
00152   for (i = 0; i < 6; i++) {
00153     bmp280_rawData[i] = str[i];
00154   }
00155   return 0;
00156 }
00157 
00158 //******************************************************************************
00159 int BMP280::ReadCompDataRaw(char *bmp280_rawData) {
00160   char reg;
00161   char rxbytes;
00162 
00163   reg = BMP280_PRESS_MSB;
00164   rxbytes = 6;
00165 
00166   if (reg_read(reg, bmp280_rawData, rxbytes) != 0) {
00167     return -1;
00168   }
00169   return 0;
00170 }
00171 
00172 //******************************************************************************
00173 void BMP280::ToFloat(char *bmp280_rawData, float *Temp_degC, float *Press_Pa) {
00174   bmp280_rawPress = (uint32_t)(bmp280_rawData[0] << 12) |
00175                     (bmp280_rawData[1] << 4) | (bmp280_rawData[2] >> 4);
00176 
00177   bmp280_rawTemp = (uint32_t)(bmp280_rawData[3] << 12) |
00178                    (bmp280_rawData[4] << 4) | (bmp280_rawData[5] >> 4);
00179 
00180   *Temp_degC = compensate_T_float(bmp280_rawTemp);
00181   *Press_Pa = compensate_P_float(bmp280_rawPress);
00182 }
00183 
00184 //******************************************************************************
00185 int BMP280::ReadCompData(float *Temp_degC, float *Press_Pa) {
00186   char bmp280_rawData[6];
00187 
00188   if (ReadCompDataRaw(bmp280_rawData) != 0) {
00189     return -1;
00190   }
00191   ToFloat(bmp280_rawData, Temp_degC, Press_Pa);
00192   return 0;
00193 }
00194 
00195 //******************************************************************************
00196 int BMP280::reg_write(char reg, char value) {
00197   int result;
00198   char cmdData[2] = {(char)reg, value};
00199   result = i2c->write(slaveAddress, cmdData, 2);
00200   if (result != 0)
00201     return -1;
00202   return 0;
00203 }
00204 
00205 //******************************************************************************
00206 int BMP280::reg_read(char reg, char *value, char number) {
00207   int result;
00208   char cmdData[1] = {(char)reg};
00209 
00210   result = i2c->write(slaveAddress, cmdData, 1);
00211   if (result != 0)
00212     return -1;
00213   result = i2c->read(slaveAddress, value, number);
00214   if (result != 0)
00215     return -1;
00216   return 0;
00217 }
00218 
00219 //******************************************************************************
00220 int BMP280::Sleep(void) {
00221   // Configure the I2C interface
00222 
00223   if (reg_read(BMP280_CTRL_MEAS, &bmp280_ctrl_meas.all, 1) != 0) {
00224     return -1;
00225   }
00226   bmp280_ctrl_meas.bit.mode = 0b00; // put everything to sleep mode...
00227 
00228   if (reg_write(BMP280_CTRL_MEAS, bmp280_ctrl_meas.all) != 0) {
00229     return -1;
00230   }
00231   return 0;
00232 }
00233 
00234 //******************************************************************************
00235 void BMP280::Reset(void) {
00236   reg_write(BMP280_RESET, 0xB6); // Initiate a Soft Reset
00237 }
00238 
00239 //******************************************************************************
00240 int BMP280::Detect(void) {
00241   if (reg_read(BMP280_ID, &bmp280_id, 1) != 0) {
00242     return -1;
00243   }
00244 
00245   if (bmp280_id == 0x58) {
00246     return 1;
00247   }
00248   return 0;
00249 }
00250 
00251 //******************************************************************************
00252 int BMP280::ReadId(void) {
00253   if (reg_read(BMP280_ID, &bmp280_id, 1) != 0) {
00254     return -1;
00255   }
00256   return bmp280_id;
00257 }
00258 
00259 //******************************************************************************
00260 float BMP280::compensate_T_float(int32_t adc_T) {
00261   float var1, var2, T;
00262   var1 =
00263       (((float)adc_T) / 16384.0 - ((float)dig_T1) / 1024.0) * ((float)dig_T2);
00264 
00265   var2 = ((((float)adc_T) / 131072.0 - ((float)dig_T1) / 8192.0) *
00266           (((float)adc_T) / 131072.0 - ((float)dig_T1) / 8192.0)) *
00267          ((float)dig_T3);
00268 
00269   t_fine = (int32_t)(var1 + var2);
00270 
00271   T = (var1 + var2) / 5120.0;
00272 
00273   return T;
00274 }
00275 
00276 //******************************************************************************
00277 float BMP280::compensate_P_float(int32_t adc_P) {
00278   float var1, var2, p;
00279   var1 = ((float)t_fine / 2.0) - 64000.0;
00280   var2 = var1 * var1 * ((float)dig_P6) / 32768.0;
00281   var2 = var2 + var1 * ((float)dig_P5) * 2.0;
00282   var2 = (var2 / 4.0) + (((float)dig_P4) * 65536.0);
00283   var1 = (((float)dig_P3) * var1 * var1 / 524288.0 + ((float)dig_P2) * var1) / 524288.0;
00284   var1 = (1.0 + var1 / 32768.0) * ((float)dig_P1);
00285   if (var1 == 0.0) {
00286     return 0; // avoid exception caused by division by zero
00287   }
00288   p = 1048576.0 - (float)adc_P;
00289   p = (p - (var2 / 4096.0)) * 6250.0 / var1;
00290   var1 = ((float)dig_P9) * p * p / 2147483648.0;
00291   var2 = p * ((float)dig_P8) / 32768.0;
00292   p = p + (var1 + var2 + ((float)dig_P7)) / 16.0;
00293   return p;
00294 }