adafruit / Adafruit_Blinka

Add CircuitPython hardware API and libraries to MicroPython & CPython devices
https://learn.adafruit.com/circuitpython-on-raspberrypi-linux
MIT License
457 stars 349 forks source link

i2c address not being recognized? #365

Open maha-haji opened 4 years ago

maha-haji commented 4 years ago

Hi,

I have no issues using the HTU21D, but when I run [hex(x) for x in i2c.scan()] it does not show up in my list of i2c device addresses (i.e. I do not see '0x40' anywhere). Running sudo i2cdetect -y 1 in the command line, it does show up correctly.

Any suggestions on what I might be doing wrong?

Thanks!

ladyada commented 4 years ago

the sensor works fine when you use it, do other i2c items appear? what ocmputer and os are you using

maha-haji commented 4 years ago

yes, I also have a BMP280 that I can see the i2c address of, as well as a BNO055. I'm using a Raspberry Pi 4 Model B, running the latest Raspbian OS

ladyada commented 4 years ago

could be it doesnt like how we scan for devices, its not a 'standard' thing

caternuson commented 3 years ago

Any special reason for the current use of read_byte() in the scan() function? It seems like most other scans use a test write instead of a read, and success if simply getting an ACK at given address.

I just did quick test changing to using quick_write: https://github.com/adafruit/Adafruit_Python_PureIO/blob/f4d0973da05b8b21905ff6bab69cdb652128f342/Adafruit_PureIO/smbus.py#L278 and it seems to work.

Pi 4 with a HTU21D on I2C:

(blinka) pi@raspberrypi:~ $ python3
Python 3.7.3 (default, Dec 20 2019, 18:57:59) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import board
>>> i2c = board.I2C()
>>> i2c.scan()
[64]
>>> 
makermelissa commented 3 years ago

No idea 🤷‍♀️. It's been that way for quite a while.

ladyada commented 3 years ago

there was a reason for this, i think... beaglebone did not have the ability to write without data?

kaolpr commented 1 year ago

Well, I came across that issue too. @ladyada what would you say on giving an option to scan using write? It would require modification of busio.py along with microcontroller files. Microcontrollers not supporting write without data can raise an exception.

ladyada commented 1 year ago

the best thing we can do is if you have something in busio.py that determines the platform its running on and doesn't do a bus-scan that way for whatever platform it doesnt work.

for the individual chips that freak out we use the probe=false 'don't try to scan me while creating the busdevice' https://docs.circuitpython.org/projects/busdevice/en/latest/api.html

kaolpr commented 1 year ago

Well, I was rather thinking of changing busio.I2C.scan method definition to include with_write: bool=False or sth similar.

ladyada commented 1 year ago

we'd rather not change the API as its platform dependent and we don't have it in main CircuitPython - you can add platform dependant code within the scan function - that's the PR we'd accept to review!

yacobucci commented 2 weeks ago

I just ran into this with an SHT45. The BMP390 and PCA9546A report correctly. As noted above, i2cdetect also reports all devices correctly.

It looks like i2cdetect uses a MODE_AUTO by default and switches between write_quick and read_byte depending on i2c bus address.

https://github.com/mozilla-b2g/i2c-tools/blob/3a8a0c5515b4890dfb412971511c932f31d93d9c/tools/i2cdetect.c#L68

            case MODE_AUTO:
                if ((i+j >= 0x30 && i+j <= 0x37)
                 || (i+j >= 0x50 && i+j <= 0x5F))
                    cmd = MODE_READ;
                else
                    cmd = MODE_QUICK;
                break;
            }

How about this solution for the adafruit_blinka/microcontroller/generic_linux/i2c.py scan function? (line 43).

I only have raspberry pi 4 and 5 for testing though.

ladyada commented 2 weeks ago

thats... extremely wierd, why is it address dependant??

yacobucci commented 2 weeks ago

Great question, this is all I know from their manpage:

As there is no standard I2C detection command, i2cdetect uses arbitrary SMBus commands (namely SMBus quick write and SMBus receive byte) to probe for devices. By default, the command used is the one believed to be the safest for each address. See options -q and -r to change this behavior.

And the option help:

   -q     Use  SMBus  "quick  write"  command for probing.  Not recommended. This is known to corrupt the Atmel AT24RF08 EEPROM found on many IBM Thinkpad laptops.

  -r     Use SMBus "receive byte" command for probing.  Not recommended. This  is  known  to lock SMBus on various write-only chips (most notably clock chips at address 0x69).