Two CD4051 on same address affect each other channel reading

Hi guys, I'm using CD4051 for multiplexing 10K potentiometers on Seeed Xiao. The muxs address (A,B,C) are connected on the same pins on the Xiao. All works as intented but when I crank up a potentiometers Mux 0 Channel 3 for exemple it affect the reading of Mux 1 Channel 3

Sensor 0.3 reads: 1023 
Sensor 1.3 reads: 84

In this example the pot of Sensor 0.3 is to the max and the pot of Sensor 1.3 is to the min

I think it can be the high resistor value of the pots

What do u think of ?

I'm using this circuit

Let’s see your wiring.

I'm using the schematics provided in my first post. The second CD4051 ABC's are on the same pins as the first and the O/I are on two differents pins

Yes we are aware, you were asked to give us a view of your actual wiring.

Try taking 2 readings from each input, discard the first then use the second.

1 Like

The circuit is on PCB, so u don't gonna see very well, do u want me to report it on Fritzing ?

Do as you wish.

I have already done this fix without any improvement:

int readSensor(int sensorPin, const byte which)
{
  // select correct MUX channel
  digitalWrite(addressA, (which & 1) ? HIGH : LOW); // low-order bit
  digitalWrite(addressB, (which & 2) ? HIGH : LOW);
  digitalWrite(addressC, (which & 4) ? HIGH : LOW); // high-order bit
  // now read the sensor
  analogRead(sensorPin);
  return analogRead(sensorPin);
} // end of readSensor

Here u go

I don't know for sure but I suspect the first analogue read will be removed by the compiler because it will see nothing is done with the result. As an experiment try a serial print of the first read to guarantee it is not optimised out, and to allow you to see if there is any difference between the first and second read.

Tested, same behavior :smiling_face_with_tear:

Ok. While you were doing that I asked a friend and he doesn't think the first read will be optimised out. I don't have any more suggestions, if I do I will return.

I don't think so. You mentioned two mux, there is only one there. It uses LDRs not pots. There is too much room for error in the interpretation. We need to see the actual schematic.

Myself, I don't have time to decode a Fritzing. Please give me a diagram that tells me instantly how it works (a real schematic).

The circuit is on PCB

You're not going to tell me that was manufactured without a schematic, I hope?

At the moment it is just as likely to be a hardware, as a software problem. But it's unknown which...

Breaking it down even further, it could be a design or else a build issue.

Thank u mate

I'm sorry about the quality of the schematic, I'm a noob in that, I'm more a programmer but the idea is here

Remove the second mux and feed the pots to the same 4051, different inputs.

Does the problem go away ?


BTW

We do not see any decoupling on the 4051s

I built your circuit, well, as close as I can as I don't have a Seed Xiao. I used a Nano Every instead. As I don't have your code, other than your int readSensor(int sensorPin, const byte which) function, I used my own, but kept your int readSensor(int sensorPin, const byte which) function for the reading.

Here is the circuit on breadboard:

Here is my code, with readings taken every 200ms:


const uint8_t addressA = 21;
const uint8_t addressB = 20;
const uint8_t addressC = 19;

const int16_t sensor0 = A0;
const int16_t sensor1 = A1;

void setup() {
    Serial.begin(115200);
    char fileName[] = {__FILE__};
    Serial.println(fileName);

    pinMode(addressA, OUTPUT);
    pinMode(addressB, OUTPUT);
    pinMode(addressC, OUTPUT);
    pinMode(LED_BUILTIN, OUTPUT);
    
    Serial.println("Setup complete");
}

void loop() {
    readSensors();
    runLED();
}

void readSensors() {
    uint32_t currentMillis = millis();
    static uint32_t lastMillis;
    const uint32_t interval = 200;
     if (currentMillis - lastMillis >= interval) {
        lastMillis += interval;

        Serial.print("Sensor 0 reading = ");
        Serial.println(readSensor(sensor0, 0));     
        Serial.print("Sensor 1 reading = ");
        Serial.println(readSensor(sensor1, 1));  
    }
}

int readSensor(int sensorPin, const byte which) {
  // select correct MUX channel
  digitalWrite(addressA, (which & 1) ? HIGH : LOW); // low-order bit
  digitalWrite(addressB, (which & 2) ? HIGH : LOW);
  digitalWrite(addressC, (which & 4) ? HIGH : LOW); // high-order bit
  // now read the sensor
  analogRead(sensorPin);
  return analogRead(sensorPin);
} // end of readSensor


void runLED() {
    uint32_t currentMillis = millis();
    static uint32_t lastMillis;
    const uint32_t interval = 500;
    if (currentMillis - lastMillis >= interval) {
        lastMillis += interval;
        digitalWrite(LED_BUILTIN, !(digitalRead(LED_BUILTIN)));
    }
}

And here is the result in the serial monitor, starting with both pots at their lowest (not quite 0) then turning the left hand one up slowly to maximum, followed by the right hand one. I think it is clear they do not interact.

