How to connect two MUXs with an arduino board?

Hello everyone,

I am using two 16-1 multiplexers to measure the voltage across 32 pressure sensors. The voltage reading looks great at the first glance. But i found some problems.

First, I have removed the sensor 25 to sensor 32 but the reading of sensor 25 to 32 still remained there. This is so weird! The MUX's legs with nothing connected should show 0.

Second, i removed the analog pin of MUX 2, A1 from the arduino uno. The voltage readings for sensor 17-32 drop from about 1V to 3V to about 0.2V . But there are no connection from MUX 2 and arduino uno now!!! This happend to analog pin of MUX 1,A0 from arudino uno as well. When i removed A0, the reading change from about 0V to 1-3V. (There might have a secret interference between analog A0 and A1?)

Thirdly, I have done also check it individually, one mux with a sensor and second mux is isolated completely from arduino. It works well.

Therefore, I wondered what is the best way of connection of two multiplerxers to an arduino borad, so the interference between two MUXs are free from each other and display the correct reading?

Please let me know if there are still anything unclear..

Why?
As you found out it does not. This is because on the input to the A/D converter is a sample and hold capacitor. This is charges up by the voltage on the analogue input. If that pin has nothing connected to it, then it is floating and will not be driving the sample and hold capacitor at all. So it retains its charge voltage and reads the same value.

Pickup on an open input can eventually move the voltage a bit in a random way.

1 Like

It can get worse. Some sensors can't sink current (LM34 I'm looking at you) so if the voltage goes down they don't discharge the hold capacitor and the readings are too high.

If you have strange things happening read the data sheets on the parts involved. Particularly toward the end and the footnotes where they hide the ugly details.

1 Like

Thank you both for the quick response. How about connecting two MUXs and it is able to measure the voltage reading?

What kind of the MUX, exactly?

1 Like

Remember that when your signal goes through a Mux chip, it will then go through the mux chip inside the Arduino as well, so two mixes in series.

The diagram you drew of the two external mux chips had no inputs shown, only an output. By outputting to a different analogue input then the data select pins can be the same. But why have you included a 3V3 line on that drawing? What is it doing? I can't help but think that this is wrong.

Passing through two chips will in effect introduce more serial resistance to the signal path so the output impedance of your sensors need to be slightly higher. Basically the output impedance is a measure of how much current your sensor can produce, which is not the same as how much voltage.

One way of mitigating the lack of current drive is to read each mux position twice and only use the second one, as that will be much more accurate.

2 Likes

Yes. The schematic you show looks correct. You set the four address pins to select the input for the two MUX's and then read from A0 and A1 to read the two MUX's.

Don't expect floating inputs to read 0 so if your sketch needs to know which inputs are connected you will have to tell it somehow. You can build the value into your sketch if it won't change often or use some kind of input (Serial, Keypad, encoder+button...) to tell it at run time.

1 Like

Reading 16 ports of mux for thermocouples and thermistors; just add 1 more address for 32 ports.

Yes, the thermocouples (commercial for engine monitoring) all worked without issue. Accuracy tracked from 0C to 100C ... did not test up to 200C as engine fluids generally under 300F.
The MAX31855 is solely for Exhaust Gas Temp, EGT.

#include "./MAX31855.h"              // Local (embedded) library

int thermoDO    = 51;                // SPI Data Out
int thermoCS_1  = 52;                // first EGT thermocouple amp Chip Select
int thermoCLK   = 53;                // common SPI clock to both 31855s
int thermoCS_2  = 50;                // second EGT thermocouple amp Chip Select used in Europa design

int8_t addr_0   = 36;               // 2^0    Addressline 0 going to analog mux
int8_t addr_1   = 34;               // 2^1    Addressline 1 going to analog mux
int8_t addr_2   = 32;               // 2^2    Addressline 2 going to analog mux
int8_t addr_3   = 30;               // 2^3    Addressline 3 going to analog mux

/* CONCEPT
 *  A single MAX31855 chip will be used in conjunction (front-ended) by a 16 channel analog switch. channel_address_ 0-3 will be set HIGH/LOW 
 *  to represent 0 through 15 address.  Then, after settling delay(?) the thermocouple object will be called similarily to below.  Address will
 *  be incremented, allowed to settle, and the thermocouple object called again.  These calls must take place from within tab JSON and a small
 *  function created so it can be called from the main program loop on tab: Engine_Monitor_1.  Each JSON function must print a unique identifier
 *  so that the downstream CodeRed program can select the tag, convert to a numeric and assign a label.
 */
MAX31855 thermocouple_(thermoCLK, thermoCS_2, thermoDO);


