Looping on analog read giving strange readings

I have 9 piezos wired up based off the knock tutorial. The wiring seams to be correct but I am having a very strange issue. I have all of the pins in an int array and I loop through them and check analogRead on them to detect a knock on whatever piezo might have been hit.

The issue though is that in the loop, when I check pin A5, it shows that something was hit even though I don't have a piezo hooked up to it. All of the other readings are correctly showing 0 though.

At the same time, if I check pin A5 outside of the loop, it gives the bad reading and then when it is checked inside the loop, it gives the correct reading of 0. My sketch is:

const int threshold = -1;//300;
const int sensorCount = 9;
const int sensors[sensorCount] = {A5, A4, A3, A2, A1, A0, 10, 9, 8};

void setup() {
  Serial.begin(9600);
}
 
void loop() {
  //if I comment this part out, the bad reading shows up inside of the loop
  Serial.println("");
  int reading = analogRead(A5);
  Serial.print("sensor: ");
  Serial.print(A5);
  Serial.print(" reading: ");
  Serial.println(reading);
  Serial.println("");
  delay(1000);
  
  for (int i = 0; i < sensorCount; i++) {
    Serial.print("sensor: ");
    Serial.print(i);
    Serial.print("-");
    Serial.print(sensors[i]);
    int reading = analogRead(sensors[i]);
    
    if (reading >= threshold) {
      Serial.print(" reading: ");
      Serial.println(reading);
      delay(500);
    }
  }
}

and the output is:

sensor: 23 reading: 190

sensor: 0-23 reading: 0
sensor: 1-22 reading: 0
sensor: 2-21 reading: 0
sensor: 3-20 reading: 0
sensor: 4-19 reading: 0
sensor: 5-18 reading: 0
sensor: 6-10 reading: 0
sensor: 7-9 reading: 0
sensor: 8-8 reading: 0

sensor: 23 reading: 190

sensor: 0-23 reading: 0
sensor: 1-22 reading: 0
sensor: 2-21 reading: 0
sensor: 3-20 reading: 0
sensor: 4-19 reading: 0
sensor: 5-18 reading: 0
sensor: 6-10 reading: 0
sensor: 7-9 reading: 0
sensor: 8-8 reading: 0

From your output I'd guess that you're using an Arduino Leonardo. Is that correct?

Why do you expect to read a 0 if you haven't connected a sensor to the pin? The read value is more or less random because any electrical noise around could influence the reading. If you connect the pin to GND and you're still reading 190 outside the loop, that would be strange.

The pin is connected to ground with a 1Mohm resistor between it and ground. The rest of the pins read correctly 0.

The oddest part is, whatever pin I put at position 0 in the sensors array, is the pin that is giving me bogus readings. So for example, if I change my array to this:

const int sensors[sensorCount] = {A4, A5, A3, A2, A1, A0, 10, 9, 8};//switched positions of A4 and A5

Then it is pin A4 that gives me the bad readings. I am using an Arduino Micro

Replace the 1M? by a 1k? resistor and measure again. The source impedance of the analog inputs shouldn't be more than about 10k?.

1M is way higher than the recommended maximum input impedance of 10k...

Just don't bother reading an unconnected pin!

Don't worry, all of my pins are connected :slight_smile:

So, I should be using a 1Kohm resistor? The tutorials I have read always say 1Mohm: example here.

But that doesn't really explain why all of the other pins give me a good reading of 0 while whatever pin happens to be in the 0 position of the array gives a crazy reading only on the first time through the loop. There really seams to be something that I am not understanding here that when the loop() method starts again, it resets the analog read reference?

Also, is there any information on what the impedance does / how it is measured? I don't think I fully understand the underlining concept with what the resistor does in the circuit.

Also, is there any information on what the impedance does / how it is measured?

Impedance as its name suggests "impedes" the flow of current, the unit of measurement is the ohm.

The tutorials I have read always say 1Mohm

That is because the program uses only one sensor. When switching the internal analogue to digital converter to the other pins, the capacitor on the sample and hold has to charge up or discharge down to the new value. If the impedance is to high it takes too long for the capacitor to adjust it's value.
As you can't actually do an analogue read of those last three pins your input to the A/D is floating, that is picking up interference. With such a high input impedance on the first real input it has not got time enough to adjust to the real voltage. Hence you see the rubbish.

Ok so I replaced all of the resistors with 1Kohm resistors but now I am getting very low readings from the piezos. For example, my threshold was originally set to 300, now I have to use a threshold value of 2 and since my values are so low, sometimes I miss a knock.

I have a total of 9 analog pins reading the piezo sensors. At the moment I have only 1 piezo connected (all resistors are connected and grounded), and I am often getting a reading of 1 from the other pins. How can I set this up to make my readings as accurate as possible?

shiznatix:
Don't worry, all of my pins are connected :slight_smile:

So, I should be using a 1Kohm resistor? The tutorials I have read always say 1Mohm: example here.

If they are connected then the readings aren't necessarily spurious pickup, but
at that impedance you will see some crosstalk, its fundamental with a shared ADC
and multiplexing.

Perhaps you should ignore all but the channel with the largest response at each
point in time, so that it effectively is masking out the other channels.

I replaced all of the resistors with 1Kohm resistors but now I am getting very low readings from the piezos.

Yes you will. It is a compromise between not picking up interference and not damping the output too much.
Maybe a 20K to 100K would be a better compromise.

Grumpy_Mike:
Maybe a 20K to 100K would be a better compromise.

Is there any way to calculate this to a more exact number? It would be nice to be able to know what value of resistor for ## of piezos. The issue is that I might want to add more piezos in the future but changing resistors on a PCB would be difficult. Also, what works on a breadboard never works the same on a PCB (1Mohm was fine on a breadboard but on a PCB obviously it sucks) so it would be great to know what will work before soldering.

Is there any way to calculate this to a more exact number?

No because you need to know a lot of things that you don't know, like the impedance of the transducer, the mechanical force you give it and the efficiency of the transducer.
The good news it that once you have found a sutiable value it does not change if you add more transducers.

Ok, I will try 60Kohm and hope for the best.

But, this leaves a lot of questions open for me. I am sure I am wrong on many points here so if someone could help me understand what is going on, I would appreciate it.

As far as I understand, if I reduce the imdedance (move from 1 Mohm to 1 Kohm), then not as much current will flow through the piezo into the monitoring pin and thus my readings will be lower. But this makes it a bit strange to me. If I an doing analogRead, aren't I reading how much current goes into the pin? If that is true, then how does the ground line to grounded Arduino pin read anything?

Also, I don't really understand why having more piezos would change the required resistor value. If 1 Mohm is fine for 1 piezo, why is it too much for multiple piezos and why if I now find the correct resistor value, would I not have to change it if I add more piezos?

If I an doing analogRead, aren't I reading how much current goes into the pin?

No you are not. You are measuring the voltage on that pin. The current through the resistor to ground produces a voltage across the resistor, that is what you measure. The higher are the resistances the more voltage is produced for a given current.

f 1 Mohm is fine for 1 piezo, why is it too much for multiple piezos

You have been told this already. It is because you have to charge the input capacitor on the sample an hold circuit from this voltage.
There is only one A/D converter and there is a sample and hold circuit on the front end. In front of that is a switch which switches through the voltage from one of the six analogue inputs.
With only one sensor the voltage never gets switched and so the capacitor voltage always tracks what is on the input. Once you put more than one sensor on and switch between the two you need a lower impedance to charge the capacitor quicker, or you need longer for that capacitor to reach the input voltage, hence a double read perhaps even with a delay in between.