Hello everyone,
I am a student working on a positioning project using two ESP32-DW3000 modules. I have reviewed the TWR distance measurement example code from the following link: GitHub - br101/libdeca: UWB Library for Decawave/Qorvo DW3000. However, when I built the main program according to the instructions, I noticed that the system’s distance measurement does not follow the TWR method.
For example, as shown in the diagram below, the anchor device should be the one that emits the poll pulses, the tag device receives the poll pulses and sends back a response message, and the tag device will calculate the ToF as (Tloop - Treply) / 2.
However, when running the program built from the above library, I noticed that the anchor device only runs the twr_start
function, and the tag device is the one that calculates and prints out the measurement results using the twr_set_observer(twr_done_cb)
function. The file main.c is here:
/* SPI Master Half Duplex EEPROM example.
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include “freertos/FreeRTOS.h”
#include “freertos/task.h”
#include “driver/spi_master.h”
#include “driver/gpio.h”
#include “sdkconfig.h”
#include “esp_log.h”
#include “dw3000_hw.h”
#include “dwhw.h”
#include “dwmac.h”
#include “dwphy.h”
#include “dwproto.h”
#include “ranging.h”
/*
This code demonstrates how to use the SPI master half duplex mode to read/write a AT932C46D EEPROM (8-bit mode).
*/
#define IS_ANCHOR 0
static const char TAG = “main”;
static void twr_done_cb(uint64_t src, uint64_t dst, uint16_t dist,
uint16_t num)
{
ESP_LOGI(TAG,“TWR Done %04X: %d cm”, (uint16_t)dst, dist);
}
void test_twr(void)
{
// decadriver init
dw3000_hw_init();
dw3000_hw_reset();
dw3000_hw_init_interrupt();
// libdeca init
dwhw_init();
dwphy_config();
dwphy_set_antenna_delay(DWPHY_ANTENNA_DELAY);
uint16_t PANID = 0x1234; // Example PANID
#if IS_ANCHOR == 1
uint16_t MAC16 = 0x5678; // Example MAC16
#else
uint16_t MAC16 = 0x5677; // Example MAC16
#endif
dwmac_init(PANID, MAC16, dwprot_rx_handler, NULL, NULL);
dwmac_set_frame_filter();
twr_init(10000 /TWR_PROCESSING_DELAY/, false);
twr_set_observer(twr_done_cb);
// two way ranging to 0x0001
#if IS_ANCHOR == 1
dwmac_set_rx_reenable(true);
dwt_forcetrxoff();
dwt_rxenable(DWT_START_RX_IMMEDIATE);
#else
twr_start(0x5678);
#endif
}
void app_main(void)
{
test_twr();
while (1) {
// Add your main loop handling code here.
vTaskDelay(100/portTICK_PERIOD_MS);
#if IS_ANCHOR == 0
twr_start(0x5678);
#endif
}
}
I’m not sure where I went wrong. Could you please help me check the code again? I would like to write a program for the two devices, ANCHOR and TAG, to properly follow the TWR method, with the ANCHOR sending the poll pulse, the TAG sending back the response, and the ANCHOR calculating and printing the result.
Thank you for your help!