Digital Pin, INPUT, PULLUP, OUTPUT

Hi everyone, I'm new to Arduino, I was reading the documentation when I came accross this:

"The pullup resistors are controlled by the same registers (internal chip memory locations) that control whether a pin is HIGH or LOW. Consequently, a pin that is configured to have pullup resistors turned on when the pin is an INPUT, will have the pin configured as HIGH if the pin is then switched to an OUTPUT with pinMode(). [u]This works in the other direction as well, and an output pin that is left in a HIGH state will have the pullup resistors set if switched to an input with pinMode()[/u]."

from https://www.arduino.cc/en/Tutorial/DigitalPins

[u]Part1:[/u] I tried to switch from INPUT_PULLUP to OUTPUT :

  pinMode(8, INPUT_PULLUP);
  delay(1000);
  pinMode(8, OUTPUT);
  delay(1000);

When I connect a diode to pin 8, it goes from being dim (INPUT_PULLUP), to beign bright(OUTPUT) as expected.

[u]Part2:[/u] But when I try to switch from OUTPUT HIGH to INPUT it doen't work:

  pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);
  delay(1000);
  pinMode(8, INPUT);
  delay(1000);

It should go from bright to dim, but it doesn't. It goes from bright to OFF. Is it a mistake in the documentation, or I understood it wrong ? :confused:

Thanks for your help.

Because...

pinMode(8, INPUT);

Configures the pin for INPUT with NO pullup Therefore it writes a LOW to turn the pullup off, thus overwriting your previous digitalWrite(8, HIGH);

Either...

pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);
  delay(1000);
  pinMode(8, INPUT_PULLUP);
  delay(1000);

Or...

pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);
  delay(1000);
  pinMode(8, INPUT);
  digitalWrite(8, HIGH);
  delay(1000);

Edit: although why you'd chose the second example (other than for academic interest) I'm not sure.

Thanks for reporting this error in the documentation @whoisthisagain!

If you would like to help save others from this confusion in the future, you can report it (and any other corrections or improvements you would like to suggest) to Arduino via this form: https://www.arduino.cc/en/ContactUs

That's the best method for alerting the people at Arduino who have the access to update the website content.

pcbbc: Therefore it writes a LOW to turn the pullup off, thus overwriting your previous digitalWrite(8, HIGH);

Thank you @pcbbc , simple and clear. 8)

pert: If you would like to help save others from this confusion in the future, you can report it (and any other corrections or improvements you would like to suggest) to Arduino via this form: https://www.arduino.cc/en/ContactUs

Ok @pert, Got it! :wink:

1. Fig-1 as shown below is the internal architecture of PB0-bit/line of ATmega328P MCU at conceptual level.


Figure-1:

2.

whoisthisagain:

pinMode(8, INPUT_PULLUP);

delay(1000);
 pinMode(8, OUTPUT);
 delay(1000);




When I connect a ~~diode~~ LED8 to pin 8, it goes from being **dim** (INPUT_PULLUP), to beign **bright**(OUTPUT) as expected.

Explanation: (a) With pull-up connected in input mode, gate/buffer-GOB0 is OFF; switch-S is closed; Rip comes into circuit; LED is dim due to insufficient current in the Rip(35k)-R1(1k)-LED8 circuit.

(b) In output mode, Rip goes out-of-circuit; gate/buffer-GOB0 is ON; LED8 gets sufficient current, and it is bright (ON).

3.

pinMode(8, OUTPUT);

digitalWrite(8, HIGH);
 delay(1000);
 pinMode(8, INPUT);
 delay(1000);




But when I try to switch from **OUTPUT** HIGH to **INPUT** it doesn't work: It should go from **bright to dim**, but it doesn't. It goes from **bright to OFF**.
Is it a mistake in the documentation, or I understood it wrong ?

Explanation: In “INPUT” mode, Rip is not in circuit due to open condition of switch-S; GOB0 (Output buffer Gate for B0 bit) is OFF. LED8 receives no current; so, it (LED8) is OFF which is TRUE.

4. The LED8 will go from “bright” to “dim” if this instruction is executed: pinMode(8, INPUT_PULLUP); in stead of this code: pinMode(8, INPUT);.

5. Conclusion: You understood “RONG”!

GolamMostafa: 5. Conclusion: You understood "RONG"!

Are you saying that this sentence of the "Digital Pins" tutorial is correct?

This works in the other direction as well, and an output pin that is left in a HIGH state will have the pullup resistors set if switched to an input with pinMode()."

Arduino 1.0.1 change notes "Added INPUT_PULLUP argument to pinMode() function. The INPUT mode now explicitly disables the pullup resistors" https://www.arduino.cc/en/Reference/Changes

Yes, so the documentation was correct up until the release of Arduino IDE 1.0.1 in 2012.

There's another related error I noticed in that tutorial (though not so serious):

Prior to Arduino 1.0.1, it was possible to configure the internal pull-ups in the following manner:

pinMode(pin, INPUT);           // set pin to input
digitalWrite(pin, HIGH);       // turn on pullup resistors

It should say:

Prior to Arduino 1.0.1, it was necessary to configure the internal pull-ups in the following manner:

It's still possible to do this (though I don't know whether it's supported by every single boards core), but prior to Arduino IDE 1.0.1 it was the only way.

this internal pull-up tricks are only for classic ATmega

pert:
Are you saying that this sentence of the “Digital Pins” tutorial is correct?

“This works in the other direction as well, and an output pin that is left in a HIGH state will have the pullup resistors set if switched to an input with pinMode().”

My understanding does not match with what is told in the above sentence withing opening-closing double quotes(" and ").

When DPin-8 (Fig-1 of Post#4) is made input, GOBO is OFF; because, 0 is written into DDRB0-bit of DDRB register. Then how is it possible to have HIGH on DPin-8 which was “output and HIGH” a while ago? DPin-8 will be at “floating state” without any external circuit.

Juraj: this internal pull-up tricks are only for classic ATmega

Some other cores emulate this behavior: https://github.com/arduino/ArduinoCore-samd/blob/1.8.6/cores/arduino/wiring_digital.c#L86L89

  if ( (PORT->Group[port].DIRSET.reg & pinMask) == 0 ) {
    // the pin is not an output, disable pull-up if val is LOW, otherwise enable pull-up
    PORT->Group[port].PINCFG[pin].bit.PULLEN = ((ulVal == LOW) ? 0 : 1) ;
  }

GolamMostafa: My understanding does not match with what is told in the above sentence withing opening-closing double quotes(" and ").

OK, so we're now in agreement that @whoisthisagain understood it right and that, in the year 2020, this is a mistake in the documentation?

GolamMostafa: When DPin-8 (Fig-1 of Post#4) is made input, GOBO is OFF; because, 0 is written into DDRB0-bit of DDRB register. Then how is it possible to have HIGH on DPin-8 which was "output and HIGH" a while ago? DPin-8 will be at "floating state" without any external circuit.

they set the pin LOW in pinMode(pin, INPUT) to turn off the pull-up and yes the pin will be floating without external circuit

Juraj: they set the pin LOW in pinMode(pin, INPUT) to turn off the pull-up and yes the pin will be floating without external circuit

Bravo! :)

Thank you so much all of you! It is amazing how much one can learn from an online forum.

Thank you @GolamMostafa. Your picture made everything clear. I've been looking for that. Do you have more similar? Because I would like to understand the inner working of Arduino; and the diagrams I have been seeing online are like chinese to me (nothing against Chinese ;) ).

whoisthisagain:
Thank you so much all of you! It is amazing how much one can learn from an online forum.

Thank you @GolamMostafa. Your picture made everything clear. I’ve been looking for that. Do you have more similar? Because I would like to understand the inner working of Arduino; and the diagrams I have been seeing online are like chinese to me (nothing against Chinese :wink: ).

I have many self-drawn pictures based on experience and data sheets on the architecture and programming of ATmega328P MCU and UNO. Tell me the name of specific module of the MCU whose picture is to be delivered. For example: Digital IO Controller or ADC Module. Anyway, I am posting below two diagrams – one on UNO’s signal signatures and the other one on ADC Module.


Figure-1: Digital IO lines structure of MCU/UNO


Figure-2: ADC module of MCU

If you have any question, I will be delighted to try to answer.

50lxy.png

whoisthisagain: Thank you so much all of you! It is amazing how much one can learn from an online forum.

Thank you @GolamMostafa. Your picture made everything clear. I've been looking for that. Do you have more similar? Because I would like to understand the inner working of Arduino; and the diagrams I have been seeing online are like chinese to me (nothing against Chinese ;) ).

There are lots more pretty pictures in the data sheet for the processor, and it is amazing what you can learn from that!