Measuring Arduino Internal Pull-up Resistors
The Arduino (and many other boards) have a very useful time-and-cost saving feature ideal for when you are working with buttons and switches - namely internal pull-up resistors on the GPIO pins which can be enabled / disabled at will in software. This means you don't have to clutter your board up with pull-up resistors of your own for all the buttons and things, and also means they can be turned off and on to give your design much more flexibility.
But nowhere can you find out actually what the resistance of these resistors are. Why not? Simply because nobody knows.
All that can be said is "they are around such-and-such a value". The Arduino manual pages say they are about 20KΩ. The ATMega328P datasheet says "Min 20KΩ ... Max 50KΩ". That's a pretty huge range, really.
But what actually is the value of these pull-up resistors? How can we find out? Well, fortunately it's pretty simple thanks to Ohm's Law.
Ohm's Law tells us that "the current through a conductor between two points is directly proportional to the voltage across the two points" and that proportion is the resistance of the conductor. So logically, if we can know the voltage across the pull-up resistor and the current flowing through the pull-up resistor we can calculate the resistance.
And we can.
The operation is quite simple: for an unconnected IO pin simply set it to an input with the pullup enabled:
And then measure the current that flows between that pin and ground with a multimeter.
And since we know the voltage the chip runs at (5V - but measure it with the multimeter just to make sure; mine measured 4.98V) we can now calculate the resistance:
You can't do it on pins 0 and 1 of the Arduino UNO because those pins are connected to the USB interface chip, and that makes a complete mockery of the results. But, leaving out those two pins, I ran the test on every pin of two seemingly identical Arduino UNOs, and this is the result:
|Pin||mA 1||Ω 1||mA 2||Ω 2|
- Board 1 Average: 37289Ω
- Board 2 Average: 34229Ω
So even though the boards look identical there is quite a difference in the pull-up resistor values. Within a single chip the values are fairly consistent, though, so we can assume that pins 0 and 1, if they were disconnected from the USB chip, would also be around the same value as the rest of the pins. But you can't measure the value in one chip and assume it's the same in another chip, because it won't be.
And why don't they make the resistors more accurate? Well, they could, but why would they? Increasing the accuracy increases the cost, and for pull-up resistors it really doesn't matter what the value is as long as it's not too small (which would make too much current flow) or too large (which would slow down the input pin's gate charge rate). So they keep it cheap and "good enough" without having to worry too much about it.