I2C bus doesn't see scd40 CO2 sensor

CircuitPython on hardware including Adafruit's boards, and CircuitPython libraries using Blinka on host computers.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
fxsvelo
 
Posts: 39
Joined: Thu Jan 02, 2014 3:13 pm

I2C bus doesn't see scd40 CO2 sensor

Post by fxsvelo »

I got one of these CO2 sensors:
https://www.adafruit.com/product/5187

When connected to a Pi Pico it works just fine with a 7 Segment display.

But when I connect it to a Pi 3, it doesn't show up on the I2C bus, even when other devices do.

There's a BMP280, an ADS1015, a 7 Segment Display backpack, and a Plantower pm25 (via UART).

$ python i2c_bus_scan.py
I2C addresses found: ['0x48', '0x70', '0x76'][

I also tried just the scd40 by itself. No luck

$ python i2c_bus_scan.py
I2C addresses found: []

Any ideas?

thanks

Raspberry Pi 3: Raspbian Buster Version 10
Python 3.7.3
Blinka 6.15.0
adafruit-circuitpython-scd4x==1.2.1

User avatar
dastels
 
Posts: 15656
Joined: Tue Oct 20, 2015 3:22 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by dastels »

You followed the Pi related instructions on https://learn.adafruit.com/adafruit-scd ... cuitpython?

Dave

User avatar
blakebr
 
Posts: 957
Joined: Tue Apr 17, 2012 6:23 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by blakebr »

Check the i2c clock speed. A recent firmware update may have upped the clock speed and your CO2 detector may not be able to run at the new higher speed. Several places show how to change the i2c clock speed.

User avatar
fxsvelo
 
Posts: 39
Joined: Thu Jan 02, 2014 3:13 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by fxsvelo »

Yes, I'm using example code from :
https://learn.adafruit.com/adafruit-scd ... cuitpython

but for testing I'm also using:
"CircuitPython Essentials I2C Scan example" i2c_bus_scan.py

Code: Select all

import board
import busio
i2c=busio.I2C(board.SCL,board.SDA,frequency=50000)

I've tried setting the frequency to 20K, 30K, 40K, 50K, 80K. I've tried initializing twice.

Other devices show up, but not the scd40.

I'd stick with the Pico since that works fine, but I want to use the Pi so that I can log to a remote server.

Bill

User avatar
blakebr
 
Posts: 957
Joined: Tue Apr 17, 2012 6:23 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by blakebr »

Bill,

I had problems when the default went to 1000000 (1MHz)
Lowered it to 400000 (400KHZ) and things worked.

Very strange.

Bruce

User avatar
fxsvelo
 
Posts: 39
Joined: Thu Jan 02, 2014 3:13 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by fxsvelo »

Progress, I guess, but no solution. In fact, I'm worse off because now I can't create any I2C device objects.

Using the instructions here:
https://learn.adafruit.com/circuitpytho ... stretching

I set /boot/config.txt:
dtparam=i2c_arm_baudrate=10000

Now i2cdetect (and gpio i2cdetect) see all the devices:

Code: Select all

$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- 62 -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- 76 --   
Though i2c_bus_scan.py still doesn't see the SCD40

Code: Select all

$ python i2c_bus_scan.py 
I2C addresses found: ['0x48', '0x70', '0x76']
Worse, now I can't create any i2c objects with the Adafruit libraries. I just get:

ValueError: No I2C device at address: 0x62 (or 0x70, 0x76, 0x48)

In this example I try setting the frequency. Either like this or just 'i2c=board.I2C()' give the same results.

Code: Select all

$ python
Python 3.7.3 (default, Jan 22 2021, 20:04:44) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import busio
>>> import board
>>> i2c=busio.I2C(scl=board.SCL,sda=board.SDA,frequency=10000)
>>> import adafruit_scd4x
>>> scd4x = adafruit_scd4x.SCD4X(i2c)
Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_bus_device/i2c_device.py", line 154, in __probe_for_device
    self.i2c.writeto(self.device_address, b"")
  File "/home/pi/.local/lib/python3.7/site-packages/busio.py", line 166, in writeto
    return self._i2c.writeto(address, buffer, stop=stop)
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_blinka/microcontroller/generic_linux/i2c.py", line 49, in writeto
    self._i2c_bus.write_bytes(address, buffer[start:end])
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_PureIO/smbus.py", line 314, in write_bytes
    self._device.write(buf)
OSError: [Errno 121] Remote I/O error

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_bus_device/i2c_device.py", line 160, in __probe_for_device
    self.i2c.readfrom_into(self.device_address, result)
  File "/home/pi/.local/lib/python3.7/site-packages/busio.py", line 156, in readfrom_into
    return self._i2c.readfrom_into(address, buffer, stop=stop)
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_blinka/microcontroller/generic_linux/i2c.py", line 56, in readfrom_into
    readin = self._i2c_bus.read_bytes(address, end - start)
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_PureIO/smbus.py", line 181, in read_bytes
    return self._device.read(number)
OSError: [Errno 121] Remote I/O error

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_scd4x.py", line 97, in __init__
    self.i2c_device = i2c_device.I2CDevice(i2c_bus, address)
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_bus_device/i2c_device.py", line 50, in __init__
    self.__probe_for_device()
  File "/home/pi/.local/lib/python3.7/site-packages/adafruit_bus_device/i2c_device.py", line 163, in __probe_for_device
    raise ValueError("No I2C device at address: 0x%x" % self.device_address)
ValueError: No I2C device at address: 0x62


User avatar
blakebr
 
Posts: 957
Joined: Tue Apr 17, 2012 6:23 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by blakebr »

Bill,

Have you played with the pull-up resistors? Try 2,200 ohms on each line pulled up to the 3.3 volt bus. The documentation says 4,700 ohms but I have had success down to 1,000 ohms.

I would go back to 100000 (100kHz)

It is strange that scan sees your devices but you can’t talk to them.

Bruce

User avatar
fxsvelo
 
Posts: 39
Joined: Thu Jan 02, 2014 3:13 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by fxsvelo »

I tried 2.2K pull up resistors. Now all the devices show up with the i2cdetect scan, but the code still gives the "No I2C device at address: ..." error.

I also went back to 100kHz.

The only thing that works is to remove the SCD or a couple of other devices from the bus and reboot.

Could the SCD40 be bad? Otherwise it seems my only option at this point is to use the SCD on a separate microcontroller and communicate with it wired or wireless.

User avatar
blakebr
 
Posts: 957
Joined: Tue Apr 17, 2012 6:23 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by blakebr »

Bill,

Strange...

CircuitPython has the ability to support more than one i2c bus.
SDA & SCL along with SDA1 & SCL1.
You may want to use board.D?? instead of SDA, SCL, SDA1, CSL1

Code: Select all

# Setup I2C and I2C1 busses
i2c  = busio.I2C(board.SCL,  board.SDA)  # SCL =GPIO25, SDA =GPIO24
i2c1 = busio.I2C(board.SCL1, board.SDA1) # SCL1=GPIO23, SDA1=GPIO22
while not i2c.try_lock():
  pass
print("i2c.scan()  = ", end="")
print( i2c.scan(), end="\t") # [87,104], 0x57, 0x68
print([hex(x) for x in i2c.scan()])
while i2c.unlock():
  pass

while not i2c1.try_lock():
  pass
print("i2c1.scan() = ", end="")
print( i2c1.scan(), end="\t") # [60], 0x3C
print([hex(x) for x in i2c1.scan()])
while i2c1.unlock():
  pass
###########################################################
print("")
Bruce

User avatar
fxsvelo
 
Posts: 39
Joined: Thu Jan 02, 2014 3:13 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by fxsvelo »

Hmm... SCL1 and SDA1 don't exist in my version of board. So that code didn't work for me.

What I was able to do was:
- Create a software I2C bus
$ sudo dtoverlay i2c-gpio bus=4 i2c_gpio_delay_us=1 i2c_gpio_sda=23 i2c_gpio_scl=24

- Confirm the bus with "i2cdetect -y 4"

- Using the Adafruit Extended Bus library, create an I2C object for the new bus, put the SCD40 on that bus, and get the SCD40 to work correctly if I add pull up resistors in an i2c-4 configuration only with nothing connected to i2c-1:

from adafruit_extended_bus import ExtendedI2C as I2C
i2c4 = I2C(4)
scd4x = adafruit_scd4x.SCD4X(i2c4)

Where it fails is in the setup with the other I2C bus and devices. It will give data readings at first, but shortly after the scd4x.data_ready test repeatedly fails.

Are we back to clock stretching?
I tried setting the frequency on the bus:
i2c4 = I2C(4, frequency=100000) # default is 400000

and then down to 40000, but with no success.

User avatar
blakebr
 
Posts: 957
Joined: Tue Apr 17, 2012 6:23 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by blakebr »

Bill,

I guess I was not clear. There is the SDA SCL that CircuitPython defines. You can select another pair of pins, say board.D25 and board.D24 and call them your second port. It sounds like that is what you did.

Bruce

User avatar
blakebr
 
Posts: 957
Joined: Tue Apr 17, 2012 6:23 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by blakebr »

Bill,

Do you have access to an oscilloscope, logic probe, etc.? Look at the SDA and SCL lines on both i2c ports. What is happening before and after failure?

If you don't have any test equipment, a transistor driving an LED may be just as good. I am not sure what this will give us, but it just may help.

Bruce

User avatar
fxsvelo
 
Posts: 39
Joined: Thu Jan 02, 2014 3:13 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by fxsvelo »

Here's what I was able to do:

- Create a software I2C bus
$ sudo dtoverlay i2c-gpio bus=4 i2c_gpio_delay_us=1 i2c_gpio_sda=23 i2c_gpio_scl=24

- Confirm the bus with "i2cdetect -y 4"

- Using the Adafruit Extended Bus library, create an I2C object for the new bus, put the SCD40 on that bus, and get the SCD40 to work correctly if I add pull up resistors in an i2c-4 configuration only with nothing connected to i2c-1:

from adafruit_extended_bus import ExtendedI2C as I2C
i2c4 = I2C(4)
scd4x = adafruit_scd4x.SCD4X(i2c4)

Where it fails is in the setup with the other I2C bus and devices. It will give data readings at first, but shortly after the scd4x.data_ready test repeatedly fails.

So I swapped buses. I put the SCD40 on i2c-1 and everything else (7 segment, BMP280, ADC) on i2c-4.

This now seems to work reliably.

BUT... I'm still curious to understand why it wouldn't work before. Alas, no I don't have an oscilloscope or logic probe. Any suggestions on how to use the transistor/LED approach? Would any of the Arduino based oscilloscopes work?

thanks

User avatar
blakebr
 
Posts: 957
Joined: Tue Apr 17, 2012 6:23 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by blakebr »

Hi,

Amazon has an oscilloscope for $35. You can find lower prices but they are generally a kit that you must solder and put together.
Check that it is not a kit, unless your want the 'fun' of putting it together. I have one of these. It is not a $299 O'scope but for $35 you get what you pay for. The $35 version will be fun to play with and to decide if you need one of the $299 scopes. This is your most versatile option.

https://www.amazon.com/dp/B079CPDVRG/?c ... _lig_dp_it

For $11 you can get 4 breadboards and a logic probe at Amazon. I have this and it works great. This is your easiest option.

https://www.amazon.com/EEEEE-Breadboard ... 136&sr=8-8


The transistor thing will need:
2x 1000 ohm resistor (value not critical, 1000 to 5000 on base, 300 to 2000 on LED)
1x NPN Transistor
1x LED

1 resistor from the GPIO pin under test to the base of the transistor.
The emitter of the transistor to ground
The collector to one pin of the LED
The other LED pin to the one lead of the other resistor
The other resistor lead to +3.3 volts +5 volts

If the LED does not light up reverse its leads.
This is your lowest cost option.

Bruce

User avatar
tpowellAQ
 
Posts: 1
Joined: Thu Jun 03, 2021 2:53 pm

Re: I2C bus doesn't see scd40 CO2 sensor

Post by tpowellAQ »

I have a similar situation. I have the SCD-41 daisy chained to a BME688, and PMSA0031 air quality breakout, and all three are then connected to a Qwiic Mux board which then goes back to a Pi B+. I've been using the circuitpython library to contact these devices (as well as 4 INA219s, and an MCP9808). I've had no issues contacting any of my other I2C devices, but I've had no luck contacting the SCD-41. I have another similar setup that uses the SCD-30 rather than SCD-41, and I have had no issues with that. Inserting the SCD-30 into this system doesn't give me any problems either. At this point, the simplest solution seems to be to forgo the SCD-41 and go back to the SCD-30.

Locked
Please be positive and constructive with your questions and comments.

Return to “Adafruit CircuitPython”