Problems reading from multiple analog inputs *SOLVED*

So I'm creating this basic control pad, which involves 4x toggle switches and 4x buttons. All of the switches are connected to a single analog input and all of the buttons are connected to a separate analog input. The circuit design for both of them is pretty much identical, and looks very similar to this (basically, I just chose different resistor values):

Basically, the idea is to be able to toggle multiple buttons and switches using just 2 wires. For the most part, it works fine... IF I only read from just one of the two inputs at a time.

Here's my code in the loop:

for (int i=0;i<4;i++) {
		for (int j=0;j<8;j++) {
			//Buttons
			if ((analogRead(A5)>analog_array[i][j]-3) && (analogRead(A5)<analog_array[i][j]+3)) {
				Serial.println(i);
			}
			//Switches
			if ((analogRead(A4)+3>analog_array[i][j]) && (analogRead(A4)-3<analog_array[i][j])) {
				Serial.println(i);
			}
		}
	}

And here's what the "analog_array" looks like:

const int analog_array[4][8] = {{ 806,825,850,858,863,869,885,893 },
				{ 609,672,744,775,858,869,885,893 },
				{ 560,638,744,775,850,863,885,893 },
				{ 317,638,672,775,825,863,869,893 }};

So here's the specifics of the problem:
If I disable the lines of code under "//Switches", it works fine. It'll read any button combination just as I expect it would, and it'll continue to do so with any combination of the switches I toggle on or off.
HOWEVER...
If I enable the lines of code under "//Switches", suddenly, everything is broken. It will only read button presses if the 1st or 3rd switch is flipped on. It seems to always read if the 1st or 4th switch is toggled on, but it will sometimes read the 2nd or 3rd switch depending on which button I press. In other words, it seems completely arbitrary.

Here's what I tried so far:

  • Adding delays in various parts of the loop
  • Using different analog inputs
  • Running the loops completely separately (one after the other)
  • Reading the analog inputs into variables and compare them in the "if" statements that way
  • Plugging the analog inputs into different pins

I'm out of ideas. This logic is pretty straight-forward. My program is only using about 6% of the Arduino's memory (I'm using an ATMega 1280).

analogRead(A4)+3

This looks odd, to me. What do you expect that value to be? What is the actual value at run time?

I just speak for the circuit, not the program.
100k is v-e-r-y v-e-r-y high value. The internal capacitor doesnt have time to discharge so to follow next switch/input. Also the ratios some kOhm over 100k is a very small dynamic range.
So, better use a 1k resistor for gnd (recalculate the analogRead values).

dougp:
This looks odd, to me. What do you expect that value to be? What is the actual value at run time?

Whoops I forgot I was just experimenting with that. But basically I just wanted it to increment 3 from the value. The idea is to give it some flexibility in the event there's a little bit of noise in the signal.
In other words, I'm checking if the signal value approximately matches one of the values in analog_array.
Functionally, this shouldn't be any different than the minus-3 that I have involved in the other Button checker.

demkat1:
I just speak for the circuit, not the program.
100k is v-e-r-y v-e-r-y high value. The internal capacitor doesnt have time to discharge so to follow next switch/input. Also the ratios some kOhm over 100k is a very small dynamic range.
So, better use a 1k resistor for gnd (recalculate the analogRead values).

Like I said before, I'm using a similar design but not the same one. I used resistors of MUCH lower values, because as you said, 100k is very high. I think the largest one I'm using is something like 2k.
Either way, the resistor values don't explain my symptoms.

How I did it.
Say the ADC values for 4 switches were, 100, 300, 500 and 700, the halfway points between them would be approximately 200, 400 and 600, so:

if(analogRead(pin) > 100) // no switch < 80
{
  if(ADC < 200)
    switch = 1;
  else if(ADC < 400)
    switch = 2;
  else if(ADC < 600)
    switch = 3;
  else
    switch = 4;
}

outsider:
How I did it.
Say the ADC values for 4 switches were, 100, 300, 500 and 700, the halfway points between them would be approximately 200, 400 and 600, so:

Thanks for the reply, but that won't work for me, for 2 reasons:

  1. I need to register combinations of multiple button presses (which my current code checks for just fine).
  2. The code I currently have works, but ONLY if I check for 1 of the 2 analog inputs. If I try checking both, for whatever unknown reason, it seems to fail. Although you're using a very different approach, it doesn't so much address the issue as to why the code I have now fails.

In other words, the problem I'm having is it seems the logic I currently have is failing, and I don't know why.

}
//Switches
if ((analogRead(A4)+3>analog_array[i][j]) && (analogRead(A4)-3<analog_array[i][j])) {
  Serial.println(i);<<<<<<<<<<
}

Should that be Serial.println(j)?

Can you write a complete sketch that shows the problem?

Can you draw a schematic with the ACTUAL resistor values and pins you use?

The use of Pin A4 should not have an effect on the use of Pin A5 unless they are wired together somehow or the input impedance is too high. If the resistor to ground is 2K or lower (" I think the largest one I'm using is something like 2k.") then the impedance should not be a problem.

An Arduino has only one ADC and it can be switched to the different analog pins. When you change pin it is a good idea to discard the first reading in case it has some residual voltage from the previous pin. Something like this

adcVal = analogRead(A5);
adcVal = analogRead(A5);
if (adcVal > // etc etc

...R

Robin2:
An Arduino has only one ADC and it can be switched to the different analog pins. When you change pin it is a good idea to discard the first reading in case it has some residual voltage from the previous pin. Something like this

Interesting... looks like you actually solved my problem! My code is working just as I expected now.

It's also great to know that this was more of a hardware quirk, one that I never knew about.

schmidtbag:
Interesting... looks like you actually solved my problem! My code is working just as I expected now.

It's also great to know that this was more of a hardware quirk, one that I never knew about.

It should only be a problem when the impedance of the input signal is higher than 100 kOhms. If your resistors are, asu you said, all lower than 2 kOhms you should not be having this problem.

1 Like