Skip to content

adafruit_bme680.py, class Adafruit_BME680, _perform_reading(): infinite loop #66

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

Closed
mtetcs opened this issue Aug 1, 2023 · 6 comments · Fixed by #75
Closed

adafruit_bme680.py, class Adafruit_BME680, _perform_reading(): infinite loop #66

mtetcs opened this issue Aug 1, 2023 · 6 comments · Fixed by #75

Comments

@mtetcs
Copy link

mtetcs commented Aug 1, 2023

We have an environmental test setup here with several BME680s attached via a TCA9548A. On rare occasions when attempting to read a BME680, we can see _perform_reading() getting stuck in the loop shown below, which effectively halts the data acquisition. Normally each device takes exactly 8 iterations of this loop to collect a value. If we force the loop to terminate after N=20 iterations, successive device reads are successful.

The code below assumes that it will eventually receive new_data, though it seems this isn't always the case. Perhaps this could be modified to address the assumption, and to handle the case that a no-new-data event occurs on the first device read and the values for temp/rh/press/... will be unset?

while not new_data:
    data = self._read(_BME680_REG_MEAS_STATUS, 17)
    new_data = data[0] & 0x80 != 0
    time.sleep(0.005)
@caternuson
Copy link
Contributor

Can you provide a short, simple, complete example sketch that can be used to demonstrate the issue.

@mtetcs
Copy link
Author

mtetcs commented Aug 2, 2023

In principle, the Usage Example in the docs is sufficient to demonstrate the issue, given the presence of the hardware in question. We only sample every 10s for the application here.

Perhaps the gist of the issue is that hardware isn't always 100% reliable. Arguably the best place to handle temporarily unresponsive hardware is in its API, rather than handling it downstream where it would necessitate an additional layer of complexity to forcibly terminate hung read operations. _perform_reading() could plausibly raise a BlockingIOError if it doesn't receive an acceptable response after a given number of iterations, in preference to an infinite loop.

@caternuson
Copy link
Contributor

Is the inclusion of the TCA9548A necessary? Or do you get the same issue even without the TCA being used?

@mtetcs
Copy link
Author

mtetcs commented Aug 3, 2023

No and no. There was no issue with the BME680 hardware in either configuration.

@caternuson
Copy link
Contributor

OK, if there's no issue, then not sure what the issue is?

Is there any issue when using just a single BME680 (no TCA9548A) and running the example code from this library?
https://github.com/adafruit/Adafruit_CircuitPython_BME680/blob/main/examples/bme680_simpletest.py

@mtetcs
Copy link
Author

mtetcs commented Aug 4, 2023

The issue reported is that _perform_reading() fails to consider the possibility that the hardware may be non-responsive. Instead of failing gracefully and allowing the caller to deal with the problem, it enters an infinite loop, halting progression.

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

Successfully merging a pull request may close this issue.

2 participants