19:31:31.174 -> Sensor 0 reading = 64
19:31:31.174 -> Sensor 1 reading = 66
19:31:31.374 -> Sensor 0 reading = 64
19:31:31.374 -> Sensor 1 reading = 66
19:31:31.574 -> Sensor 0 reading = 64
19:31:31.574 -> Sensor 1 reading = 88
19:31:31.774 -> Sensor 0 reading = 64
19:31:31.774 -> Sensor 1 reading = 149
19:31:31.974 -> Sensor 0 reading = 64
19:31:31.974 -> Sensor 1 reading = 198
19:31:32.174 -> Sensor 0 reading = 64
19:31:32.174 -> Sensor 1 reading = 243
19:31:32.374 -> Sensor 0 reading = 63
19:31:32.374 -> Sensor 1 reading = 274
19:31:32.574 -> Sensor 0 reading = 64
19:31:32.574 -> Sensor 1 reading = 310
19:31:32.774 -> Sensor 0 reading = 64
19:31:32.774 -> Sensor 1 reading = 358
19:31:32.974 -> Sensor 0 reading = 64
19:31:32.974 -> Sensor 1 reading = 391
19:31:33.174 -> Sensor 0 reading = 64
19:31:33.174 -> Sensor 1 reading = 396
19:31:33.374 -> Sensor 0 reading = 64
19:31:33.374 -> Sensor 1 reading = 436
19:31:33.574 -> Sensor 0 reading = 64
19:31:33.574 -> Sensor 1 reading = 497
19:31:33.774 -> Sensor 0 reading = 63
19:31:33.774 -> Sensor 1 reading = 561
19:31:33.974 -> Sensor 0 reading = 64
19:31:33.974 -> Sensor 1 reading = 623
19:31:34.174 -> Sensor 0 reading = 63
19:31:34.174 -> Sensor 1 reading = 675
19:31:34.374 -> Sensor 0 reading = 62
19:31:34.374 -> Sensor 1 reading = 731
19:31:34.574 -> Sensor 0 reading = 64
19:31:34.574 -> Sensor 1 reading = 771
19:31:34.774 -> Sensor 0 reading = 62
19:31:34.774 -> Sensor 1 reading = 821
19:31:34.974 -> Sensor 0 reading = 63
19:31:34.974 -> Sensor 1 reading = 851
19:31:35.174 -> Sensor 0 reading = 64
19:31:35.174 -> Sensor 1 reading = 1021
19:31:35.374 -> Sensor 0 reading = 64
19:31:35.374 -> Sensor 1 reading = 1021
19:31:35.574 -> Sensor 0 reading = 63
19:31:35.574 -> Sensor 1 reading = 993
19:31:35.774 -> Sensor 0 reading = 64
19:31:35.774 -> Sensor 1 reading = 1022
19:31:35.974 -> Sensor 0 reading = 64
19:31:35.974 -> Sensor 1 reading = 1022
19:31:36.174 -> Sensor 0 reading = 64
19:31:36.174 -> Sensor 1 reading = 1023
19:31:36.374 -> Sensor 0 reading = 64
19:31:36.374 -> Sensor 1 reading = 1023
19:31:36.574 -> Sensor 0 reading = 64
19:31:36.574 -> Sensor 1 reading = 1022
19:31:36.774 -> Sensor 0 reading = 65
19:31:36.774 -> Sensor 1 reading = 1023
19:31:36.974 -> Sensor 0 reading = 80
19:31:36.974 -> Sensor 1 reading = 1023
19:31:37.174 -> Sensor 0 reading = 136
19:31:37.174 -> Sensor 1 reading = 1022
19:31:37.374 -> Sensor 0 reading = 200
19:31:37.374 -> Sensor 1 reading = 1022
19:31:37.574 -> Sensor 0 reading = 264
19:31:37.574 -> Sensor 1 reading = 1022
19:31:37.774 -> Sensor 0 reading = 321
19:31:37.774 -> Sensor 1 reading = 1022
19:31:37.974 -> Sensor 0 reading = 359
19:31:37.974 -> Sensor 1 reading = 1022
19:31:38.174 -> Sensor 0 reading = 423
19:31:38.174 -> Sensor 1 reading = 1022
19:31:38.374 -> Sensor 0 reading = 486
19:31:38.374 -> Sensor 1 reading = 1022
19:31:38.574 -> Sensor 0 reading = 537
19:31:38.574 -> Sensor 1 reading = 1022
19:31:38.774 -> Sensor 0 reading = 572
19:31:38.774 -> Sensor 1 reading = 1022
19:31:38.974 -> Sensor 0 reading = 621
19:31:38.974 -> Sensor 1 reading = 1022
19:31:39.174 -> Sensor 0 reading = 623
19:31:39.174 -> Sensor 1 reading = 1022
19:31:39.374 -> Sensor 0 reading = 648
19:31:39.374 -> Sensor 1 reading = 1022
19:31:39.574 -> Sensor 0 reading = 718
19:31:39.574 -> Sensor 1 reading = 1022
19:31:39.774 -> Sensor 0 reading = 767
19:31:39.774 -> Sensor 1 reading = 1022
19:31:39.974 -> Sensor 0 reading = 825
19:31:40.014 -> Sensor 1 reading = 1022
19:31:40.174 -> Sensor 0 reading = 854
19:31:40.174 -> Sensor 1 reading = 1022
19:31:40.374 -> Sensor 0 reading = 899
19:31:40.374 -> Sensor 1 reading = 1022
19:31:40.574 -> Sensor 0 reading = 925
19:31:40.574 -> Sensor 1 reading = 1022
19:31:40.774 -> Sensor 0 reading = 975
19:31:40.814 -> Sensor 1 reading = 1022
19:31:40.974 -> Sensor 0 reading = 1021
19:31:41.014 -> Sensor 1 reading = 1022
19:31:41.174 -> Sensor 0 reading = 1023
19:31:41.174 -> Sensor 1 reading = 1022

This of course does not prove anything as I am not using your exact code or your exact circuit, but maybe it gives you something to think about.

Please post your actual schematic, the one used to make the PCB, and photos of your board.

2 Likes

Telecom wires :grin:

1 Like

I have a lifetime supply. Probably several lifetimes. Optical fibre will not work as well I don't think!