Contiki DWM1001, how to calculate distance done by broadcast?

Hey, I’ve been playing with dwm1001 and I managed to send a message via broadcast.

But my goal is to send message from one dwm1001 (master), the other dwm1001 will send msg including distance between master and itself and its address.

Thanks!

#include "contiki.h"
#include "net/rime/rime.h"
#include <stdio.h>

#define BROADCAST

#define RIME_CHANNEL 146
#define RIME_TYPE "broadcast"
static struct broadcast_conn bc;
static const struct broadcast_callbacks bc_cb = {};

PROCESS(frame_sender_process, "SENDER");

AUTOSTART_PROCESSES(&frame_sender_process);

PROCESS_THREAD(frame_sender_process, ev, data)
{
  static struct etimer timer;
  static unsigned long tx_count = 0;

  PROCESS_EXITHANDLER(broadcast_close(&bc);)

  PROCESS_BEGIN();

  printf("%s sender %d.%d starting...\r\n",
         RIME_TYPE,
         linkaddr_node_addr.u8[0],
         linkaddr_node_addr.u8[1]);

  broadcast_open(&bc, RIME_CHANNEL, &bc_cb);

  etimer_set(&timer, CLOCK_SECOND);

  while (1)
  {
    PROCESS_WAIT_EVENT();
    if (ev == PROCESS_EVENT_TIMER)
    {
      tx_count++;

      printf("Sending %s message: %d seq\r\n",
             RIME_TYPE, tx_count);

      char *msg = "Hello";

      packetbuf_clear();
        packetbuf_set_datalen(sprintf(packetbuf_dataptr(),
                                      "%s", msg) +
                              1);


      broadcast_send(&bc);

      etimer_reset(&timer);
    }
  }

  PROCESS_END();
}
// recv
#include "contiki.h"
#include "net/rime/rime.h"
#include "net/packetbuf.h"

#include <stdio.h>

PROCESS(frame_receiver_process, "RECEIVER");

AUTOSTART_PROCESSES(&frame_receiver_process);

static unsigned long rx_count = 0;

#define BROADCAST

#define RIME_CHANNEL 146
#define RIME_TYPE "broadcast"
static void recv_callback(struct broadcast_conn *c, const linkaddr_t *from);
static struct broadcast_conn bc;
static const struct broadcast_callbacks bc_cb = {recv_callback};

static void recv_callback(struct broadcast_conn *c, const linkaddr_t *from)
{
  // printf("msg got\n");
  // int tx_count = -1;
  // if (packetbuf_datalen() == sizeof(tx_count))
  //   packetbuf_copyto(&tx_count);

  printf("| %s | message received from %02x.%02x (%i) - RSSI = %d\r\n",
         (char *)packetbuf_dataptr(),
         from->u8[0], from->u8[1], rx_count,
         (signed short)packetbuf_attr(PACKETBUF_ATTR_RSSI));
  // packetbuf_dataptr();
  // packetbuf_clear();
  rx_count++;
}

PROCESS_THREAD(frame_receiver_process, ev, data)
{
  static struct etimer timer;

  PROCESS_EXITHANDLER(broadcast_close(&bc);)

  PROCESS_BEGIN();

  printf("BQU:0:%u:%u\r\n", RTIMER_NOW(), RTIMER_ARCH_SECOND);
  printf("R %d.%d starting...\r\n", linkaddr_node_addr.u8[0],
         linkaddr_node_addr.u8[1]);

  broadcast_open(&bc, RIME_CHANNEL, &bc_cb);

  etimer_set(&timer, CLOCK_SECOND * 5);

  while (1)
  {
    PROCESS_WAIT_EVENT();
    if (ev == PROCESS_EVENT_TIMER)
    {
      // printf("Receiver %lu\r\n", rx_count);
      // print_sys_status(dw_read_reg_64( DW_REG_SYS_STATUS, DW_LEN_SYS_STATUS ));
      etimer_reset(&timer);
    }
  }

  PROCESS_END();
}

You want to know the distance between the two? Unless you have perfectly synchronised clocks on both of them then this can’t be done with a single broadcast.

You measure distance by measuring how long the message took to travel between the two. You can only do that if you know both when it was sent and when it arrived. This requires at least two messages.

The most basic implementation is A to B and then B to A in a process called Single Sided Two Way Ranging (SS TWR). B sends the reply a fixed time after receiving the first message. A can take the time between sending and receiving, subtract Bs response time and the end result is a time that is equal to twice the distance (there and back) divided by the speed of light.

A more accurate method is Double sided TWR. This can be optimised by combining messages but is in effect two SS TWR measurements A to B and then B to A and averaging the result.

I’ve skipped some of the details like antenna delays and click biases in the description above but there are plenty of more detailed descriptions and examples of this process around.