Tag Archives: Guide

The Arduino Nano 33 BLE Sense Sensor Library You Have Been Waiting For

Quick Links

UPDATE 21/03/2023

Nano33BLESensor has a new release with version 1.1.0 now available. It solves some issues related to MbedOS and dependency version issues.

The Arduino Nano 33 BLE Sense was released in July 2019 and was a real step up for Arduino! Using the Arm Cortex-M4F based nRF52840, the Nano 33 BLE’s arrival made the days of Atmel based 8-bit microcontrollers seem numbered. With the proliferation of dirt cheap Arduino clones this was probably the result of Arduino seeing the writing on the wall that keeping it simple was probably not going to bring in the dough anymore. In the end the sheer amounts of fairly useless Arduino projects seem a bit dull these days, and with more complex offerings such as the Nano 33 series, a new era of seriously cool projects may be on the horizon.

Previously in The Hacky Super Loop Arduino Nano 33 BLE Sense Example You Have Been Waiting For I attempted to address the lack of meaningful working examples for this board. The interfaces for each sensor are not always ideal, and no concrete examples are widely available that enable uses to utilise Mbed OS to gather sensor values.

The ability to use Mbed OS with Arduino is a real step up for Arduino. Finally, a reasonably performant and relatively deterministic way of arranging our more complex Arduino projects! In attempt to simplify the collection of sensor data and at the same time utilise the power of Mbed OS, Nano33BLESensor was born.

The Nano33BLESensor Library

Nano33BLESensor leverages Mbed OS to automatically place sensor measurements in a ring buffer that can be integrated into programs in a simple manner. This means Nano33BLESensor takes care of placing measurements in to the buffer “in the background”, and your program can retrieve them from the buffer at a later time when your program has time. It can be found on GitHub here. It can also be found using Arduino’s Library Manager, and available when searched for when using the Arduino IDE. Simple examples also exist to help get people started.

Nano33BLESensor Features

  • Class implementation with common interface for the following sensor measurements
    • 3-axis Accelerometer
    • 3-axis Gyroscope
    • 3-axis Magnetic
    • RMS Microphone
    • Barometric Pressure
    • Temperature (with humidity)
    • Proximity
    • RGBC Colour
    • Gesture
  • Mbed OS usage, allowing easy integration with programs.
  • Ring buffer usage, allowing the softening of time constraints in regard to the reading sensor measurements.
  • Excellent examples for all sensors designed for BLE and Serial Plotter that help you to get started.

In the end, the result of this is:

  • Super simple initialisation of on board sensors.
  • No code required beyond initialisation for collection of sensor data.
  • Super simple usage of sensor data.
  • Common interface among different sensors.
  • Using Mbed OS effectively makes the reading of sensor measurements happen “in the background”, and keeps it out of the main program loop.

Nano33BLESensor Examples

The Nano33BLESensor Library comes with a series of powerful examples that include sensor measurement data output using both Serial and Bluetooth. It is possible to view this data at the same time using Arduino’s Serial Plotter and a Bluetooth packet analysis tool such as Bluetooth LE Explorer. Some of the examples available on the GitHub repository are as follows:

Below are the results of a few of those examples.

Accelerometer Example

Gyroscope Example

Entire IMU Sensor Example

In order to view the data in a visually acceptable way, Bluetooth LE Explorer must be configured in a specific way. The below animation shows this setup.

How Nano33BLESensor Simplifies Sensor Usage

Here are a couple of examples of how Nano33BLESensor simplifies the collection of sensor data with the Nano 33 BLE Sense. For the full API, you can checkout the GitHub repository.

Initialising the on board accelerometer, reading data, and printing it.


#include <Arduino_LSM9DS1.h>

float accelerometerX, accelerometerY, accelerometerZ;
void setup()

void loop()
    IMU.readAcceleration(accelerometerX, accelerometerY, accelerometerZ);
    Serial.printf("%f,%f,%f\r\n", accelerometerX, accelerometerY, accelerometerZ);


#include "Nano33BLEAccelerometer.h"

Nano33BLEAccelerometerData accelerometerData;
void setup()

void loop()
     Serial.printf("%f,%f,%f\r\n", accelerometerData.x, accelerometerData.y, accelerometerData.z);

Initialising the on board colour sensor, reading data, and printing it.


#include <Arduino_APDS9960.h>

int colourR, colourG, colourB, colourC;
void setup()
void loop()
  if (APDS.colorAvailable())
    APDS.readColor(colourR, colourG, colourB, colourC);
    Serial.printf("%d,%d,%d,%d\r\n", colourR, colourG, colourB, colourC);


#include "Nano33BLEColour.h"

Nano33BLEColourData colourData;
void setup()

void loop()
    Serial.printf( "%d,%d,%d,%d\r\n", colourData.r, colourData.g, colourData.b, colourData.c);

Initialising the on board temperature sensor, reading data, and printing it


#include <Arduino_HTS221.h>

float temperature, humidity;
void setup()
void loop()
  temperature = HTS.readTemperature();
  humidity = HTS.readHumidity();
  Serial.printf("%f, %f\r\n", temperature, humidity);


#include "Nano33BLETemperature.h"

Nano33BLETemperatureData temperatureData;
void setup()

void loop()
    Serial.printf("%f,%f\r\n", temperatureData.temperatureCelsius, temperatureData.humidity);


Nano33BLESensor enables some interesting possibilities with the Nano 33 BLE. It simplifies the usage of onboard sensors by using a common interface, and leverages Mbed OS to allow the softening of time constraints in regard to the reading sensor measurements. It is hoped that this library will be useful to someone down the track!

Setup Guide for SEGGER J-Link and SystemView with STM32 Nucleo Boards

SEGGER SystemView is a very cool graphical tool for embedded systems that enables the visualisation of run-time behaviour in an application by the recording on configurable events. These events can be recorded using J-Link, IP, or UART communication. A huge plus for using SystemView is that it is totally free to use, provided that in one event recording session you do not exceed one million recorded events. This limit is actually very easy to exceed in larger applications, but still renders the free version of the software very useful.

I recently setup SystemView to work with a STM32 Nucleo based development board to debug the behaviour of FreeRTOS in a visual manner. In this setup I was also using System Workbench for STM32 with SEGGER J-Link debugging. This particular setup was pretty neat because it provided multiple methods for debugging the system, and was entirely free. The STM32 Nucleo and Discovery boards are very well suited for this use case as they contain an on-board ST-LINK programmer/debugger, and SEGGER provide a free way to convert the ST-LINK module to a J-Link module.

The entire setup was a little protracted so I kept notes on everything I did to get everything work. It is these notes that I will share in this post. It is not meant to be an exhaustive guide and will not provide any kind of in depth information about how SystemView works, but is provided here in the hope that it may save someone else time somewhere down the track.

It is assumed that you already have System Workbench for STM32 installed. Beyond that, I completed each tasks in the following order:

  1. Converting ST-LINK into J-Link
  2. GNU MCU Eclipse install
  3. SEGGER J-Link Install
  4. J-Link debug configuration setup in System Workbench
  5. SystemView Install
  6. Adding SystemView Module to System Workbench project

Converting ST-LINK into J-Link

Instructions are here.

  • Install ST-LINK USB drivers (should already be done): Download
  • Install J-Link software package V5.12b or later : Download
  • Install SEGGER STLinkReflash utility: Download
  • Start the STLinkReflash utility (STLinkReflash.exe)
    • Agree to the license terms (enter “A”)
    • Connect ST-LINK on-board to PC 
    • Select “Upgrade to J-Link” (Enter “1”)
    • Wait for operation to complete

GNU MCU Eclipse Install

Open System Workbench for STM32 (Eclipse) and do the following:

  • Open Eclipse Marketplace
  • Search for GNU MCU Eclipse and install
  • Confirm all features
  • Agree to the license terms
  • Wait for operation to complete
  • Restart Eclipse

SEGGER J-Link Install

Instructions are here.

  • Install J-Link: Download
  • Test install with connected converted J-Link board by running JLinkGDBServerCL with CMD. On my system this is located at “C:\Program Files (x86)\SEGGER\JLink\JLinkGDBServerCL.exe”. 
    • Accept the terms of use as they pop up.
    • Select the correct target device. For me it is STM32F429ZI. This will differ depending on the development board you are using.

J-Link Debug Configuration Setup in System Workbench

Instructions are here.

  • Define the path in Eclipse for J-Link folder. Window→Preferences→MCU→Global SEGGER J-Link Path
    • Create new J-Link Debug Configuration (Run→Debug Configurations→GDB SEGGER J-Link Debugging)
    • On Debugger tab add Device name (see Supported Device names for precise names). For my project it is STM32F429ZI. This will differ depending on the development board you are using.
    • On Startup tab add CPU freq and SWO freq (must be a sub-multiple of 6Mhz). On my board CPU freq is 180Mhz
    • On Common tab, change the Save as option to Shared file.
    • Add {cross_prefix} and {cross_suffix} build variables (Window→Preferences→C/C++/Build Variables)
      • cross_prefix=”arm-none-eabi-
      • cross_suffix=””
      • These may already exist, if they do not, do not added them again.

SystemView Install

  • Download installer: Download
  • Follow the prompts and install

Adding SystemView Module to System Workbench project

  • Add the SystemView module to the project (it is architecture independent). It can be found in C:\Program Files (x86)\SEGGER\SystemView_V252d on my system. It includes the following files:
    • SEGGER
      • SEGGER.h
      • SEGGER_RTT.h
      • SEGGER_SYSVIEW_ConfDefaults.h
      • SEGGER_SYSVIEW_Int.h
      • SEGGER_RTT.c
    • Config
      • Global.h
      • SEGGER_RTT_Conf.h
      • SEGGER_SYSVIEW_Conf.h
  • Inside main() function (or other startup function) add the SEGGER_SYSVIEW_Conf() initialisation function. 


If all is well, everything is ready to start debugging with J-Link, SystemView and System Workbench for STM32.