# UWB Localization Feather

The Ultra-WideBand Feather incorporates the Decawave DWM1000 module and an ATSAMD21 ARM Cortex M0 into the Adafruit feather form-factor. The DWM1000 module is an IEEE802.15.4-2011 UWB compliant wireless module capable of precision indoor positioning and high data rates, making this board perfect for robotics projects where localization is required.

Features:
– Decawave DWM1000 for precision tracking
– ARM Cortex M0 for fast & powerful applications
– Adafruit Feather compatible to integrate with a wide existing ecosystem
– SWD interface for programming and debugging applications
– USB-C connector
– Intergrated LiPo battery charger with status and voltage available in code
– Intergrated RGB LED

## Hardware

### Design

As mentioned in the introduction, the UWB Feather consists of an ATSAMD21 ARM Cortext M0+ for the brains and a Decawave DWM1000 module for the ultra-wide band wireless, in the feather form-factor. The design is relatively simple consisting of 17 unique BoM items on a 2-layer PCB. Pinout is Adafruit M0 Feather compatible

LiPo charging is handled by the MCP73832 single-cell, fully integrated charge management controller. Battery voltage can be monitored on D9, however is access to all the IO is required, JP1 can be cut to free up this pin. 3.3 volt regulation is preformed by the AP2112K-3.3 low dropout linear regulator, providing up to 600mA.

Pinout is fully compatible with the Adafruit M0 feather line for easy code portability. The DWM1000 IO lines are connected to the SPI bus and digital pins 2, 3 & 4 for RST, IRQ & SPI_CS respectivly (which are not exposed via the header). D13 is also connected to the onboard LED, as is standard among many Arduino-compatible boards.

Programming can be preformed over the SWD header or via USB if loaded with a corresponding bootloader such as the uf2-samdx1 from Microsoft. See firmware for more.

The DWM1000 has a One Time Programmable (OTP) user programmable memory for storing calibration information (see 1.6 in the datasheet). To program this region the VDD3V3 pins may need to be raised to 3.8 volts temporarily. To do this JP2 can be cut and a separate power supply can be connected to selectively boost the power to the module.

### Version 1.0 Schematic

UWB Feather Version 1.0 Schematic. Eagle files available in project repository

## Firmware

Firmware can be loaded over the SWD connector using a programmer such as the J-Link from Segger. Shown above is the J-Link EDU Mini. To start programming the board, we need to load our bootloader then set up our tool chain.

I’ll be using Atmel Studio for flashing the bootloader. To do so, plug in the J-Link and open Atmel Studio. Then select Tools > Device Programming. Under Tool select the J-Link and set Device to ATSAMD21G18A then click Apply.

Connect the J-Link to the feather SWD header and apply power either over USB or via the battery. Once connected, under Device Signature click Read. The Device Signature and Target Voltage text boxes should propagate accordingly. If they do not check the connections and try again.

To flash the bootloader we first need to disable the BOOTPROT fuse. To do this select Fuses > USER_WORD_0.NVMCTRL_BOOTPROT and change to 0 Bytes. Click Program to upload the changes.

Now we can flash the bootloader by selecting Memories > Flash and set the location of the bootloader. Ensure Erase Flash before programming is selected and click Program. If all goes well D13 on the board should begin to pulse.

Now you’ll need to set the BOOTPROT fuse to the 8kB bootloader size. To do this select Fuses > USER_WORD_0.NVMCTRL_BOOTPROT and change to 8192 Bytes. Click program to upload the changes.

Now that the bootloader has been flashed D13 should be pulsing and if plugged in over USB, a mass storage device should appear. This is where UF2 files can be uploaded for programming the board.

### Flashing firmware with PlatformIO

Firmware can be uploaded over the UF2 protocol or directly via the SWD interface. Here we’ll be using PlatformIO for its ease and simplicity. To get started create a new PIO project and select Adafruit Feather M0 as the target board. When uploading over SWD with a J-Link set the upload_protocol in platformio.ini as shown below.

[env:adafruit_feather_m0]
platform = atmelsam
framework = arduino
upload_protocol = jlink

Now you can program the board with the simplicity of the Arduino framework.

### Flashing the Anchor

The DWM1000 modules can be configured to be anchors or tags. Generally anchors are kept at known static locations and tags use anchors to get a relative position to them. To test the DWM1000 module you can upload the DW1000-Anchor example from the GitHub repository.

### DW1000 Anchor

Simple anchor program for the UWB feather




To flash this program with PlatformIO, from PIO Home, select Open Project then find the location of the DW1000-Anchor folder in the GitHub repository. Then click the PIO upload button and it will automagically find the attached debug probe (ensure it is connected and the board is powered).

The tag firmware will need to be uploaded to another board. Then the result can be viewed in a serial terminal.

## Going further

Further improvements to this project will include development on a new DW1000 library, list other projects that utilize this ranging technology. For the latest up to date documentation for this board visit learn/uwb-feather

Thanks for reading. Leave any thoughts or criticisms in the comments below.

