Getting started with the UWB Feather.
Note: Work on creating the example documentation is still in progress.
To get started, install the PlatformIO package and board files as shown below and follow the guide to get started. To use the DWM1000 install the thotro/arduino-dw1000 library.
To put the board into programming mode, double press the reset button. The RGB LED will fade blue slowly if a connection is successful.
Install the PIO repository & board package
Add UWB Feather board support
Download the board file from https://dl.prototypingcorner.io/pio/boards/prototypingcorner_uwb_feather.json and place this in your PlatformIO core directory /boards directory (see the PIO guide if you get stuck)
{
"build": {
"arduino": {
"ldscript": "flash_with_bootloader.ld"
},
"core": "prototypingcorner",
"cpu": "cortex-m0plus",
"extra_flags": "-DARDUINO_ARCH_SAMD -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS -D__SAMD21G18A__",
"f_cpu": "48000000L",
"hwids": [
[
"0x1209",
"0x8192"
]
],
"mcu": "samd21g18a",
"system": "samd",
"usb_product": "Prototyping Corner UWB Feather",
"variant": "uwb_feather"
},
"debug": {
"jlink_device": "ATSAMD21G18",
"openocd_chipname": "at91samd21g18",
"openocd_target": "at91samdXX",
"svd_path": "ATSAMD21G18A.svd"
},
"frameworks": [
"arduino"
],
"platforms": [
"atmelsam"
],
"name": "Prototyping Corner UWB Feather",
"upload": {
"disable_flushing": true,
"maximum_ram_size": 32768,
"maximum_size": 262144,
"native_usb": true,
"offset_address": "0x2000",
"protocol": "sam-ba",
"protocols": [
"sam-ba",
"blackmagic",
"jlink",
"atmel-ice"
],
"require_upload_port": true,
"use_1200bps_touch": true,
"wait_for_upload_port": true
},
"url": "https://prototypingcorner.io/l/uwb_feather",
"vendor": "Prototyping Corner"
}
Add the prototypingcorner samd package
Next you’ll need to modify the atmelsam package list to add the prototyping corner package repository. In the PlatformIO core directory go to platforms/atmelsam and open the platform.json file.

Here add https://dl.prototypingcorner.io/pio/packages/manifest.json
to the packageRepositories
list (as shown above) to add the Prototyping Corner package repository.

Then add support for the framework by pasting the below snippet into the packages
list as shown above.
"framework-arduino-samd-prototypingcorner": {
"type": "framework",
"optional": true,
"version": "~1.6.2"
},
That’s it, head on over the the PIO boards page and you should see the UWB feather show up

Getting updates
Board support is still a work in progress, luckily if you need to update just run this PIO command (press F1 from within VSCode to get the command window up)
PlatformIO: Update platforms & packages

