Introduction
When paired with an appropriate antenna configuration, UWB radio technology allows for TWR (Two-Way Ranging), TDoA (Time Difference of Arrival) and/or AoA (Angle of Arrival) measurements between small RF pulses. In other words, the radio chipset is designed to measure the distance between two radios using very precise timing (to the pico-second level of accuracy). Leveraging this radio technology can provide sub-10cm accuracy ranging performance between two devices configured in a wireless two-way ranging session. This exceeds the performance and reliability of typical RSSI-based range determination systems such as those used with BLE or Wi-Fi signals.
Refer to the Canvas Software Suite website for more details. Many aspects of Canvas Software Suite will be used throughout this application note.
This application note will use multiple Sera NX040 UWB DVK’s to establish UWB Ranging sessions and demonstrate 2D and 3D positioning. Each Sera NX040 DVK will send BLE advertisements containing ranging data, which will be collected by the BL654 USB adapter running Canvas Firmware. This is then passed to the Xbit Desktop application where 2D/3D Visualization based on range data can be observed.
Requirements
Two Sera NX040 DVKs (2D Ranging) or Four Sera NX040 DVKs (3D Ranging)
BL654 USB adapter (451-00004, Nordic/Zephyr Variant)
Workstation with available USB port compatible with the USB micro cable to the DVK
Install Python (version 3.11.6 is recommended. Version 3.12 or newer is not yet supported).
Install pyocd
Xbit VS Code Extension linked below will attempt to install pyocd for you.
On Linux, udev rules need to be added to allow pycod to be run as non-root: https://github.com/pyocd/pyOCD/blob/main/udev/README.md
Canvas Xbit Desktop application
Preparing the Hardware
The first step to using the Sera NX040 DVK is to load Canvas firmware. This will give you access to a MicroPython environment on the NX040 module. From there you can develop Python applications to control the BLE radio, UWB radio and peripherals on the board.
.jpg)
The Canvas Firmware for Sera NX040 DVK can be found here: Sera NX040 FW.
This .hex file can be loaded using the Xbit VS Code Extension, or from the command line using the pyocd tool from the Command Prompt:
pyocd flash -t nrf52833 -e chip 480-00336-Rx.x.x.xxxxxxxxx_full-image.hex
After programming the .hex file, the DVK is prepared to load python scripts using the Xbit VS Code Extension.
Xbit VS Code Extension
VS Code is one of the industry’s most popular source code editors and Canvas Software Suite provides a VS Code Extension called Xbit. This extension provides an easy interaction with Canvas Firmware compatible DVKs and IoT products for loading Python scripts to the device, interacting with the python REPL prompt and underlying RTOS shell prompt (if supported by the device).
Installing Xbit VSCode Extension
To get started, open the Extensions tab within VS Code, search for Xbit and install the Xbit tools for VS Code extension. You may need to restart VS Code to use the extension. To start using the extension, click the Xbit sidebar icon typically on the left-hand side of the VS Code window.

On the first run of the extension, you are prompted to select a folder for the tool to store the Python virtual environment. When prompted, click and select a location for the tool to store its virtual environment. The tool will create its own subfolder named xbit.venv
in the folder you select and operate from there.
Once the Xbit VS Code extension (Xbit VSC) is installed, an icon appears in the sidebar menu of VS Code where you can access USB devices running compatible Canvas Firmware. With the Sera NX040 DVK attached to your workstation, clicking on the icon for Xbit VSC displays an entry in the USB DEVICES panel corresponding to each attached board. If a Python REPL is detected, a name appears next to each device serial port and an icon indicating the type of interface available. A >>> icon indicates a Python REPL prompt. You can also enable the Zephyr RTOS shell prompt in the Xbit VS Code extension settings. If enabled in the extension settings, the $~ icon indicates a Zephyr RTOS shell prompt.

If a USB serial port is detected but the identity of the port cannot be determined, you’ll see a generic device listing the name of the serial port with a generic USB icon. At any time you can refresh the list of devices by clicking the refresh button in the USB DEVICES header bar.

Tag-to-Tag Ranging Python Script
To test out ranging between two or more Sera NX040 DVK boards, a simple Python “auto tag-to-tag” script was developed for basic ranging and 2D/3D positioning demonstration purposes.
The uwb_ranging_demo.py Python script automatically boots up and finds other similarly programmed DVKs and begins a ranging session. Once DVKs establish a ranging session, ranging data is available in BLE advertisements that can be viewed using the Tag-to-Tag Applet within the Xbit Desktop or Xbit Mobile tool.
Note you’ll need to create a main.py file on your DVK using the Xbit VS Code extension. The easiest way to program Python files is to drag and drop a Python source file from your operating system’s “file explorer” window right onto the row for your device in the USB DEVICES panel. Rename the file to main.py by right-clicking and selecting Rename File. The file must be named main.py in order for the DVK to run the script on startup.
Alternatively, you may right-click on the DVK Module COM port and select Create File to manually create and name a new file, then copy/paste content into the file from the uwb_ranging_demo.py Python script using the VS Code editor.

