Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    BME280’s RH over 100%

    BME280’s RH over 100%

    mdf-terra
    Occasional Visitor

    We are using several BME280 are are getting values of over 100% RH when the temperatures is <0C on one of the sensors. It seems to quickly spike up, but then maintains the same character as other sensors and eventual drop and return inline with the rest. Any help would be appreciated, thank you.

    MicroPython Code

    from machine import I2C
    
    class BME280():
    
        def __init__(self, iicadr=0x076, i2c=None, sda='P22', scl='P21', traceDebug=False, sdAccess=False): # 2.2.9b
            self.trace = traceDebug
            self.adr = iicadr
            self.sdAccess = sdAccess # 2.2.9b
    
            # 2.2.21
            self.temperature = 0
            self.temperature_fine = 0
            self.tempDAC = 0  # DAC equivalent
            self.pressure = 0
            self.presDAC = 0
            self.humidity = 0
            self.humDAC = 0
    
            # Section 3.12  These coefficient are used to test  compensate  _temperature()  _pressure()  pg #23 BMP280
            self.CoeffData = bytearray(26)   # 2.00  bytearray(12*2)
            self.dig_t1 = 27504  # U 0x88 0x89
            self.dig_t2 = 26435  # S 0x8A 0x8B
            self.dig_t3 = -1000  # S 0x8C 0x8D
            self.dig_p1 = 36477  # U 0x8E 0x8F
            self.dig_p2 = -10685  # S 0x90 0x91
            self.dig_p3 = 3024  # S 0x92 0x93
            self.dig_p4 = 2855  # S 0x94 0x95
            self.dig_p5 = 140  # S 0x96 0x97
            self.dig_p6 = -7  # S 0x98 0x99
            self.dig_p7 = 15500  # S 0x9A 0x9B
            self.dig_p8 = -14600  # S 0x9C 0x9D
            self.dig_p9 = 6000  # S 0x9E 0x9F
            self.dig_h1 = 75 # 2.00   U 0x0A1
    
            # 2.00
            self.CoeffHData = bytearray(7)
            self.dig_h2 = 376 # S 0x0E1 0x0E2
            self.dig_h3 = 0 # U 0x0E3
            self.dig_h4 = 286 # S 0x0E4 0x0E5
            self.dig_h5 = 50 # 0x0E5 0x0E6
            self.dig_h6 = 30 # 0x0E7
    
            # I2C bus declaration is extenal
            # MCP are connected on I2C bus #1   SDA-P22   SCL-P21
            #                      I2C bus #2   SDA-P18   SCL-P17
            #
            if i2c is not None: # 2.2.18
                self.i2c1 = i2c
            else:
                # from machine import I2C
                self.i2c1 = I2C(0, mode=I2C.MASTER, pins=(sda, scl))
    
    
        # fetch the calibration coefficients from CoeffData buffer
        def getCoeffU16(self, pointer):
            result = (self.CoeffData[pointer+1]  << 😎 | self.CoeffData[pointer]
            if self.trace :
                print('Upointer {:2}: {}'.format (pointer, result) )
            return result
    
        def getCoeffS16(self, pointer):
            result = (self.CoeffData[pointer+1] << 😎 | self.CoeffData[pointer]
            if result > 32767:
                result -= 65536
            if self.trace :
                print('Spointer {:2}: {}'.format (pointer, result) )
            return result
    
        # Section 3.12  These coefficient are used to test  compensate  _temperature()  _pressure()
        # read calibration data, used to format temperature and pressure
        # carreful to the bytes order  see page#23 of the datasheet
        def getCalibCoeff(self):
            self.i2c1.readfrom_mem_into(self.adr, 0x88, self.CoeffData)
            # return  self.CoeffData
            if self.trace:
                print("CoeffData: $") # + str(self.CoeffData) )
                for i in self.CoeffData:
                    print(" %X," % i, end = "")
                print("")
            self.dig_t1 = self.getCoeffU16(0)  # U 0x88 0x89
            self.dig_t2 = self.getCoeffS16(2)  # S 0x8A 0x8B
            self.dig_t3 = self.getCoeffS16(4)  # S 0x8C 0x8D
            self.dig_p1 = self.getCoeffU16(6)  # U 0x8E 0x8F
            self.dig_p2 = self.getCoeffS16(8)  # S 0x90 0x91
            self.dig_p3 = self.getCoeffS16(10)   # S 0x92 0x93
            self.dig_p4 = self.getCoeffS16(12)   # S 0x94 0x95
            self.dig_p5 = self.getCoeffS16(14)   # S 0x96 0x97
            self.dig_p6 = self.getCoeffS16(16)   # S 0x98 0x99
            self.dig_p7 = self.getCoeffS16(18)   # S 0x9A 0x9B
            self.dig_p8 = self.getCoeffS16(20)   # S 0x9C 0x9D
            self.dig_p9 = self.getCoeffS16(22)   # S 0x9E 0x9F
            self.dig_h1 = self.getCoeffU16(24) >> 8  # 2.00 keep $A1 only
    
            # 2.00
            self.i2c1.readfrom_mem_into(self.adr, 0xE1, self.CoeffHData)
            if self.trace:
                print("CoeffHData: $") # + str(self.CoeffHData) )
                for i in self.CoeffHData:
                    print(" %X," % i, end = "")
                print("")
            self.dig_h2 = self.CoeffHData[0] | ( self.CoeffHData[1] << 8)
            self.dig_h3 = self.CoeffHData[2]
            self.dig_h4 = (self.CoeffHData[4] & 0x0F) | (self.CoeffHData[3] << 4)
            self.dig_h5 = ((self.CoeffHData[4] & 0x0F0) >> 4) | (self.CoeffHData[5] << 4 )
            self.dig_h6 = self.CoeffHData[6]
            if self.trace:
                print("dig_h2: $%X %d" % (self.dig_h2, self.dig_h2))
                print("dig_h3: $%X %d" % (self.dig_h3, self.dig_h3))
                print("dig_h4: $%X %d" % (self.dig_h4, self.dig_h4))
                print("dig_h5: $%X %d" % (self.dig_h5, self.dig_h5))
                print("dig_h6: $%X %d" % (self.dig_h6, self.dig_h6))
    
    
        # Detect and init sensor
        def begin(self):
            int = 0 # 2.2.9b
            try:
                did = self.i2c1.readfrom_mem(self.adr, 0xD0,1)
                int = did[0]
    
                if self.trace :
                    print("Read device ID:" + str(did[0]))
                    print("Fetch calibration coefficients:")
    
                # read calibration coefficient to correct raw data
                self.getCalibCoeff()
    
                # 2.00 Write to humidity ctrl
                # ovsmp = 2   osrs_h[2:0]= 010
                self.i2c1.writeto_mem(self.adr, 0xF2, bytes([0b010]))
    
                # 4.3.4  Write to REG_CONTROL
                # pressure ovsmp = 2  reso 1.31 Pa     osrs_p[7:5]= 010
                # temperature ovsmp = 2  reso 0.0025 C   osrs_t[4:2]= 010
                # Power mode normal b[1:0]= 11
                self.i2c1.writeto_mem(self.adr, 0xF4, bytes([0b01001011]))
    
                # configurate the sensor
                # 4.3.5 Write to REG_CONFIG
                # Stanby 250ms  t_sb[7:5]= 011
                # IIR filter 4   filter[4:2]= 010
                # interface I2C  [1:0]= 00
                self.i2c1.writeto_mem(self.adr, 0xF5, bytes([0b01101000]))
                print('Detected BME280 - Temp/Humidity/Pressure Sensor Adr:' + str(self.adr) )
    
            except Exception as e: # 2.2.9b
                scratch =  'BME280 - Temp/Humidity/Pressure Sensor (Adr:' + str(self.adr) + ') not found - '  # 2.2.9b  print('BME280 - Temp/Humidity/Pressure Sensor (Adr:' + str(self.adr) + ') not found.')
                file_errLog(0, scratch + str(e), self.sdAccess)  # 2.2.9b
                # 2.2.18 print('Begin I2C1 scan ...')
                # 2.2.18 print(self.i2c1.scan())
                int = 0
    
            finally:
                return int == 0x060
    
    
    
        # Section 3.12   checked, 519888 => 25.08248 C
        def compensate_temperature(self, raw_temperature):
            var1 = (raw_temperature / 16384.0 - self.dig_t1 / 1024.0) * self.dig_t2
            var2 = raw_temperature / 131072.0 - self.dig_t1 / 8192.0
            var2 = var2 * var2 * self.dig_t3
            self.temperature_fine = (var1 + var2)
            self.temperature = self.temperature_fine / 5120.0
            # if (self.temperature != 0):
            #    self.temperature = round(self.temperature, 2)
    
    
        # Section 3.12  checked, 415148 => 100653.3 Pa
        def compensate_pressure(self, raw_pressure):
            var1 = self.temperature_fine / 2.0 - 64000.0
            var2 = var1 * var1 * self.dig_p6 / 32768.0
            var2 = var2 + var1 * self.dig_p5 * 2
            var2 = var2 / 4.0 + self.dig_p4 * 65536.0
            var1 = (self.dig_p3 * var1 * var1 / 524288.0 + self.dig_p2 * var1) / 524288.0
            var1 = (1.0 + var1 / 32768.0) * self.dig_p1
            pressure = 1048576.0 - raw_pressure
            pressure = (pressure - var2 / 4096.0) * 6250.0 / var1
            var1 = self.dig_p9 * pressure * pressure / 2147483648.0
            var2 = pressure * self.dig_p8 / 32768.0
            self.pressure = pressure + (var1 + var2 + self.dig_p7) / 16.0
            # self.pressure = round(self.pressure + 0.001, 2)
    
        # 2.00
        # check 30281 => 68.66996648709039
        def compensate_humidity(self, raw_humidity):
            var1 = self.temperature_fine - 76800.0
            var2 = self.dig_h4 * 64.0 + (self.dig_h5 / 16384.0) * var1
            var3 = raw_humidity - var2
            var4 = self.dig_h2 / 65536.0
            var5 = 1.0 + (self.dig_h3 / 67108864.0) * var1
            var6 = 1.0 + (self.dig_h6 / 67108864.0) * var1 * var5
            var6 = var3 * var4 * (var5 * var6)
            self.humidity = var6 * (1.0 - self.dig_h1 * var6 / 524288.0)
    
    
        def Convert_C2F(self, DataC):
            return (DataC * 9/5) + 32
    
        def Convert_Pa2PSI(self, DataPa):
            return DataPa / 6895
    
        def Convert_Pa2ATM(self, DataPa):  # 1.15
            return DataPa / 101325
    
        # see datasheet section 3.9 Data readout
        def read(self):
            uTuPData = bytearray(6+2) # 2.00  3*2)
            self.i2c1.readfrom_mem_into(self.adr, 0xF7, uTuPData)
            pres = ( (uTuPData[0] << 16) | (uTuPData[1]  << 😎 | uTuPData[2] ) >> 4
            temp = ( (uTuPData[3] << 16) | (uTuPData[4]  << 😎 | uTuPData[5] ) >> 4
            hum = (uTuPData[6] << 😎 | (uTuPData[7]) # 2.00
    
            # 2.2.21  to detect sensor reset ...
            self.tempDAC = temp
            self.presDAC = pres
            self.humDAC = hum
    
            # Must compute temperature first then pressure
            self.compensate_temperature(temp)
            self.compensate_pressure(pres)
            self.compensate_humidity(hum) # 2.00
    
            if self.trace :
                print("Temp C: " + str(self.temperature) + " F: " + str(self.Convert_C2F(self.temperature)))
                print("Pres Pa: " + str(self.pressure) + " PSI: " + str(self.Convert_Pa2PSI(self.pressure)))
                print("Hum  RH: " + str(self.humidity) ) # 2.00
    
            # return uTuPData
            # return temp, pres
            return self.temperature, self.pressure, self.humidity  # Temp in C, Pressure in Pa, Humidity %RH
    1 REPLY 1

    BSTRobin
    Community Moderator
    Community Moderator

    Hello mdf-terra,
    Did you follow HSMI document when handling, soldering and mouting the BME280 to a PCB?
    https://www.bosch-sensortec.com/media/boschsensortec/downloads/handling_soldering_mounting_instructi...

    Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist