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

Pressure reading too high (micropython) #3

Closed
geoffklee opened this issue Nov 12, 2017 · 28 comments
Closed

Pressure reading too high (micropython) #3

geoffklee opened this issue Nov 12, 2017 · 28 comments
Assignees
Labels
Milestone

Comments

@geoffklee
Copy link

Hi,

I'm using this code on a LoPy and it seems to work well, other than that the pressure reading is too high. I'm consistently seeing readings around 21mb higher than they should be (eg currently 1038 when the real pressure is ~1017). The pressure reading also consistently rises as the temperature drops. It doesn't seem to make a difference whether I have the gas heater on or off.

I've had good success with the BMP180 measuring temp/pressure in the same environment (just a house, nothing special!)

Can you think of anything I should try?

@Gadgetoid
Copy link
Member

Do you have a Raspberry Pi to run this library on and test it against your LoPy setup? This library wasn't targeted at any MicroPython boards, so it's possible there might be issues with the opaque calculations supplied by the manufacturer to transform the sensor readings into meaningful units.

I also don't know how the sensor may correlate or deviate from pressure readings from other sources. What do you mean by real pressure? Do you have another sensor you're comparing this against?

@geoffklee
Copy link
Author

Thanks for the reply - I do have a Pi B so my next step was going to be exactly that. I'll try to get it hooked up and report back.

The 'real' pressure is as reported by a BMP180 in the same room and a weather station a couple of miles away, which agree to within 1 hPa or so. The 680 is wrong enough that it's definitely not intended output, but all the other readings seem OK.

@Gadgetoid
Copy link
Member

Yeah, that's quite significantly wrong.

I have a suspicion it could be a Python vs MicroPython issue, I'll grab a board and run some tests on it.

@Gadgetoid
Copy link
Member

A quick test of just the conversion routines disproves my theory- the _calc_temperature and _calc_pressure routines produce the same output (number of decimal places notwithstanding) on both platforms.

The temperature is used to compensate the pressure readings, and should in theory cancel out any correlative effect you might see between the two.

I'm assuming you're using this library?

@geoffklee
Copy link
Author

Yup, using this library and the breakout board from pimoroni. I wrote a little I2C wrapper class to convert the smbus *byte_data() and *block_data() calls into micropython's readfrom_mem() and writeto_mem(). This is my first foray into I2C and I'll happily believe it's my code that's at fault, but it does seem to work fine in all other respects.

I dug out a Pi B last night so will test on that tomorrow and get back to you. If I get the same weird readings, I guess that rules out a platform/code issue and we're left with a possible dodgy sensor?

@geoffklee
Copy link
Author

geoffklee commented Nov 15, 2017

Hello again. So, running this on a Pi B rev 2 gives very similar results. As you can see below I get 1040.41 as the pressure reading (yes, my house really is about 14 degrees C!). For reference a BMP180 currently gives me 1021.53 and the weather station down the road is showing 1020

Dodgy sensor?

>>> b = bme680.BME680()
>>> b.get_sensor_data()
True
>>> b.data.pressure
1040.41
>>> b.data.temperature
14.35
>>> b.data.humidity
68.477
>>> b.chip_id
97

@jorisvervuurt
Copy link

jorisvervuurt commented Nov 17, 2017

I don’t think it’s a dodgy sensor. I just noticed that mine reads ~1050 hPa at the moment, while it should read ~1030 hPa. Thats the same ~20 hPa difference you also appear to have. I think it’s miscalculating in software.

@geoffklee
Copy link
Author

Ah, interesting! I was thinking of compiling the Bosch reference driver to see if it gives a different reading, but that's a bit out of my comfort zone. Will try it if I get the time this evening though.

@Gadgetoid
Copy link
Member

This is surprising, since I rigged up the Bosch C code and my Python code to perform the same calculations so I could verify them. Perhaps an error has crept in somewhere with an incorrect sign or premature rounding.

