0

In my sketch I have a potentiometer connected to A0. The value of the pot is used to adjust the speed of a connected item.

I have set the speed to have a default value, but doing analogRead() on a pin with nothing attached gives random values rather than using the default value. The docs state "If the analog input pin is not connected to anything, the value returned by analogRead() will fluctuate based on a number of factors (e.g. the values of the other analog inputs, how close your hand is to the board, etc.)." https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/

How can I test whether something is connected to A0 and if not, use the default value?

8
  • Not in any general way, no, but it's unclear why this is a problem. Jun 16 at 1:00
  • 1
    instead of connecting the pot between Vcc and Gnd, connect it between two data pins ... setting both the data pins to LOW should result in analog reading of near 0 V ... then set both to HIGH ... etc etc
    – jsotola
    Jun 16 at 1:00
  • @DaveNewton it is as a fallback value if pot doesn't exist.
    – Steve
    Jun 16 at 1:10
  • 1
    In my sketch I have a potentiometer connected to A0 ... but doing analogRead() on a pin with nothing attached gives random values rather than using the default value. - Why is this an issue? - you say you have something connected, but you are asking how do you detect if nothing is connected. Do you, or do you not, have the pot connected to A0?
    – Nick Gammon
    Jun 16 at 9:06
  • 1
    Your last sentence is a summary of JRobert's answer - true, and being a comment it was not intended as an answer per se. I was commenting that there were a few different ways you could go about it. Stating the obvious, perhaps? :)
    – Nick Gammon
    Jun 20 at 7:33
6

The input stage of the analog-to-digital converter is a sample-and-hold capacitor. When you take an analog reading, the capacitor is connected to the input pin, it is charged to the voltage you want to measure, then it is disconnected from the input and it “holds” the voltage while the conversion is in progress.

You can leverage this capacitor to detect whether your input pin is floating. If you try to take an analog reading from a floating pin, the sample-and-hold capacitor will not be able to charge or discharge through it. You should then get a reading that is close to the previous reading you took, although not exactly the same, as floating pins a very prone to noise. Thus I suggest the following algorithm:

  • take a reading from a pin tied to GND, and discard this reading
  • take a reading from your input pin and record it
  • take a reading from a pin tied to +5V and discard it
  • take and record a second reading from your input pin

If the input pin is floating, the first recorded reading should be close to zero, and the second one close to 1023.

Here is a test sketch demonstrating this approach. It uses digitalWrite() to tie the required pins to GND and +5V, thus no external connections are needed:

const uint8_t pin_input = A0;  // the one we are interested in
const uint8_t pin_low   = A1;  // will be tied to GND
const uint8_t pin_high  = A2;  // will be tied to +5V

void setup() {
    Serial.begin(9600);
    pinMode(pin_input, INPUT);
    pinMode(pin_low, OUTPUT);
    digitalWrite(pin_low, LOW);
    pinMode(pin_high, OUTPUT);
    digitalWrite(pin_high, HIGH);
}

void loop() {
    analogRead(pin_low);  // take a reading and discard it
    Serial.print(analogRead(pin_input));
    Serial.print(" ");
    analogRead(pin_high);  // take a reading and discard it
    Serial.println(analogRead(pin_input));
    delay(200);
}

And here is a sample output from an Arduino Uno:

167 710
271 748
287 753
287 751
284 748
281 746
279 741
271 736
268 733
264 732

It looks like the capacitor does not hold its charge very well across consecutive readings. This is presumably caused by the parasitic capacitance of the input pin, which partially charges and discharges the sample-and-hold. Yet, the difference between consecutive recorded readings (about 460) is still very high, and this very clearly shows that the input pin is not connected to a stable voltage.

2

Take some number of analog readings over some period of time and look at the variation among the samples. Do this both with, and without, a potentiometer connected. You should see very stable readings with it connected, ranging over a few counts or less. Without it connected, the readings are likely to cover nearly the entire range A/D range.

A simple way to detect the pot would be to look at the difference between the highest and lowest readings. Pick a range that covers the "pot is connected" case. If the difference falls within that range, assume the pot is connected. Otherwise, assume it is not.

You could improve on this a number of ways, but a simple way would be to take, say, 50 readings, sort them by value, average the lowest 5 or 10 of them, and average the highest 5 or 10. Subtract those averages, and proceed as above.

2

The ADC input has a really high impedance (100 Meg). All you need to do to get a consistent reading (of zero) is to connect it to ground through a suitable resistor. 100K will probably be fine, and you might be able to get away with 1 Meg. It should be at least 10x bigger than your pot to avoid loading it when connected.

1
  • 1
    You are quite right, although such an arrangement would not distinguish between nothing connected and the pot turned to its lowest setting.
    – Nick Gammon
    Jun 16 at 23:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.