简体   繁体   English

如何使用 python I2C TCA9548A 从多路复用器读取

[英]How to read from multiplexer with python I2C TCA9548A

Based on the following links: https://forums.adafruit.com/viewtopic.php?f=19&t=83918&p=541562&hilit=TCA9548A#p541562 https://github.com/kizniche/Mycodo/issues/43#issuecomment-156718451 Based on the following links: https://forums.adafruit.com/viewtopic.php?f=19&t=83918&p=541562&hilit=TCA9548A#p541562 https://github.com/kizniche/Mycodo/issues/43#issuecomment-156718451

I have created the followingÑ:我创建了以下Ñ:

Multiplexer.py多路复用器.py

#!/usr/bin/python

# Change channel of TCA9548A
# Example: sudo ./multiplexer_channel.py 0

import smbus
import time
import sys

I2C_address = 0x77
I2C_bus_number = 1
I2C_ch_0 = 0b00000001
I2C_ch_1 = 0b00000010
I2C_ch_2 = 0b00000100
I2C_ch_3 = 0b00001000
I2C_ch_4 = 0b00010000
I2C_ch_5 = 0b00100000
I2C_ch_6 = 0b01000000
I2C_ch_7 = 0b10000000

def I2C_setup(i2c_channel_setup):
    bus = smbus.SMBus(I2C_bus_number)
    bus.write_byte(I2C_address,i2c_channel_setup)
    time.sleep(0.1)
    print "TCA9548A I2C channel status:", bin(bus.read_byte(I2C_address))

I2C_setup(int(sys.argv[1]))

and index2.py和 index2.py

from tentacle_pi.BMP180 import BMP180
import time
bmp = BMP180(0x70,"/dev/i2c-1")


for x in range(0,1005):
        print "temperature: %s" % bmp.temperature()
        print "pressure: %s" % bmp.pressure()
        print "altitude: %s" % bmp.altitude()
        print
        time.sleep(2)

If I execute the first file with parameters 0 to 7 (multiplexer ports), I get always a connection time out.如果我使用参数 0 到 7(多路复用器端口)执行第一个文件,我总是会遇到连接超时。

Please note I am using a raspberry PI 3 and everything is connected.请注意,我使用的是树莓派 3,一切都已连接。

If I execute the 2nd file, I GET readings, but they are always misleading (fixed readings), and btw, I think the second file will not work if I have many sensors(BMP180)如果我执行第二个文件,我会得到读数,但它们总是具有误导性(固定读数),顺便说一句,如果我有很多传感器(BMP180),我认为第二个文件将不起作用

EDIT1: 1. When we try i2cdetect y, we get nothing. EDIT1: 1. 当我们尝试 i2cdetect y 时,我们什么也得不到。 2. We found another Pythong program to work with the multiplexerÑ 2. 我们找到了另一个 Pythong 程序来使用多路复用器Ñ

# coding=utf-8

import argparse
import smbus
import time


class TCA9548A(object):
    def __init__(self, bus, address=0x70, ):
        self.i2c_address = address
        self.i2c_bus = bus
        self.bus = smbus.SMBus(self.i2c_bus)

    def setup(self, channel):
        try:
            self.bus.write_byte(self.i2c_address, channel)
            return 1, "Success"
        except Exception as msg:
            return 0, "Fail: {}".format(msg)

    def read(self):
        time.sleep(0.1)
        return self.bus.read_byte(self.i2c_address)


def menu():
    parser = argparse.ArgumentParser(description='Select I2C address and channel of TCA9548A I2C multiplexer')
    parser.add_argument('-a', '--address', metavar='ADDRESS', type=int,
                        help='I2C address of the multiplexer, only last two digits, (ex. enter "70" if 0x70)',
                        required=True)
    parser.add_argument('-b', '--bus', metavar='BUS', type=int,
                        help='I2C bus of the multiplexer',
                        required=True)
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-c', '--channel', metavar='CHANNEL', type=int,
                       help='Channel to be activated with the multiplexer')
    group.add_argument('-r', '--read', action='store_true',
                       help='Only read multiplexer and return channel number')

    args = parser.parse_args()

    i2c_address = int(str(args.address), 16)
    multiplexer = TCA9548A(args.bus, i2c_address)
    if args.channel:
        multiplexer.setup(args.channel)
    read_response = multiplexer.read()
    print("TCA9548A I2C channel status: {} (channel {})".format(bin(read_response), read_response))