Comparing the results you get with the Bosch driver would be a good start- we had some code somewhere to read/print the values. I'll see if I can dig it up.

@Gadgetoid
Copy link
Member

Good news, everyone! (for me anyway) It's not my fault! And the sensor is not faulty.

See: https://github.com/BoschSensortec/BME680_driver/commit/94fd057adfb36077d57dde21df986f6d48939b29

My Python code is a direct port of Bosch's BME680_driver code. If you read the commit linked above you'll see:

v3.5.3
 - Changed the compensation equation formulas to use shifting operation
 - Updated the "bme680_get_profile_dur" API
 - Fixed Checkpatch and made linux compatible
 - Fixed bug of temperature compensation in pressure
 - Updated self test APIs

Not only does this fix a bugbear of mine - using division in place of logical shifts - but it also "Fixed bug of temperature compensation in pressure."

D'oh!

I will port these fixes to Python ASAP.

@Gadgetoid
Copy link
Member

Okay, first run at it done. I've verified the Python code isn't riddled with syntax errors, but I've been unable to actually test it.

See: d997015

You can try this out by installing it from Git:

git clone https://github.com/pimoroni/bme680
cd bme680/library
sudo python setup.py develop

(substitute python3 if appropriate)

This will symlink this GitHub repository, so you can update to the latest development library by doing a "git pull".

Once everything is working, you can clean that up and revert to the stable library by running:

sudo python setup.py develop --uninstall

@jorisvervuurt
Copy link

I've just updated the library on my Pi and at the moment, the pressure value is spot on.
Since the bug was temperature-related, I'll check tomorrow morning to see if the value is still right.

Looking good so far!

@Gadgetoid Gadgetoid self-assigned this Nov 17, 2017
@Gadgetoid Gadgetoid added the bug label Nov 17, 2017
@Gadgetoid Gadgetoid added this to the v1.0.3 milestone Nov 17, 2017
@geoffklee
Copy link
Author

Sounds positive! I won't be able to test this until tomorrow, but will do so and report back.

@jorisvervuurt
Copy link

jorisvervuurt commented Nov 18, 2017

