Uncategorized

How can Rpi4B select multiple ADS1115 ADCs using PCA9546 I2C multiplexer?

Asked 
Active today
Viewed 29 times
1

I have a PCA9546 i2c multiplexer hook to my raspberry pi under it are 4 ads1115 i2c ADC.

My first main problem is how do you switch the address of the i2c in python the sample code that i have seems to defaulty point at 0x48. The base address of the multiplexer is 0x70 ( upto 0x77 if multiple are connected). the code seems to be using busio library and when i looked up the documentation there seems to be no way of changing the default address.

Second problem is the code takes in an i2c object for it to get data on, how do i tell the PCA9546 to toggle between its 4 sub devices

here is the code

import time
import board
import busio
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.ads1x15 import Mode
from adafruit_ads1x15.analog_in import AnalogIn

# Data collection setup
RATE = 860
SAMPLES = 1000

# Create the I2C bus with a fast frequency
i2c = busio.I2C(board.SCL, board.SDA, frequency=1000000)

# Create the ADC object using the I2C bus
ads = ADS.ADS1115(i2c)

# Create single-ended input on channel 0
chan0 = AnalogIn(ads, ADS.P0, ADS.P1)

# ADC Configuration
ads.mode = Mode.CONTINUOUS
ads.data_rate = RATE

data = [None]*SAMPLES

start = time.monotonic()

# Read the same channel over and over
for i in range(SAMPLES):
    data[i] = chan0.voltage

end = time.monotonic()
total_time = end - start


for x in range(SAMPLES):
    print((0,data[x]*1000))

print("Time of capture: {}s".format(total_time))
print("Sample rate requested={} actual={}".format(RATE, SAMPLES / total_time))
  • 1
    My answer to the following question might help for your first question. For your second question, I will try to give an answer later. raspberrypi.stackexchange.com/questions/106218/… – tlfong01 Dec 22 at 1:41
  • @tlfong01 your link doesnt seem to contain related to pca9546, perhaps the wrong link ? I have no problem accessing the i2c switch, i just need to toggle between the 4 sub devices. i have read the data sheet it has a control register but i have no idea how to do it in python – Jack 14 hours ago
  • Ah, my apologies. The link is actually for PCF8575. I remember PCF8575 is similar to PCA9546, uses A0, A1, A2 to address 8 devices. Sorry if I have mistaken. I tried 9546 a year ago, and I forgot how I did it, I need to see if I can find the old program, or read it again and try it out. Might take a couple of days. Hope to reply again then. – tlfong01 14 hours ago
  • @tlfong01 no problem in the meantime ill be asking around other forums, or i might even stumble to solution reading documentations – Jack 14 hours ago
0

Question

How to use Rpi4B to control multiple ADS1115 I2C ADCs, using PCA9546 I2C Multiplexer?


Answer

(1) PCA9645 Datasheet Section 6.1 explains the device slave address is 0x70 to 0x77. In other words, 7 PCA9645s can be placed on the same I2C bus. You use A2, A2, A0 address decode pins/bits to select which PCA9685 device (not channel) to use. The 8 PCA9685s are A2, A1, A0 hardwired with each unique combination, Gnd, Gnd, Gnd to Vcc, Vcc, Vcc as addresses 0x70 to 0x77. The link I suggested you in my very first comment for reference is for PCF8574 which also has A2, A1, A0 and use the same device address decoding trick. So you should find it helpful, well, hopefully.

(2) PCA9645 Datasheet Section 6.2 and 6.2.1 explains how to select one of the 4 mux channels of any particular device. In your case of 4 ADS1115s, each connected to 1 of the 4 PCA9645 channels, you use the control register’s 4 bits B3, B2, B1, B0 to select which channel, therefore which ADC1115 to use.

(3) You code sets I2C speed to 1,000,000 Hz = 1MHz which is a bit too high. My experiment for Rpi4B is that I2C 800kHz is about the upper limit, beyond than that the transmission is not longer stable. You will get I/O error messages.

(4) For Rpi3B, actually there is a known/confirmed hardware/firmware bug and you CANNOT set the I2C speed, even “official” doc says otherwise. In other words, Rpi3B I2C speed is a flat 100kHz, no matter what you try to do. For Rpi4B buster, you can set I2C speed from as low as 10kHz to perhaps 800kHz, at which speed, system gets unstable.

(5) AdaFruit’s ADS1115 library might be outdated. They said they no longer support Rpi and only entertains CircuitPython which is compatible to a long hardware/SBC/MCU list which sadly does NOT include Rpi. You need to search other GitHub blogs which modifies AdaFruit’s library to make it Rpi compatible. But those blogs are usually maintained by one guys, or a small group of guys which might not provide enough doc.

(6) Since AdaFruit and SparkFun used to support Arduino and now only biased to CircuitPython, their Rpi tutorials and libraries are often only applicable to the old Rpi1/2. Rpi3 is often not supported, not to mention Rpi4.

(7) Another shop that supports Rpi is Pimoroni. You might search their Rpi friendly tutorials in case you find AdaFruit library not up to date for your Rpi3/4.

(8) I hope I have answered your two questions. Please let me know if there is still things not clear.

(9) You code on ADS1115 is AdaFruit only, so might not work with Rpi. You might try again without PCA9654, and ask another question specific to ADS1115 but not PCA9654, I will try to see if I can help. Happy python programming and cheers! 🙂


References

(1) ADS1115 Datasheet – TI

(2) AdaFruit ADS1115 Module Overview – AdaFruit

(3) AdaFruit ADS1115 Module Features – AdaFruit

(4) Adafruit 4-Channel ADC Breakouts Tutorial – Bill Earl, AdaFruit (Page 7 of 24 on I2C Adressing

(5) How to interface more than 10x ADS1115 a raspberry pi? – Rpi StackExchange Q&A


Appendices

Update 2019dec25hkt1241

Appendix A – – ADS1115 Clever I2C Device Addressing

Actually ADS111s has a very clever way of device addressing, which I have not seen in other devices. Usually you need 3 address pins to decode 8 devices, and 2 address pins to decode 4 devices. But this ADS1115 can do the following:

USE ONLY ONE PIN (CALLED ADR) TO DECODE/SELECT 4 ADS1115 DEVICES,

as explain below:

Adafruit 4-Channel ADC Breakouts Created by Bill Earl Page 7 of 24

I2C Addressing The ADS11x5 chips have a base 7-bit I2C address of 0x48 (1001000) and a clever addressing scheme that allows four different addresses using just one address pin (named ADR for ADdRess). To program the address, connect the address pin as follows:

0x48 (1001000) ADR -> GND, 
0x49 (1001001) ADR -> VDD, 
0x4A (1001010) ADR -> SDA, 
0x4B (1001011) ADR -> SCL

.END

Categories: Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: