Skip to content

MCU Info Page: Arduino Nano 33 BLE

Jamie Smith edited this page Jan 7, 2024 · 14 revisions

Arduino Nano 33 BLE Overview

The Arduino Nano 33 BLE is a small Mbed-compatible board from Arduino containing a general-purpose microcontroller with Bluetooth capabilities. The Arduino Nano 33 BLE uses a U-Blox NINA-B306 module, which itself contains an nRF52840 MCU. To flash code, Arduino provides a USB bootloader, and Mbed can flash code using this bootloader or an external SWD debugger. This board is a convenient option for projects which need to use bluetooth in an affordable and small form factor!

Nano 33 BLE

Feature Overview

CPU Flash/Code Memory RAM Communication Peripherals Other Features
Cortex-M4F, clocked at up to 64 MHz Without Arduino bootloader
Total: 1MiB
Available to user:* 987 kiB
With Arduino bootloader:
Total: 960kiB
Available to user:* 923kiB
Total: 256kiB
Available to user:* 244kiB
  • 2x I2C/SPI combo
  • 1x additional SPI
  • 1x QSPI (currently not supported)
  • 2x UART
  • 1x USB
  • Bluetooth 5 radio
  • 12-input ADC (AnalogIn)
  • 4x PWM (must share a common frequency)
  • Hardware RNG
  • DMA (only supported for UART)
  • Watchdog (currently not supported)

*"Available to user" subtracts both regions of memory unusable by Mbed OS projects and the baseline memory used by a minimal build of Mbed OS.

Selecting Bootloader or SWD

There are two ways to use the Arduino Nano 33 BLE with Mbed OS: via the bootloader, and via an SWD debugger. Using the bootloader allows you to use the board as delivered, but the bootloader does not allow debugging and eats up 1/16 of the total flash space. It also requires you to press a button on the board when you want to flash code, which can be annoying for rapid development.

Using an SWD debugger, on the other hand, removes these limitations, but requires buying a bit of hardware and soldering some wires to pads on the board.

Using the Bootloader

To use Mbed with the Nano 33 BLE's bootloader, set MBED_TARGET to "ARDUINO_NANO33BLE". Additionally, set UPLOAD_METHOD to "ARDUINO_BOSSAC".

Next, you need to install the Arduino fork of bossac, the program that talks to the bootloader. To get it, you must either:

  • Install Arduino IDE, then install the board package for one of the bossac boards (e.g. Nano 33 BLE).
  • Or, download and install one of the binary packages using TinyGo's instructions page.

CMake should find it automatically, but if not, you will need to specify it manually via CMake argument, e.g. -DArduinoBossac=/path/to/bossac.

Warning: If you have non-Arduino bossac in your PATH, CMake may find that instead unless you manually specify. Unfortunately Arduino did not create any way to tell if a bossac executable is built from their fork or not.

Finally, put your board into bootloader mode by double-tapping the reset button. Find which COM port / TTY it is, and set the ARDUINO_BOSSAC_SERIAL_PORT CMake option to this (e.g. -DARDUINO_BOSSAC_SERIAL_PORT=COM8 on Windows, -DARDUINO_BOSSAC_SERIAL_PORT=/dev/ttyACM1 on Linux). Then, you should be able to upload code by running ninja flash-<your program>. Note that once code has been uploaded, you'll need to double-tap reset again the next time you want to flash code.

Using an SWD Debugger

In order to debug your board or flash code to it unattended, you'll need to mod your Arduino with an SWD debugger. I'll give a quick overview of how to do this in the following section.

As for which debugger to use, the easiest option is a CMSIS-DAP-based one, as these are cheap, ubiquitous, and work fine. A J-Link should also work if you have one (though the upload method configuration would need to be modified). For my setup, I used a Makerdiary Pitaya-Link (which runs the CMSIS-DAP firmware) as it is dirt cheap and easy to set up.

To connect the Pitaya-Link, the GND, RST, and serial pins need to be connected to the headers on the outside of the Arduino. Additionally, the SWCLK and SWDIO pins need to be connected to the small solder pads on the bottom. This is a little bit harder to get, and a proper holding device is recommended to keep the wires and the board aligned while you're soldering them. However, you only need to solder to two of the six pads, so you don't need micro-soldering equipment to do this.

Here's what my setup looked like at the Arduino end:

20221001_141701_small

And here's the debugger end:

20221001_141648_small

Note: Be careful of the serial pin connections -- the pin labeled "TXD" on the Pitaya-Link is actually an input! So connect Tx to Tx and Rx to Rx, not Tx to Rx. Also note that the "3V3" line from the debugger can be left unconnected.

Now that you have your debugger attached, build your project with MBED_TARGET set to "ARDUINO_NANO33BLE_SWD" and UPLOAD_METHOD to set "OPENOCD" or "PYOCD" (see the upload methods page for install instructions for these tools).

Then, you should be able to upload code by running ninja flash-<your program>, and you should see output on the debugger's serial port.

Warning: Uploading code with an SWD debugger will overwrite the bootloader installed on your board, preventing you from uploading code over USB. To restore it, flash the bootloader binary located here with a command like:

openocd -f interface/cmsis-dap.cfg -c "transport select swd" -f target/nrf52.cfg -c "program bootloader.elf reset exit"

Bluetooth Stacks

There are two Bluetooth stacks in existence for this microcontroller: Nordic SoftDevice and Arm Cordio. SoftDevice is closed-source and provided as a precompiled binary from Nordic, complicating the build process significantly. Arm Cordio is an open-source Bluetooth stack produced by Packetcraft and ARM, and is included as part of the Mbed OS source code (in the connectivity/FEATURE_BLE/libraries/cordio_stack folder).

Mbed OS used to support both stacks, but SoftDevice support was removed in Mbed OS 5.11 (perhaps so that ARM could promote its internally developed stack instead?). Currently only Cordio is supported and is used automatically. However, users should be aware that Cordio has issues that prevent nRF MCUs from entering a low-power state when using Bluetooth -- users have not been able to get it below ~1.5mA. Sadly, development on open-source Cordio appears to be dead as it became a private company, so this is unlikely to be fixed anytime soon.

Instead, the option that seems more promising is resurrecting the old SoftDevice interface, enabling Mbed to use Nordic's maintained stack. Mbed Community Edition is interested in doing this work but there is no concrete plan for this as of yet.

Misc MCU Info

Pin Mapping

Most Mbed boards are limited to using specific peripherals (e.g. I2C, SPI, PWM) on specific pins. However, the Nano 33 BLE and its nRF52840 allow using most peripherals (aside from USB and the ADC) on absolutely any pin on the device. This means you aren't restricted to the pins labeled as SPI and I2C in the pinout! However, you still must respect the total number of peripherals available, e.g. you can only create a total of two UARTs and four PWMs at any one time.

There's an additional consideration for SPI and I2C busses: Each of the two I2C instances shares resources with one of the three SPIs. So, if you create two I2Cs, you only can create one SPI, and if you create three SPIs you can't use I2C at all.

USB Serial

Since the Arduino Nano 33 BLE lacks a separate USB-serial converter chip, when the bootloader is used, Mbed OS uses the USB port as a USB-serial adapter so that you can view what your code is printing. Unfortunately, this prevents the USB port from being used for anything else. To change this behavior, drop the following lines in your mbed_app.json's target_overrides section:

"target.console-usb": false,
"target.console-uart": true

This will redirect the debug console to the Arduino's RX and TX pins instead, freeing up the USB port for your application to use. Of course, you'll need to connect an external 3.3V USB-serial adapter to those pins if you want to view your debug console...

Note: If you use the ARDUINO_NANO33BLE_SWD configuration, the above configuration change is applied automatically.

Timer Usage

The nRF52840 features five 32-bit timer/counter modules. Mbed OS uses TIMER1 to provide its internal time reference, leaving the other four timers (TIMER0, TIMER2-TIMER4) available for you to use.

I2C Frequencies

The Mbed HAL implementation for nRF52 currently only supports three I2C frequencies: 100kHz, 250kHz, and 400kHz. The frequency you pass to I2C::frequency() is rounded down to the nearest frequency, and frequencies below 100kHz are rounded up.

Mbed CE is interested in removing this limitation but no concrete plans have been made.

Datasheets