analogRead(0) or analogRead(A0)

by Tyilo   Last Updated November 08, 2018 23:25 PM

The arduino reference states that you would use the following code to read the value from analog pin #5:

int val1 = analogRead(5);

However to read from digital pin #5, you would pass the same pin number to digitalRead:

int val2 = digitalRead(5);

Shouldn't you use analogRead(A5) instead of analogRead(5)?

If not, what does the following code do:

int val3 = analogRead(A5);


Answers 2


To answer Tyilo's specific questions:

analogRead(5) and digitalRead(5) will read from two different places. The former will read from analog channel 5 or A5 and the latter will read from pin 5 which happens to be a digital pin. So yes, if you want to read an analog pin with digitalRead you should be using A5.

Why?

analogRead requires a channel number internally but it will allow you to give it a pin number too. If you do give it a pin number it will convert it to its corresponding channel number. As far as I can tell analogRead is the only function which uses a channel number internally, is the only one to allow a channel number, and is the only function with this undocumented pin-to-channel conversion. To understand this let's start off with some examples.

If you want to use analogRead on the first analog pin A0 you can do analogRead(0) which uses the channel number or analogRead(A0) which uses the pin number. If you were to use the pin number variant, analogRead would convert the pin number A0 to its proper channel number 0.

If you want to use digitalWrite on the first analog pin A0 you can only do digitalWrite(A0, x). digitalWrite doesn't use analog channels internally and does not let you pass it a channel number. Well, it'll let you but you'll select the wrong pin. The same applies to digitalRead and even analogWrite.

What about the pin-to-channel conversions done by analogRead? The source for that function can be found in hardware/arduino/avr/cores/arduino/wiring_analog.c You'll see that it does some simple subtraction based on the board type. The A0/A1/A2/etc. constants represent the pin number of the analog channels and can be used everywhere you need to refer to the analog inputs. For that reason they are the best option to use in your Arduino code because it's very obvious that you're using the same physical port even when you're using different functions. The definitions of those constants depend on your board.

For example, here's the analog pin definition code for the Arduino Uno in 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;

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;

Further EE discussion on analog pins: Can I use the analog pins on the Arduino for my project as digital?

Kevin Mark
Kevin Mark
April 18, 2013 18:56 PM

https://github.com/arduino/Arduino/blob/2bfe164b9a5835e8cb6e194b928538a9093be333/hardware/arduino/avr/cores/arduino/wiring_analog.c

else

if (pin >= 14) pin -= 14; // allow for channel or pin numbers
IMU
IMU
November 08, 2018 23:15 PM

Related Questions


Soldering arduino I/O pins

Updated March 23, 2016 08:10 AM

digital chip trigger output high on change input

Updated November 12, 2017 18:25 PM