Any arguments against using internal pull-ups?

I really like internal pull-ups for reading buttons and switches.
It simplifies matters a bit, to have the code and the chip doing the work, rather than external components.

But it is so easy, I think there must be a catch?
Are there any arguments against using internal pull-ups?

No catch. I use them for the same all the time.

These I believe are 10k-50k.
I use them all the time.
However in a noisy environment and with longish cables you my want to use a low external value 470=1K.

If I could have my way they would be pull-downs because it seems more logical to me somehow that pressing a button should take it HIGH, but having said that I have no problem using INPUT_PULLUP and testing for LOW on a pin. The convenience of not having to wire in an external resistor far outweighs other considerations.

Positive Logic, Negative Logic, can think of it either way: active is the level that the signal is not at normally. High when normally resting Low, and Low when normally resting High.

LarryD:
These I believe are 10k-50k.
I use them all the time.
However in a noisy environment and with longish cables you my want to use a low external value 470=1K.

THIS exactly. I had a problem with a little controller that I built to use in a rather noisy (electrically noisy) area. Simply using "PINMODE INPUT_PULLUP" was not enough. At first I thought I had really bad switches that bounced a lot (and had to write some debounce code with a hideously long 100 msec timeout to make it work).

It kept bugging me that the switches couldn't be THAT bad, so I did a little test code to read the digital ports as fast as possible and record it to SRAM. Then I looked at it. Lots of noise, and doing an FFT on the noise showed (surprise) a 60 and 120 hz component (ac line noise).

Changed to using hard wired 1K (1000 ohm) pullups. No problems now at all... solid as a rock.

For what it's worth.........

UKHeliBob:
If I could have my way they would be pull-downs because it seems more logical to me somehow that pressing a button should take it HIGH, but having said that I have no problem using INPUT_PULLUP and testing for LOW on a pin. The convenience of not having to wire in an external resistor far outweighs other considerations.

The reason pull-ups are used is that then the switches can all wire to ground (which
is usually available everywhere as the groundplane or chassis or box in which the
equipment is mounted). You don't need another wire to run Vcc to all your buttons.

Also several bus protocols use pull-up resistors and open-drain outputs, so there are
two reasons why pull-ups are more commonly wanted than pull-downs.

I think the biggest reason why active-low has become the preferred approach is that it avoids needing to supply power to remote switches/devices, which means there's less risk of a wiring fault/damage shorting the power to ground. When your only wires are ground, and something that is designed to be pulled down to ground, then it's pretty difficult to blow it up.

UKHeliBob:
If I could have my way they would be pull-downs because it seems more logical to me somehow that pressing a button should take it HIGH,

#define ACTIVATED LOW

if(switchpin == ACTIVATED) // see now it makes sense :)
  {
  // do stuff
  }

tylernt:

if(switchpin == ACTIVATED) // see now it makes sense :)

Shouldn't that have a digitalRead() in there somewhere?

There was a great tip here somewhere a while ago, to help remember the button position for pullup / active low systems. With a momentary push-button, the position of the button itself is the state...

Button up, ie inactive normal position, and in its physically "high" (= up) position, is logic high.
Button down, ie active and pressed, and in its physically "low" (= down) position, is logic low.

PeterH:

tylernt:

if(switchpin == ACTIVATED) // see now it makes sense :)

Shouldn't that have a digitalRead() in there somewhere?

Sorry, I couldn't find the "pseudocode" button. :roll_eyes:

I have one argument....

Using a resistor ensures it's pulled up, what happens when you accidentally remove the pullup or switch states accidentally and you then spend hours debugging to find it....

How do you accidentally remove the pullup? That sounds like poor coding to me. Usually its turned on in void setup and then not changed.

You're more likely to hose yourself with = when you wanted ==, or leaving out a digitalRead and then making a decision.

cjdelphi:
I have one argument....

Using a resistor ensures it's pulled up, what happens when you accidentally remove the pullup or switch states accidentally and you then spend hours debugging to find it....

You mean, in case you accidentally change the pinMode from INPUT_PULLUP to INPUT? or accidentally change the condition in an if from LOW to HIGH or vice versa?

Or are you thinking you might accidentally pull a pullup or pulldownout of a solderless breadboard?

In either case, I hardly think it would take hours to figure out what went wrong.

So nobody here has ever mistakes happen? Code vanishing?

Maybe because you used a backup, mouse / keyboard go mad accidentally deleting code, I'm not saying it will happen but it soundslike you've not been knee deep in code looking at tens of thousands if not hundreds of thousands of lines of code some of the desktop apps I've written over the past 15 years ..

But a 10k resistor to high is not that much of a deal to ensure it works properly despite of code used.

The internal pull-ups should be spot on for 99% of applications.
If you need to use lower resistors because of long lines, then it's time to rethink your circuit as long lines and micros don't mix.
Long lines leading to inputs of micros need to be buffered as the lines will act as "aerials" picking up all sorts of interference and of course induced voltage spikes.
It's not if but when, one of those spikes will take out the micro.

Thanks to all of you.

And thanks for making me aware of INPUT_PULLUP.

I have been first defining the pin as input, then used digitalWrite(pin, HIGH) to set it high.
pinMode(pin,INPUT_PULLUP); does it in a single line instead...... Sweet!

It is funny how "the way I did it the first time" has a tendency to stay, making me blind for other (sometimes smarter) solutions.

it sounds like you've not been knee deep in code looking at tens of thousands if not hundreds of thousands of lines of code

Nope, have never written something that big. Biggest was something that spanned 7 tabs in the IDE, about 25 pages when printed, 13Kbytes total when compiled. Lot of redundancy to deal with 16 buttons from a keypad. Maybe 1500 lines of typed out code.

cjdelphi:
So nobody here has ever mistakes happen? Code vanishing?

Maybe because you used a backup, mouse / keyboard go mad accidentally deleting code, I'm not saying it will happen but it soundslike you've not been knee deep in code looking at tens of thousands if not hundreds of thousands of lines of code some of the desktop apps I've written over the past 15 years ..

But a 10k resistor to high is not that much of a deal to ensure it works properly despite of code used.

Well sure, I've had code vanish, but the whole point is that in something like this, you KNOW, I mean you REALLY KNOW that an input needs to be non-floating, and all you have to do it to ensure that it isn't now floating. If an input doesn't have an external resistor on it, it either doesn't need one because of whatever component/device is attached, or it needs a pullup. I don't care how many lines of code there are, anyone past the beginner stage should be able to configure ALL the inputs and test them all (in a small test program), in less than an hour. Sheesh!