To answer Tyilo’s specific questions:
digitalRead(5) will read from two different places. The former will read from analog channel
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
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
If you want to use
digitalWrite on the first analog pin
A0 you can only do
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
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
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
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?
I spent hours on this. I thought I had a hardware problem. It turns out that I was calling
Incorrect (erroneous sample code from DFRobot ):
val = analogRead(0); //connect sensor to Analog 0
val = analogRead(A0); //connect sensor to Analog 0
analogRead() takes GPIO pin numbers.
A0 etc. are #defines for Arduino pin numbers, where
A0 == 36.
Be careful: on e.g. the FireBeetle ESP32, pin labeled “IO36/A0” (GPIO36) equals Arduino
A0, but “IO39/A1” (GPIO39) equals Arduino
A1), “IO34/A2” (GPIO34) equals Arduino