Multi environmental sensor

My version of the bme280 pressure, humidity and temperature sensor

Revision:
3:96075bee19f0
Parent:
0:40b4ebf843c6
Child:
2:bb91307d5c4d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bme280.h	Fri Apr 22 14:25:55 2016 +0000
@@ -0,0 +1,331 @@
+#ifndef BME280_H
+#define BME280_H
+
+#include "mbed.h"
+
+#if(defined(TARGET_KL25Z) || defined(TARGET_K64F))
+
+//    #define BME280i2cLOWLEVEL   1           //if the use of low-level I2C routines is needed
+//    #warning "BME280 using low level I2C routines"
+    
+#endif
+
+
+#define SEA_PRESS               1013.25             //default sea level pressure level in mb
+//#define KNOWNALT                327.0               //default known altitude in feet
+#define METERS_FEET             3.2808399
+#define FEET_METERS             0.3048006
+#define MB_INHG_DOUBLE          0.02952998751
+#define INHG_MB_DOUBLE          33.8638815767
+#define DEGC_DEGF_FLOAT         9.0 / 5.0 + 32.0
+#define DEGC_DEGF_INT           9 / 5 + 32
+
+#define BME280_WADDR                        0xEC  //i2c address write mode (CSBpin = 0);
+#define BME280_RADDR                        0xED  //i2c address read mode
+
+#define BME280_CHIP_ID_REG                  0xD0  //Chip ID Register 
+#define BME280_CAL_DATA_START_1             0x88  //Calibration data parameters
+#define BME280_CAL_DATA_START_2             0xE1  //More calibration data parameters
+#define BME280_RST_REG                      0xE0  //Softreset Register 
+#define BME280_STAT_REG                     0xF3  //Status Register 
+#define BME280_CTRL_MEAS_REG                0xF4  //Ctrl Measure Register 
+#define BME280_CTRL_HUMIDITY_REG            0xF2  //Ctrl Humidity Register
+#define BME280_CONFIG_REG                   0xF5  //Configuration Register 
+#define BME280_PRESSURE_MSB_REG             0xF7  //Pressure MSB Register 
+#define BME280_PRESSURE_LSB_REG             0xF8  //Pressure LSB Register 
+#define BME280_PRESSURE_XLSB_REG            0xF9  //Pressure XLSB Register 
+#define BME280_TEMPERATURE_MSB_REG          0xFA  //Temperature MSB Reg 
+#define BME280_TEMPERATURE_LSB_REG          0xFB  //Temperature LSB Reg 
+#define BME280_TEMPERATURE_XLSB_REG         0xFC  //Temperature XLSB Reg 
+#define BME280_HUMIDITY_MSB_REG             0xFD  //Humidity MSB Reg 
+#define BME280_HUMIDITY_LSB_REG             0xFE  //Humidity LSB Reg 
+
+// Status register bits
+#define BME280_STATUS_BUSY                  0x08
+#define BME280_STATUS_UNKNOWN               0x04
+#define BME280_STATUS_IMUPDATE              0x01
+
+#define BME280_RESET_VALUE                  0xB6
+
+// Config register equates
+#define BME280_OVERSAMPLE_SKIP              0
+#define BME280_OVERSAMPLE_x1                1
+#define BME280_OVERSAMPLE_x2                2
+#define BME280_OVERSAMPLE_x4                3
+#define BME280_OVERSAMPLE_x8                4
+#define BME280_OVERSAMPLE_x16               5
+
+#define BME280_TEMP_OVERSAMPLE              BME280_OVERSAMPLE_x1 //was x2 
+#define BME280_PRESS_OVERSAMPLE             BME280_OVERSAMPLE_x1 //was x4
+#define BME280_HUM_OVERSAMPLE               BME280_OVERSAMPLE_x1 //was x2
+
+#define BME280_MODE_SLEEP                   0
+#define BME280_MODE_FORCED                  1
+#define BME280_MODE_NORMAL                  3
+
+#define BME280_STANDBY_0m5                  0
+#define BME280_STANDBY_62m5                 1
+#define BME280_STANDBY_125m                 2
+#define BME280_STANDBY_250m                 3
+#define BME280_STANDBY_500m                 4
+#define BME280_STANDBY_1000m                5
+#define BME280_STANDBY_10m                  6
+#define BME280_STANDBY_20m                  7
+
+#define BME280_FILTER_OFF                   0
+#define BME280_FILTER_2                     1
+#define BME280_FILTER_4                     2
+#define BME280_FILTER_8                     3
+#define BME280_FILTER_16                    4
+
+//osrs_t(7..5), osrs_p(4..2), mode(1..0)
+#define BME280_CTRL_MEAS_REG_DATA           ((BME280_TEMP_OVERSAMPLE << 5) | (BME280_PRESS_OVERSAMPLE << 2) | BME280_MODE_NORMAL)
+//0(7..3), osrs_h(2..0)
+#define BME280_CTRL_HUMIDITY_REG_DATA       ((BME280_HUM_OVERSAMPLE))
+//sb(7..5), filter(4..2), 0(1), spl3w_en(0)
+#define BME280_CONFIG_REG_DATA              ((BME280_STANDBY_1000m << 5) | (BME280_FILTER_OFF << 2)) //was FILTER_4
+
+//Until it is understood why data cannot be raed out of BME280 right after BUSY goes false, the 
+//defines below introduce a variable delay in main(), based on sb bits used.
+// example: wait_ms(BME280_MAIN_WAIT);  must be put between pth.getBmeRawData(bmed_struct); accesses 
+#if   ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_0m5)
+#define BME280_MAIN_WAIT                           100
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_62m5)
+#define BME280_MAIN_WAIT                           60
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_125m)
+#define BME280_MAIN_WAIT                           120
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_250m)
+#define BME280_MAIN_WAIT                           240
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_500m)
+#define BME280_MAIN_WAIT                           100
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_1000m)
+#define BME280_MAIN_WAIT                           500
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_10m)
+#define BME280_MAIN_WAIT                           50
+#elif ((BME280_CONFIG_REG_DATA >> 5) == BME280_STANDBY_20m)
+#define BME280_MAIN_WAIT                           59
+#endif
+
+
+    /** 
+     * Create bme280 controller class
+     *
+     * @param bme280 class
+     *
+     */
+class bme280 {
+
+public:
+
+    /** 
+     * Public data structure for CME280 correction values.
+     * 
+    **/
+    typedef struct {
+        uint16_t dig_T1;    /*!< calibration parameter -> Temp T1 */  
+        int16_t  dig_T2;    /*!< calibration parameter -> Temp T2 */  
+        int16_t  dig_T3;    /*!< calibration parameter -> Temp T3 */
+          
+        uint16_t dig_P1;    /*!< calibration parameter -> Press P1 */  
+        int16_t  dig_P2;    /*!< calibration parameter -> Press P2 */  
+        int16_t  dig_P3;    /*!< calibration parameter -> Press P3 */  
+        int16_t  dig_P4;    /*!< calibration parameter -> Press P4 */  
+        int16_t  dig_P5;    /*!< calibration parameter -> Press P5 */  
+        int16_t  dig_P6;    /*!< calibration parameter -> Press P6 */  
+        int16_t  dig_P7;    /*!< calibration parameter -> Press P7 */  
+        int16_t  dig_P8;    /*!< calibration parameter -> Press P8 */  
+        int16_t  dig_P9;    /*!< calibration parameter -> Press P9 */  
+    
+        uint8_t  dig_H1;    /*!< calibration parameter -> Hum H1 */  
+        int16_t  dig_H2;    /*!< calibration parameter -> Hum H2 */  
+        uint8_t  dig_H3;    /*!< calibration parameter -> Hum H3 */  
+        int16_t  dig_H4;    /*!< calibration parameter -> Hum H4 */  
+        int16_t  dig_H5;    /*!< calibration parameter -> Hum H5 */  
+        int8_t   dig_H6;    /*!< calibration parameter -> Hum H6 */  
+    
+        uint32_t t_fine;    /*!< scratch T_FINE */
+         
+        uint8_t  ctrl_hum_reg;  /*!< config -> hum */
+        uint8_t  ctrl_meas_reg; /*!< config -> temp press mode */
+        uint8_t  config_reg;    /*!< config -> delay filter spi3w */ 
+    } bme_cal;
+         
+    /** 
+     * Public data structure to obtain CME280 data.
+     * 
+    **/
+    typedef struct {
+        int raw_temp;       /*!< raw temperature reading, 20 bits */
+        int raw_baro;       /*!< raw pressure reading, 20 bits */
+        int raw_hum;        /*!< raw humidity reading, 16 bits */
+        int corr_temp;      /*!< corrected temperature as integer*/
+        int64_t corr_baro;  /*!< corrected pressure as integer */
+        uint32_t corr_hum;  /*!< corrected humidity as integer */
+        double bme_temp;    /*!< corrected temperature as a float */
+        double bme_baro;    /*!< corrected pressure as a float */
+        double bme_hum;     /*!< corrected humidity as a float */
+    } bme_data;
+
+    /** 
+     * Public enum for selecting polarity of I2C address pin.
+     *
+     * - CSB pin = 0, user set I2C address to 0xEC
+     * - CSB pin = 1, user set I2C address to 0xEE
+     * 
+    **/    
+    enum CSBpolarity {
+        CSBpin_0,  //CSB pin is grounded, I2C address is 0xEC and 0xED
+        CSBpin_1,  //CSB pin is tied to Vdd, I2C address is 0xEE and 0xEF
+    };
+
+    /** 
+     * Create a BME280 object using the specified I2C object
+     *   - User defined use of the CSB pin
+     *   - CSB pin = 0, user set I2C address to 0xEC
+     *   - CSB pin = 1, user set I2C address to 0xEE 
+     * @param sda - mbed I2C interface pin
+     * @param scl - mbed I2C interface pin
+     * @param bme280::CSBpin_0 - CSB pin tied to ground
+     * @param bme280::CSBpin_1 - CSB pin tied to VDD
+     */
+    bme280(PinName sda, PinName scl, CSBpolarity CSBpin);
+
+    /**
+     * Destructor
+     *
+     * @param --none--
+     */
+    ~bme280();
+
+    /** 
+     * Get BME280 ID Register
+     * 
+     * @param --none--
+     *
+     * @return ID Register value
+    */ 
+    uint8_t getBmeID();
+
+    /** 
+     * Soft Reset the BME280
+     * 
+     * @param --none--
+     *
+     * @return ACK/NACK status
+    */
+    uint8_t resetBme();
+    
+    /** 
+     * Get BME280 Status Register
+     * 
+     * @param --none--
+     *
+     * @return Status Register value
+    */ 
+    uint8_t getBmeStatus();
+
+    /** 
+     * Get BME280 Raw Data
+     * 
+     * @param pointer to struct bme_data
+     *
+     * @return Status Register value. Pass-thru from getBmeStatus()
+     * @return raw data put into struct bme_data
+    */ 
+    uint8_t getBmeRawData(bme_data& bmed);
+
+    /** 
+     * Convert BME280 Raw Data using integer based routines
+     * 
+     * @param pointer to struct bme_data
+     * @param pointer to struct bme_cal
+     *
+     * @return converted data put into struct bme_data
+    */ 
+    void convertBmeRawData(bme_data& bmed, bme_cal& bmec);
+
+    /** 
+     * Convert BME280 Raw Data using all floating routines
+     * 
+     * @param pointer to struct bme_data
+     * @param pointer to struct bme_cal
+     *
+     * @return converted data put into struct bme_data
+    */ 
+    void convertBmeRawDataFloat(bme_data& bmed, bme_cal& bmec);
+    
+    /** 
+     * Initialize the BME280. 
+     * - Sets up the command registers
+     * - Loads up the calibration data
+     * 
+     * @param pointer to struct bme_data
+     *
+     * @return 0
+    */  
+    uint8_t initBme(bme_cal& bmec);
+    
+    /** 
+     * Corrected altitude (feet) from barometer at seal level (mB)
+     * 
+     * @param pointer to struct bme_data
+     * @param pressure at sea level (in mB)
+     *
+     * @return corrected altimeter (in feet)
+    */ 
+    float getAltitudeFT(bme_data& bmed, float sea_pressure);
+    
+    /** 
+     * Altitude corrected barometer (feet)
+     * 
+     * @param pointer to struct bme_data
+     * @param known_alt in feet
+     *
+     * @return corrected barometer
+    */
+    float getSeaLevelBaroFT(bme_data& bmed, float known_alt);
+    
+    /** 
+     * Altitude corrected barometer (meters)
+     * 
+     * @param pointer to struct bme_data
+     * @param known_alt in meters
+     *
+     * @return corrected barometer
+    */    
+    float getSeaLevelBaroM(bme_data& bmed, float known_alt);
+
+    /** 
+     * Return the dew point based on T & H. Slower but more accurate.
+     * 
+     * @param pointer to struct bme_data
+     *
+     * @return dew point in degrees C
+    */  
+    float getDewPt(bme_data& bmed);
+
+    /** 
+     * Return the dew point based on T & H. Faster but less accurate.
+     * 
+     * @param pointer to struct bme_data
+     *
+     * @return dew point in degrees C
+    */ 
+    float getDewPtFast(bme_data& bmed);
+    
+private:
+#if not defined  BMEi2cLOWLEVEL
+    char bme280Buffer[32];
+#endif
+    char i2cWAddr;
+    char i2cRAddr;
+    int _i2c_start(uint8_t i2c_addr);
+    void _i2c_stop();
+    uint8_t _i2c_write(uint8_t data);
+    uint8_t _i2c_readACK();
+    uint8_t _i2c_readNACK();
+  
+protected:
+    I2C     _i2c;
+}; 
+#endif
\ No newline at end of file