I successfully corrected the temperature and humidity errors by doing two things. Firstly, I separated the Raspberry Pi Zero and the Pimoroni Enviro+ boards, placed the PMS 5003 between the two boards and used ribbon cable to interconnect them. I’ve designed and built a 3D printed case to hold them. I’ve included a photo of the case.
Secondly, I logged the Enviro+ temperature and humidity readings, along with the temperature and humidity readings from a closely located Aeotec Multisensor. Those logs allowed me to undertake some machine learning using regression analysis, to develop some correction algorithms. I tried polynomial regression but found that linear regression was sufficiently accurate.
I also implemented an algorithm that adjusts the relative humidity to align with the adjusted temperature. I implemented that algorithm using August-Roche-Magnus approximation using https://bmcnoldy.rsmas.miami.edu/Humidity.html
I’m now getting temperature readings with a ±0.4 degree C accuracy and relative humidity readings with ±2% accuracy. I plan to run the ML training on a much larger sample size, with a wider variety of temperature and humidity values to fully verify the algorithms, but the early results are promising. I’ll post the final code, case design and regression analysis when I’ve completed that larger sample size.
In the meantime, here is an extract of the correction code. The corrected temperature is comp_temp and the corrected humidity is comp_hum. It’s possible that the regression compensation variables might need some adjustment if a case that differs from mine is used.
Hope that’s of use to those of you struggling to get some temperature and humidity accuracy.
Set up the regression compensation variables
cpu_temp_factor_slope = 1.038 # Linear Regression to minimise impact of CPU temp on Raw Temp
cpu_temp_factor_intercept = 12.503
comp_temp_slope = 0.623 # Linear Regression to adjust Raw Temp (with impact of CPU Temp removed) to provide compensated temp
comp_temp_intercept = 23.519
comp_hum_slope = 0.966 # Linear Regression to adjust temperature-adjusted raw relative humidity to provide compensated relative humidity
comp_hum_intercept = 15.686
cpu_temp = get_cpu_temperature()
cpu_temps = cpu_temps[1:] + [cpu_temp] # Smooth out with some averaging to decrease jitter
avg_cpu_temp = sum(cpu_temps) / float(len(cpu_temps))
raw_temp = bme280.get_temperature()
cpu_temp_factor = cpu_temp_factor_slope * (avg_cpu_temp - raw_temp) + cpu_temp_factor_intercept
raw_temp_without_cpu_impact = raw_temp - cpu_temp_factor
comp_temp = comp_temp_slope * raw_temp_without_cpu_impact + comp_temp_intercept
raw_hum = bme280.get_humidity()
dew_point = (243.04 * (math.log(raw_hum / 100) + ((17.625 * raw_temp) / (243.04 + raw_temp)))) / (17.625 - math.log(raw_hum / 100) - (17.625 * raw_temp / (243.04 + raw_temp)))
temp_adjusted_hum = 100 * (math.exp((17.625 * dew_point)/(243.04 + dew_point)) / math.exp((17.625 * comp_temp) / (243.04 + comp_temp)))
comp_hum = comp_hum_slope * temp_adjusted_hum + comp_hum_intercept