Reputation: 34018
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
#!/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
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.
Please note I am using a raspberry PI 3 and everything is connected.
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)
EDIT1: 1. When we try i2cdetect y, we get nothing. 2. We found another Pythong program to work with the multiplexerÑ
# 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
EDIT2: coming with pics
Edit3: I restarted the PI, and now I can see the i2c on 77 address.
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.
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
Upvotes: 4
Views: 11613
Reputation: 305
I modified your original example, and this is what works for me:
My TCA9548A.py is as follows:
#!/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:
#!/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. 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. 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.
I have another multiplexer which I'll call by its custom address 0x71. I pulled it's A0 pin high to VCC to change the address to 0x71 for that multiplexer. 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. 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.
Upvotes: 2