// ________________________________________________________________________SPI bus #1

float thermocouple_channel( int mux_address) {
    switch(mux_address) {
      case 0:
        digitalWrite(addr_0, LOW); digitalWrite(addr_1, LOW); digitalWrite(addr_2, LOW); digitalWrite(addr_3, LOW); 
        break;
      case 1:
        digitalWrite(addr_0, HIGH); digitalWrite(addr_1, LOW); digitalWrite(addr_2, LOW); digitalWrite(addr_3, LOW); 
        break;
      case 2:
        digitalWrite(addr_0, LOW); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, LOW); digitalWrite(addr_3, LOW); 
        break;
      case 3:
        digitalWrite(addr_0, HIGH); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, LOW); digitalWrite(addr_3, LOW); 
        break;
      case 4:
        digitalWrite(addr_0, LOW); digitalWrite(addr_1, LOW); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, LOW); 
        break;
      case 5:
        digitalWrite(addr_0, HIGH); digitalWrite(addr_1, LOW); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, LOW); 
        break;
      case 6:
        digitalWrite(addr_0, LOW); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, LOW); 
        break;
      case 7:
        digitalWrite(addr_0, HIGH); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, LOW); 
        break;
      case 8:
        digitalWrite(addr_0, LOW); digitalWrite(addr_1, LOW); digitalWrite(addr_2, LOW); digitalWrite(addr_3, HIGH); 
        break;
      case 9:
        digitalWrite(addr_0, HIGH); digitalWrite(addr_1, LOW); digitalWrite(addr_2, LOW); digitalWrite(addr_3, HIGH); 
        break;
      case 10:
        digitalWrite(addr_0, LOW); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, LOW); digitalWrite(addr_3, HIGH); 
        break;
      case 11:
        digitalWrite(addr_0, HIGH); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, LOW); digitalWrite(addr_3, HIGH); 
        break;
      case 12:
        digitalWrite(addr_0, LOW); digitalWrite(addr_1, LOW); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, HIGH); 
        break;
      case 13:
        digitalWrite(addr_0, HIGH); digitalWrite(addr_1, LOW); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, HIGH); 
        break;
      case 14:
        digitalWrite(addr_0, LOW); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, HIGH); 
        break;
      case 15:
        digitalWrite(addr_0, HIGH); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, HIGH); 
        break;        
    }
     delay(75);
     float temp = 0.00;
     double c = thermocouple_.readCelsius();
     if (isnan(c)) {
      // error code here
     } else {
      temp = thermocouple_.readInternal() ;
      temp = thermocouple_.readFarenheit() ;
     }
     return (temp) ;
}

1 Like

The input of my MUXs is sensor 1-16 and sensor 17-32.

I didn't include 3V3 line.

Sorry for my bad writing..

That seems to be a link to the membrane key pad and not the Mux.

OK so you have missed the enable signal off your diagram. This is pin number 15 and must be connected to ground.

I have checked my system in following way:

Case1:

In case 1, i used the schematic diagram as above, two MUXs are connected in this way. The reading is unexpected, when i pressing the first sensor, first sensor and fifth sensor respond; when i pressing the second sensor, second sensor and six sensor respond and sometime the other are not respond.

Case2: With the same circuitry, I removed the A1 connection and my code only read the A0 reading. However, these is still reading on A1 pin. The reading on A0 also incorrect or no respond when I pressing on the pressure sensor.

Case3: With similar circuitry, but removed the MUX2 completely from the arduino and no breadboard is used. This give correct respond i.e. sensor A has respond when sensor A is pressed.

Case4: With similar circuitry, but removed the MUX2 completely from the arduino and no breadboard is used. I have connected only the first 8 pressure sensors on the MUX and only the first 8 pressure sensors display values, the rest is 0! Picture attached.

image

From these trials, I think the disturbance are coming from MUXs, they both influenced each other.

But i still have not idea how to solve it.

did u include the CS_1?

With only 1 mux, CS was hardwired.
2 chip (32 channels) does require implementing a chip select via a digital i/o although the high-address line a4 should be utilized as the CS, !CS line and save a digital port.
eg: a4 a3 a2 a1 a0
15 == 01111
16 == 10000

You can us an separate inverter IC (a tiny expense if you are I/O constrained) of use a cheap switching transistor to invert the a4 signal.

If one is not constrained for I/O, then just use a separate digital pin for CS0 and CS1 knowing the lines are complimentary.

Transistors are cheap:
How to Build an Inverter with a Transistor (learningaboutelectronics.com)
but do add to the power budget.

So many tradeoffs

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