Skip to main content

Pin and Id

If you are new to electronics, you may get confused about pins and Ids when programming for your board. So in this guide, let's know more about the pins and learn how to set them.


All boards have pins that stick out of the MCU to connect other components easily.

The pins on the two sides of SwiftIO Feather board

When an external device communicates with your board through a pin, it is actually connected to the corresponding peripheral on the MCU. A peripheral refers to a part of device on MCU for a specific usage. An MCU may contain many common peripherals with different usages, like GPIO, I2C, SPI, UART, and so on.

Peripherals on MCU

However, normally, the number of pins are limited for many reasons. Therefore, most pins are multiplexed to provide more functionalities. In other words, a pin may connect to several peripherals' interfaces using a multiplexer (or mux). You can consider a mux as a switch between a pin and the peripherals it connectes to. The pin can select one of them as needed.

This pin multiplexing technique allows the same set of pins to achieve many different functions. For example, in the image below, the pin are muxed to GPIO, UART, PWM peripherals on the MCU, so it can be configured to any of these usages. BTW, some peripherals require a group of pins, like UART which needs a pin for transmission (TX) and one for reception (RX). Say you need a PWM signal, you can designate that pin as a PWM pin in your code, so the mux will automatically select the desired peripheral for it.

Pin multiplexing

As for pin configuration, briefly speaking, MCU provides registers, that is, a block of storage spaces that allow you to read and write data. Some are dedicated to the pins. When you configure a pin (property, status, etc), the related registers are set. When you read pin status, you are reading values from those registers.


And there are so many pins on an MCU... So they are numbered for identification. The numbers of pins and their properties are all up to the MCU. The pins on boards, usually on two sides, may not adopt the same pin name as the MCU. When you call a pin on your board using its name, Id in our case, you actually call the corresponding pin with the specified task on MCU.

All Ids of your board are stored in the library MadBoard. The Ids are formed with a letter (or word) which indicates its functions and a number: D0, D1, A0, PWM0A, I2C0, SPI0...

  • By convention, the numbers of Ids start from 0🤣.
  • As mentioned before, some pins are multiplexed, so D0 and A0 may refer to the same physical pin on your board. And it's not surprising that three or four Ids relate to a single physical pin.
  • Besides, some usages require more than one pin, such as I2C - it needs the pins SCL and SDA, so the Id I2C0 refers to both pins (SCL0 and SDA0). And similarly, Id SPI0 refers to all three pins (SCK0, SDO0, SDI0).
  • What's more, some Ids don’t match any physical pins on board, such as RED, BLUE. They allow you to access the onboard hardware, like the onboard LED💡.
  • Different boards have a specific hardware layout with a different pin arrangement. So you can find Id files for each type of board in this library. For example, the available Ids for SwiftIO Feather board are in SwiftIOFeather.swift.


Till now, you still cannot match the Ids with the pins on your hardware🤔.

👀Well, if you take a closer look at the pin connectors on the two sides of your board, you will find silkscreens beside them which indicate part of the usages. Of course, not all usages are marked as there’s not enough available space for silkscreens. And for detailed info, you need the pinout that comes with the board. It shows all the possible usages for each pin. Here is a pinout diagram for the SwiftIO Feather board for example:

SwiftIO Feather board pinout

In the diagram above, you may notice the pins P0 to P35 are all multiplexed pins and have several usages. They don’t have a predefined purpose, hence you need to configure them for specific purpose through code.

Let’s look at pin P6 for example. It’s labeled with D6, A6, and SCK0. That means the pin is muxed to GPIO, AnalogIn, SPI peripherals. So MCU can configure it to act as digital input/output, analog input, or clock line for SPI.

Pin P6 on the board

Furthermore, the pinout maps the pins on board with their Ids, so it would be useful when you build circuits or code for your board.


BTW, there is no strict rule on naming the pins, so the pin name may be different for boards from other brands.

Usage example

After you clarify these concepts, let's dive into pin usages.

Step 1

At first, you need to import the SwiftIO library. It gives you access to the different peripherals on the MCU.

import SwiftIO

Step 2

As for the Ids, you need another library called MadBoard.

import MadBoard

You don't need to distinguish the board type here. And different boards may all have Ids called A0, D0… so the code for a board may also work for another type of board.

Step 3

Suppose that you need a digital output pin. First of all, you tell the specific usage:

let pin = DigitalOut(...)

DigitalOut is one of the classes in the SwiftIO library. It activates the pin to serve as a digital pin.

Step 4

Wait… It’s not finished yet! After all, the pins P0 to P35 are all marked with D prefix on the pinout and can all be used to output digital signals. MCU cannot know which one you are going to use. So, you specify a pin using its Id: D0, D1, or any other pin. And Ids are stored in an enum called Id in MadBoard, so the complete statement should be:

let pin = DigitalOut(Id.D0)

Only then does the MCU know that you want the pin P0 to serve as digital output pin. And the pin will get prepared and ready for the following task.

At last, if one digital pin is not enough, you can create more instances using other pins in the same way. If you need a pin for analog input, you can use any pin labeled with A except A0, since DO and A0 map to the same physical pin which already serves as a digital pin.