My trial of BME280 library, tested with Adafruit BME280 module

Dependents:   test_BME280

Files at this revision

API Documentation at this revision

Comitter:
Rhyme
Date:
Wed May 10 09:11:01 2017 +0000
Parent:
0:5ace1cc7a9f2
Commit message:
First working version

Changed in this revision

BME280.cpp Show annotated file Show diff for this revision Revisions of this file
BME280.h Show annotated file Show diff for this revision Revisions of this file
diff -r 5ace1cc7a9f2 -r 7b525853bad0 BME280.cpp
--- a/BME280.cpp	Tue May 09 06:32:36 2017 +0000
+++ b/BME280.cpp	Wed May 10 09:11:01 2017 +0000
@@ -54,7 +54,9 @@
 #define REG_H2_LSB 0xE1
 #define REG_H2_MSB 0xE2
 #define REG_H3     0xE3
-
+#define REG_H4     0xE4
+#define REG_H5     0xE5
+#define REG_H6     0xE7
 
 /*
  * Register description
@@ -129,6 +131,28 @@
  * 0xFD bit[7:0] hum_msb[7:0]    MSB part uh[15:8]
  * 0xFE bit[7:0] hum_lsb[7:0]    LSB part  uh[7:0]
  */
+ /*
+  * Compensation parameter storage, naming and data type
+  * Register addr,  Register content,    Data type
+  * 0x88/0x89,      dig_T1[7:0]/[15:8],  unsigned short
+  * 0x8A/0x8B,      dig_T2[7:0]/[15:8],    signed short
+  * 0x8C/0x8D,      dig_T3[7:0]/[15:8],    signed short
+  * 0x8E/0x8F,      dig_P1[7:0]/[15:8],  unsigned short
+  * 0x90/0x91,      dig_P2[7:0]/[15:8],    signed short
+  * 0x92/0x93,      dig_P3[7:0]/[15:8],    signed short
+  * 0x94/0x95,      dig_P4[7:0]/[15:8],    signed short
+  * 0x96/0x97,      dig_P5[7:0]/[15:8],    signed short
+  * 0x98/0x99,      dig_P6[7:0]/[15:8],    signed short
+  * 0x9A/0x9B,      dig_P7[7:0]/[15:8],    signed short
+  * 0x9C/0x9D,      dig_P8[7:0]/[15:8],    signed short
+  * 0x9E/0x9F,      dig_P9[7:0]/[15:8],    signed short
+  * 0xA1,           dig_H1[7:0],         unsigned char
+  * 0xE1/0xE2,      dig_H2[7:0]/[15:8],    signed short
+  * 0xE3,           dig_H3[7:0],         unsigned char
+  * 0xE4/0xE5[3:0], dig_H4[11:4]/[3:0]  signed short
+  * 0xE5[7:4]/0xE6, dig_H5[3:0]/[11:4]  signed short
+  * 0xE7,           dig_H6[7:0],        signed char
+  */
 
 void BME280::init(void)
 {
@@ -140,12 +164,10 @@
     
     data[0] = REG_CTRL_MEAS ;
     data[1] = (0x3 << 5) /* temp oversample x4 */
-            | (0x3 << 3) /* pres oversample x4 */
+            | (0x3 << 2) /* pres oversample x4 */
             | (0x00)      /* Sleep Mode */
             ;
     writeRegs(data, 2) ;
-readRegs(REG_CTRL_MEAS, data, 1) ;
-printf("ctrl_meas: 0x%02X\n", data[0]) ;
     
     data[0] = REG_CONFIG ;
     data[1] = (0x4 << 5) /* standby 500ms */
@@ -179,10 +201,19 @@
     /* read dig_H regs */
     readRegs(REG_H1, data, 1) ;
     dig_H1 = data[0] ;
-    readRegs(REG_H2_LSB, data, 3) ;
+    readRegs(REG_H2_LSB, data, 2) ;
     dig_H2 = (data[1] << 8) | data[0] ;
-    dig_H3 = data[2] ;
+    readRegs(REG_H3, data, 1) ;
+    dig_H3 = data[0] ;
+    readRegs(REG_H4, data, 3) ; 
+    dig_H4 = (data[0] << 4) | (data[1] & 0x0F) ;
+    dig_H5 = (data[2] << 4) | (data[1] >> 4) ;  
+    readRegs(REG_H6, data, 1) ;
+    dig_H6 = data[0] ;
 // printf("dig_H1:0x%04X, dig_H2:0x%04X, dig_H3:0x%04X\n",dig_H1, dig_H2, dig_H3) ;    
+// printf("dig_H4:0x%04X, dig_H5:0x%04X, dig_H6:0x%04X\n",dig_H4, dig_H5, dig_H6) ;   
+ 
+    trigger() ; /* dummy measure */
 }
 
 BME280::BME280(PinName sda, PinName scl, int addr) 
