Potentiometers affecting each others when connected to 74HC4051

Status
Not open for further replies.

loveaurell

Well-known member
I'm trying to implement a small scale version of this circuit https://www.pjrc.com/teensy/schematic_ioexpand.png
I'm using one 74HC4051 and two linear 10k pots. The output of the 74HC4051 is fed to A0, and digital pins 2 3 4 is controlling the channels on the 74HC4051.

The 6, 7 and 8 pins on the 74HC4051 are connected to ground. Pin 16 is connected to +5V.

However, the two linear 10k pots I'm using seems to affect each other when connected through the 74HC4051. And the values are not linear, one of the pots are increasing slowly until approximately 70-80% and then moves quickly up to max value. When I connect the pots direcly to two separate analog pins on the teensy, they seem to behave as expected. I have tried to replace the 74HC4051 but got the same result.

Is there something I have overlooked here? Is 10k a suitable potentiometer value?

Code:
const int pinChannelBit1 = 2;
const int pinChannelBit2 = 3;
const int pinChannelBit3 = 4;

const int controlInput1 = 14;

int potValue;

void setup() {
  pinMode(pinChannelBit1, OUTPUT);
  pinMode(pinChannelBit2, OUTPUT);
  pinMode(pinChannelBit3, OUTPUT);
  
  analogReadResolution(7);
}

void loop() { 
  selectPinChannel(0);
  potValue = analogRead(controlInput1);
  
  Serial.print("Pot 1: ");
  Serial.println(potValue);
  
  selectPinChannel(1);
  potValue = analogRead(controlInput1);
  
  Serial.print("Pot 2: ");
  Serial.println(potValue);
  Serial.println();
  
  delay(500);
}

// select 74HC4051 channel
void selectPinChannel(int channel) {
   digitalWrite(pinChannelBit3, HIGH && (channel & B00000100));
   digitalWrite(pinChannelBit2, HIGH && (channel & B00000010));
   digitalWrite(pinChannelBit1, HIGH && (channel & B00000001));

  delayMicroseconds(50);
}
 
Last edited:
The first question is, which Teensy are you using? The 3.x series have enough analog inputs so that you do not forcibly have to multiplex these. The 74HC4051 are not ideal switches for precision applications, they add a internal resistance of several hundreds of ohms (depending on manufacturing tolerances, temperature and supply voltage) in series with the connected potentiometer wiper which may have an impact on the results. That's just a (IMNSHFO too) cheap way to work around the limited number of analog inputs of outdated CPUs.
 
It's the 3.2 teensy. The reason for using the 74HC4051 is that I'm planning to create a midi controller with around 50 pots and buttons, but I'm trying to get comfortable with the components first.

I was hoping that It would provide enough precision for 7-bit values at least since it's stated as an example here: https://www.pjrc.com/teensy/td_midi.html

But my circuit doesn't behave reliably at all. Could larger pot values help?
 
Heres a picture of my breadboard.
IMG_1402.jpg
 
If It turns out that the 74HC4051 is not the right tool for this, is there another way to expand the number of inputs of the teensy?
 
Is that a 0.1 uF capacitor on the 74HC4051 output?

If so, you're going to need to allow at least 3 ms from the time you change the 74HC4051 control pins to when you call analogRead(). Your code above has only 0.05 ms. It needs to be at least 60X longer to allow the resistance of the pot and '4051 to slowly change the capacitor.
 
Ah, when I wrote above, there was no picture, so I was not aware of the capacitor. Paul is right, that introduces an additional "time constant". 10k Pots are basically fine, 5k Pots will draw more supply current but will reduce the problem. Then, I would replace the 100nF by a 10nF capacitor to reduce the "charge change" time and you could go away with a 500us delay between switching the 4051 and doing analogRead.
 
Yes it's 0.1 uF :) That makes sense. Tried to increase delay and it behaves more reliably now, I guess I should have included an image in the first place.

How do I calculate how large capacitor is needed?

I noticed that without one, the measured value was fluctuating +-30 at 10 bit resolution, and I still get some fluctuation when the pot is close to the border between two 7-bit values.

What values would be ideal for steady values at low delay? Switching channel 8 times per loop would itself make 4ms of delay. Is it possible to go lower the without using too much current?
 
Last edited:
Even the best capacitor will not solve all noise problems on the ground and the supply line which will occasionally cause "jumping" between two adjacent values, as does the ADC itself. You can better reduce this effect by reading the values with 8 bits resolution and apply some simple recursive digital low pass filtering:
Y += (newReading - Y) >> 2; and then rounding and scaling down:
Y(7bit) = (Y(8bit) + 1) >> 1;

