Go Down

Topic: Realistic max amount of multiplexed inputs on ADC? (Read 305 times) previous topic - next topic

duramaxhd

Hi everyone...

This is kind of more of a "theoretical" question and probably slightly open to interpretation and tolerances.....but given the 10-bit ADC on a 3.3v Arduino, using good 1% tolerance resistors, what would be a good "safe" maximum amount of switches I could run multiplexed on a resistor network?

IE, if I want to tie a 5 or 6 position DIP switch to one ADC input using a resistor network, that would be 32 or 64 max possibilities/ADC readings. (2^5, 2^6)

Im all out of inputs, and theres no room on the PCB to use an external I/O expander, shift register, etc.

Using 1% resistors, is 32/64 levels feasible and pretty safe as far as making sure things are spread out enough to accurately read each of the DIP switch positions?

Im going to make a bunch of these boards, so even using tight 1% resistors I do have to account for that 1% swing.


Second question...what is a good rule of thumb for choosing resistor values to ensure a nice even spread over 5 or 6 mux'd inputs? All the same value? Increasing in value? Min? Max?

Third question.... obviously for each reading, I would do

if ((val > 120) && (val < 130)){
do this;
}

Is there a simpler/more efficient way of having the Arduino automatically determine a range?

if (val == 120, +/- 5) or something like that.

Thanks

Delta_G

Third question.... obviously for each reading, I would do

if ((val > 120) && (val < 130)){
do this;
}

Is there a simpler/more efficient way of having the Arduino automatically determine a range?

if (val == 120, +/- 5) or something like that.
No, you did it right the first way. 
If at first you don't succeed, up - home - sudo - enter.

PaulRB

What you could do is calculate what you expect to be the values half way between each switch position, and put these in an array. Then you can take an analog reading and use a for loop to scan the array to figure out the switch position.

duramaxhd

What you could do is calculate what you expect to be the values half way between each switch position, and put these in an array. Then you can take an analog reading and use a for loop to scan the array to figure out the switch position.
Ok thanks...so basically just 3.3v/32 steps.... (call it 3v to leave some error at either end).

3/32 =  0.094v separation between steps.

1024/32 = 32.

So each ADC reading should be roughly 32 steps apart if I want even spacing? With 1% resistors, I would think if I do +/- 10 steps for error......should be ok?

Unless Im doing something stupid with my math/logic.

PaulRB

For a 32 position switch, you will be using only 31 resistors. The extreme positions will be wired directly to 5V and 0V. So position 0 should read pretty much exactly zero and position 31 should read almost exactly 1023. Position 1 should read 1023*1/31=33, position 30 should read 1023*30/31=990 and so on. But these (1-30 positions) are subject to the inaccuracies of the resistors. So the expected values should be 0, 33, 66, 99... 990, 1023.

Grumpy_Mike

#5
Today at 10:20 am Last Edit: Today at 10:21 am by Grumpy_Mike
You work out the voltages at each switch position and set the thresholds half way between these voltages.
Put these thresholds in an array and use a while loop to go through the array starting at zero compairing your input voltage to the values. When an array position exceeds your input voltage the array position is your switch position.

PaulRB

Alternatively, you could add or subtract an offset of around 16~17 to the result of analogRead(), and then use map() to get one of 32 values. You would then have to adjust the result by one to compensate for the original offset. The advantage is using the offset is that it should remove the problem of the uncertainty in the resistor values, as long as the errors in the resistors values are reasonably random.

Code: [Select]
int result = map( analogRead(A1), -16, 1007, 1, 32);

Go Up