I am setting up a Raspberry Pi to record data (CO2, humidity, and temperature) from the Sensirion SCD30 sensor. My code is in Python 3, using the SMBus library to communicate with the sensor over the I²C pins in the Raspberry Pi's GPIO. There is a command to determine whether the sensor is ready to send data.
Link to SCD30 interface datasheet
Link to SCD30 library for Arduino by Sparkfun
The value 0x0202
is sent over I²C, and three bytes of data are returned:
0x00 0x00 0x81 for data not ready
0x00 0x01 0xB0 for data ready
The first two bytes are the MSB and the LSB of the data ready value. Combined properly, they should be 0x0000
and 0x0001
.
The third byte is the CRC8 of the first two bytes. This is calculated with a polynomial of 0x31
and an initialization of 0xFF
.
About half the time, the bytes are sent in the wrong order. Instead of MSB LSB CRC
it is sent MSB CRC LSB
. For example, if the data is ready it might send 0x00, 0xB0, 0x01
instead of 0x00, 0x01, 0xB0
. I can't figure out why this is happening, and I'm concerned there is some corruption or issues in sending data. I could change the code to recognize if the CRC is the second byte, but I would like to find the underlying problem.
I am sending and receiving I²C data using the smbus
library. This is my code to send commands and read data:
bus = smbus.SMBus(0)
I2C_ADDRESS = 0x61
def sendCommand(self, cmd): # Sends a 2 byte command (cmd)
data = [0]*2
data[0] = cmd >> 8 # Splits 2 byte command into MSB and LSB
data[1] = cmd & 0xFF
bus.write_i2c_block_data(I2C_ADDRESS, data[0], data[1:])
def readRegister(self, reg, length): # Sends 2 byte command (reg) and receives (length) bytes
sendCommand(reg)
data = bus.read_i2c_block_data(I2C_ADDRESS, 0, length)
return data
For the example I gave above, I would run the following code:
ready = readRegister(0x0202, 3) # Returns a list of 3 bytes
print(ready)
And it would return a list of the three bytes demonstrated above.
The SMBus library is not right, as the SCD30 requires longer I²C commands than the Linux i2c-dev
library provides.
We are successfully using pigpiod for talking via Python to the sensor. Our code for the SCD30 and install instructions (as well as solutions for the clock stretching issue) can be found here on GitHub.
What sort of tools and skills have you got?
(My first reaction was to search for SCD30 errata, but I can't find any, nor does quick web search reveal any similar problems.)
If you have an oscilloscope or logical analyser, look at SCL and SDA, and confirm the problem is on Raspberry Pi (could be on the sensor as well).
Can you replace any hardware components of the setup - just to eliminate the odd chance of something being faulty.
Can you rewrite the code in C (using /dev/i2c-x), and see if the problem still persists - this would either tell you problem is either in the kernel driver for the I²C master, wiring, SCD30 chip or in library smbus
or other software that sits between your piece of code and the kernel driver.
Good luck
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With