Press "Enter" to skip to content

Positioning System Using DecaWave’s DW1000 UWB Chip

DecaWave’s DW1000

DW1000 is a UWB communication and ranging module manufactured by DecaWave. It provides a fairly good ranging accuracy (< 2 cm). Not only a simple anchor-tag ranging system, let’s make a practical centimeter-level precision indoor positioning system using it.

System Design


A setup is shown in a figure below:

  • Anchors
    • They are deployed in a site of interest and their positions—2D/3D coordinates are known.
    • They are implemented on Arduino Pro Mini for the following reasons:
      • Arduino Pro Mini’s low power consumption
      • Anchor’s fast response requirement (order of milliseconds)
      • Anchor’s simple tasks (receiving and transmitting UWB frames)
  • A tag
    • A tag is composed of two components—Raspberry Pi and Arduino Pro Mini
    • Raspberry Pi controles a higher level indoor positioning system
      • It triggers Arduino Pro Mini to probe anchors and measure distance between it and each anchor
      • It requests distance measurements on Arduino Pro Mini and locate itself through trilateration
    • Arduino Pro Mini
      • It is required due to similar reasons of anchors
      • It receives commands from Raspberry Pi and executes the corresponding process.
        Processes are:

        • Probing anchors nearby and exchanging series of frames with each anchor
          to measure distance
        • Reporting probed anchors and measured distance values

An overall sequence diagram is illustrated below.
Tag (Arduino) is actually composed of Arduino Pro Mini and DW1000.

State Machine: Tag

A figure below is a state diagram of a tag:

When a Raspberry Pi commands via I2C to scan, it goes into SCAN state and broadcasts a PING message. Going into PONG state immediately, it waits for PONG messages from anchors nearby for a certain duration. I set it to 100 ms.

If it discovers 3 or more anchors during the PONG state, it goes into ROUNDROBIN state. It exchanges 4 messages with each discovered anchor sequentially, i.e., POLL to an anchor, POLL_ACK from an anchor, RANGE to an anchor, and RANGE_REPORT from an anchor.
After sending POLL and RANGE message, it waits for a response message for a certain timeout of 10 ms.

After 4 messages are exchanged with each anchor, it calculates distance between an anchor using Tx/Rx timestamp. It adopts two-way ranging algorithm, which is a bit computational intensive, but I think it is not that much intensive. For more information about two-way ranging,
please refer the official appliclation note APS013 by DecaWave.

State Machine: Anchor

A state diagram of an anchor is simple:

  • It normally stays at IDLE state
  • If it receives a PING message, it tries to send a PONG message with a random delay between 0 and 90 ms to avoid the collision and goes into PENDING_PONG state
  • If it receives a POLL message and sends a POLL_ACK message, it goes into RANGE state and waits for a RANGE message is received
    • If timeout of 10 ms expires, it returns to IDLE state
    • If it receives a RANGE message, it sends a RANGE_REPORT message to a tag


The whole implementation can be found in my GitHub repository. I used arduino-dw1000 library for controlling DW1000 using Arduino. I followed wiring between Arduino Pro Mini and DW1000 as defined in examples/Ranging{Anchor,Tag} of the library. Only I2C interface is needed to connect Raspberry Pi and Arduino Pro Mini.

Here is the scan, ranging and positioning result of applicaiton prototype.