Erratic mux behaviour reading many pots via CD74HC4067

Hey there,
i have a setup using a teensy 4.0, a CD74HC4067 and 10 pots connected to it.

In my readout loop i have a delayMicroseconds() to allow the mux to settle after changing the channel:

for (uint8_t channel = 0; channel < 10; channel++)
  {
    mp.setChannel(channel);
    delayMicroseconds(80);
    Serial.print(String(analogRead(A1)) + "\t");
    
  }

Now, sometimes this works as expected, going as low as 50-60 us to get reliable results. But then, sometimes, when using a similar loop within a bigger project, my readings explode: each potentiometer seems to affect the one on the next channel, and to a lesser degree the ones following after that. This behavious gets less the higher I make the settling delay, but only gets usable when it's >1000us, which is way too much for my application.

The weird thing here is, that sometimes, in a clean new debugging project with just the readout loop, it runs fine at 60us. But then once it somehow goes into "slow" mode, it shows the same erratic behaviour even when i upload the clean debug project.

Did anybody ever experience something similar or has any explanation for it?

The hardware is soldered up on a perf board, pretty permanent. And since it sometimes works perfect, and sometimes when i just up the "settle" time, i think i can eliminate connection issues here.

Edit: I am not using the EN pin, but i doubt that will help? Again, sometimes, it seems to work perfectly fine. Also, I did try another CD74HC4067, same behaviour. It is cheap amazon shields though.

Perhaps the impedance of your sensors is too high for the multiplexer. Try an impedance converter (opamp) before or after the mux.

1 Like

The sensor is the ADC of the teensy, I am pretty sure that this would have the right impedance to read analog pots? One of the most common use cases, and I haven't really seen anybody use opamps for the signal between a mux and a MPU?

Also, as I said, sometimes it works as expected with "normal" settling delays. Earlier today i was comparing different 4067 libraries to see if this helps, and for a good while i was getting perfect results at 60us with the same hardware setup. Only when I then went back to my bigger project, the problems came back. And pertained when trying to run the small, clean debugging sketch again.

Thanks for your input though!

FWIW here is the full code of the bigger sketch - the mux loop runs by itself within a function, so the rest of the code shouldn't affect it. In this paste, the settling delay is set to 1500us!!! Which barely makes it work as expected and is wayyy to much for realistic use.

Are any of the inputs to the multiplexer unused and not connected to anything? That would do it.

1 Like

yes thats indeed the case, the last 6 are NC. but they are also not being scanned. should i ground them? still baffled as to why it worked just fine earlier today...

The mux may have been damaged since then by static or EMF. Open inputs are a no-no with MOS devices.

1 Like

Yes.

Because unconnected they float. This will initially not give trouble because the charge is zero from switch on. But as time goes on they begin to increasingly pick up interference which induces what is called cross talk. This affects signals on used channels.

1 Like

Ok thanks a lot, i just grounded the remaining 6 inputs on the PCB but sadly get the same erratic readings. Could the IC indeed be damaged now? Or should I look somewhere else?

EDIT:
so currently, any input on the mux affects the TWO following inputs, not the one before. I assume its not cross talk on the input side but rather the switch needing to long to settle? Might indeed be a damaged IC?

Replace it by a new one and try again.

1 Like

You said it works for a time, with a simple sketch. Maybe stuff you are doing in the rest of the sketch is screwing something up.

1 Like

If only it was in an IC socket... gotta resolder it all :sob:

well, so yesterday i had these same problems. ended up raising the delay to 1500us for it to work at all. then earlier today i was doing some testing with different libraries, and for a good while it worked on 60us, no matter which library I used (yeh after all, changing channels is just 3-4 digitalWrites, i know). But now, i can't get it to be reliable on <1000us at all, no matter which sketch or which library i use.

i'm gonna see if i have another one of those mux shields around and then resolder it. worst case i have to order new ones first. EDIT2 - this was the last sealed package of the muxes i have around, not gonna resolder an open one which might also be broken. i'll be back in 2 days...

EDIT. also, i was lying, it does affect all successive inputs and not only two. getting less and less with every successive input. So each reading will be a mix of its actual value and the predecessors... thinking about it this way, i am pretty sure the chip is fried? it does seem like electric cross bleed, but only one direction?

No experience with the Teensy, but on an Atmega you would do this.

    mp.setChannel(channel);
    analogRead(A1); // dummy read
    Serial.print(String(analogRead(A1)) + "\t");

Every input of the 4067 should also have a 100n ceramic capacitor to ground.
Leo..

2 Likes

thanks, I did try dummy reads, one or several, without any change in the results. That's why they were not in the code I posted anymore...

Time to try those 100n caps.
74HC4067 code I wrote for an Atmega, in case you're interrested (untested).
Leo..

// 74HC4067 mux board with 16 x 10k pot, connected to VCC/GND/MUX inputs
// optional 16*100n ceramic cap between mux inputs and mux ground
const byte controlPin[] {4, 5, 6, 7}; // control pins s0-s3
const byte muxCommon = A0;
byte potvalue[16]; // holds 16 pot values

void setup() {
  Serial.begin(9600);
  for (byte i = 0; i < 4; i++) pinMode(controlPin[i], OUTPUT);
}

void loop() {
  // read the pots
  for (byte i = 0; i < 16; i++) { // 16 channels
    for (byte s = 0; s < 4; s++) digitalWrite (controlPin[s], bitRead(i, s));
    potvalue[i] = analogRead(muxCommon); // dummy read, if needed
    potvalue[i] = analogRead(muxCommon); // 0-15
  }
  // print
  for (byte i = 0; i < 16; i++) {
    Serial.print(potvalue[i]);
    Serial.print(",");
  }
  Serial.println();
  delay(250);
}

A tip how to do this. Do not try and remove the chip, it is suspect anyway, but use a fine pair of side cutters and snip every pin from the IC.

Then you remove the body of the chip and you have the individual pins sticking out. A fine pair of tweezers and an iron from underneath will allow you to easily pull the out one at a time.

Then clean the solder off the tracks with solder wick and replace with a socket.

Or for a development prototype always use sockets for ICs, like I do.

thanks for the tip but what i used in this case is a commercial shield module which has an smd version of the chip soldered on... not a whole lot of pin snipping to de here.

any time i do my own pcbs with DIP ICs, i make sure to use an IC socket.

anyways, new shields arrived already, will hopefully get to re-solder on sunday...

thanks again everybody, will report back after testing!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.