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
... View more