01-26-2022 05:16 PM
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
02-07-2022 06:50 AM
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...