if __name__ == "__main__":
    menu()

When we try to execute it like this:当我们尝试像这样执行它时:

sudo python index3py -a 70 -b 1

we also get a connection timeout我们也得到一个连接超时

I am starting to believe that maaybe we have something wrongly connected.我开始相信也许我们有一些错误的联系。

We used adafruit wiring sample我们使用了 adafruit 接线样本

EDIT2: coming with pics EDIT2:附带图片

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

Edit3: I restarted the PI, and now I can see the i2c on 77 address. Edit3:我重新启动了 PI,现在我可以在 77 地址上看到 i2c。

However I am getting misleading results, I tried all 7 channels with the same program (index2.py)changed 70 to 77. and I get always a temperature which makes no sense.但是我得到了误导性的结果,我尝试了所有 7 个频道,将相同的程序 (index2.py) 更改为 70 到 77。我总是得到一个没有意义的温度。

pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index3.py -a 77 -b 1 -c 0
TCA9548A I2C channel status: 0b11111000 (channel 248)
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index2.py
temperature: -125.599998474
pressure: 40287
altitude: -31.4230690002

temperature: -52.5
pressure: 40183
altitude: -31.5887317657

temperature: -52.5
pressure: 40281
altitude: -37.2313270569

temperature: -52.5
pressure: 40284
altitude: -34.078414917

^CTraceback (most recent call last):
  File "index2.py", line 11, in <module>
    time.sleep(2)
KeyboardInterrupt
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index3.py -a 77 -b 1 -c 1
TCA9548A I2C channel status: 0b1 (channel 1)
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index2.py
temperature: -125.699996948
pressure: 40166
altitude: -31.7548980713

temperature: -52.4000015259
pressure: 40163
altitude: -34.5762786865

^CTraceback (most recent call last):
  File "index2.py", line 11, in <module>
    time.sleep(2)
KeyboardInterrupt
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index3.py -a 77 -b 1 -c 2
TCA9548A I2C channel status: 0b0 (channel 0)
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index2.py
temperature: -125.699996948
pressure: 28375
altitude: 1204.44226074

temperature: -52.4000015259
pressure: 28303
altitude: 1222.52453613

^CTraceback (most recent call last):
  File "index2.py", line 11, in <module>
    time.sleep(2)
KeyboardInterrupt
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index3.py -a 77 -b 1 -c 3
TCA9548A I2C channel status: 0b0 (channel 0)
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index2.py
temperature: -125.699996948
pressure: 28304
altitude: 1205.19128418

temperature: -52.5
pressure: 28301
altitude: 1222.90002441

^CTraceback (most recent call last):
  File "index2.py", line 11, in <module>
    time.sleep(2)
KeyboardInterrupt
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index3.py -a 77 -b 1 -c 4
TCA9548A I2C channel status: 0b100 (channel 4)
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index2.py
temperature: -125.699996948
pressure: 40136
altitude: -46.9332351685

temperature: -52.5
pressure: 40116
altitude: -47.5958938599

^CTraceback (most recent call last):
  File "index2.py", line 11, in <module>
    time.sleep(2)
KeyboardInterrupt
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index3.py -a 77 -b 1 -c 5
TCA9548A I2C channel status: 0b101 (channel 5)
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index2.py
temperature: -125.699996948
pressure: 40185
altitude: -46.9332351685

temperature: -52.5
pressure: 40136
altitude: -47.0986480713

^CTraceback (most recent call last):
  File "index2.py", line 11, in <module>
    time.sleep(2)
KeyboardInterrupt
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index3.py -a 77 -b 1 -c 6
TCA9548A I2C channel status: 0b0 (channel 0)
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index2.py
temperature: -125.699996948
pressure: 28365
altitude: 1216.15002441

