Go Down

Topic: internal pullup resistors & digitalWrite (Read 17145 times) previous topic - next topic


My thoughts were to keep the pin variable consistant,  to what its purpose has been in the past.  A third variable would indicate that we were doing something different than what we had done in the past.

I have programmed other Atmel chips on their platform and I could have sworn that I set output pullups... I might be wrong, but it does seem that we can't do it on the mega 168/328. Sorry for the confussion but I was quite sure they could be set.

Because the outputs can't be set it may just make more sense to set up the function for the 2 variable inputs as suggested.


Coding Badly, I like your way of putting it.  We could think of pins as having three modes: OUTPUT, INPUT, and PULLUP.  In this case, would INPUT mode explicitly disable the pullup?


In this case, would INPUT mode explicitly disable the pullup?

I would think so.  Otherwise, how would you disable them?   :-?


In this case, would INPUT mode explicitly disable the pullup?

I also think this is easy to understand:

INPUT             (input mode without pull-up)
INPUT_PULLUP (input mode with pull-up on)
OUTPUT          (output mode)

Coding Badly

Mar 23, 2010, 07:26 am Last Edit: Mar 23, 2010, 07:27 am by bcook Reason: 1

If INPUT turns off the internal pullup, the risk is that existing code will break.

I believe there are two cases that would fail if INPUT disables the pullup...

1. The user assumed pinMode would not alter the pullup.

2. The user first called digitalWrite( pin, HIGH ) to enable the pullup then called pinMode( pin, INPUT ) to ensure the pin is configured as an input.

I've searched and searched the web site and the forum and I cannot find a single instance of either of these cases.  I cannot find any existing code that would break.

I agree with the two above.  INPUT should disable the internal pullup.  That appears to be consistent with what users currently expect.


Coding Badly: thanks for checking that.

Also, I'd like to step back a bit and ask a question to those of you who think the current system is confusing.  I was talking to Leah (Buechley, creator of the LilyPad and my advisor) about this and we both have the sense that pullup resistors are tricky to explain to people, but that the actual syntax to enable them is not as much of a problem.

Is this something we might better address with improved documentation explaining the existence and functionality of pullup resistors rather than changing the syntax for enabling them?


I think it needs both.

Certainly the docs could do a better job of explaining the whole concept and implementation in the Arduino system.

But I also think that the current mechanism is non-intuitive. It's not so much syntactically confusing as it is semantically disconnected. It is a mode in which you want the pin to behave, and the way you enable that mode is with a command (digitalWrite) that has nothing to do with the mode of a pin, but is otherwise used to send data out on it. We've overloaded the semantics of digitalWrite with another command that changes the mode.

Does that make sense?

That's why I favor some solution that uses a pinMode command to accomplish this.



I think its a combination of the two things as well. Internal pull ups are not obvious and need explanation, but the code that enables them at the moment tends to look like a coding error to a beginner rather than something that has a clear purpose even if you are not sure what - without a comment you simply wouldn't know by looking at the code - alot of other arduino syntax you can guess what it is doing and have a good chance of being close.

For someone who is in a class they get the explanation, and in time it often makes sense, but for someone who is working alone and using the documentation it may be harder. The pages explaining pullups are heavy on text with no diagrams or pictures, so look more intimidating than the pages that they may have been looking at that go with the example sketches.


From a code readability standpoint, I like:

pinMode(pin, INPUT);
pinMode(pin, OUTPUT);

Coding Badly

When would this one be needed...

pinMode(pin, INPUT);


to stop old code from breaking, i think it would be harsh to make it a requirement to use the new syntax exclusively  immediately and break old code.

also when you very first start and are introducing the idea of digital input and don't want to introduce to many things at once.

Its useful for people to build the circuit with the external resistor so they can see the resistor - it provides a concrete demonstration of the two resistances that gives a swing in voltage on the pin (one changing resistance, the switch being an extreme example of this, one fixed resistance - this is a really important concept for many sensors, and what follows soon after, analogue sensors) and to add the internal resistor into the mix while doing that complicates unnecessarily at that point. Then introduce the idea that you can reduce the number of external components for the digital pins, but the trade off is the code gets slightly more complicated.