Here is some links to papers that utilize the DW1000 IC and may be useful for integrating this module

Decawave UWB Clock Drift Correction and Power Self-Calibration
https://www.mdpi.com/1424-8220/19/13/2942/htm

## 15 thoughts on “UWB Localization Feather”

1. it is a really cool project, with an easy platform to prototype in the UWB RTLS field.
Are you going to sell this on Tindie?

1. Jed Hodson says:

Thanks, glad you liked it. I plan to finalize the V1.1 hardware over the next few days and I am considering selling them on Tindie, so stay tuned!

1. Ricardo de Lemos says:

looking forward to the update. I want to bring this into my home automation setup.

2. Bill says:

Hello,
Thanks for posting all of this. I have been working on my own DWM1000 proto-board that follows this guide. I’ve built up my own boards and they can be programmed with no apparent issue, but I’m running into an issue where the DWM1000 modules are getting insanely hot and I don’t understand why. Just curious if you have experienced anything like this? The anchor starts off at 26C then move up to ~30C, then jump to ~175C.

1. Jed Hodson says:

Hi Bill,
Yes I have noticed this as well on my board however haven’t had much time to investigate it yet. After a little searching the best thing I’ve found about the issue is from this project log of a project that uses the DWM1000 module:

Thermal drift: DWM1000 does not have a TCXO. Depending on surrounding temperature and update rate (i.e. self heating due to radio usage), the measured distance can drift 3-5 cm before thermal equilibrium has been reached. This process can be as slow as half an hour or more.

It seems to be related to update-rate and the radio output power levels. What library were you using to control the module?

I will keep this post updated with anything else I find.

1. Bill says:

Okay, that makes sense. I might need to enable the ADC clock before I run through the temp and voltage measurement procedure.

I’ve been using the source code from the thotro git repo. Did you have to make any major modifications to that code to get the ranging example to work? I haven’t been able to connect a tag and an anchor. I thought it was a heating issue but now it must be something else. Did you have to figure out what the modules OTP EUI for the address argument passed through startAsAnchor() or startAsTag() or can you pass through an arbitrary address?

1. Jed Hodson says:

I did need to make some modifications to the board definitions to get my boards to work (see https://prototypingcorner.io/learn/uwb-feather/). I also just pushed some test scripts I used to the GitHub repository (the anchor AND tag example code). Tag code at https://github.com/prototyping-corner/UWB-Feather/blob/version-1.1/firmware/DW1000-Anchor/src/tag.h. Its also important the the mode parameter in the DW1000RangingClass::startAsAnchor function is the same on both the anchor and tag. As for the address argument anything random should work fine, I haven’t had any issues with that part.

The repository is a bit of a mess at the moment. I plan to tidy everything up over the next week. I also have plans to start working on a new DW1000 library. Let me know how you get on.

1. Bill says:

Awesome! This is very helpful, thank you so much. I did find yesterday that my SPI CLK was running at 24MHz, so I dropped it to 12MHz and it started printing valid statements. When it was running at 24MHz, it was reporting a voltage of 3.32V with a temp at 178C and the device ID wasn’t coming out to 0xDECA0130. But now it’s reporting 3.36V at 32C and an ID of 0xDECA0130. So making progress. I thought the SPI CLK was being divided down from a 48MHz clock, but I guess that’s not the case. I’m making a 4-layer board with some added power protection circuitry. I’d be happy to share it with you if you’re interested.

1. Jed Hodson says:

That’s awesome and a good thing I’ll keep in mind if I run into a similar issue. I’d love to take a look at what your working on.

2. Alex says:

Hi Bill, I would be interested in learning more about your project… I’m thinking about using UWB for indoor tracking.

3. Taehyoung Shim says:

Dear Jed Hodson,
I received two UWB Feather boards yesterday, and checked them.
There are no problem when I tested RGB LED and Batteries via Configuration.h and main.cpp.
However, during DWM1000 module test, I can NOT find the solution how I can operate both Anchor and Tag. I already compiled and uploaded the binary codes of them with using DW1000Ranging.h libraries from thotro/arduino-dw1000, but I can NOT see any messages in serial monitor after “### TAG ###” or “### ANCHOR ###”.
Could you help me how to solve this problem? I guess DWM1000 module dose NOT work on my boards.
BRs,
Taehyoung Shim

1. Jed Hodson says:

Hi Tawhyoung,
Which code sample did you try? I personally tested each board shipped on the code in the repository at github.com/prototyping-corner/UWB-Feather/tree/version-1.1/firmware/DW1000-Anchor. Line 19 and 20 are used to choose between anchor and tag. There is also some changes that need to be made to your board definition that can be found at prototypingcorner.io/learn/uwb-feather. If your still unable to get it to work send me a email at jed (at) prototypingcorner.io and I’ll help you through it.

1. Cherif says:

Bonjour Jed Hodson, les codes de la bibliotheque DW1000 ne marchent pas avec mes ultra wide band que j’ai achété dernierement. Pouvez-vous m’aider svp?