INPUT_PULLUP Uncertainty

Trying to test the Analog Inputs on a Nano, so thought reading the values of all 8 inputs without any termination should return something near 0, and then the inputs with INPUT_PULLUP on each Analog Input should return something close to 1023. However, INPUT_PULLUP has no effect on the value read, which is around 230 whether or not the pull-up is specified.

Do I have a misunderstanding of how INPUT_PULLUP and AnalogRead work?

An Analogue pin is designed to read in a voltage between 0 and 5v.

If nothing is connected to an ADC pin, then its called 'floating' where random values are read.

If you applied a Pull Up , which mean connecting the pin to +5v via a resistor then you get a totally false reading.

The typical way to test out an ADC port is with a 10k pot or similar, connected between 0v and +5v with the slider to the input pin, you should then see a reading between 0 and 1023 as you move the slider.

a 10k pot or similar, connected between 0v and +5v with the slider to the input pin,

How is the potentiometer with the slider all the way to +5V any different than an input with an internal pull-up to 5V? Should be supplying 5V to the input pin either way, shouldn't it?

Is it possible to use an internal pullup resistor and treat the pin as an analog input at the same time? (I don't know).

You need to read the Atmel datasheet.

...R

Tested it on a 328 based board; get a reading of approx. 1000 with internal pullup. Get a reading of 200 to 300 with normal input mode.

Only reading a single input.

// Edit: the code

void setup()
{
  Serial.begin(9600);

  pinMode(A0, INPUT_PULLUP);
}

void loop()
{
  static int cnt = 0;
  if (cnt > 100)
    pinMode(A0, INPUT);

  Serial.print(cnt); Serial.print(": "); Serial.println(analogRead(A0));
  delay(250);
  cnt++;
}

Yes, that's what I'd expect. Since D1 drops the USB's 5V a little, reading should be a little less than 1023. With INPUT_PULLUP on some input pins, still get about 200 - 300 on those pins. Once I figure out how to post code I'll add it...

Okay, here's the code and results...

// the setup function runs once when you press reset or power the board
void setup() {
  Serial.begin(9600);         // Initialize the connection to Serial Monitor
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
  
  pinMode(A0, INPUT);    // Test Input
  pinMode(A1, INPUT_PULLUP);    // Test Input
  pinMode(A2, INPUT);    // Test Input
  pinMode(A3, INPUT_PULLUP);    // Test Input  
  pinMode(A4, INPUT);    // Test Input
  pinMode(A5, INPUT_PULLUP);    // Test Input
  pinMode(A6, INPUT);    // Test Input
  pinMode(A7, INPUT_PULLUP);    // Test Input
}

// the loop function runs over and over again forever
void loop() {

 int inputRead;
  int chan;

  for (chan = 0; chan <= 7; chan+=1){    
    inputRead = analogRead(chan); 
    Serial.print("Input ");
    Serial.print(chan);
    Serial.print(" is " );
    Serial.println(inputRead);    
  } // End For
  
  Serial.println("===================="); 
  
} // End Loop

and the results from Serial Monitor...

Input 0 is 223
Input 1 is 1018
Input 2 is 783
Input 3 is 1019
Input 4 is 772
Input 5 is 1022
Input 6 is 766
Input 7 is 550

Without pull-ups, get this...
Input 0 is 220
Input 1 is 232
Input 2 is 231
Input 3 is 253
Input 4 is 282
Input 5 is 292
Input 6 is 289
Input 7 is 229

See my error...
was using
pinMode(0, INPUT);
instead of
pinMode(A0, INPUT);

Inputs 2, 3, 6, & 7 look odd...
A2, 4, & 6 are higher than expected 200 - 300.
A7 is lower than expected. Is something different about A7 internally?

Swapped the pull-ups to 0, 2, 4, 6 and get similar results on pin 6 ad pin 7, about 600 not 1000.

Found this in Nano data...
"Analog pins 6 and 7 cannot be used as digital pins."

So perhaps this causes these pins to act a little differently with pull-ups.

Appears then that the analog inputs and pull-ups are functioning normally.

rickso234:
Yes, that's what I'd expect. Since D1 drops the USB's 5V a little, reading should be a little less than 1023.

D1 and USB 5V are irrelevant and misleading in this context.

The supplied voltage is Vcc, be it 4.8 or 5.2v, The ADC works on Vcc **and divides it up into 1024 steps.

** correction in the case of the Atmega 328 chip it has its own internal reference, so is similarly unaffected by variations in the supply voltage.

Checking on the Analogue Pull Up , seems it is permissible, though think it would be very rare that anyone reading in an analogue voltage would want to use a pull up.

Would be interesting to know of any practical applications doing that..

If using INPUT_PULLUP on analog inputs, the equivalent resistance value is 30K-50K. However, the input impedance should be <= 10K when taking analog readings for stable and accurate results. Especially when switching to a different input, it will take time for the internal ADC capacitor charge or discharge and settle. A common solution is to add a 100nF capacitor from the analog input to GND to effectively lower the input impedance. Also, doing a double read (don't use the first) will give more accurate results.

rickso234:
Found this in Nano data...
"Analog pins 6 and 7 cannot be used as digital pins."

So perhaps this causes these pins to act a little differently with pull-ups.

Well, they don't have any pull-ups since those are part of the digital circuitry.

Hi,

rickso234:
Trying to test the Analog Inputs on a Nano, so thought reading the values of all 8 inputs without any termination should return something near 0, and then the inputs with INPUT_PULLUP on each Analog Input should return something close to 1023. However, INPUT_PULLUP has no effect on the value read, which is around 230 whether or not the pull-up is specified.

Do I have a misunderstanding of how INPUT_PULLUP and AnalogRead work?

I know you are trying to check the operation of your analog inputs.
You have found that the PULL-UP does not work on a pin in analog mode.
That's good, other wise the PULL-UP would distort your analog input voltage going to the ADC by applying an offset.
#10 and we are still talking about something that sounds SOOOO logical to do.
As suggested the way to check your analog input is with a pot.

http://www.arduino.cc/en/tutorial/potentiometer
Done... Tom... :slight_smile:

I can't find the reference right now, but I was under the impression that one should not call pinMode on pins that will be read with analogRead. Have I imagined that?

If the analog source being read has low source impedance, than the 30-50K pullup resistor will only marginally impact the reading.

TomGeorge:
You have found that the PULL-UP does not work on a pin in analog mode.

Well, that's not true.

It works, but it is an approximately 30k pull-up. No more, no less. At such a relatively high impedance, it may require a capacitor to hold the value whilst analogRead samples it, such as to read a LDR.


ChrisTenone:
I can't find the reference right now, but I was under the impression that one should not call pinMode on pins that will be read with analogRead. Have I imagined that?

The only interesting situation, is if you set it as an output. I don't think analogRead alters pinMode.

Was surprised to see a difference in behavior between
pinMode(0, INPUT_PULLUP);
and
pinMode(A0, INPUT_PULLUP);

The first does not connect a pull-up while the second does.
Also, have used analogRead on pins without first having defined pinMode

A0 is not the same as 0.

Serial.print(F("pin A0 = ")); Serial.println(A0);

Your first snippet simply switched on the pull-up on pin 0 (the RX pin).

ricky101:
** correction in the case of the Atmega 328 chip it has its own internal reference, so is similarly unaffected by variations in the supply voltage.

That would be 1.1V reference that is in all AVR's?

1.1V for 328P
Selectable 2.56V or 1.1V ADC reference voltage for 1284P & 2560