pimoroni / enviro

MIT License
101 stars 79 forks source link

Enviro Indoor temperature reading bug? #178

Open b-g opened 1 year ago

b-g commented 1 year ago

Hi there! Many thanks for the great Enviro Indoor board!

However there seems to be something really fishy with my temperature reading, I've noticed that the onboard temperature reading is constantly far too high. I tried to confirm this, by connecting an additional BME688 breakout with the same chip to cross check e.g.

2023-05-29 07:51:27 [info     / 119kB] > onboard -> OrderedDict({'temperature': 22.86, 'humidity': 44.67, 'pressure': 886.53, 'gas_resistance': 86692, 'aqi': 13.2, 'luminance': 117, 'color_temperature': 4420, 'voltage': 0.0})
2023-05-29 07:51:27 [info     / 115kB] > breakout -> temperature: 17.94859 humidity: 60.15883 pressure: 88765.46 gas_resistance: 57334.83 status: 160 gas_index: 0 meas_index: 0 

A46E2822-9EE6-4B94-8046-9BE81C5DC4BD_1_105_c

I'm aware of "compensate for additional heating when on usb power" in https://github.com/pimoroni/enviro/blob/main/enviro/boards/indoor.py#L53 and https://github.com/pimoroni/enviro/blob/main/enviro/config_defaults.py#L4 DEFAULT_USB_POWER_TEMPERATURE_OFFSET = 4.5. Looking on the my readings, the +4.5 seems rather to make things a lot worse. 🤨?

Questions:

Bonus: I've couldn't find any documentation in this repo to connect a BreakoutBME68X to the Enviro Indoor ... this did the trick for me: Add the lines below to main.py (around here https://github.com/pimoroni/enviro/blob/main/main.py#L73-L78) and the import from breakout_bme68x import BreakoutBME68X on top.

  enviro.logging.info(f"> onboard -> {reading}")
  bme = BreakoutBME68X(enviro.i2c)
  temperature, pressure, humidity, gas_resistance, status, gas_index, meas_index = bme.read()
  enviro.logging.info(f"> external -> temperature: {temperature} humidity: {humidity} pressure: {pressure} gas_resistance: {gas_resistance} status: {status} gas_index: {gas_index} meas_index: {meas_index} ")

Here is the full main.py:

# Enviro - wireless environmental monitoring and logging
#
# On first run Enviro will go into provisioning mode where it appears
# as a wireless access point called "Enviro <board type> Setup". Connect
# to the access point with your phone, tablet or laptop and follow the
# on screen instructions.
#
# The provisioning process will generate a `config.py` file which 
# contains settings like your wifi username/password, how often you
# want to log data, and where to upload your data once it is collected.
#
# You can use enviro out of the box with the options that we supply
# or alternatively you can create your own firmware that behaves how
# you want it to - please share your setups with us! :-)
#
# Need help? check out https://pimoroni.com/enviro-guide
#
# Happy data hoarding folks,
#
#   - the Pimoroni pirate crew

# uncomment the below two lines to change the amount of logging enviro will do
# from phew import logging
# logging.disable_logging_types(logging.LOG_DEBUG)

# import enviro firmware, this will trigger provisioning if needed
import enviro
import os

from breakout_bme68x import BreakoutBME68X

try:
  # initialise enviro
  enviro.startup()

  # if the clock isn't set...
  if not enviro.is_clock_set():
    enviro.logging.info("> clock not set, synchronise from ntp server")
    if not enviro.sync_clock_from_ntp():
      # failed to talk to ntp server go back to sleep for another cycle
      enviro.halt("! failed to synchronise clock")  

  # check disk space...
  if enviro.low_disk_space():
    # less than 10% of diskspace left, this probably means cached results
    # are not getting uploaded so warn the user and halt with an error
    enviro.halt("! low disk space")

  # TODO this seems to be useful to keep around?
  filesystem_stats = os.statvfs(".")
  enviro.logging.debug(f"> {filesystem_stats[3]} blocks free out of {filesystem_stats[2]}")

  # TODO should the board auto take a reading when the timer has been set, or wait for the time?
  # take a reading from the onboard sensors
  enviro.logging.debug(f"> taking new reading")
  reading = enviro.get_sensor_readings()

  enviro.logging.info(f"> onboard -> {reading}")
  bme = BreakoutBME68X(enviro.i2c)
  temperature, pressure, humidity, gas_resistance, status, gas_index, meas_index = bme.read()
  enviro.logging.info(f"> breakout -> temperature: {temperature} humidity: {humidity} pressure: {pressure} gas_resistance: {gas_resistance} status: {status} gas_index: {gas_index} meas_index: {meas_index} ")
  reading["temperature2"] = temperature

  # here you can customise the sensor readings by adding extra information
  # or removing readings that you don't want, for example:
  # 
  #   del readings["temperature"]        # remove the temperature reading
  #
  #   readings["custom"] = my_reading()  # add my custom reading value

  # is an upload destination set?
  if enviro.config.destination:
    # if so cache this reading for upload later
    enviro.logging.debug(f"> caching reading for upload")
    enviro.cache_upload(reading)

    # if we have enough cached uploads...
    if enviro.is_upload_needed():
      enviro.logging.info(f"> {enviro.cached_upload_count()} cache file(s) need uploading")
      if not enviro.upload_readings():
        enviro.halt("! reading upload failed")
    else:
      enviro.logging.info(f"> {enviro.cached_upload_count()} cache file(s) not being uploaded. Waiting until there are {enviro.config.upload_frequency} file(s)")
  else:
    # otherwise save reading to local csv file (look in "/readings")
    enviro.logging.debug(f"> saving reading locally")
    enviro.save_reading(reading)

  # go to sleep until our next scheduled reading
  enviro.sleep()

# handle any unexpected exception that has occurred
except Exception as exc:
  enviro.exception(exc)
sjefferson99 commented 12 months ago

@b-g My understanding of the introduction of the offset was a simple fix for the theory that the USB power supply was heating the ground plane which was a heat sink for various power supply circuits. I have found on my weather board this was the case and that my temperature is also a little off even on the battery supply. I am now running it every minute with wifi upload by connecting a USB supply to the battery connector via a lipo battery and charger. I have made some fixes in PRs for the weather board based on a similar offset for USB to indoor, but yet to apply for the battery power mode.

The temperature offset is done in the boards/indoor.py file in the function starting at line 53, this is done here as temperature also affects humidity from measured humidity. My plan was to put an external BME board in as you have and measure them over time to understand if the offset is linear over ranges of environment temperatures and and then put appropriate logic in that function (for the weather board in my case) for USB and non-USB.

It would be interesting to see your results if the indoor temperature changes significantly over time if you are capturing temperature and temperature2.

sjefferson99 commented 12 months ago

@b-g I've added your example to the documentation in PR #184 to make this easier for others in future.