Any of the suggestions in this thread would be an improvement but if the two parameter suggestion is semantically clearer then it deserves further consideration

when you very first start and are introducing the idea of digital input and don't want to introduce to many things at once.

Digital input is almost always introduced using buttons. These require pull-ups so the concept does need to be explained from the start, although often an external pull-up resistor is introduced before internal pull-ups. However I think that many non-technical people would find it easier to get something going if the button example used internal pull-ups instead of the external pull-downs:
 pinMode(buttonPin, INPUT_PULLUP );    
rather than having to understand and deal with : "a 10k resistor needs to be attached from pin 2 to ground" (sounds of user fumbling through pack of components trying to find the correct resistor)

Breaking existing code would be a problem but I wonder if there is any code that relied on the pull-ups being enabled when changing from output mode to input mode. Pull-ups change their state if the pin is switched to output mode and the pin state is changed, so code that does not explicitly set pull-up state when switching from output to input  is a potential source of bugs. Is anyone aware of any code that does switch from output to input that requires pull-ups in a particular state but does not set them explicitly. If not, assuming the current method for setting pull-ups was still supported, old code would not break.


The example code that ships with arduino currently uses a switch connected to 5V, with a resistor to ground.

This was so you don't have to explain things like the switch pulled the digital in LOW, so digitalWrite HIGH to turn the LED on(it was counter-intuitive to a lot of people).

It feels to me like part of the dilema here is a choice of where you put that bit of complication as you start - a more complicated external circuit (an extra component and more wires), or more complicated code (if low write high, rather than if high write high, and possibly another parameter).

Having a simple code link between switch and LED in the button example, makes introducing pullups soon after more complicated, as you need to reverse the logic of the code/hardware as well at that point.

Having an external resistor at the beginning feels like more preperation for the road ahead to me (it will be needed for other circuits), but I know different people will have different takes on it.


Mar 28, 2010, 05:34 am Last Edit: Mar 28, 2010, 05:35 am by mem Reason: 1
Hi nick,
This was so you don't have to explain things like the switch pulled the digital in LOW, so digitalWrite HIGH to turn the LED on(it was counter-intuitive to a lot of people).

Yes, a lot of things that beginners need to know can be counter intuitive at first, but explaining it as follows is perhaps clearer:

"when the switch is pushed LOW (digitalRead is LOW) the LED is turned on (digitalWrite HIGH)"

As you say, different people have different takes on this, but FWIW, mine is  that the following code (without the external resistor) is easer:

Code: [Select]
void setup() {
 // initialize the LED pin as an output:
 pinMode(ledPin, OUTPUT);      
 // initialize the pushbutton pin as an input with pull-up resistor enabled:
 pinMode(buttonPin, INPUT_PULLUP);    

void loop(){
 // read the state of the pushbutton value:
 buttonState = digitalRead(buttonPin);

 // check if the pushbutton is pushed Down
 // if it is pushed, the buttonState will be LOW:
 if (buttonState == LOW) {    
   // turn LED on:    
   digitalWrite(ledPin, HIGH);  
 else {
   // turn LED off:
   digitalWrite(ledPin, LOW);


I don't think the your discription is significantly different ;) the thing that confuses people is that one is off (the common perception of LOW), so why are you turning the LED on.

When the example in the distribution was as you code, but without enabling pullups you would still be using an external resistor to build the circuit as using the pullup is so opaque in code it was not appropriate for what maybe the second bit of code a beginner sees. so you had the comlexity of the code, and of the circuit.

If there was a more transparent syntax for pullups I think the balance would tip to what you suggested, a simpler build at first, against slightly more complicated syntax.

It kind of mirrors pin 13 with the flashing LED - you can just plug an LED in without worrying about resistors. Its easier at first as some physical complexity is hidden, but you then need to understand whats going on on the board to go further - if you want to go further you are more likely to have the motivation to do it.

Go Up