FreeScale (the CPU manufacturer) recommends a 10nF (0.01uF) capacitor.
 
Opps, make that delay closer to 4ms.

Here's some explanation about why you need the delay, and how to calculate it.

What's happening here is the capacitor is storing charge which represents the voltage of the previously selected pot. When you change the 74HC4051 control signals, the resistance of the pot plus resistance of the switch inside the 74HC4051 begin slowly charging or discharging the capacitor. The voltage changes in an exponential decay, where the "time constant" is calculated by multiplying the capacitance times resistance.

The worst case resistance is half the pot value, plus whatever the 74HC4051 happens to be. In this circuit it looks like you're running the 74HC4051 from 5V. Hopefully it's actually a 74HCT4051... the "HC" ones don't have guaranteed logic input thresholds to be controlled from 3V signals when running at 5V, but "HCT" does. TI's datasheet says 180 ohms worst case at room temperature, or 270 at extreme temperature. They don't say what it is at 3V, which is pretty typical of semiconductor vendors when a spec is really terrible. I'd plan on 1K from the 74HCT4051 if it's running at 3V. But for 270 ohms, plus 5K from the pot, your time constant is 0.527 ms.

The formula to convert measurement error to required time constants is -ln(error), where "error" is between 0 to 1.0, and "ln" is natural log. You can never get zero error... the natural log of zero is minus infinity. But if you're making a 10 bit measurement, an error of 1/1024 means you'll be off by only 1. That's 6.93 time constants. Or if you want 1/2048 error, you have to wait 7.62 time constants, which is 4.01 ms.

If you want to measure a large number of pots or other signals using a 74HC4051, obviously you want to keep those time constants short so you don't need such a long delay. The simplest way is to minimize the capacitance. That's contrary to the normal non-74HC4051 advice, where adding capacitance tends to improve analog measurement quality. It does, but only if the capacitor has stabilized to the right voltage before you make the measurement. I'd recommend using only 470 pF capacitance, or no capacitor at the A0 pin at all. Of course, there's always some capacitance. I'd plan on about 15 pF from the two chips, and maybe a few more pF more for the breadboard & wire.

Without any capacitor, only 20 pF from the pins + wires, you'd have a time constant of 0.1 us. So even a 1 us delay ought to be enough.

If you use a 470 pF capacitor, which might improve your measurements, you'll get a 2.6 us time constant, which requires about 20 us delay.

Something to consider is the pot makes up most of the resistance that controls the speed. 1K pots will be much faster than 10K. They also will consume 3.3 mA of current each, which can add up to quite a lot of current if you have many pots on your MIDI controller. 10K is probably a pretty good choice. 100K should be avoided.

Obviously a big capacitor really slows things down. I'd done quite a bit of testing with different capacitors on Teensy 3.2. Values over 1 nF really don't make much difference. Without the rapid signal switching of a 74HC4051 switch, the slowness of a big capacitor is still much faster than a human can move the pot. But when you connect a 74HC4051 switch, you need fast signal switching, which means limiting the size of any capacitor you add.

Hopefully this lengthy explanation makes sense. I'm going to add a link from the MIDI page, since this is a problem that's come up a few times. Hopefully this can save anyone else from such a frustrating problem.
 
Also on the capacitor, the type of material can make a difference. If you use a ceramic capacitor, look for a NP0/C0G type. Most plastic film "poly" capacitors also work well.
 
Thank you very much for the great explanation! I'll play around with the values ans see if I can lower the delay.

I'll also try the digital low pass filtering to see if that helps, Theremingenieur.
 
The worst case resistance is half the pot value, plus whatever the 74HC4051 happens to be. In this circuit it looks like you're running the 74HC4051 from 5V. Hopefully it's actually a 74HCT4051... the "HC" ones don't have guaranteed logic input thresholds to be controlled from 3V signals when running at 5V, but "HCT" does. TI's datasheet says 180 ohms worst case at room temperature, or 270 at extreme temperature. They don't say what it is at 3V, which is pretty typical of semiconductor vendors when a spec is really terrible. I'd plan on 1K from the 74HCT4051 if it's running at 3V. But for 270 ohms, plus 5K from the pot, your time constant is 0.527 ms.

No, it's "HC", as in the MIDI example. I changed to using the 3.3V output pin instead.
 
The resistance of the switches will be higher when you have only 3.3V power. How much higher is a good question. You can be pretty sure it's not nice, since TI specs the part to run with as little as 2V power, but they don't give any performance data below 4.5V. Always remember datasheets look like comprehensive technical specs, but they're marketing material with a single purpose, to sell you the chip. Anything less desirable is usually glossed over or just omitted.

