For your calculations, the formula in my last prosting is the one to use and your value is correct.
In January, I gave the same formula but with units! Since gas_reading is in the unit of Ohms and humidity_reading in % relative humidity the slope factors needs to be in units of Log(Ohm)/%rh to be mathematically correct. In practice, you can just drop the units.
The formula is meant to compensate the impact of water vapor on the gas resistance. It is also processed logarithmically due to the gas resistance spreading over several orders of magnitude, depending on the concentration of volatile compounds. It does not give you an absolute air quality value, as the Bosch library does. From the size of their code files I conclude that they do some way more advanced calculations in order to compute their air quality index.
What I do is, I record the maximum readings of the compensated gas value und then compute the percentage of the current value. In my office, a drop from 100% to 95% usually means that it is about time to open a window. When breathing against it or opening a sharpie right in front of it it drops even further.
Thanks for the confirmation! What I’m still not sure yet is whether the resulted IAQ value ( 13.027 in the output above) is a value ranging between 0 to 500 or is it 13.027%?
How do you do this?
Sorry for all these questions. I’m currently working on a monitoring plugin to embed the BME680 sensor into open source monitoring software (like Icinga, Nagios, Sensu, etc).
I’m also trying to get Bosch to open up about their algorithm, but that will be dfficult or even impossible I guess.
So far, using your formula, the results are pretty steady:
My approach does not implement an IAQ value in the range of 0 to 500 as the Bosch library does. It is more an improvement on the IAQ example included in the pimoroni python library, which also returns a percentage value. However, this method needs a ceiling value to compare with.
What I observed is that the sensor has a much longer burn-in-time as the 5 minutes given in the Bosch documentary and even after some hours the resistance continuous to increase slowly. If it then runs for several weeks, the value is subjected to long-time drifts. Hence, you need to update your ceiling value in some way.
What I do is, after burn-in I take the current (compensated) gas resistance as ceiling. Then, about every 5 minutes, I compare the current resistance to my ceiling. If it is larger, it is appended to a list of at most 50 values. Their mean value then becomes the new ceiling. Once the list is full, the oldest value is dropped. This method helps to mitigate the impact of short time spikes in the resistance while also slowly raising the ceiling during upwards drifts. The oldest value is also dropped and replaced with the current reading every full hour, allowing the ceiling to slowly follow a downwards drift of the sensor.
Since my first post in this forum, I also got the original Bosch library running on an Arduino mega. There is a lot of math going on in there. I doubt they would ever disclose their code.
I finally got around to clean up my code and uploaded it to github:
There, I summarize most of the information I was able to collect about the inner workings of the BME680.
Feel free to use it in your projects. It is still far inferior to the BSEC library (which in turn also seems to ignore some issues) but it may help to get at least some sense from the gas resistance.
thanks for publishing your library. Meanwhile I went for the BSEC Library in combination with a raspberry pi. Very nice finding of the +1.5°C self heating offset. That might explain the high IAQ readings after some days.
Awesome work! Just wondering what your thoughts were on other ways of calibrating the sensor presented on this forum (eg here and here)? Just wanted to pick your brain, given the work you have done.
I’m trying to write a Magic Mirror module for the BME680, so will be including your calculations there rather than going down the BSEC library route.