@@ -199,11 +230,6 @@
     m_cs = new DigitalOut(cs, 1) ;
     m_spi = new SPI(mosi, miso, sck) ;
     m_spi->format(8, 3) ;
-#if 0
-#if defined (TARGET_KL25Z)
-    *((uint8_t *)0x40076000) |= 0x01 ; /* lsb first  */
-#endif
-#endif
     m_i2c = 0 ;
     m_addr = 0 ;
     init() ;
@@ -235,7 +261,6 @@
     *m_cs = 0 ;
     m_spi->write(addr | 0x80) ;
     for (int i = 0 ; i < len ; i++ ) {    
- //     m_spi->write((addr+i)|0x80) ;  // spacify address to read
       data[i] = m_spi->write((addr+i)|0x80) ; 
     } 
     m_spi->write(0x00) ; // to terminate read mode
@@ -245,7 +270,6 @@
 void BME280::spi_writeRegs(uint8_t * data, int len) {
    *m_cs = 0 ;
    for (int i = 0 ; i < len-1 ; i++ ) {
-// printf("writing 0x%02X := 0x%02X\n", (data[0]+i)^0x80, data[i+1]) ;
       m_spi->write((data[0]+i)^0x80) ; /* register address */
       m_spi->write(data[i+1]) ; /* data to write */
 
@@ -288,7 +312,6 @@
     data[1] = (data[1] & 0xFC) /* keep oversampling */
             | (0x2)      /* Forced Mode */
             ;
-//    data[1] = 0x38 | 0x02 ;
     writeRegs(data, 2) ;
 }
 
@@ -306,98 +329,74 @@
     return(data[0]) ;
 }
 
-void BME280::readData(uint8_t data[]) 
-{
-    readRegs(REG_PRESS_MSB, data, 8) ;
-printf("Data Read: ") ;    
-for(int i = 0 ; i < 8 ; i++ ) {
-    printf("%02X ", data[i]) ;
-}
-printf("\n") ;
-}
-
-float BME280::getTemperature(uint8_t data[]) 
+float BME280::getTemperature(void) 
 {
-    uint32_t temp_raw;
-    float tempf;
-//    uint8_t data[3];
- 
-//    readRegs(REG_TEMP_MSB, data, 3) ;
- 
-    temp_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
- 
-    int32_t temp;
- 
-    temp =
-        (((((temp_raw >> 3) - (dig_T1 << 1))) * dig_T2) >> 11) +
-        ((((((temp_raw >> 4) - dig_T1) * ((temp_raw >> 4) - dig_T1)) >> 12) * dig_T3) >> 14);
- 
-    t_fine = temp;
-    temp = (temp * 5 + 128) >> 8;
-    tempf = (float)temp;
- 
+    float tempf ;
+    uint8_t data[3] ;
+    BME280_S32_t var1, var2, T ;
+    BME280_S32_t adc_T ;
+    
+    readRegs(REG_TEMP_MSB, data, 3) ;
+    adc_T = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
+    
+    var1 = ((((adc_T>>3) - ((BME280_S32_t)dig_T1<<1))) * ((BME280_S32_t)dig_T2)) >> 11;
+    var2 = (((((adc_T>>4) - ((BME280_S32_t)dig_T1)) * ((adc_T>>4) - ((BME280_S32_t)dig_T1))) >> 12) *
+        ((BME280_S32_t)dig_T3)) >> 14;
+    t_fine = var1 + var2;
+    T = (t_fine * 5 + 128) >> 8;
+    
+    tempf = (float)T;
     return (tempf/100.0f);
-    
 }
 