You are then prompted for a file name to create on the device.

Type the name of the file you’d like to create (in this case, main.py
) and then press Enter to create it.
Editing Python Files on a Device
You can simply drag and drop Python files onto the device using your operating system’s file explorer window, e.g., dragging a main.py or boot.py file onto the row for your device in the USB DEVICES panel within Xbit VSC.
Alternatively, if there are already files on your device that you’d like to edit, you can edit them directly by clicking on them in the USB DEVICES panel to open an editor. You can then copy/paste the contents of one of the sample applications (e.g., the uwb_ranging_demo.py sample application) into the file on the device if you’d like to get up and running quickly.

To save a file back to the device, press Ctrl+S (or equivalent Save File hotkey) and the Xbit extension will upload the contents of the file back to the attached device’s filesystem.
Once saved to the device, reset the DVK to start up the scripts. To reset, you may press the NX040 RST button on the DVK, send EOF using the button within the Xbit VS Code extension, or type Ctrl+D
into the REPL terminal).

This script uses BLE scanning to find nearby boards. An algorithm determines a DVK to act as the UWB initiator. All other DVKs take a UWB responder role, acting as “fixed” anchor points. A UWB multicast ranging session is initiated between the UWB initiator and all nearby UWB responders. Range to each UWB responder is advertised by the UWB initiator in BLE advertisements such that a nearby desktop or mobile reporting tool can capture and visualize the ranging data.
Configuring the DVK for UWB Ranging
Once the main.py script is installed on the DVK (containing the contents from uwb_ranging_demo.py), the configuration needs to be set to instruct the main.py script how the UWB radio should operate.
There is a "config" dictionary that the UWB ranging main.py script uses to determine whether to operate as a fixed/anchor node or a mobile/tag node. In order to get ranging info from the 2 DVKs in this setup, you'll need to configure both for anchor mode.
Modifying the Configuration
First, ensure the desired DVK is selected under the Xbit USB DEVICES panel.
Note: Instead ofModule
you may seeSera NX040 DVK
depending on the revision of the board you have:

At the DVK REPL, accessible in the VS Code TERMINAL tab, type "config" to see the dictionary that holds the current configuration. Here is an example output when configured as an anchor:

Set the anchor_mode configuration value to 1 by typing
config["anchor_mode"] = 1
Save the configuration to the configuration file by typing and executing the function
config_save()

Reboot each DVK after changing their configuration with
Ctrl+D
at the REPL or by pressing the RESET button on the DVKs (near the small SWD header on the corner of the board near the module).
This configures the DVKs to behave as anchors which will force them to initiate a continuous two-way ranging session. This is the only ranging application available between two development kits.
Modifying the Color of the RGB LED
The LED colors on each DVK can be changed to distinguish between DVKs.
To view the base_led color in a hexadecimal form from configuration, type
hex(config["base_led"])
To set the base_led color using a hexadecimal "RGB" value, type
config["base_led"] = 0xf00000
(this sets the LED to high intensity red)Save the setting by typing
config_save()
.Reset the DVK for the new color to take effect.
To set base_led color to a lower intensity red type
config["base_led"] = 0x0f0000
.Though not required, we recommend setting the range_led to a slightly brighter intensity of the same color used for base_led type
config["range_led"] = 0x3f0000
(this sets the LED to medium intensity red).Though not required, we recommend setting the error_led to "off" (i.e., black), type
config["error_led"] = 0x000000
.
Once you've set the RGB color for the base_led, this color will be broadcast as part of the BLE advertisement from the DVK and reflected in the sphere within the Xbit ranging ppplet that represents the node to assist in identifying each DVK.
Capturing and Visualizing Range Data over BLE
With the DVKs now programmed as anchors and in a continuous two-way ranging session, range information is passed via Bluetooth Low Energy advertisements. Xbit Desktop application software is designed to capture that data and visualize the advertisement data. When used with a BL654 USB adapter programmed with appropriate Xbit USB Python script, Xbit Desktop provides a framework to quickly build small applications or applets, providing a graphical interface that updates based on data from BLE devices.
Xbit Desktop Application
The Xbit standalone desktop application provides a framework that developers can use to quickly interact with and visualize data from Bluetooth Low Energy devices. Xbit is short for cross(X) platform (B)luetooth (I)nterface (T)ool. This application is designed to run on Mac/Windows/Linux desktop platforms and provides a framework for development of applets, small purpose-built “mini-applications” that can be bundled with the tool to enable various software development workflows with a friendly graphical user interface.
We’ve developed and provide an applet to view ranging and/or positioning data between 2 or more Sera NX040 DVK boards. It works by capturing BLE advertisements from nearby devices, interpreting the ranging data and converting the ranges into a dynamic 3D rendered model.
The Xbit Desktop application installers can be found on GitHub here:
https://github.com/LairdCP/Canvas_Xbit_Desktop
Xbit Mobile Application
The Xbit mobile application provides a framework developers can use to quickly interact and visualize data from Bluetooth Low Energy devices using an iOS or Android phone/tablet. The mobile application functions similarly to the desktop application allowing install/update of applets for interacting with devices over a BLE interface.
Xbit Applets
The Xbit Desktop and Mobile applications provide a list of available applets. This list is updated from an update server each time the application is launched. From within the Xbit application, to install an applet, identify the applet you want and click Install. The applet is downloaded and installed to local storage on your device. Each applet contains the source code and resources required to run itself. If an update is available, you can click the Update button to update the applet.
USB Bluetooth Adapter
The Xbit Desktop tool depends on local USB access to a BL654 USB Adapter (P/N 451-00004) programmed with a build of Canvas firmware allowing control of the BL654 radio on the USB adapter via Python scripts running on the module. With the USB adapter installed in the workstation, you may select the corresponding USB serial port from the tool and provide BLE functionality to XBIT applets.


