I found several older topics concerning strange readings from the BME280-sensor due to the influence of the CPU-Temperature. The Python examples do contain code to compensate for this effect and if I tweak the compensation factor I get fairly good values for the temperature.
However humidity is a different affair. I can’t get any decent readings, all values are far to low. I found some code in the weather-and-light.py example which tries to compensate for CPU temperature and uses the compensated temperature:
However, this code looks like guesswork to me and doesn’t produce correct values either. In aforementioned older topics I found several ideas for workarounds but no hint on how to do a simple compensation within the code. Maybe someone has an idea here, would be nice to use a small fleet of pi zeroes to measure room climate and collect the data.
Hi,
I started with Enviro+ end of last year and also got deviations.
According Wikipedia the relative humidity of an air-water mixture is defined as
the ratio of the partial pressure of water vapor in the mixture to the equilibrium vapor pressure of water
over a flat surface of pure water at a given temperature.
Vapor pressure is an exponential funktion of temperature and therefore also relative humidity.
I add to the weather example the correction. I test it together with the “Enviro + Air Quality” directly connected to a Pi Zero WH and alternatively connected to an GPIO extension of a Pi 400. Applying the corrections the deviation from an calibrated hygrometer was 1% humidity, within the tolerance of ±3% accuracy of the sensor.
Here the listing
#!/usr/bin/env python3
import time
import math as m # add math to allow exponential function
from bme280 import BME280
try:
from smbus2 import SMBus
except ImportError:
from smbus import SMBus
import logging
logging.basicConfig(
format='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s',
level=logging.INFO,
datefmt='%Y-%m-%d %H:%M:%S')
logging.info("""weather.py - Print readings from the BME280 weather sensor.
Press Ctrl+C to exit!
""")
bus = SMBus(1)
bme280 = BME280(i2c_dev=bus)
# Get the temperature of the CPU for compensation
def get_cpu_temperature():
with open("/sys/class/thermal/thermal_zone0/temp", "r") as f:
temp = f.read()
temp = int(temp) / 1000.0
return temp
# According Wikipedia the relative humidity of an air-water mixture is defined as
# the ratio of the partial pressure of water vapor in the mixture to the equilibrium vapor pressure of water
# over a flat surface of pure water at a given temperature
# The reading of humidy from sensor is at raw_temp. When we correct the temperature we must als correct the humidy
# by the ratio of equilibrium vapor pressure at raw_temp and reported temperature
#Antoinconstants for Water to calculate vapor pressure or boiling temperature
AntA=18.88579 # pressure in hPa
AntB=-3994.017
AntC=233.874 # Temperature in °C
# Calculate vapor pressure at T of water using Antoine equation
def pvap(T):
pv=m.exp(AntA+(AntB/(T+AntC)))
return pv
# Calculate boiling temperature of water using Antoine equation
def tboil(pres):
tboil=AntB/(m.log(pres)-AntA)-AntC
return tboil
# Tuning factor for compensation. Decrease this number to adjust the
# temperature down, and increase to adjust up
# factor = 2.25 for enviro mounted directly on pi-zero
factor = 12 # value for enviro mounted at an pi400 GPIO extension
cpu_temps = [get_cpu_temperature()] * 5
while True:
cpu_temp = get_cpu_temperature()
# Smooth out with some averaging to decrease jitter
cpu_temps = cpu_temps[1:] + [cpu_temp]
avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
raw_temp = bme280.get_temperature()
temperature = raw_temp - ((avg_cpu_temp - raw_temp) / factor) #compensated temperature
pressure = bme280.get_pressure()
raw_humid = bme280.get_humidity()
dew_point = tboil(raw_humid / 100 * pvap(raw_temp)) # humid is in %, devide by 100 to get factor
humidity = raw_humid * pvap(raw_temp) / pvap(temperature) # compensate hum. by ratio of the vapor pressure at Temperatures
logging.info("""Pressure: {:05.2f} hPa Temperature: {:05.2f} *C Humidity: {:05.2f} %
Raw-Temp: {:05.2f} *C Raw-Humid: {:05.2f} % dew_point: {:05.2f} *C
""".format(pressure, temperature, humidity, raw_temp, raw_humid, dew_point))
time.sleep(1)
I also add the dew_point, a value that is related to the absolute humidity (g Water per m³ air).
Good look with your setup - Use the correct tuning factor for temperature compensation.
Thanks for the code, I will test this sooner or later. Right now I settled with GPIO-Extension-Ribboncables. The values look good so far, but it is not the nicest of setups …