temperature: -52.5
pressure: 28297
altitude: 1215.96289062

^CTraceback (most recent call last):
  File "index2.py", line 11, in <module>
    time.sleep(2)
KeyboardInterrupt
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index3.py -a 77 -b 1 -c 7
TCA9548A I2C channel status: 0b0 (channel 0)
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index2.p
python: can't open file 'index2.p': [Errno 2] No such file or directory
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ sudo python index2.py
temperature: -125.699996948
pressure: 28368
altitude: 1219.89953613

temperature: -52.5
pressure: 28283
altitude: 1219.71179199

temperature: -52.5
pressure: 28353
altitude: 1219.71179199

^CTraceback (most recent call last):
  File "index2.py", line 11, in <module>
    time.sleep(2)
KeyboardInterrupt
pi@pi1:~/Documents/NodeJSProjects/PythonTests $ ^C

I modified your original example, and this is what works for me:我修改了你原来的例子,这对我有用:

My TCA9548A.py is as follows:我的TCA9548A.py如下:

#!/usr/bin/python
# intended for import to change channel of TCA9548A
# import then call I2C_setup(multiplexer_addr,multiplexer_channel)

import smbus
import time
import sys

channel_array=[0b00000001,0b00000010,0b00000100,0b00001000,0b00010000,0b00100000,0b01000000,0b10000000]

def I2C_setup(multiplexer,i2c_channel_setup):
    bus = smbus.SMBus(1)
    bus.write_byte(multiplexer,channel_array[i2c_channel_setup])
    time.sleep(0.01)
    #uncomment to debug #print("TCA9548A I2C channel status:", bin(bus.read_byte(multiplexer)))

And then in the same directory I have a file read_sensor.py which makes use of your example:然后在同一目录中,我有一个文件read_sensor.py使用您的示例:

#!/usr/bin/python

import TCA9548A

# set specific multiplexer to a specific channel
# TCA9548A.I2C_setup( multiplexer_addr , multiplexer_channel )
TCA9548A.I2C_setup(0x70,5)

Next, import libraries as needed and get data from your sensor.接下来,根据需要导入库并从传感器获取数据。 I have multiple BMP280's which all have the same 0x76 address.我有多个 BMP280,它们都具有相同的 0x76 地址。 So when I read from that BMP280 sensor at 0x76 the multiplexer will only have that one channel selected and open to the I2C lines.因此,当我从 0x76 的 BMP280 传感器读取数据时,多路复用器将只选择一个通道并打开 I2C 线路。 Next I may go TCA9548A.I2C_setup(0x70,6) and then read again from BMP280 at 0x76 but I'll receive data from the next BMP280 on channel 6 of that multiplexer.接下来我可能会 go TCA9548A.I2C_setup(0x70,6)然后在 0x76 从 BMP280 再次读取,但我将在该多路复用器的通道 6 上接收来自下一个 BMP280 的数据。

I have another multiplexer which I'll call by its custom address 0x71.我有另一个多路复用器,我将通过其自定义地址 0x71 调用它。 I pulled it's A0 pin high to VCC to change the address to 0x71 for that multiplexer.我将它的 A0 引脚拉高到 VCC,以将该多路复用器的地址更改为 0x71。 Please note my code here does not make use of the ability for the multiplexer to select no channel, so be aware the last selected channel of any multiplexer will be open to the I2C lines.请注意我这里的代码没有利用多路复用器的能力 select 没有通道,所以请注意任何多路复用器的最后选择的通道将对 I2C 线路开放。 I didn't use the Wire.write(0) method like in Adafruit's example ... so perhaps before using channels on multiple multiplexers either select unused channels on unused multiplexers or use GPIO to pull the multiplexer RST pin low to disable it.我没有像在Adafruit 的示例中那样使用Wire.write(0)方法......所以也许在使用多个多路复用器上的通道之前,select 未使用的多路复用器上的未使用通道或使用 GPIO 将多路复用器 RST 引脚拉低以禁用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM