ESP32 UWB Pro cant get measurements past 5 meters

Good day all,

I am trying to see the general range of my esp32 uwb pro device, i have uploaded a general anchor and tag code unto each device and notice that they become inactive after a few metres (2+) and cant recognize each other. Any input is appreciated.

anchor code:

//anchor #4 setup


// be sure to edit anchor_addr and select the previously calibrated anchor delay
// my naming convention is anchors 1, 2, 3, ... have the lowest order byte of the MAC address set to 81, 82, 83, ...

#include <SPI.h>
#include "DW1000Ranging.h"
#include "DW1000.h"

// leftmost two bytes below will become the "short address"
char anchor_addr[] = "87:00:5B:D5:A9:9A:E2:80"; //#4

//calibrated Antenna Delay setting for this anchor
uint16_t Adelay = 16580;

// previously determined calibration results for antenna delay
// #1 16630
// #2 16610
// #3 16607
// #4 16580

// calibration distance
float dist_m = (285 - 1.75) * 0.0254; //meters

#define SPI_SCK 18
#define SPI_MISO 19
#define SPI_MOSI 23
#define DW_CS 4

// connection pins
const uint8_t PIN_RST = 27; // reset pin
const uint8_t PIN_IRQ = 34; // irq pin
const uint8_t PIN_SS = 4;   // spi select pin

void setup()
{
  Serial.begin(115200);
  delay(1000); //wait for serial monitor to connect
  Serial.println("Anchor config and start");
  Serial.print("Antenna delay ");
  Serial.println(Adelay);
  Serial.print("Calibration distance ");
  Serial.println(dist_m);

  //init the configuration
  SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
  DW1000Ranging.initCommunication(PIN_RST, PIN_SS, PIN_IRQ); //Reset, CS, IRQ pin

  // set antenna delay for anchors only. Tag is default (16384)
  DW1000.setAntennaDelay(Adelay);

  DW1000Ranging.attachNewRange(newRange);
  DW1000Ranging.attachNewDevice(newDevice);
  DW1000Ranging.attachInactiveDevice(inactiveDevice);

  //start the module as an anchor, do not assign random short address
  DW1000Ranging.startAsAnchor(anchor_addr, DW1000.MODE_LONGDATA_RANGE_LOWPOWER, false);
  // DW1000Ranging.startAsAnchor(ANCHOR_ADD, DW1000.MODE_SHORTDATA_FAST_LOWPOWER);
  // DW1000Ranging.startAsAnchor(ANCHOR_ADD, DW1000.MODE_LONGDATA_FAST_LOWPOWER);
  // DW1000Ranging.startAsAnchor(ANCHOR_ADD, DW1000.MODE_SHORTDATA_FAST_ACCURACY);
  // DW1000Ranging.startAsAnchor(ANCHOR_ADD, DW1000.MODE_LONGDATA_FAST_ACCURACY);
  // DW1000Ranging.startAsAnchor(anchor_addr, DW1000.MODE_LONGDATA_RANGE_ACCURACY,false);
}

void loop()
{
  DW1000Ranging.loop();
}

void newRange()
{
  //    Serial.print("from: ");
  Serial.print(DW1000Ranging.getDistantDevice()->getShortAddress(), HEX);
  Serial.print(", ");

#define NUMBER_OF_DISTANCES 1
  float dist = 0.0;
  for (int i = 0; i < NUMBER_OF_DISTANCES; i++) {
    dist += DW1000Ranging.getDistantDevice()->getRange();
  }
  dist = dist/NUMBER_OF_DISTANCES;
  Serial.println(dist);
}

void newDevice(DW1000Device *device)
{
  Serial.print("Device added: ");
  Serial.println(device->getShortAddress(), HEX);
}

void inactiveDevice(DW1000Device *device)
{
  Serial.print("Delete inactive device: ");
  Serial.println(device->getShortAddress(), HEX);
}

tag code

// currently tag is module #5
// The purpose of this code is to set the tag address and antenna delay to default.
// this tag will be used for calibrating the anchors.

#include <SPI.h>
#include "DW1000Ranging.h"
#include "DW1000.h"

#define SPI_SCK 18
#define SPI_MISO 19
#define SPI_MOSI 23
#define DW_CS 4

// connection pins
const uint8_t PIN_RST = 27; // reset pin
const uint8_t PIN_IRQ = 34; // irq pin
const uint8_t PIN_SS = 4;   // spi select pin

// TAG antenna delay defaults to 16384
// leftmost two bytes below will become the "short address"
char tag_addr[] = "7D:00:22:EA:82:60:3B:9C";

void setup()
{
  Serial.begin(115200);
  delay(1000);

  //init the configuration
  SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
  DW1000Ranging.initCommunication(PIN_RST, PIN_SS, PIN_IRQ); //Reset, CS, IRQ pin

  DW1000Ranging.attachNewRange(newRange);
  DW1000Ranging.attachNewDevice(newDevice);
  DW1000Ranging.attachInactiveDevice(inactiveDevice);

// start as tag, do not assign random short address

   DW1000Ranging.startAsAnchor(tag_addr, DW1000.MODE_LONGDATA_RANGE_LOWPOWER, false);
}



void loop()
{
  DW1000Ranging.loop();
}

void newRange()
{
  Serial.print(DW1000Ranging.getDistantDevice()->getShortAddress(), HEX);
  Serial.print(",");
  Serial.println(DW1000Ranging.getDistantDevice()->getRange());
}

void newDevice(DW1000Device *device)
{
  Serial.print("Device added: ");
  Serial.println(device->getShortAddress(), HEX);
}

void inactiveDevice(DW1000Device *device)
{
  Serial.print("delete inactive device: ");
  Serial.println(device->getShortAddress(), HEX);
}

What might that be? Please post a link to the product page, and a photo of the setup, showing how everything is arranged and powered.

1 Like

currently im just using 2 devices, the tag powered by my laptop so i can read the serial monitor and another (the anchor )powered by a 5v,2a adapter

I don't know if that device is properly configured by the code I wrote for the basic UWB module (posted above), and don't have the new one to test.

The first thing to do is to make sure that the Pro versions perform as expected with whatever examples MakerFabs provides. If they do, then look very carefully at the respective libraries and initialization options chosen, and make changes as needed.

1 Like

is it possible to use both versions of the library with their respective device together? eg, this pro module's version of the libr and a module the uses the classic dw1000 module library.

If by "classic" you mean the original DW1000 library by Thomas Trojer, it will not work with my code.

I know nothing about any library that might have been modified for use with the Pro version of the UWB module from MakerFabs.

could you specify and/or list what exactly makes it unusable with your code?

After looking it up on the makerfabs site, the same code is used for the esp32 uwb and uwb pro (which is what i have )but a different code is specified for specifically the uwb pro with display.

directly from link:

/*

For ESP32 UWB or ESP32 UWB Pro

*/

#include <SPI.h>
#include "DW1000Ranging.h"

#define ANCHOR_ADD "86:17:5B:D5:A9:9A:E2:9C"

#define SPI_SCK 18
#define SPI_MISO 19
#define SPI_MOSI 23
#define DW_CS 4

// connection pins
const uint8_t PIN_RST = 27; // reset pin
const uint8_t PIN_IRQ = 34; // irq pin
const uint8_t PIN_SS = 21;   // spi select pin

void setup()
{
    Serial.begin(115200);
    delay(1000);
    //init the configuration
    SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
    DW1000Ranging.initCommunication(PIN_RST, PIN_SS, PIN_IRQ); //Reset, CS, IRQ pin
    //define the sketch as anchor. It will be great to dynamically change the type of module
    DW1000Ranging.attachNewRange(newRange);
    DW1000Ranging.attachBlinkDevice(newBlink);
    DW1000Ranging.attachInactiveDevice(inactiveDevice);
    //Enable the filter to smooth the distance
    //DW1000Ranging.useRangeFilter(true);

    //we start the module as an anchor
    // DW1000Ranging.startAsAnchor("82:17:5B:D5:A9:9A:E2:9C", DW1000.MODE_LONGDATA_RANGE_ACCURACY);

    DW1000Ranging.startAsAnchor(ANCHOR_ADD, DW1000.MODE_LONGDATA_RANGE_LOWPOWER, false);
    // DW1000Ranging.startAsAnchor(ANCHOR_ADD, DW1000.MODE_SHORTDATA_FAST_LOWPOWER);
    // DW1000Ranging.startAsAnchor(ANCHOR_ADD, DW1000.MODE_LONGDATA_FAST_LOWPOWER);
    // DW1000Ranging.startAsAnchor(ANCHOR_ADD, DW1000.MODE_SHORTDATA_FAST_ACCURACY);
    // DW1000Ranging.startAsAnchor(ANCHOR_ADD, DW1000.MODE_LONGDATA_FAST_ACCURACY);
    // DW1000Ranging.startAsAnchor(ANCHOR_ADD, DW1000.MODE_LONGDATA_RANGE_ACCURACY);
}

void loop()
{
    DW1000Ranging.loop();
}

void newRange()
{
    Serial.print("from: ");
    Serial.print(DW1000Ranging.getDistantDevice()->getShortAddress(), HEX);
    Serial.print("\t Range: ");
    Serial.print(DW1000Ranging.getDistantDevice()->getRange());
    Serial.print(" m");
    Serial.print("\t RX power: ");
    Serial.print(DW1000Ranging.getDistantDevice()->getRXPower());
    Serial.println(" dBm");
}

void newBlink(DW1000Device *device)
{
    Serial.print("blink; 1 device added ! -> ");
    Serial.print(" short:");
    Serial.println(device->getShortAddress(), HEX);
}

void inactiveDevice(DW1000Device *device)
{
    Serial.print("delete inactive device: ");
    Serial.println(device->getShortAddress(), HEX);
}

Adjusting the antenna delay is not possible with the original library. There may be other problems as well.

What maximum range do you get for the Pro, using the MakerFabs library and examples?

im not really in a capacity to test the maximum range of the device right now, but using the makerfabs library i get upwards of 25m which is the length of the building im currently in. However the pro is advertised to measure up to 150m, not entirely sure if that is only possible with the high power mode or both the high and low power mode right now.

Your code does work with the makerfabs library, it just has the range/looping issue when trying to autocalibrate the anchors using your code after testing. It also allows for the meaurement of the devices above to and above 25m. However with your modified library, although it gives accurate readings, and allows for the usage of the anchor autocalibration code, after moving the devices 2-3m apart, they become inactive (deletes device). Thus only allowing me to use it for distances 2-3m and under.

You will need to study the two libraries carefully and modify one of them to reconcile all the differences.

Currently I'm using the makerfabs library where in the code i post the distances and coordinates to a database. The results are accurate but i see occasional innacuracy due to factors like movement, suddden obstructions, possible ranging errors etc. For example the maximum length of the building im in is 22m, max width is 14.49m, so once a distance falls outside that range it is filtered out and isn't posted to the database.

The issue however rises when the tag is for stationary for example, and the distance would read: 9,9,9,9,13,9,9,9,9. So the position of the tag hasnt moved but there is an error that falls within the bounds of the area that im in. Do you have any advice on how i could filter that out? Im currently using the trilat_2d_3a code.

i currently have this statement as the last thing in the newRange() function after trilat2d_3a() has been called, once detected==3:

if (detected == 3) { // three measurements TODO: check millis() wrap

#ifdef DEBUG_DIST
        // print distance and age of measurement
        uint32_t current_time = millis();
        for (i = 0; i < N_ANCHORS; i++) {
            Serial.print(last_anchor_distance[i]);
            Serial.print("\t");
            Serial.println(current_time - last_anchor_update[i]); // age in millis
        }
#endif

        trilat2D_3A();

        // output the values (X, Y and error estimate)
        Serial.print("P= ");
        Serial.print(current_tag_position[0]);
        Serial.write(',');
        Serial.print(current_tag_position[1]);
        Serial.write(',');
        Serial.println(current_distance_rmse);

 if ( current_tag_position[0] <= 22.51 &&   current_tag_position[1] <= 15.00 current_tag_position[i] <= 30) { 

//post distance and coordinate data to the database

}
else {
            Serial.println(" Not valid");
        }
    }
}  // end newRange

The most effective way to reduce or eliminate occasional outliers is to use a median filter, for example with five readings.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.