-float BME280::getHumidity(uint8_t data[]) 
+float BME280::getPressure(void) 
 {
-    uint32_t hum_raw;
-    float humf;
-//    uint8_t data[2];
+    BME280_S32_t adc_P ;
+    BME280_S64_t var1, var2, p ;
+    float pressf;
+    uint8_t data[3];
  
-//    readRegs(REG_HUM_MSB, data, 2) ;
- 
-    hum_raw = (data[0] << 8) | data[1];
- 
-    int32_t v_x1;
+    readRegs(REG_PRESS_MSB, data, 3) ;
+    adc_P = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
  
-    v_x1 = t_fine - 76800;
-    v_x1 =  (((((hum_raw << 14) -(((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * v_x1)) +
-               ((int32_t)16384)) >> 15) * (((((((v_x1 * (int32_t)dig_H6) >> 10) *
-                                            (((v_x1 * ((int32_t)dig_H3)) >> 11) + 32768)) >> 10) + 2097152) *
-                                            (int32_t)dig_H2 + 8192) >> 14));
-    v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * (int32_t)dig_H1) >> 4));
-    v_x1 = (v_x1 < 0 ? 0 : v_x1);
-    v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
+    var1 = ((BME280_S64_t)t_fine) - 128000;
+    var2 = var1 * var1 * (BME280_S64_t)dig_P6;
+    var2 = var2 + ((var1*(BME280_S64_t)dig_P5)<<17);
+    var2 = var2 + (((BME280_S64_t)dig_P4)<<35);
+    var1 = ((var1 * var1 * (BME280_S64_t)dig_P3)>>8) + ((var1 * (BME280_S64_t)dig_P2)<<12);
+    var1 = (((((BME280_S64_t)1)<<47)+var1))*((BME280_S64_t)dig_P1)>>33;
+    if (var1 == 0) {
+        return 0; // avoid exception caused by division by zero
+    }
+    p = 1048576-adc_P;
+    p = (((p<<31)-var2)*3125)/var1;
+    var1 = (((BME280_S64_t)dig_P9) * (p>>13) * (p>>13)) >> 25;
+    var2 = (((BME280_S64_t)dig_P8) * p) >> 19;
+    p = ((p + var1 + var2) >> 8) + (((BME280_S64_t)dig_P7)<<4);
  
-    humf = (float)(v_x1 >> 12);
- 
-    return (humf/1024.0f);
+    pressf = (float)(p >> 8) ;
+    return (pressf/100.0f);
 }
 
-float BME280::getPressure(uint8_t data[]) 
+float BME280::getHumidity(void) 
 {
-    uint32_t press_raw;
-    float pressf;
-//    uint8_t data[3];
+    BME280_S32_t adc_H;
+    BME280_S32_t v_x1_u32r ;
+    float humf;
+    uint8_t data[2];
  
-//    readRegs(REG_PRESS_MSB, data, 3) ;
- 
-    press_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
- 
-    int32_t var1, var2;
-    uint32_t press;
+    readRegs(REG_HUM_MSB, data, 2) ;
+    adc_H = (data[0] << 8) | data[1];
  
-    var1 = (t_fine >> 1) - 64000;
-    var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * dig_P6;
-    var2 = var2 + ((var1 * dig_P5) << 1);
-    var2 = (var2 >> 2) + (dig_P4 << 16);
-    var1 = (((dig_P3 * (((var1 >> 2)*(var1 >> 2)) >> 13)) >> 3) + ((dig_P2 * var1) >> 1)) >> 18;
-    var1 = ((32768 + var1) * dig_P1) >> 15;
-    if (var1 == 0) {
-        return 0;
-    }
-    press = (((1048576 - press_raw) - (var2 >> 12))) * 3125;
-    if(press < 0x80000000) {
-        press = (press << 1) / var1;
-    } else {
-        press = (press / var1) * 2;
-    }
-    var1 = ((int32_t)dig_P9 * ((int32_t)(((press >> 3) * (press >> 3)) >> 13))) >> 12;
-    var2 = (((int32_t)(press >> 2)) * (int32_t)dig_P8) >> 13;
-    press = (press + ((var1 + var2 + dig_P7) >> 4));
- 
-    pressf = (float)press;
-    return (pressf/100.0f);
+    v_x1_u32r = (t_fine - ((BME280_S32_t)76800));
+    v_x1_u32r = (((((adc_H << 14) - (((BME280_S32_t)dig_H4) << 20) - (((BME280_S32_t)dig_H5) * v_x1_u32r)) +
+        ((BME280_S32_t)16384)) >> 15) * (((((((v_x1_u32r * ((BME280_S32_t)dig_H6)) >> 10) * (((v_x1_u32r *
+        ((BME280_S32_t)dig_H3)) >> 11) + ((BME280_S32_t)32768))) >> 10) + ((BME280_S32_t)2097152)) *
+        ((BME280_S32_t)dig_H2) + 8192) >> 14));
+    v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((BME280_S32_t)dig_H1)) >> 4));
+    v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
+    v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
+    humf = (float)(v_x1_u32r >> 12) ;
+
+    return (humf/1024.0f);
 }