I’m afraid it didn’t fix the problem. :-(
I just checked and it now reads ~1043 hPa at ~13 degrees C, where it should read ~1023 hPa. It does seem to give correct readings at ~21 degrees C though...

@geoffklee
Copy link
Author

Same results here. I'm seeing this sort of thing if I warm the sensor up gently then let it cool (reference pressure is ~1018hPa):

13.44 C,1040.25 hPa,63.93 %RH,2132 Ohms
14.90 C,1036.87 hPa,62.52 %RH,35057 Ohms
16.78 C,1032.67 hPa,61.85 %RH,57254 Ohms
17.89 C,1030.35 hPa,60.47 %RH,58319 Ohms
...
26.48 C,1014.99 hPa,35.37 %RH,112361 Ohms
25.02 C,1017.22 hPa,35.73 %RH,123106 Ohms
...
14.61 C,1037.44 hPa,58.15 %RH,57109 Ohms

Definitely still an issue with the temperature compensation (gas readings look odd but they tend to take a while to settle down).

If you have a file I could compile against the Bosch API I'd love to test that: unfortunately my C isn't good enough to construct one myself.

@geoffklee
Copy link
Author

Ok, so I managed to hack together something that uses the Bosch C code and can confirm that it seems to work as expected. Currently:

T: 13.40 degC, P: 1021.07 hPa, H 57.11 %rH

whereas the latest python code is giving me:

13.04 C,1045.02 hPa,59.151 %RH

Pressure reading seems stable with temperature changes using the C library, too.

@jorisvervuurt
Copy link

jorisvervuurt commented Nov 19, 2017

Very interesting! How's the gas measurement compared to the Python code?
I also noticed that the library no longer works under Python 3.

Looks like it's back to the drawing board for @Gadgetoid or @sandyjmacdonald...

@geoffklee
Copy link
Author

geoffklee commented Nov 19, 2017

Gas sensor looks reasonable & stable, too (now that I've got my head slightly more around what the C code is doing and managed to make it loop)

result: 0, T: 14.96 degC, P: 1019.60 hPa, H 54.17 %rH , G: 134784 ohms
result: 0, T: 14.94 degC, P: 1019.60 hPa, H 54.19 %rH , G: 136199 ohms
result: 0, T: 14.93 degC, P: 1019.58 hPa, H 54.20 %rH , G: 137419 ohms
result: 0, T: 14.92 degC, P: 1019.56 hPa, H 54.22 %rH , G: 138547 ohms

If you promise not to laugh (I've never written any C before!), the code is here: https://gist.github.com/gkluoe/a297f6bcf76e4466f1bfa6fd40038983

@ghost
Copy link

ghost commented Nov 19, 2017

If anyone wants to check their workings-out, CircuitPython code for Adafruit's BME680 breakout is here: https://github.com/adafruit/Adafruit_CircuitPython_BME680 and will, presumably (it's slightly beyond me), be easily comparable to Micropython/Python code.

@Gadgetoid
Copy link
Member

Try the Python code as of #4 being merged, it could well be that floating point results were propagating through the calculations and causing the difference.

In the interim I'll have a look over the Bosch code versus our port, and see if anything has been overlooked in the new fixes.

@geoffklee
Copy link
Author

No change for me using the latest python code - but then I'm using 2.7 where, as I understand, it '/' and '//' are functionally the same...

@Gadgetoid
Copy link
Member

I'm a little bit stumped with this- perhaps I'm barking up the wrong tree. I'm genuinely surprised that back-porting the upstream fix for what sounds like exactly the same issue hasn't fix this though. Perhaps it's fixed one discrepancy and revealed another. Looks like I've got some more testing and debugging to do.

@geoffklee
Copy link
Author

Couldn't leave this alone - I think I found the issue: #5

@robmarkcole
Copy link

@gkluoe are you using this board with micro/circuit-python?

@geoffklee
Copy link
Author

@robmarkcole yup. Or at least, I was. I haven't put it back on the LoPy yet since moving it over to the pi for debugging. I wrote a little I2CAdapter class, as the methods provided by machine.i2c are a little different from the SMBus methods this code expects. I can commit the code somewhere public this evening if you like.

@robmarkcole
Copy link

Hi @gkluoe would be grateful, thanks 🙏

@geoffklee
Copy link
Author

geoffklee commented Nov 28, 2017

Ho @robmarkcole

So as not to hijack this issue, I've opened a new one for micropython support at #7

@giampiero7
Copy link
Contributor

Hi, not sure if it is intended or an error, but, comparing the BME680_driver C code to this python port, I've noticed a difference in the _calc_pressure function:

https://github.com/pimoroni/bme680/blob/50902ac08ee9ba850186cf6132f9a0fac37b07ad/library/bme680/__init__.py#L327

VS

https://github.com/BoschSensortec/BME680_driver/blob/e6b9bbade923d792d9ccd822ab5fada99bf40501/bme680.c#L915

if (pressure_comp >= BME680_MAX_OVERFLOW_VAL)

https://github.com/BoschSensortec/BME680_driver/blob/e6b9bbade923d792d9ccd822ab5fada99bf40501/bme680_defs.h#L323

/** BME680 pressure calculation macros */
/*! This max value is used to provide precedence to multiplication or division
 * in pressure compensation equation to achieve least loss of precision and
 * avoiding overflows.
 * i.e Comparing value, BME680_MAX_OVERFLOW_VAL = INT32_C(1 << 30)
 */
#define BME680_MAX_OVERFLOW_VAL      INT32_C(0x40000000)

Hope it helps...

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

No branches or pull requests

5 participants