I2C not working with 74HC151 multiplexer (EDIT: Trying with SoftI2C.h now)

Hello there, I’m working on a project where I am taking readings from multiple sensors which use I2C to talk to my microcontroller. Using the Wire.h library, I have successfully managed to get one sensor to output successfully, now I just need to get them all working; or rather I need to select which is active at any given time.

For this I am using a SN74HC151N multiplexer, but for some reason I cannot get it to work. In the code below I am simply trying to get one sensor to come through (D0, from datasheet) and initialise it, but from testing I have found that the program will not pass the Wire.endTransmission(); line.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#define address 0x1E
Adafruit_PCD8544 display = Adafruit_PCD8544(20,19,17,21,18);
int ma = 0;          // A
int mb = 1;          // B
int mc = 2;          // C
int strobe = 3;      // Not G

void setup() {
  // Pins to control what is coming through mux
  pinMode(ma,OUTPUT);
  pinMode(mb,OUTPUT);
  pinMode(mc,OUTPUT);
  pinMode(strobe,OUTPUT);
  
  // Set everything to low (D0 enabled) (strobe low to allow data through)
  digitalWrite(ma,LOW);
  digitalWrite(mb,LOW);
  digitalWrite(mc,LOW);
  digitalWrite(strobe,LOW);
  
  // Initialise the active I2C device
  Wire.begin();
  Wire.beginTransmission(address);
  Wire.write(0x02);
  Wire.write(0x00);
  Wire.endTransmission();   // This is the line that breaks it, program does not get past here
  
  // Initialise LCD display
  display.begin();
  display.setContrast(60);
  display.clearDisplay();
}

I’m unsure why the connection is failing, and have tried changing ports for everything, but with no luck. If anyone has any advice, I would greatly appreciate it. Thanks in advance.

Datasheet can be found here:

EDIT 1: Working with this library instead now (also, title change):
http://playground.arduino.cc/Main/SoftwareI2CLibrary

I2C is bidirectional. Those chips aren't.

If you can't change the device addresses then a better idea is to use software I2C with a different pair of Arduino pins for each device.

Thanks for the reply Fungus.

Taking you’re advice, I’ve done some research and read through other forum posts, and now I’m trying to use the SoftI2C.h library (link below). I’ve changed it up a little, but for the most part it’s a copy/paste test using just one I2C device but I can’t get it to work. It’s returning values which don’t change over time and are very different from what I received when testing with the Wire.h library. Any suggestions?

#define SCL_PIN 0
#define SCL_PORT PORTB
#define SDA_PIN 1
#define SDA_PORT PORTB
#define address 0x1E
#include <SoftI2CMaster.h>

// Irrelevant code not included

int a,b,c;

int readVal(boolean last) {
  uint8_t msb,lsb;
  lsb = i2c_read(false);
  msb = i2c_read(last);
  return (int)((msb<<8)|lsb)/64;
}

void readI2C(void) {
  i2c_start(address|I2C_WRITE);
  i2c_write(0x02);
  i2c_rep_start(address|I2C_READ);
  a = readVal(false);
  b = readVal(false);
  c = readVal(true);
  i2c_stop();
}

void setup() { 
  i2c_start(address|I2C_WRITE);
  i2c_write(0x0A);
  i2c_write(B00000010);
  i2c_stop();
  // Irrelevant code not included
}

void loop() {  
  readI2C();

  // Irrelevant code not included
}

Utilising library and example code from this page:
http://playground.arduino.cc/Main/SoftwareI2CLibrary

Did you read the datasheet for the 74HC151 ? Does it say anywhere that it is an I2C device ? If someone only speaks English, is it going to do you any good to speak to them in Russian ? You cannot use I2C with a 74H151. I shouldn't have to tell you that. It is clear from the datasheet. There is nothing more to discuss on this post.

The SoftI2C library is designed for using I2C when A4 & A5 are already in use, NOT for using I2C with NOT-I2C devices. You didn't read the 74HC151 datasheet and you didn't read the information about SoftI2C http://playground.arduino.cc/Main/SoftwareI2CLibrary

You're wasting our time. We don't mind helping people with no experience, but we do mind wasting our time with people who are too lazy to read datasheets or Playground page explanations.

raschemmel: You're wasting our time. We don't mind helping people with no experience, but we do mind wasting our time with people who are too lazy to read datasheets or Playground page explanations.

I'm fairly sure he was only trying to multiplex the I2C signals with the SN74HC151N.

OTOH we still know nothing about the sensors or how they work, what the "working" I2C code looks like, what values he's receiving, what values he expected, nothing at all for anybody to work with. Time is indeed running out.

I’m fairly sure he was only trying to multiplex the I2C signals with the SN74HC151N.

You hope. We won’t know until he posts a schematic.
@OP,
Draw a schematic and post a photo of it.

Yes, he actually has the chips confused. The chip he wants is a 74HC*4051*, and he needs two of them, one for the SDA and one for SCL. If you only wanted to use four sensors, a single 74HC4052 would be perfect. Going to be much more efficient than using SoftI2C though that would be remotely possible.

I was wondering why this was in "LEDs and Multiplexing" but I suppose it is indeed "multiplexing". :D Mostly we expect to see discussions of display or keyboard multiplexing here.

I didn't know you could MUX an I2C signal while it is sending or recieving data.

You can't change where signals are connect to while data is moving, but assuming that the AVR is the only master then you can select which bus the AVR 2Wire signals are connected to before you call the Wire routines.

I bet you can get away with only muxing SDA vs having to do both SDA and SCK. Tie all the SCK signals together. Since only the slave on the selected bus will see his address, only that slave will respond. All the other slaves on the non selected buses should see an address of 0xff/0x7f from the idle pullups and remain silent.

