Someone refresh my memory on how pin numbers work

It's been quite a while since I wrote my last Arduino sketch, probably around a year or more. So, I'm not sure if I remember wrong, if something changed with the functions, or if it's just me and my cheapo parts :grin:

Hopefully someone will help me get to the bottom of this one.

I had a project involving LEDs and shift registers that I did some time ago using an UNO. Then I modified it to run directly from a homemade board with an ATMEGA328 on it. It worked fine. So I decided to take it a step further and use a nano with a home made shield to neaten it up and shrink the board.

So I bought one of those cheap $2 chinese nano clones off Ebay. The ones that use the CH340 USB that's a pain to get going... but I got it going.

I pull up the sketch on an UNO, plug in my circuit, and it works just fine. I plug the nano into the protoboard, and look up a board pinout. According to what I see on the internet, D2 is board pin 5, D3 board pin 6, and so on. So I set up my sketch:

#define DIG2 5
#define DIG3 6
#define DIG4 7

and so on. And... the thing goes haywire. LEDs don't work, shifters don't work, nothing works.

Playing around with the pins and blink sketch, I found that D2 is #2, D3 is #3, D4 is #4, and so on. Real easy. Changed that in the sketch, and now the circuit is up and running.

So, can someone clear this one up for me? As I remember it, what you usually did was use the board pin number to address the output pins, or if you were using a standalone atmega, you addressed with the chip pin number.

I don't remember it being D2 is #2, D3 is #3, D4 is #4, etc. But of course, I haven't touched this stuff in a year or more so I could be perfectly wrong. If that's the case, for analog pins would I do the same thing... use 2 for A2, 3 for A3, and so on?

Chinese clone or not, download the latest IDE, and have a look at the Language Reference
Your clone can be picked from the tools>board menu. At the top of the boards menu is the new boards manger so you can add from a selection of special arduino boards. But i have the pro mini 5V 16MHz clone and works fine, be sure the “cpu” matches your clone voltage and speed. Programmer USBisp for the clone boards you need an USB/serial adapter

digitalWrite(2, HIGH); //turn digital pin 2 high

analogRead(3); //read voltage on Analog pin 3

with direct port manipulation, no?
DDRD = (1<<PD2);
PORTD = (1<<PD2);

You might want to use A0 A2 A3 etc. in your code as it adds to documentation

const byte batteryPin = A0;
. . .
int batteryVoltage = analogRead( batteryPin );

For direct port manipulation, all bets are off !


If you are using a Nano, you do not need a diagram. The 'Arduino' PIN numbers are printed on the circuit board. For example, digitalRead(4) will read from the pin marked '4'.
These are, of course, different from the PIN numbers on the atmeg a chip.

So, can someone clear this one up for me? As I remember it, what you usually did was use the board pin number to address the output pins, or if you were using a standalone atmega, you addressed with the chip pin number.

You never use AVR chip physical pin numbers.
All the Arduno API functions use Arduino pin numbers.
The Arduino core code uses mapping tables to map the Arduino pin numbers to a particular port and bit number which correspond to a particular phsysical pin number.

In order to get the desired pin labeled on the board you must use the proper arduino pin number.

i.e. for digital API functions you use an Arduino digital pin number so if you see a 4 on the PCB then you use 4, if you see 13 you use 13.

Things get messy when using the analog APIs, since the pin numbering space for analog pins is different than the digital pins.
Compounding to the confusion is that analogWrite() has nothing to do with analog as it is performing a digital operation and uses Arduino digital pin numbers whereas analogRead() is an analog function and uses Arduino analog pin numbers.

Arduino analog pin 0 is not the same as Arduino digital pin 0

So when using digital API functions like digitalWrite(), pinMode(), digitalRead(), analogWrite() you use an Arduino digital pin number, and for an analog function like analogWrite() you use an Arduino analog pin number.

Note that on the official Arduino boards you will see a tilda ~ next to the digital pins that support pwm which means that they support the digital function analogWrite()

There is some ugly code in the core code that assumes that if you give a naked constant to AnalogRead() like 0, 1, etc... that you meant Arduino analog pin and not Arduino digital pin.
(remember analog pin 0 is not the same pin as digital pin 0)
But if you use a constant that is bigger than the maximum analog channels, the code will assume you passed in an Arduino digital pin number will attempt to convert it back to the matching Arduino analog pin number.
For example on the UNO if you use 14 in analogWrite() it will use Arduino analog pin 0.

So while all this sounds messy (and it is) the mess is for the most a bit hidden if you use some of the symbols available and keep a few things in mind.

When using the digital pins for API functions that include pinMode(), digitalWrite(), digitalRead(), analogWrite(), as well as others, you will use digital pin numbers like 0, 1, 2, that match the digital pin numbers printed on the PCB.
For analogWrite() the only digital pins that work are the ones with the ~ next to them.

When using the analog pins labeled A0, A1, .... An etc... on the PCB, there are corresponding symbols to use that pin number that work for both digital and and analog functions.

digitalWrite(A0, HIGH); will set the A0 pin HIGH.
digitalRead(A0); will read the A0 value (HIGH or LOW)
analogRead(A0) will read the A0 pin analog value

The easiest way to handle things is to always use the pin marking on the PCB to reference the pin in all the API functions.
Use numeric constants for the digital pin numbers, and A0, ....An for the Analog pins.
Just keep in mind that analogWrite() is NOT an analog function so it uses digital pin numbers and it will only work on the pins that have the tilda ~ marking.

--- bill

1 Like