The Arduinoreference can be a bit obscure about the proper use of pin numbers on the analog pins. Should you for example use analogRead(0), or analogRead(A0), afterall if u use “0” wouldn’t that refer to the digital pin ‘0’?
Well, no worries about that: analogRead(0) and digitalRead(0) will read from two different places. The former will read from analog channel 0 or A0 and the latter will read from pin 0 which happens to be a digital pin. The Arduino KNOWS the difference between digitalRead(0) and analogRead(0) because of the difference in commands.
However, the analogpins can also be used as digitalpins and in that case ofcourse the Arduino doesnt see the difference between ‘0’ and ‘0’ (nor can you) so in that case you should use digitalRead(A0) or its ‘digital’ pin number as in digitalRead(14).
The analog pin definition code for the Arduino Uno can be found in thefile hardware/arduino/avr/variants/standard/pins_arduino.h
static const uint8_t A0 = 14;
static const uint8_t A1 = 15;
static const uint8_t A2 = 16;
static const uint8_t A3 = 17;
static const uint8_t A4 = 18;
static const uint8_t A5 = 19;
static const uint8_t A6 = 20;
static const uint8_t A7 = 21;
So, to summarize, for analogRead you can use the following:
- analogRead(0); // channel number
- analogRead(A0); //pin number
for a digitalRead on analogpin A0, you have to use one of the following:
- digitalRead(A0); // channel number
- digitalRead(14); // pin number
for digitalWrite on analogpin A0, you should use one of the following:
- digitalWrite(A0,x); // channel number
- digitalWrite(14,x);// pin number
The analogWrite command ofcourse is a different story as that only has a function on the PWM pins. The analogWrite() command can be called on any of the pins, but it only does something on the PWM pins. On non-PWM ditial pins and all analog pins, it simply calls digitalWrite(). The analogRead command ONLY has a function on the analog pins.
OK that is clear. A source of confusion however may be the use of constants. For instance if you want to read the value of an LDR on analogpin 0, but you like to use a constant so you can refer to the port by a name like ‘LDRpin’.
Well, again, both of the following definitions will work:
- const byte LDRpin=0;
- const byte LDRpin=A0;
and then followed by: analogRead(LDRpin);
The problem however comes when you start using that constant for other commands on that pin, like ‘pinMode’.
It isnt always necessary to set pinMode as usually when you use analogRead your Arduino will understand you are doing a read function, but suppose you want to use the internall pull-up resistor on A0, so you dont need an external resistor for your resistor-LDR voltage divider.
If you would do:
const byte LDRpin=0;
followed by:
pinMode(LDRpin, INPUT_PULLUP);
analogRead(LDRpin);
you will get false readings as you haven’t set the pull up resistor on pin A0, but on pin 0 which is a completely different (digital) pin. You will not only get false readings on A0, but may have completely false function on digital pin 0 as well.
Sure, that would also happen if you are not using a constant, but chances are that when you write pinMode(0,INPUT_PULLUP), you immediately realise something is wrong.
So that is one reason why it is better to always use ‘A0’ ( or A0…A5 for that matter).
ofcourse using
const byte LDRpin=14;
also is not a good idea as that would get the right pin in “pinMode” but not in analogRead. Using the pinnumber “14” is also not a good idea with regard to portability. Yes, 14 refers to pin A0, but not in all arduino’s
For comparaison here is the analog pin definition code for the Arduino Mega:
static const uint8_t A0 = 54;
static const uint8_t A1 = 55;
static const uint8_t A2 = 56;
[…]
static const uint8_t A13 = 67;
static const uint8_t A14 = 68;
static const uint8_t A15 = 69;