pimoroni / sgp30-python

Python library for the SGP30 air quality sensor
https://shop.pimoroni.com/products/sgp30-air-quality-sensor-breakout
MIT License
38 stars 18 forks source link

Set_baseline and get_baseline return inverted values #4

Closed juanruitina closed 4 years ago

juanruitina commented 4 years ago

Hi! Trying to store and restore baseline values as specified in the sensor's documentation, I've found out that either get_baseline is getting or set_baseline is setting VOC and CO2 baseline values in that order, instead of CO2 and VOC as I would expect.

I verified this behaviour with this modified script from test.py:

from sgp30 import SGP30
import time
import sys

sgp30 = SGP30()

restored_baseline_co2 = 0xFECA
restored_baseline_voc = 0xBEBA
print('set_baseline: CO2: {0} 0x{0:x}, VOC: {1} 0x{1:x}'.format(
    restored_baseline_co2, restored_baseline_voc))

result = sgp30.command(
    'set_baseline', (restored_baseline_co2, restored_baseline_voc))

result = sgp30.command('get_baseline')
print('get_baseline: CO2: {0} 0x{0:x}, VOC: {1} 0x{1:x}'.format(
    result[0], result[1]))

print("Sensor warming up, please wait...")

def crude_progress_bar():
    sys.stdout.write('.')
    sys.stdout.flush()

sgp30.start_measurement(crude_progress_bar)
sys.stdout.write('\n')

while True:
    result = sgp30.get_air_quality()
    print(result)
    time.sleep(1.0)

Then the console returns this:

set_baseline: CO2: 65226 0xfeca, VOC: 48826 0xbeba
get_baseline: CO2: 48826 0xbeba, VOC: 65226 0xfeca

This results in abnormally low CO2 readings (always <400 ppm) and high VOC readings (>400 ppb), inconsistent with previous readings. When I manually invert the stored values, readings are reasonable again. I couldn't find any issues with my code nor with __init__.py that might explain this behaviour, but maybe I missed something.

Is this intentional? Any clue what might be happening here? Thanks!

juanruitina commented 4 years ago

I tested with Adafruit's driver and it works as expected. When looking at their driver, I noticed it seems to set the TVOC and eCO2 baseline values in that order (see the array in the for loop).

I guess my problem was assuming that set_baseline passed eCO2 and TVOC baseline values in that order, and not the other way round. If that's the case, it would be great if this were documented, one comment in test.py would be enough! 👌

phooey commented 4 years ago

I've noticed the same thing, and according to the SGP30 datasheet, when getting the baseline the eCO2 value is returned before the TVOC value, and when setting the baseline the parameter order is TVOC, eCO2:

The command “sgp30_get_iaq_baseline” returns the baseline values for the two air quality signals. The sensor responds with 2 data bytes (MSB first) and 1 CRC byte for each of the two values in the order CO2eq and TVOC. These two values should be stored on an external memory. After a power-up or soft reset, the baseline of the baseline compensation algorithm can be restored by sending first an “sgp30_iaq_init” command followed by a “sgp30_set_iaq_baseline” command with the two baseline values as parameters in the order as (TVOC, CO2eq).

So this is an error with this library. I will try to create a pull request with a correction.