How can I read the Arduino Nano 33 IoT pinout?

I spent some time yesterday trying to get interrupts to work. It took longer than it should have, I think.

I ran into two problems. First, I don't know what a "pin number" is. If I call an API like pinMode() or digitalWrite(), the documentation says the pin parameter is meant to be "the Arduino pin number".

What is this number? I thought it would be the IC pin number, 1 thru 30 for the Nano 33 IoT module. Then, I realized there's no pin 1 identification on my board.

I looks like the number really is the ... well, it seems to be something that doesn't have a name. If I want to use the pin marked "~D2" in the pinout diagram as an output, I'd call pinMode(2, OUTPTUT). Why does "~D2" have a tilde in its name when other digital pins don't?

What about other pins, like the analog inputs and outputs, or interrupts? How are they numbered and identified in code?

I wanted to use "D7" for my interrupt input. The pinout says it is also "INT[6]". Do the square brackets have any significance?

Something I read somewhere says I should use digitalPinToInterrupt() to translate a pin number to an interrupt pin number. So I coded this:

  int pinNumber = 7;
  pinMode(pinNumber, INPUT);
  attachInterrupt(digitalPinToInterrupt(pinNumber), crossingHandler, RISING);

but it didn't work. I spent a lot of time fooling with this, and discovered that digitalPinToInterrupt() outputs whatever its input parameter is so it doesn't seem to be doing any translation at all.

Eventually, I found this post which says that only pins 2, 3, 9, 10, and 11 work as external interrupts. Why do so many other pins show an "INT[n]" designation in the pinout? Oddly, several pins show the same number for n. For example, three different pins show "INT[2]". Why is it so?

How are the pin assignments on the pinout diagram meant to be read? How do I translate them to parameters that I can pass the API?

The ~D2 means it is both a Digital pin and a PWM capable pin. You can use mnemonics, so pinmode(D2, INPUT_PULLUP); works.
In the case of interrupts, you MUST use the

digitalPinToInterrupt(pin)

where pin is D2
perhaps a bit of reading of the NANO 33 IoT hardware page including the datasheet will be instructive. In case you do not know it's whereabouts, it is under both Hardware and Documentation/Hardware. Here is the link https://docs.arduino.cc/hardware/nano-33-iot/

Not quite true, but good advice nevertheless

1 Like

Thanks!

I've read the datasheet. It doesn't say anything about tildes or preprocessor symbols. Or answer any of my other questions. Am I looking at the wrong document?

If I try using D2, I get an error because the symbol is not defined. Maybe I'm meant to use some library or header? Which one? I don't see any mention of symbols like D2 on the pinMode() documentation page.

C:\Projects\Adruino1\Blinkers2\blinkers2\blinkers2.ino:117:11: error: 'D2' was not declared in this scope
   pinMode(D2, OUTPUT);
           ^~
C:\Projects\Adruino1\Blinkers2\blinkers2\blinkers2.ino:117:11: note: suggested alternative: 'A2'
   pinMode(D2, OUTPUT);
           ^~
           A2

Since digitalPinToInterrupt() only ever returns its own input, why must it be called?

  for (int p = 1; p < 24; p++)
  {
    crossingHandler();
    Serial.print("pin number ");
    Serial.print(p);
    Serial.print(" maps to interrupt ");
    Serial.println(digitalPinToInterrupt(p));
  }

gives this output:

08:03:13.272 -> pin number 1 maps to interrupt 1
08:03:13.272 -> pin number 2 maps to interrupt 2
08:03:13.272 -> pin number 3 maps to interrupt 3
08:03:13.272 -> pin number 4 maps to interrupt 4
08:03:13.272 -> pin number 5 maps to interrupt 5
08:03:13.272 -> pin number 6 maps to interrupt 6
08:03:13.272 -> pin number 7 maps to interrupt 7
08:03:13.272 -> pin number 8 maps to interrupt 8
08:03:13.272 -> pin number 9 maps to interrupt 9
08:03:13.272 -> pin number 10 maps to interrupt 10
08:03:13.272 -> pin number 11 maps to interrupt 11
08:03:13.272 -> pin number 12 maps to interrupt 12
08:03:13.272 -> pin number 13 maps to interrupt 13
08:03:13.272 -> pin number 14 maps to interrupt 14
08:03:13.272 -> pin number 15 maps to interrupt 15
08:03:13.272 -> pin number 16 maps to interrupt 16
08:03:13.272 -> pin number 17 maps to interrupt 17
08:03:13.272 -> pin number 18 maps to interrupt 18
08:03:13.272 -> pin number 19 maps to interrupt 19
08:03:13.272 -> pin number 20 maps to interrupt 20
08:03:13.272 -> pin number 21 maps to interrupt 21
08:03:13.272 -> pin number 22 maps to interrupt 22
08:03:13.272 -> pin number 23 maps to interrupt 23

I know, but it's what I call a coders white lie.

True, but not always, and besides it's what the creators said to do, they must have a reason.

They indeed do. It makes sure that an interrupt on pin 2 always translates to the correct interrupt vector.

For an Uno, pin 2 is INT0.
For a Mega, pin 2 is INT4 (and INT0 is the SCL pin).

I found an old post that the Arduino GOAT participated in. Read ALL of it, and I think your questions will be answered. I see that @sterretje gave an excellent answer regarding the use of digitalPinToInterrupt in post #7 already. Here is the link https://forum.arduino.cc/t/what-pins-are-called-when-and-how/105569/13

@omar9k I forgot, I also found the following in the documents mentioned on the web page for the board. There is a lot more there, but the link in my previous post does a better job of explaining, I think.


Thanks! The copy of the data sheet that I have has that table, but doesn't include the "finding PWM pins" section.

This doesn't help me confirm which pins can be used as interrupts, but at least the mistery of the tilde is solved.

That discusses symbols for analog pins, A0 thru A7 and so on. I can't find definitions for the digital pin symbols you've told me to use, like D2

Certainly possible that digitalPinToInterrupt() isn't an identity function on other boards. But why would it be for the Nano 33 IoT?

From the pinout diagram, D2 is INT[10]. And D11 is INT[0].

Why does digitalPinToIOnterrupt(2) return 2, and not 10?

I must still be missing some piece here.

#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606)
// Interrupts
#define digitalPinToInterrupt(P) ( P )
#endif

Maybe on SAMD chips the mapping is done in some different way?

The Hardware Abstraction Layer makes it possible to write code for any processor. If you ever want to port e.g. an AVR code to the Nano 33 IoT it will stay functional; or vice versa.

I do not know; the SAMD21 is a complicated processor (for me) and I have never looked at it.