Using internal pullup

I was wondering why it seems that people are avoiding using the internal input pullup function. I've seen several cases where the active output was chosen to pull high against possible contention to avoid using that input function or an external pullup resistor. I know that the specs say it could be as high as 50k but that is still not all that bad for short wires. Dwight

dwightthinker: I've seen several cases where the active output was chosen...

The what?

I think Dwight is referring to the fact that one can use digitalWrite(somePin, HIGH) to enable the internal pull-up.

I'm reasonably new to Arduino (first IDE version 1.6.6); I've read somewhere that the first libraries did not support INPUT_PULLUP and the above digitalWrite (on a pin configured as input) is used to switch the internal pull-up on. Might be wrong though.

I was wondering why it seems that people are avoiding using the internal input pullup function.

I've never used an external pull-up with the Arduino.

I've seen several cases where the active output was chosen to pull high against possible contention to avoid using that input function or an external pullup resistor.

If you're connecting an output that drives high & low (like an Arduino output) to an Arduino input, there's no need for a pull-up since the input will always be hard-driven high or low.

In cases where an analog input might "float" you may need to pull it down with an external resistor.

My understanding is that the INPUT_PULLUP function puts the resistor to the input and also writes a high to the output port. I'm currently using the inputMode with INPUT_PULLUP to be a high for communications with a PS2 mouse. I use two lines for a low. A write of LOW and a pinMode to output. It creates a good looking signal on a scope and works well. I look at the library in the playground and it does a hard pullup before switching to input mode. It might be that the older compiler didn't support it but one wonders why new users don't take advantage of it. It is really handy for things like switches. Dwight

DVDdoug: I've never used an external pull-up with the Arduino. If you're connecting an output that drives high & low (like an Arduino output) to an Arduino input, there's no need for a pull-up since the input will always be hard-driven high or low.

In cases where an analog input might "float" you may need to pull it down with an external resistor.

There are case where the pin is used as a bidirectional signal pin, such as the PS2 mouse. In this case, the only valid hard signal on the wire is a hard pull down. The line is suppose to have a soft pullup when not being driven from the uP. Dwight

sterretje: I've read somewhere that the first libraries did not support INPUT_PULLUP

Correct.

and the above digitalWrite (on a pin configured as input) is used to switch the internal pull-up on.

Correct.

This...

  pinMode( 7, INPUT_PULLUP );

...and this are functionally equivalent on AVR processors...

  pinMode( 7, INPUT );
  digitalWrite( 7, HIGH );

The reason for this seeming bizarrness is that there are trios of registers that control the GPIO functions of the AVR pins: PINx, PORTx, and DDRx (replace x with A, B, C, D, etc).

PINx is usually only read from, and is used by digitalRead to read the digital level asserted on the pin. It has nothing to do with this issue.

DDRx stands for "Data Direction Register" and is used to set the pin as either input or output. Originally, this was the only register written by pinMode.

PORTx is the output register of the pins, usually only written to. It pulls double duty, and the meaning of its bits changes depending on the value in the DDRx register. If DDRx sets the pin to an output, the value you write to PORTx makes the pin assert that digital level.

When DDRx sets the pin to input, PORTx controls the pullup resistor. When the PORTx bit is 0, the pullups are disabled; when 1, pullups are enabled.

Setting the appropriate input configuration of the pin always requires setting BOTH the DDRx and PORTx registers. Originally, this had to be done with separate pinMode and digitalWrite commands. pinMode has since been updated: INPUT and INPUT_PULLUP both force the PORTx register to the correct value.

OUTPUT, however, does not write to the PORTx register. If you were INPUT_PULLUP and you pinMode to OUTPUT, the outut will be asserted HIGH; if you were just INPUT and pinMode to output, the pin will be asserted LOW.

I've never used an external pull-up with the Arduino.

I have but only when I wanted to have a much stronger pull up, in the presence of potential interference. I would normally use a 4K7 or a 3K3 pull up, but on rare occasions I have gone for a 1K where there was a lot of motor current floating about.

dwightthinker: My understanding is that the INPUT_PULLUP function puts the resistor to the input and also writes a high to the output port.

Pin, not port. You'll cause no end of confusion if you same port when you mean pin.

And don't confuse PINx with pin either. PINx is one of the Port INput registers. Ports on ATmega microcontrollers are 8 bit sets of pins sharing common control registers as outlined above. For instance the D port is controlled by PORTD, PIND, DDRD and on the Uno port D consists of pins RX, TX and D2..D7.

I take it that when you use an analog input pin as a digital input, the pinMode( input, INPUT_PULLUP) function also works?

( I haven't tried that yet)...

regards

Allan.

I guess my confusion was that INPUT_PULLUP was an added operand to pinMode(). Much of the code examples must have been written before it was added. As for port versus pin, I am quite aware that there are physical 8 bit ports mapped to pin numbers. When writing code with pin numbers, the concept of port can be any combination of one to n pins, depending on the logical purpose. If writing at the low level code it would be port/pins. It may not be normal to think of a single pin as a port but in current day uP with a SERDIS, it is typical to call the single pin as a port when used that way. My use of the word port was not meant to confuse. Dwight

allanhurst: I take it that when you use an analog input pin as a digital input, the pinMode( input, INPUT_PULLUP) function also works?

Correct.

The digital pin driver is independent from the analog-to-digital converter. Which means you can perform an ADC read on a digital output.

Indeed you can tell if the output is overloaded even (by the ADC result being too far from 0 or 1023)…

I was wondering why it seems that people are avoiding using the internal input pullup function.

My curiosity is why internal pullups aren’t turned on by default, thereby preventing any floating pins on startup. Would be a nice (optional) feature to have in the IDE.

So write yourself a couple of lines to put in your sketches:

void setup(){
  for (byte x=0; x<20; x=x+1){ // 32 for a '1284P, 70 for a Mega
  pinMode (x, INPUT_PULLUP);
  }
}

Take advantage of the fact that all pins are set to inputs after a reset.

Yeah, it's quite simple to do, but I think very few take the effort (I'm guilty) or even consider this. Ironic that more care is taken to prevent unconnected inputs on external IC's than the Arduino itself.

I guess a side effect is that if the pin is set as output without turning off the pullup first, the output will default high. Probably 50% of the time this is needed anyways.

My curiosity is why internal pullups aren't turned on by default, thereby preventing any floating pins on startup. Would be a nice (optional) feature to have in the IDE.

Because then they fight external pullups you might add to prevent peripherals switching on during reset.

In a micropower application an internal 30k pull-up fighting an external 4k7 pull-down is drawing 140uA, but many micropower circuits are designed for 5uA sort of level. That would mean not being able to use any pull-downs at all.

(Actually in that situation any input pin not externally needing a pull-down would have internal pull-ups enabled to prevent floating, a floating pin can consume a lot of current too if it floats somewhere in the middle)

MarkT
Good one.

.

Well, as is, it would be up to the user to enable pullups for unused inputs. If on by default, it would be up to the user to disable those not required. Why have multiple antennae feeding interference into the MCU?

Spoiled I guess, from using FPGAs where this is a setup option prior writing to the configuration prom.