Since you have between 0 to 5K from those 10K pots, the pot resistance (when near the center of its range) is the limiting factor. Even if the on resistance is about 4X (that'd be my guess, based on my understanding of the transistors that are probably inside the chip), the pot is still the limiting factor. Just don't shave the delay in your code to the minimum and you should be fine.
 
You can better reduce this effect by reading the values with 8 bits resolution and apply some simple recursive digital low pass filtering:
Y += (newReading - Y) >> 2; and then rounding and scaling down:
Y(7bit) = (Y(8bit) + 1) >> 1;

Is "Y" in the first row representing the previous 8-bit value?
Could you please explain how this works or link to a resource? I know what bitshifting is but I'm not familiar of how to use it.

This is how I understand it:
Lets assume the value would change 1 7bit step, 2 8bit steps.

previous8bitReading = 134; //67 in 7bit
new8bitReading = 136;

Y(8bit) = previous8bitReading + (new8bitReading - previous8bitReading) >> 2;
Y(8bit) = previous8bitReading + (136 - 134) >> 2; //134

Y(7bit) = (Y(8bit) + 1) >> 1;
Y(7bit) = 135 >> 1; //67

It looks like even the change by 1 7bit value is removed, leaving the previous value unchanged.
 
You are right, the maths are correct, but I didn't consider some resolution problems, please accept my apologies, I wrote that in a hurry. Please allow a few hours, I will rewrite it correctly when I'll be at home after work.
 
Hi, I've got a follow up question on this.

I just completed my midi controller with some knobs and buttons and midi in/out. I left out the capacitor in the midi in circuit since I suspected it might affect the amount of delay I need after switching between the multiplexer channels.

Now, when I receive midi messages I notice that some random pots change readings. I guess the 0.1 uF capacitor will fix that.

But since it's connected between vcc and ground, does it matter where in the circuit it's positioned? Should it be as close to the pc900 power supply pin as possible?
 
I have found it best to connect the 3.3v to the positive of the pots while driving the Teensy with 5volts. I connect the 3.3v to the AREF and specify AREF as external.
I am currently running with 48 pots. I sample four times and average for each pot. The biggest noise issue I had was with an XBee on the 3.3v so I moved it onto the 5 volt power (Xbee explorer). I did find one pot to be noisy and replaced it.

I have VERY low noise level down to +- 1 with some spikes to +- 2 (of 0-1023).
 
I have teensy 2.0+ and have a question about the capacitor is it really need to work with the 74HC4051. I have a few the non "t" version coming in the mail. Is the code at the top of the page work? I need to know because I'm planning on using 1 74HC4051 to run 6 buttons off one pin of the teensy's digital pin and 7 more running on the analog pins. 2 chips will be for Slide Potentiometers and the last 5 will be for normal Potentiometers.
 
I'm not 100% sure if it works since I went on using the "T" version for my real projects after this, just to be on the safe side. But I think the code should work. You might need to adjust the delay after the channel switching though and depending on how great resolution you need, you might have to implement some smart way to handle jitter in the readings. You might also need to experiment with analog read averaging. I found out I got best results with a 100microsecons delay and an averaging of 10.

For my projects, I've needed at most 0-127 so I have read at higher resolution and discarded the "change" if it's been less than a low resolution value step. (For example on row 265 here: https://bitbucket.org/loveaurell/ro...154/src/mks50_controller/mks50_controller.ino)
 
I'm not 100% sure if it works since I went on using the "T" version for my real projects after this, just to be on the safe side. But I think the code should work. You might need to adjust the delay after the channel switching though and depending on how great resolution you need, you might have to implement some smart way to handle jitter in the readings. You might also need to experiment with analog read averaging. I found out I got best results with a 100microsecons delay and an averaging of 10.

For my projects, I've needed at most 0-127 so I have read at higher resolution and discarded the "change" if it's been less than a low resolution value step. (For example on row 265 here: https://bitbucket.org/loveaurell/ro...154/src/mks50_controller/mks50_controller.ino)

Thanks for saying the code some what works but you didn't answer the other question is the capacitor really needed it is not shown on here but you guys kept talking about it. Which should I believe the website or this forum thread?
 
Sorry. No, I've left it out and it did work anyway. If you experience jittery readings I guess you could try and add it. For a more technical and correct answer, someone with more experience might have to fill me in. I just know what have worked for me.
 
Status
Not open for further replies.
Back
Top