Sensirion / python-i2c-scd

Python Driver for Sensirion I²C Carbon Dioxid Sensor - SCD41
https://sensirion.github.io/python-i2c-scd/
BSD 3-Clause "New" or "Revised" License
6 stars 3 forks source link

Basic example Raspberry Pi Python without Bridge #1

Closed CesarJG closed 2 years ago

CesarJG commented 3 years ago

Hi,

first of all many thanks for the effort made developing the drivers for this CO2 sensor.

At https://sensirion.github.io/python-i2c-scd/quickstart.html#sensorbridge-example there is a basic example using the SensorBridge. Could you possible provide a python example for users without the SensorBridge? (Sensor directly connected to Raspberry Pi GPIO pins).

I am trying to figure out which sensor to buy (SCD30 or SCD41). Would this library also work for SCD30?

Many thanks in advance and best regards.

MBjoern commented 3 years ago

Hi there

Thank you for using our sensors and libraries.

We have lots of examples and dirvers available for the SCD30 and SCD40 sensor: See here

For Raspberry Pi via GPIOs, we have drivers working out of the box for the SCD4x here and for the SCD30 (requiring minor tweaks by copying the linux i2c implementation into the root directory of the driver) here

Have fun testing and prototyping and let us know what Use Case you're developing.

CesarJG commented 3 years ago

Hi,

thanks for your response but I was specifically asking for a python example without the SensorBridge. Something like here: https://sensirion.github.io/python-i2c-scd/quickstart.html#sensorbridge-example .I think that would be very helpful for non experienced users without the SensorBridge.

Regards.

CesarJG commented 3 years ago

Hi,

thanks for your response but I think all the provided examples are written in c. I was asking for a python example like at https://sensirion.github.io/python-i2c-scd/quickstart.html#sensorbridge-example . I think that would be a perfect addition for non experienced users without the SensorBridge.

Best regards.

psachs commented 3 years ago

Hi,

This python driver is for SCD41 only. Currently we don't have a public available python driver for SCD30. You can however also use this driver with the I2C bridge. To do so the sensor needs to be connected to the standard i2c pins (GPIO 2 => SDA; GPIO3 => SLC) of the raspberry pi and you need to install our python i2c driver: https://pypi.org/project/sensirion-i2c-driver/

from sensirion_i2c_driver import LinuxI2cTransceiver, I2cConnection
from sensirion_i2c_scd import Scd4xI2cDevice

with LinuxI2cTransceiver('/dev/i2c-1') as i2c_transceiver:
    i2c_connection = I2cConnection(i2c_transceiver)    
    scd41 = Scd4xI2cDevice(i2c_connection)

    # start periodic measurement in high power mode
    scd41.start_periodic_measurement()

    # Measure every 5 seconds
    while True:
        time.sleep(5)
        co2, temperature, humidity = scd41.read_measurement()
        # use default formatting for printing output:
        print("{}, {}, {}".format(co2, temperature, humidity))
        # custom printing of attributes:
        print("{:d} ppm CO2, {:0.2f} °C ({} ticks), {:0.1f} %RH ({} ticks)".format(
            co2.co2,
            temperature.degrees_celsius, temperature.ticks,
            humidity.percent_rh, humidity.ticks))
    scd41.stop_periodic_measurement()
CesarJG commented 3 years ago

Hi again,

I think that is what I was looking for. I think I will go for the SCD41 :)

Many thanks for your time and keep doing such a good job.

CesarJG commented 3 years ago

Hi,

Today arrived my SCD41 Evaluation Board and I would like to inform you that the above example seems not to work. I become:

python3 co2-test.py Traceback (most recent call last): File "co2-test.py", line 10, in scd41.start_periodic_measurement() File "/usr/local/lib/python3.7/dist-packages/sensirion_i2c_scd/scd4x/device.py", line 56, in start_periodic_measurement result = self.execute(Scd4xI2cCmdStartPeriodicMeasurement()) File "/usr/local/lib/python3.7/dist-packages/sensirion_i2c_driver/device.py", line 61, in execute return self._connection.execute(self._slave_address, command) File "/usr/local/lib/python3.7/dist-packages/sensirion_i2c_driver/connection.py", line 116, in execute return self._interpret_response(command, response) File "/usr/local/lib/python3.7/dist-packages/sensirion_i2c_driver/connection.py", line 205, in _interpret_response raise response sensirion_i2c_driver.errors.I2cTransceiveError: I2C transceive failed: [Errno 121] Remote I/O error

I am somewhat confused since "i2cdetect -y 1" shows the address of the sensor (among others that I already had):

 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f

00: -- -- -- -- -- -- -- 0a -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- 62 -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- 76 --

The command "i2cdetect -l|sort" outputs the following:

i2c-1 i2c bcm2835 I2C adapter I2C adapter

The funny thing is that with the tutorial from https://github.com/Sensirion/raspberry-pi-i2c-scd4x written in c everything worked out of the box, with the sensor printing the data without any problem. Maybe there is something wrong with the python library? Please let me know if you would like more info. For now I will try to make a workaround by launching the c program and parse its output from inside a python script.

Best regards.

MBjoern commented 2 years ago

Hi there

I was able to reproduce the same error when trying the above script (with some more imports though). I also checked the i2cdetect and i2cget -y 1 0x62 0 to check if the sensor is responsive and made sure the c code works properly...

In the end i got it to work after power cycling the SCD4x (unplug vdd and replug and try to run the script again). Did you try that?

Let me know how it goes.

Best regards Björn

rbuffat commented 2 years ago

I ran into the same issue (Running the example code in a python:3.9 based Docker container on a raspberry pi 4).

Currently, it looks as the following commands help to mitigate the issue. But I have yet to confirm if this is works reliably.

...
scd41 = Scd4xI2cDevice(i2c_connection)
scd41.stop_periodic_measurement()
time.sleep(1)
scd41.reinit()
time.sleep(5)
# start periodic measurement in high power mode
scd41.start_periodic_measurement()
...

It is based on https://github.com/Sensirion/raspberry-pi-i2c-scd4x/blob/master/scd4x_i2c_example_usage.c#L48-L51 Interestingly, scd41.wake_up() will result in the same error when used before scd41.stop_periodic_measurement() contrary to the raspberry pi C sample code.

psachs commented 2 years ago

I re-open this issue so we can better track the underlying problem. The Python driver should behave the same as the raspberry PI C driver as they both connect to /dev/i2c-1 to communicate with the sensor.

Since we access a file-like device we have to ensure that only once process is communicating with it at the same time. Else we might get some I/O errors.

psachs commented 2 years ago

I tested all scripts and input several times on a Raspberry Pi with an SCD41 connected to i2c-1 and could not reproduce any of the errors.

I therefore assume it is not a problem with the Python driver.

MycroHarvest commented 9 months ago

To get @psachs 's code to work I also had to add this line to the imports

from sensirion_i2c_scd import Scd4xI2cDevice

After installing the scd package with

pip install sensirion-i2c-scd

psachs commented 8 months ago

@MycroHarvest thanks for the note. Of course you are correct. I will edit my response to fix the missing import in the example.