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

I'm using your code for the SPS30 which is really cool but I have a problem. #1

Open
jbasemvd opened this issue Dec 24, 2021 · 5 comments

Comments

@jbasemvd
Copy link

I'm hoping you can help me with an error running example.py. I get this error:

Serial number: CCC69E8DCEAD8B5F
Status register: {'speed_status': 'ok', 'laser_status': 'ok', 'fan_status': 'ok'}
Traceback (most recent call last):
File "/home/pi/Source/SPS30/example.py", line 13, in
print(f"Auto cleaning interval: {pm_sensor.read_auto_cleaning_interval()}s")
File "/home/pi/Source/SPS30/sps30.py", line 167, in read_auto_cleaning_interval
data = self.i2c.read(NBYTES_AUTO_CLEANING_INTERVAL)
File "/home/pi/Source/SPS30/i2c/i2c.py", line 21, in read
return list(self.fr.read(nbytes))
OSError: [Errno 121] Remote I/O error

If I remove/comment the line print(f"Auto cleaning interval: {pm_sensor.read_auto_cleaning_interval()}s")line I get readings as expected:

Do you have any thoughts on what might be happening?

Here is the code I'm using which is the example.py file included in the download:

import sys
import json
from time import sleep
from sps30 import SPS30

if name == "main":
pm_sensor = SPS30()
print(f"Firmware version: {pm_sensor.firmware_version()}")
print(f"Product type: {pm_sensor.product_type()}")
print(f"Serial number: {pm_sensor.serial_number()}")
print(f"Status register: {pm_sensor.read_status_register()}")
#print(f"Auto cleaning interval: {pm_sensor.read_auto_cleaning_interval()}s")
pm_sensor.start_measurement()

while True:
    try:
        print(json.dumps(pm_sensor.get_measurement(), indent=2))
        sleep(2)

    except KeyboardInterrupt:
        print("Stopping measurement...")
        pm_sensor.stop_measurement()
        sys.exit()

Thanks advance,
Walt

@dvsu
Copy link
Owner

dvsu commented Dec 28, 2021

Hi Walt,

OSError: [Errno 121] Remote I/O error relates to I2C device connection. It can be either caused by loose wiring or R/W timing. At first, I thought it might be caused by loose wiring. But judging from the output, it might not be the case. serial_number() and read_status_register() methods share the same I2C class and it seems to function properly. Then the cause may be the latter.

I scan through the latest Sensirion SPS30 datasheet (page 18), and discover that there is command execution time difference between firmware version 1.0 and 2.2. Could you check your SPS30 FW version once again and confirm whether this is the cause? If it is, try to introduce some delay and see whether it solves the problem.

def read_auto_cleaning_interval(self) -> int:
        # sleep(0.05) # this delay may not be required, but feel free to try
        self.i2c.write(CMD_AUTO_CLEANING_INTERVAL)
        sleep(0.05) # try adding this delay
        data = self.i2c.read(NBYTES_AUTO_CLEANING_INTERVAL)

At the same, I will check it on my side when I get the RasPi board and sensor ready. I will keep you updated.

Dave

@jbasemvd
Copy link
Author

jbasemvd commented Dec 28, 2021 via email

@drevil75
Copy link

drevil75 commented Jan 1, 2023

Hello Dave,

i had the same problem like walt. I've tried the sleep commands and it's working.
My SPS30 has the FW-Version: 2.3

But i've an additional Question.
In the response below is a key/value for "particle_count" pm0.5: 1234..
But there is no similar key/value under "mass density".
I've tried to add the key/value pair in the sds30.py, but i still get no density for pm0.5.

Do you know why?

BR
Mirko

@drevil75
Copy link

drevil75 commented Jan 1, 2023

...and here the response..
{ "sensor_data": { "mass_density": { "pm1.0": 8.004, "pm2.5": 10.587, "pm4.0": 12.279, "pm10": 13.211 }, "particle_count": { "pm0.5": 49.857, "pm1.0": 61.257, "pm2.5": 63.669, "pm4.0": 64.11, "pm10": 64.223 }, "particle_size": 0.704, "mass_density_unit": "ug/m3", "particle_count_unit": "#/cm3", "particle_size_unit": "um" }, "timestamp": 1672603643 }

@dvsu
Copy link
Owner

dvsu commented Jan 3, 2023

Hi Mirko,

Regarding your second question, it is in fact the limitation of the sensor. If you refer to the latest datasheet, specifically on page 2 and 6, it states that the supported measurements are

Mass concentration: PM1.0-PM10 (measured in µg/m³)
Number concentration: PM0.5-PM10 (measured in counts/cm³)

Also, the specification on page 2 says that the condition for particle to be considered as PM1.0 is by having mass concentration size, ranging from 0.3 to 1.0 μm. So, theoretically, the sensor is able to detect mass density between the range, but it is difficult to differentiate whether the measured mass density is of particle size ranging from 0.3 to 0.5 μm, or 0.5 to 1.0 μm. In other words, the sensor may be able to measure the mass density of PM0.5, but with the trade-off of low precision. I guess, Sensirion chose to combine the measurement as mass density of PM1.0 instead to ensure the measurement precision stay within targeted range.

Dave

Reference

SPS30 Datasheet

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

No branches or pull requests

3 participants