How to control the P1 and P0 port pins of Arduino Nano 33 BLE Sense

Samuel Adesola
3 min readMay 23, 2024

Hello and welcome to this quick guide, let's get straight into it. Traditional Arduino boards, the UNO, nano, etc are laid out regarding the pin numbering, both digital and analog and we can easily address these GPIO pins in Arduino sketches without having to worry about anything called mapping or pin availability.

When Arduino Nano 33 BLE Sense came, a few things came along with it that need to be studied, first, the board runs on the microcontroller nrf52840 which has lots of pins (48 or so) and we can control some that the Arduino Nano 33 BLE Sense supports, the second thing is that there are two ports pins available on the board, Port 0 and port 1 and lastly, there are two ways we can program the board: The traditional Arduino method or using Real-Time Operating System (RTOS) and this is the better and recommended method.

Now observe the diagram below

This was taken from the board’s pinout: https://content.arduino.cc/assets/Pinout-NANOsense_latest.pdf

One thing you will observe is the pins numbered with D and A, D1, D2, and the like, these are mappings of the original nRF52840 pins to Arduino-like naming, what this means is that we can easily write our Arduino code and reference the pins using the D and A pins, this is the traditional Arduino way of doing things, let's say we want to blink and LED connected to D6, we can write:

int led = 6;

void setup(){
pinMode(led, OUTPUT);
}

void loop(){
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led, LOW);
delay(1000);
}

As much as this is a straightforward way of getting things done, it is not advised for the Nano 33 BLE Sense board, therefore we have to go the way of RTOS. The problem that now presents itself is that we can’t use the Arduino pin numbering while programming the board using RTOS via the mbed.h header file, so how do we get our pin numbers? Let's go back to the schematic above, we have port 0 pins in the form P0.13 and port 1 pins in the form P1.02, these are the pins we will use.

How do we get the pin number?

Let's say we want to use the P1.14 pin (D6), we have to multiply 32 by 1 (P1 part) and add 14 (.14 part)

Again:

P1.14 = 32 * 1 + 14 = 46 = p46;

P0.13 = 32*0 + 13 = 13 = p13;

The preceding “p” e.g. p46 must be added. Let's look at an example of tunning on an LED using mbed.h RTOS library:

#include "mbed.h"

// D6 - P1.14
//D13 - P0.13 = 32 * 0 + 13 = 13 = p13
// 32 * 1 + 14 = 32 + 14 = 46 = p46

static const PinName led = p46 //Same thing as pin D6, check the calculation above

static mbed::DigitalOut myLed(led);

void setup() {

}

void loop() {
myLed = 1;
}

And that is it, just do the right calculation and you will be able to control all the GPIO pins on the Nano 33 BLE Sense board.

You can check out this video which is part of my tutorial series on TinyML to learn more or see a demo: https://youtu.be/VDJx7d4BaVg

--

--

Samuel Adesola

I am an embedded system engineer. Most of my works focus on IoT, AI and Machine Learning. With years of experience in programming and electronics