Setting up your BL654 USB Adapter with Canvas Firmware
In order for the Xbit Desktop application to access BLE, you will need to insert a BL654 USB Adapter (P/N 451-00004, Nordic Zephyr Variant) into your workstation. The BL654 USB Adapter must first be programmed with Canvas Firmware and appropriate python script in order to interoperate with applets within the Xbit Desktop application.
To program your BL654 USB adapter, locate the pinhole in the plastic housing near the end of the word CONNECTIVITY on the top labeling.

With the adapter plugged into the workstation, use a paper clip or similar to press and release the button through the pin-hole to place the adapter into bootloader mode. If done properly, the LED begins to slowly fade on and off, indicating it is in bootloader mode.
Once in bootloader mode, the USB adapter firmware can be updated using nRFConnect for Desktop. If unfamiliar with programming .hex files using nRFConnect for Desktop, please review the BL654 USB Dongle User Guide for Nordic/Zephyr linked here.
The Canvas Firmware image for the BL654 USB adapter allows it to run Python scripts to control the BLE functionality from a workstation. Thexbit_usb Python script provides Bluetooth Low Energy scanning and connection capabilities to the Xbit Desktop applets over USB. Program the .hex file linked below onto your BL654 USB adapter using nRFConnect for Desktop:
Canvas Firmware for BL654 USB Adapter:
https://github.com/Ezurio/canvas_python_firmware
Once this .hex file is programmed to the USB adapter, the next step is to get thexbit_usb Python script files programmed onto the USB adapter. For Python programming information, refer to section https://rfpros.atlassian.net/wiki/spaces/VA/pages/1996128261/Sera+NX040+UWB+Ranging+App+Note#Editing-Python-Files-on-a-Device of this application note.
Download the files located in thexbit_usb Python script repository and drag and drop each file onto your device using Xbit VS Code (i.e., xbit_lib.py
and xbit_usb.py
). Rename the xbit_usb.py
file to main.py
using Xbit VS Code so it runs on startup. Reboot the USB adapter to start running the new script by clicking the EOF button or typing CTRL+D
into the REPL terminal near the bottom of the VS Code window.
Your BL654 USB adapter is now ready to use with Xbit Desktop Applets for BLE scanning and connections.
Sera NX040 Tag-to-Tag Applet
An applet has been developed to view ranging and/or positioning data between 2 or more Sera NX040 DVK boards by capturing BLE advertisements from nearby devices, interpreting the ranging data and converting the ranges into a dynamic 3D rendered model.
To run this applet, you must attach a compatible USB-BLE adapter running thexbit_usb Python script. Open the Xbit tool and use the Connect tab to open the serial port associated with the USB adapter running thexbit_usb Python script. Next, navigate to the Applets tab and select the Sera NX040 Tag-to-Tag applet icon.