This will automatically pull and install the latest version of the UWB Feather package.
Configuration.h
The following is the pin assignment. Note in future releases this will be included in the support package.
#ifndef CONFIGURATION_H
#define CONFIGURATION_H
#include <Arduino.h>
#define DW1000_RST 2
#define DW1000_IRQ 3
#define DW1000_CS 4
#define LED_RED 26
#define LED_GREEN 31
#define LED_BLUE 30
#define BATTERY_VOLT 25
#define BATTERY_CHARGE 27
#endif
Main.cpp
The following is example code use to test the module. It shows how to use the RGB LED, measure voltage and monitor charge status. View the full project on the GitHub repository
/**
* UWB Feather feature test
* Short set of testing program onboard features of the UWB feather
*/
#include <Arduino.h>
#include "DW1000Ranging.h"
// Decawave DW1000 pins
#define DW1000_RST 2
#define DW1000_IRQ 3
#define DW1000_CS 4
// RGB LED pins
#define LED_RED 26
#define LED_GREEN 31
#define LED_BLUE 30
// Battery sense pins
#define BATTERY_VOLT 25
#define BATTERY_CHARGE 27
/** Pulse a pin for a set amount of time */
void pulse(int pin, int interval) {
digitalWrite(pin, HIGH);
delay(interval);
digitalWrite(pin, LOW);
delay(interval);
}
/** Calculate the battery voltage on battery pin */
float getBatteryVoltage() {
float measuredvbat = analogRead(BATTERY_VOLT);
measuredvbat *= 2; // we divided by 2, so multiply back
measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage
measuredvbat /= 1024; // convert to voltage
return measuredvbat;
}
void setup() {
/** Wait for the serial monitor to be open before starting the program */
Serial.begin(9600);
while(!Serial);
Serial.println("Starting...");
/** Setup our pins */
pinMode(LED_RED, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
pinMode(BATTERY_CHARGE, INPUT);
/** Test the RGB LED */
Serial.println("Testing RGB LED...");
Serial.println("RED");
pulse(LED_RED, 1000);
Serial.println("GREEN");
pulse(LED_GREEN, 1000);
Serial.println("BLUE");
pulse(LED_BLUE, 1000);
/**
* Test the DWM1000 module
* Device ID will print out:
* Device ID: DECA - model: 1, version: 3, revision: 0
* if connectivity to the DWM1000 was successful
*/
Serial.println("Testing DWM1000 module");
DW1000Ranging.initCommunication(DW1000_RST, DW1000_CS, DW1000_IRQ);
DW1000Ranging.startAsTag("7D:00:22:EA:82:60:3B:9C", DW1000.MODE_LONGDATA_RANGE_ACCURACY);
delay(1000);
char msg[128];
DW1000.getPrintableDeviceIdentifier(msg);
Serial.print("Device ID: "); Serial.println(msg);
DW1000.getPrintableExtendedUniqueIdentifier(msg);
Serial.print("Unique ID: "); Serial.println(msg);
DW1000.getPrintableNetworkIdAndShortAddress(msg);
Serial.print("Network ID & Device Address: "); Serial.println(msg);
DW1000.getPrintableDeviceMode(msg);
Serial.print("Device mode: "); Serial.println(msg);
/** Test the battery */
Serial.println("Testing battery...");
Serial.println("Running battery test for 20 seconds");
long millisNow = millis();
// For 20 seconds display the reading on the BATTERY_VOLT and BATTERY_CHARGE pins
// BATTERY_VOLT will float around 4.3V if there is no battery plugged in
while(millis() < millisNow + 20000) {
// Calculate the battery voltage
Serial.print("VBat: "); Serial.println(getBatteryVoltage());
// The BATTERY_CHARGE signal is active low, so dont forget to invert it
Serial.print("Charge: "); Serial.println( ! digitalRead(BATTERY_CHARGE) );
delay(500);
}
Serial.println("Testing complete");
}
void loop() { /** Nothing to loop */ }
Using the DWM1000
Create a new DW1000Ranging instance using the pin definitions from configuration.h. Don’t forget to install the thotro/arduino-dw1000 using either the PIO library manager or downloading it to the lib folder.
DW1000Ranging.initCommunication(PIN_RST, PIN_SS, PIN_IRQ);
Further reading
Here is some links to papers that utilize the DW1000 IC and may be useful for integrating this module
Decawave Application Notes
This is a great resource for everything to do with the DW1000, everyone working with this board should take a look at what information is available here
https://www.decawave.com/application-notes/
Decawave UWB Clock Drift Correction and Power Self-Calibration
https://www.mdpi.com/1424-8220/19/13/2942/htm
UWB Positioning
https://www.decawave.com/wp-content/uploads/2018/12/Ultra-Wideband-Wireless-Positioning-Systems_2014-03-27.pdf
Still to come
Work that on its way:
– New DW1000 library (to replace thotro/arduino-dw1000)
– Create library for easy of use (i.e. charge status interrupt, LED control)
– Examples!
– Multilateration code samples
Questions?
For any help with getting started contact hi@prototypingcorner.io, or take a look at our product forums (coming soon)