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?
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.
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.
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.
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 10231/31=33, position 30 should read 102330/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.
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.
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.
int result = map( analogRead(A1), -16, 1007, 1, 32);