\ No newline at end of file
diff -r 5ace1cc7a9f2 -r 7b525853bad0 BME280.h
--- a/BME280.h	Tue May 09 06:32:36 2017 +0000
+++ b/BME280.h	Wed May 10 09:11:01 2017 +0000
@@ -2,18 +2,24 @@
 #define _BME280_H_
 #include "mbed.h"
 
+typedef int32_t  BME280_S32_t ;
+typedef uint32_t BME280_U32_t ;
+typedef long long signed int BME280_S64_t ;
+
+#if 0
 #define BME280_U32_t uint32_t
 #define BME280_S32_t int32_t
 #define BME280_S64_t int64_t
+#endif 
 
 /**
  * BME280 Environmental sensor
  *
- * Note: Interface selection is done by the value of CSB (chip select)
- * if CSB is pulled-up, I2C interface is active.
- * if CSB is pulled-down, SPI interface is active.
- * After CSB has been pulled down once (regardless of whether any clock cycle occurred)
- * the I2C interface is disabled until the next power-on-reset.
+ * @note Note: Interface selection is done by the value of CSB (chip select)
+ * @note if CSB is pulled-up, I2C interface is active.
+ * @note if CSB is pulled-down, SPI interface is active.
+ * @note After CSB has been pulled down once (regardless of whether any clock cycle occurred)
+ * @note the I2C interface is disabled until the next power-on-reset.
  */
 
 class BME280
@@ -38,20 +44,74 @@
   */
 BME280(PinName sck, PinName miso, PinName mosi, PinName cs) ;
 
+/**
+ * BME280 destructor
+ */
 ~BME280() ;
 
+/** 
+ * software reset
+ *
+ * @param none
+ * @returns none
+ */
 void reset(void) ; 
+
+/**
+ * initialization
+ *
+ * @param none
+ * @reurns none
+ */
 void init(void) ;
-void trigger(void) ; /* forced mode */
+
+/**
+ * trigger for one-shot measure
+ *
+ * @param none
+ * @returns none
+ */
+void trigger(void) ; 
+
+/**
+ * check status register for the device activity
+ *
+ * @param none
+ * @returns uint8_t measuring (0x08) or in NVM udpate (0x01)
+ */
 uint8_t  busy(void) ;
 
+/**
+ * get device ID
+ *
+ * @param none
+ * @returns uint8_t ID for BME280 0x60
+ */
 uint8_t getID(void) ;
 
-void readData(uint8_t data[]) ;
-  
-float getTemperature(uint8_t data[]) ;
-float getHumidity(uint8_t data[]) ;
-float getPressure(uint8_t data[]) ;
+/**
+ * get Temperature
+ *
+ * @param none
+ * @returns float temperature in degree Celsious
+ */
+float getTemperature(void) ;
+
+/**
+ * get Humidity
+ *
+ * @param none
+ * @returns float humidity in %
+ */
+float getHumidity(void) ;
+
+/**
+ * get Pressure
+ *
+ * @param none
+ * @returns float pressure in hPa
+ */
+float getPressure(void) ;
 
 private:
   SPI *m_spi ;
@@ -60,12 +120,24 @@
   int m_addr ;
   BME280_S32_t t_fine ;
   
-  uint16_t dig_T1, dig_T2, dig_T3 ;
-  uint16_t dig_P1, dig_P2, dig_P3 ; 
-  uint16_t dig_P4, dig_P5, dig_P6 ; 
-  uint16_t dig_P7, dig_P8, dig_P9 ;
-  uint16_t dig_H1, dig_H2, dig_H3 ;
-  uint16_t dig_H4, dig_H5, dig_H6 ;
+  uint16_t dig_T1 ;
+  int16_t  dig_T2 ;
+  int16_t  dig_T3 ;
+  uint16_t dig_P1 ; 
+  int16_t  dig_P2 ;
+  int16_t  dig_P3 ; 
+  int16_t  dig_P4 ;
+  int16_t  dig_P5 ;
+  int16_t  dig_P6 ; 
+  int16_t  dig_P7 ;
+  int16_t  dig_P8 ;
+  int16_t  dig_P9 ;
+  uint8_t  dig_H1 ;
+  int16_t  dig_H2 ;
+  uint8_t  dig_H3 ;
+  int16_t  dig_H4 ;
+  int16_t  dig_H5 ; 
+  int8_t   dig_H6 ;
 
   void i2c_readRegs(int addr, uint8_t *data, int len) ;
   void i2c_writeRegs(uint8_t *data, int len) ;