Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grow BME280 readings for temperature and humidity errors #231

Closed
JMBRillie opened this issue Jan 8, 2025 · 1 comment
Closed

Grow BME280 readings for temperature and humidity errors #231

JMBRillie opened this issue Jan 8, 2025 · 1 comment

Comments

@JMBRillie
Copy link

JMBRillie commented Jan 8, 2025

Pre-Script Note

I'm running my enviro grow 'out of the box' - but have now seen that it's not running the latest release.
I will update to the latest version and see if that changes anything.

My set-up

From the log.txt file:

running Enviro 0.0.10, MicroPython 856e08b1931b88271816a2f60648f6ff332235b2, enviro v1.20.4 on 2023-08-04

I am running the enviro grow on USB power recording every 5 minutes and updloading to an MQTT server every reading.

The Problem

I have noticed some errors in the temperature and humidity readings from the BME280.

  1. There is an offset error in reported temperature, probably from USB power generating heat as in
    Enviro Weather heats up under USB power #134,
    enviro indoor picow (0.0.9) reporting ~3C higher temperature #137,
    Enviro Indoor temperature reading bug? #178.
    Or from the WiFi as in
    enviro indoor picow 0.0.9 jittery temperature #138,
    enviro indoor picow 0.0.9 jittery temperature #138.
    I've also seen some PRs for this problem
    Adjust temperature under usb power #142,
    Add usb temp compensation to weather #160,
    Weather battery temperature compensation #186.
    This is not the concern of this issue.

  2. There are irregular errors of approximately -0.7 degC and +2% RH. I understand the relative humidity is calculated from the temperature reading, so the error is likely with the temperature reading.
    This is the concern of this issue, and I haven't seen any other issues covering this.

The errors are visible from a graph of the data:

image

For the last few days I've had the board next to Raspberry Pi Zero with a BME280 sensor connected on a breakout board and 20cm cables (So I think it is independant of any heat generated by the Pi). This has been taking readings every minute.

image

The consistency of these readings give me confidence that the spurrious results are not from some nearby device turning on or off periodically etc. and are in fact erroneous.

I wrote a short python script to analyse the data and report how many times the temperature dipped by more than 0.3 degC in one reading and then went back up by more than 0.3 degC the next reading. I found that each day had about 10 events (8-13).

What I've tried

When I tried debugging the problem I found that the first few readings from the BME280 were potentially quite different from each other. I've seen a comment to discard the first reading, and otherwise I expect the difference is due to heating of the PCB as the Pico wakes up and starts to draw more power.
For example, the first 10 readings taken in a loop with a 150ms delay were:

Reading Value [DegC]
0 22.444
1 25.536
2 25.472
3 25.402
4 25.343
5 25.303
6 25.277
7 25.261
8 25.248
9 25.241

We can see the first reading is wildly off, but the subsequent readings are approaching a steady state value.
I thought then, that the errors might have been caused by this varying temperature reading - if sometimes it took a reading slightly faster, before the board had warmed up or perhaps the opposite.
So I wrote a small function that takes a new reading every 150ms until the variation in the readings is below a desired value. It then takes an average of the recent readings (the ones all within the desired variation) and reports the average as the reading.
Code below:

# Take repeated BME280 readings until the desired resolution has been kept for the specified time
def get_stable_temp(stable_res_mK, stable_time_s, timeout_s):
    print("Taking temp reading...")
    dwell_time_ms = 150
    stable_count_tgt = stable_time_s*1000 // dwell_time_ms
    timeout_count = timeout_s*1000 // dwell_time_ms
    
    readings = [[-400 for reading in range(stable_count_tgt)] for metric in range(3)]
    counter = 0
    while counter < timeout_count:      
      reading = bme280.read()
      for m, metric in enumerate(reading):
        readings[m][counter%stable_count_tgt] = metric
        if not m:
          print(counter," ",metric," Deg C")

      if counter > stable_count_tgt:
        if (max(readings[0]) - min(readings[0]))*1000 < stable_res_mK:
          avg_readings = [(sum(readings[m])/len(readings[m])) for m in range(len(reading))]
          print("Time taken to get stable reading = ", counter*dwell_time_ms/1000, "s")
          return avg_readings
      counter += 1
      time.sleep(dwell_time_ms/1000)
      
    return False

This is then called at the start of get_sensor_readings() instead of bme280.read()

def get_sensor_readings(seconds_since_last, is_usb_power):
  # bme280 returns the register contents immediately and then starts a new reading
  # we want the current reading so do a dummy read to discard register contents first
  
#   bme280.read()
#   time.sleep(0.1)
#   bme280_data = bme280.read()

  bme280_data = get_stable_temp(10, 2, 120)

This means that the data recorded is the average of several readings taken every 150ms over a period of 2s when the maximum and minimum of those readings were less than 10mK away from each other - and if the temperature did not settle within 120s the function would have returned False, causing an error. (I realise 10mK is a bit excessive as the BME280 only claims a accuracy of +/- 500mK at 25 degC, but it passes)

Unfortunately, this did not fix the problem - the graph shown previously is actually with this code implemented.

Does anyone have any ideas? Has anyone seen this problem too?
I'm fairly confident I could clean up the data automatically in post, but I'd rather get the raw data to be as accurate and free from errors as possible.

@JMBRillie
Copy link
Author

It looks like the firmware update to v0.2.0 and Pimoroni Pico and MicroPython to v1.22.2 has fixed this issue.

I've run the updated firmware for the last two days and the anomalies are gone now. (Without any averaging of the readings)
It's only been a short time but given how many there were before and that it's gone to zero now - I think this has solved the problem.

image

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant