difference between digitalWrite and pinmode

Hi all,

I was wondering if I can use pinMode on analog inputs without problems.

The arduino site Arduino Site states the following :

Pullup resistors

The analog pins also have pullup resistors, which work identically to pullup resistors on the digital pins. They are enabled by issuing a command such as

digitalWrite(A0, INPUT_PULLUP); // set pullup on analog pin 0

Be aware however that turning on a pullup will affect the values reported by analogRead().

So my obvious questions are,

  • what then is exactly the difference between digitalWrite and pinMode
  • Is this legal as well?
    pinMode(A0, INPUT_PULLUP);

do you know what a pull-up circuit is? it is a circuit that sets the pin at voltage, but with very low current (big resistance). if you connect such a pin to ground, the connection to ground 'wins' and the value on the pin falls to LOW.

and a pull-down circuit connects the pin to ground with high resistance. without pull-up or pull-down the voltage measured on pin changes randomly, it is 'floating'

if you do digitalWrite HIGH the pin has 'strong' voltage which, if you would connect it to ground would allow current flowing without limit (a 'short') and destroying the pin.

so INPUT_PULLUP activates the internal pull-up circuit of the MCU, which is useful for example if you connect a button between the pin and ground. if the button is pushed, the value at pin is LOW. if the button doesn't connect the pin to ground then the internal pull-up connects it to voltage and you read HIGH state at the pin.

Juraj:
do you know what a pull-up circuit is?

Yes, i do, still thanks for explaining...

But the question was about the difference between digitalWrite and pinMode.

If you follow the link, you see the example I quoted.

I was wondering, maybe this a typo and should it read pinMode instead of digitalWrite, if not, what then is the difference between :

digitalWrite(A0, INPUT_PULLUP);

and

pinMode(A0, INPUT_PULLUP);

The first one seems to be an error on that page. It might work or not depending on the value that INPUT_PULLUP represents (can't check now).

Kevin77 asks what is the difference between "digitalWrite(A0, INPUT_PULLUP);" and "pinMode(A0, INPUT_PULLUP);".

I think the explanation at https://www.arduino.cc/en/Tutorial/AnalogInputPins is somewhat confusing.

If the reference of digitalWrite() is true, the second argument to it is either "HIGH" or "LOW" and not "INPUT_PULLUP". But the source code of digitalWrite() is CURRENTLY implemented if the second argument is LOW or others. As a result digitalWrite(pin, INPUT_PULLUP); is identical to digitalWirte(pin, HIGH);

So my opinion is
1.

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

and

pinMode(pin, INPUT_PULLUP);

are identical.

  1. pinMode(A0, INPUT_PULLUP); is legal because the reference of digitalWrite() says "The analog input pins can be used as digital pins, referred to as A0, A1".

mkgt00:
I think the explanation at https://www.arduino.cc/en/Tutorial/AnalogInputPins is somewhat confusing.

If the reference of digitalWrite() is true, the second argument to it is either "HIGH" or "LOW" and not "INPUT_PULLUP".

I agree, but I have come across other examples where the reference omits certain options.

Also
digitalWrite(A0,INPUT_PULLUP);

compiles without errors and value of INPUT_PULLUP = 2.

mkgt00:
So my opinion is
1.

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

and

pinMode(pin, INPUT_PULLUP);

are identical.

  1. pinMode(A0, INPUT_PULLUP); is legal because the reference of digitalWrite() says "The analog input pins can be used as digital pins, referred to as A0, A1".

I am inclined to agree, then again I am a complete amateur in this field who hardly knows a thing about the in's and out's of the atmega...

digitalWrite(A0, INPUT_PULLUP) is an error, which may lead to unexpected behavior for some boards

mkgt00 and sterretje. you plan to check all board packages for pinMode implementation?

Juraj:
digitalWrite(A0, INPUT_PULLUP) is an error, which may lead to unexpected behavior for

If this is true (and it probably is), who do you contact to report an error on that page?

Thanks everyone!

There already is an open issue on this:

Refer to the link given in Post#8, the execution of the following codes on UNO clearly establishes that:

digitalWrite(A0, INPUT_PULLUP); is a valid instruction, and it connects an internal pull-up resistor to the input pin of an analog channel. This pull-up could be a different one from that one which we connect to the input of a digital input-pin by the command pinMode(4, INPUT_PULLUP); or pinMode(A0, INPUT_PULLUP);.

void setup() 
{
  Serial.begin(9600);
  analogReference(DEFAULT);
  digitalWrite(A0, INPUT_PULLUP);
}

void loop() 
{
  unsigned int x = analogRead(A0);
  Serial.println(x, HEX);
  delay(2000);

}

Observation:
1. digitalWrite(A0, INPUT_PULLUP); is executed with A0-pin disconnected from any external circuit/signal; the Serial Monitor shows almost a constant value (theoretically, it should be 0x3FF).

2. digitalWrite(A0, INPUT_PULLUP); is not executed, and the A0-pin is kept disconnected from any external circuit/signal; the Serial Monitor shows values between 0x3FF and 0x00 which means that the A0-pin is at floating condition.

digitalWrite(A0, INPUT_PULLUP); on Uno is digitalWrite(A0, HIGH);. on Uno! you can't test all Arduino boards. one must hold to reference and do not use nonsense

It is not the win-win game; it is the question of technical validation in favor of the proposition which could be wrong!

digitalWrite(pin,INPUT_PULLUP) is the same as digitalWrite(pin,2) (INPUT_PULLUP is just #define). That in turn is the same as digitalWrite(pin,HIGH), because 2 is not equal to 0.

See source https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_digital.c

The key part of the code for digitalWrite is:

if (val == LOW) {
 *out &= ~bit;
 } else {
 *out |= bit;
 }

where *out is a pointer to the PORTx register, and bit is (1<<(number of pin within port).

When the corresponding bit in the PORTx register is set, if the pin is an output, it will drive the pin HIGH, and if it's set as input, it will enable the pullups.

Corresponding code from pinMode, if it matters to anyone:

if (mode == INPUT) { 
 uint8_t oldSREG = SREG;
                cli();
 *reg &= ~bit;
 *out &= ~bit;
 SREG = oldSREG;
 } else if (mode == INPUT_PULLUP) {
 uint8_t oldSREG = SREG;
                cli();
 *reg &= ~bit;
 *out |= bit;
 SREG = oldSREG;
 } else {
 uint8_t oldSREG = SREG;
                cli();
 *reg |= bit;
 SREG = oldSREG;
 }

here, *reg is pointer to the DDRx register, which sets whether the pin is an input or output.

The saving of SREG, cli() to disable interrupts, then restoring SREG after (which will turn interrupts back on, if they were on before) is needed to make the operation atomic (ie, to prevent an interrupt from happening in in the middle of that read-modify-write process implied by |= and &=); there is a similar safeguard in digitalWrite, only outside of the if statement.

(note that above discussion applies to AVR micros, not ones with other architectures)

They should have defined enumerated types for pin modes. Then that line would have triggered an error.

digitalWrite(A0, INPUT_PULLUP) is an error, which may lead to unexpected behavior for some boards

mkgt00 and sterretje. you plan to check all board packages for pinMode implementation?

I implictly assumed the board is uno. I wrote the code happen to work on uno because of its implementation. That's it. I do not say digitalWrite(A0, INPUT_PULLUP) is legal.

DrAzzy:
The key part of the code for digitalWrite is:

if (val == LOW) {

*out &= ~bit;
} else {
*out |= bit;
}

This explains why a 2 does not throw an error...

This may be a silly question but where can I find this code?

On my Mac it's here: /Applications/Arduino.app/contents/Java/hardware/arduino/avr/cores/arduino/wiring_digital.c

Thank you, on mine as well!

This is interesting!