Using the applet for Tag-to-Tag ranging using 2 DVK boards
To view distance between two DVKs, press Start Scan, then turn on each DVK and wait for them to show up on the display. Note that the actual 3D position of the DVKs is not meaningful since the only data being captured is a single distance measurement between the two DVKs (i.e., no angular or positional data is available). In this mode with 2 DVKs, it works best if you configure the anchor_mode setting to a value of 1. This will configure the DVKs to initiate a unicast two-way-ranging session and advertise range via BLE.
Click Start Scan to initiate scanning and receiving BLE advertisementss from the attached USB BLE adapter. The BLE advertisements from the Sera NX040 DVK boards are captured and processed. As advertisements are received, small spheres representing each board will appear on the 3D field of view and placed at a distance from one another based on the reported range data. Lines are drawn between each sphere with a label indicating distance in either feet or meters (configurable) between each board.

Using the applet for 2D Positioning using 3 DVK boards
To demonstrate 2D positioning, you will need three DVK boards programmed with the uwb_ranging_demo.py Python script. Two DVKs will be configured for anchor mode and the third will be configured for tag mode.
Refer to section https://rfpros.atlassian.net/wiki/spaces/VA/pages/1996128261/Sera+NX040+UWB+Ranging+App+Note#Configuring-the-DVK-for-UWB-Ranging for details regarding anchor_mode configuration in VS Code. In that sectionn two DVKs were configured as anchor_mode = 1. The third DVK for 2D positioning will be configured as a “mobile tag”. To setup as a “mobile tag”, set the “anchor_mode" configuration value to "0" by typing config["anchor_mode"] = 0
.
1. Power on the first two DVK boards and locate them in corners of the room along the same wall and at the same height you would like to measure 2D position of the 3rd DVK. These first 2 DVKs are your anchor points.
2. In the Tag-to-Tag applet, specify the width, length and height of your room to adjust the 3D visualization to the size of your testing environment.

3. Click Start Scan to start capturing ranging data. You’ll see the distance and position of the 2 DVK boards as spheres in the Tag-to-Tag Applet. Once the distance has been established and appears to be accurate, click Lock Anchors to lock them in place in the 3D visualization. You can then use the rotation and shift sliders to position the anchors in the simulated room represented by the background grid in the tool.

4.) Power on the 3rd DVK which represents the mobile tag device. Now that you’ve specified and locked the anchors, the ranges reported between this third mobile tag DVK and the two fixed anchor DVKs are used to draw a sphere representing the mobile tag at a position in the room. Positioning is most accurate when all three DVKs are at the same height since position is determined by finding the intersection point of two circles centered on each anchor point.

Using the applet for 3D Positioning using 4 DVK boards
To demonstrate 3D positioning, you’ll need four DVK boards programmed with the uwb_ranging_demo.py Python script. Three DVKs will be configured for anchor mode and the fourth will be configured for tag mode. Refer to section https://rfpros.atlassian.net/wiki/spaces/VA/pages/1996128261/Sera+NX040+UWB+Ranging+App+Note#Using-the-applet-for-2D-Positioning-using-3-DVK-boards for details on configuring the DVK for tag mode.
1. Power on the first three DVK boards and locate them in corners of the room, ideally encompassing the entire space you’d like to range within. These first 3 DVKs are your anchor points.
2.) In the Tag-to-Tag applet, specify the width, length and height of your room to adjust the 3D visualization to the size of your testing environment.

3. Click Start Scan to start capturing ranging data. View the distance and position of the three DVK boards as spheres in the Tag-to-Tag applet. Once the distance is established and appears to be accurate, click Lock Anchors to lock them in place inthe 3D visualization. You can then use the rotation and shift sliders to position the anchors in the simulated room represented by the background grid in the tool. Note since there is no orientation known ahead of time, you have the option to flip the anchors on X and Z axes to match the correct orientation of your setup. Set the height of the Anchors by selecting each anchor in the Front View Panel and dragging them to the appropriate height.

4. Power on the fourth DVK which represents the mobile tag device. Now that you’ve specified and locked the anchors, the ranges reported between this fourth mobile tag DVK and the three fixed anchor DVKs are used to draw a sphere representing the mobile tag at a position in the room. Positioning is most accurate when anchor tags are well above or below the mobile DVK. Position of the mobile DVK is determined by finding the intersection point of 3 spheres centered on each anchor point.

Positioning Using Ranging Spheres
As mentioned in the above sections, each anchor uses a ranging sphere for locating a tag device. For 3D positioning using 4 DVK’s, a tag is accurately located in both location and height by the intersection point of all three spheres. Each anchor’s sphere is sized to keep the tag on its outer boundary. As the tag moves further away from and anchor its sphere will become larger. As a tag moves closer to an anchor its sphere will shrink in size. The tag can be tracked by each sphere keeping it in its outer boundary which then becomes the intersection point of the three spheres.
To view the spheres and follow the tag in the spheres intersection point select the Show Ranging Spheres option. You will need to move the camera around (click an drag the mouse) to find the best view of the spheres and intersection point.