--- bill

raschemmel:
Did you read the datasheet for the 74HC151 ? Does it say anywhere that it is an I2C device ?

You’re wasting our time. We don’t mind helping people with no experience, but we do mind wasting our time with people who are too lazy to read datasheets or Playground page explanations.

Yes I did read the datasheet, but I will admit that I forgot to check for that. The fellow at the store said that it would work, so I took him on his word; newbie mistake, my apologies.

The SoftI2C library is designed for using I2C when A4 & A5 are already in use, NOT for using I2C with NOT-I2C devices

I am planning on using 4 I2C devices, not just the one. I wanted to get the code working for a single device first so that I could understand what I was doing.

fungus:
OTOH we still know nothing about the sensors or how they work, what the “working” I2C code looks like, what values he’s receiving, what values he expected, nothing at all for anybody to work with.

I’m using two HMC5883L magnetometers and two ADXL345 accelerometers (everything is triple axis). I have been doing my testing with one of the magnetometers, and expected initial readings of something like 200,-120,200 (they were what I got using Wire.h), but using the SoftIC2.h library I’m getting 480,480,480 (or something along those lines).

raschemmel:
Draw a schematic and post a photo of it.

I have attached two images, one for how I connected everything with the multiplexer, the other for how I hooked everything up when using SoftI2C.h. Sorry about the poor quality.

bperrybap:
I bet you can get away with only muxing SDA vs having to do both SDA and SCK. Tie all the SCK signals together.

Upon reading this somewhere else in these forums I have given this a shot, but I couldn’t get it to work with the multiplexor I was using (due to it not being the wrong one, I suppose).

Kadin_S: Yes I did read the datasheet, but I will admit that I forgot to check for that.

It's not something for which you could check - I2C and that chip simply have nothing to do with each other. YOu have to know what you want to do in detail.

Kadin_S: The fellow at the store said that it would work, so I took him on his word; newbie mistake, my apologies.

LMFAO! "The fellow at the store said"!

Kadin_S: I am planning on using 4 I2C devices, not just the one. I wanted to get the code working for a single device first so that I could understand what I was doing.

Dead right. You then need a 74HC4052. Two channels, SDA and SCL, four devices, don't worry about tying things together. You need pull-ups on each I2C slave when using a multiplexer in this fashion. Clearly you have to wait for each transaction to fully complete before switching, but otherwise should be no problem.

Kadin_S: I couldn't get it to work with the multiplexer I was using (due to it not being the wrong one, I suppose).

Dead right.

raschemmel: OMG ! I2C is a BUS ! .ALL OF THE DEVICES ARE SUPPOSED TO ON THE BUS ALL THE TIME! YOU DON'T NEED TO MUX A BUS. Do you know what a Bus is ?

Pull your head in. :zipper_mouth_face:

raschemmel: OMG ! I2C is a BUS ! .ALL OF THE DEVICES ARE SUPPOSED TO ON THE BUS ALL THE TIME! YOU DON'T NEED TO MUX A BUS. Do you know what a Bus is ?

So - what do you suppose this is then? Did you not read this recent thread in detail and note reply three?

Give me one reason to MUX an I2C Bus where each device gas a unique address .

raschemmel:
Give me one reason to MUX an I2C Bus where each device gas a unique address .

No, but when you are using more than one of the same device with the same address, there clearly is a reason.

Addendum:
Are you perhaps confusing this situation with Dallas Semiconductor “one wire” bus where every device is manufactured with a unique ID?

No but now I see why they did that.

Kadin_S:

bperrybap: I bet you can get away with only muxing SDA vs having to do both SDA and SCK. Tie all the SCK signals together.

Upon reading this somewhere else in these forums I have given this a shot, but I couldn't get it to work with the multiplexor I was using (due to it not being the wrong one, I suppose).

Both signals (SDA and SCK) are bidirectional so you still must use a bi-directional switch even if you don't mux/switch the SCK signal.

--- bill

or a DPDT relay...

raschemmel: or a DPDT relay...

But that now probably requires a transistor, and a diode and the processor will have to blind wait many milliseconds (probably 10-20) to give the contacts time to move and then let the contacts settle after changing states. Not to mention it needs quite a bit more current and is typically much larger than using a analog switch chip. IMHO, an analog switch/mux/demux chip is a much better solution.

@OP, Have you tried any basic troubleshooting techniques like isolating 3 of the 4 devices and trying to run the code with only ONE device on the bus ? (and rotate devices until you have tested all four ?)

Paul__B:

Kadin_S: I am planning on using 4 I2C devices, not just the one. I wanted to get the code working for a single device first so that I could understand what I was doing.

Dead right. You then need a 74HC4052. Two channels, SDA and SCL, four devices, don't worry about tying things together. You need pull-ups on each I2C slave when using a multiplexer in this fashion. Clearly you have to wait for each transaction to fully complete before switching, but otherwise should be no problem.

I've ordered two 74HC4052 multiplexers, and am waiting for them to arrive now. These look like exactly what I need, thanks for pointing them out.

Another question though, what is the difference between the 74HC4052 and one of these: http://www.dsscircuits.com/i2c-multiplexer Is it just the addition of the interrupt inputs and output? And if so, what could make one of them preferable to a 74HC4052?

raschemmel: @OP, Have you tried any basic troubleshooting techniques like isolating 3 of the 4 devices and trying to run the code with only ONE device on the bus ? (and rotate devices until you have tested all four ?)

Yeah I have tried this, but with no luck unfortunately.