If you say it works up to 60 ms but goes wrong for longer times.
A 32 bit time would overflow at 2^32 / (128*499.2e6) = 67 ms.
I suspect that you still have a 32 bit overflow issue somewhere.
If you say it works up to 60 ms but goes wrong for longer times.
A 32 bit time would overflow at 2^32 / (128*499.2e6) = 67 ms.
I suspect that you still have a 32 bit overflow issue somewhere.
this should not happen with delay 60ms as DW1000 has overflow when exceeds ~17s, I think your code has some problem when using sprintf
.
you can try:
uint64_t last_dw_systime;
while (1)
{
uint64_t timestamp = get_system_timestamp_u64();
char dataseq[50];
sprintf((char*)&dataseq, "current: %lu \r\n", timestamp);
port_tx_msg(dataseq, strlen(dataseq));
uint64_t Dt = timestamp - last_dw_systime;
sprintf((char*)&dataseq, "diff: %08x%08x\r\n", Dt >> 32, Dt);
port_tx_msg(dataseq, strlen(dataseq));
last_dw_systime = timestamp;
HAL_Delay(60);
};
@chxt sorry I don’t really know about sprintf
here is the code result for delay 60ms , I have add space between
current: 807751680
diff: 00000000 00000000
current: 656876032
diff: 00000000 00000000
current: 505660928
diff: 00000000 00000000
result for delay 70ms
current: 1314433536
diff: 00000001 00000000
current: 1803096064
diff: 00000001 00000000
current: 2291286528
diff: 00000001 00000000
current: 2779574272
diff: 00000001 00000000
so there is the problem with sprintf?
also the get_system_timestamp_u64 function is below
static uint64_t get_system_timestamp_u64(void)
{
uint8_t ts_tab[5];
uint64_t ts = 0;
int i;
dwt_readsystime(ts_tab);
for (i = 4; i >= 0; i--)
{
ts <<= 8;
ts |= ts_tab[i];
}
return ts;
}
sorry,
should be:
sprintf((char*)&dataseq, "diff: %08lx%08lx\r\n", Dt >> 32, Dt);
I forgot the l
flag, could you give it a try
thanks @chxt , but it seems to be the same
current: 3396481536
diff: 0000000100000000
current: 3882179584
diff: 0000000100000000
current: 73342464
diff: 0000000100000000
current: 495520768
diff: 0000000100000000
I’m sure it’s the problem from sprintf.
and maybe this will work (explicit use of hi/lo part of the timestamp):
uint64_t last_dw_systime;
while (1)
{
uint64_t timestamp = get_system_timestamp_u64();
char dataseq[50];
sprintf((char*)&dataseq, "current: %lu \r\n", timestamp);
port_tx_msg(dataseq, strlen(dataseq));
uint64_t Dt = timestamp - last_dw_systime;
uint32_t Dt_hi = Dt >> 32;
uint32_t Dt_lo = Dt;
sprintf((char*)&dataseq, "diff: %08lx%08lx\r\n", Dt_hi, Dt_lo);
port_tx_msg(dataseq, strlen(dataseq));
last_dw_systime = timestamp;
HAL_Delay(60);
};
uint32_t last_lo = 0;
uint8_t last_hi = 0;
while (1)
{
uint8_t dt[5];
dwt_readsystime(dt);
uint32_t lo = 0;
uint8_t hi = 0;
memcpy(&lo, dt, 4);
hi = dt[4] ;
char dataseq[50];
sprintf((char*)&dataseq, "current: hi-> %d lo %lu \r\n", hi, lo);
port_tx_msg(dataseq, strlen(dataseq));
sprintf((char*)&dataseq, "diff: hi-> %d lo %lu \r\n", hi - last_hi, lo - last_lo);
port_tx_msg(dataseq, strlen(dataseq));
last_lo = lo;
last_hi = hi;
HAL_Delay(70);
};
output
current: hi-> 77 lo 3835064832
diff: hi-> 1 lo 549956608
current: hi-> 79 lo 89716736
diff: hi-> 2 lo 549619200
current: hi-> 80 lo 638417920
diff: hi-> 1 lo 548701184
current: hi-> 81 lo 1187227648
diff: hi-> 1 lo 548809728
current: hi-> 82 lo 1736324608
diff: hi-> 1 lo 549096960
current: hi-> 83 lo 2284209664
diff: hi-> 1 lo 547885056
current: hi-> 84 lo 2832536064
diff: hi-> 1 lo 548326400
current: hi-> 85 lo 3382010880
diff: hi-> 1 lo 549474816
current: hi-> 86 lo 3931201536
diff: hi-> 1 lo 549190656
current: hi-> 88 lo 184390656
diff: hi-> 2 lo 548156416
In [249]: (1* 65536 * 65536 + 548156416) * DWT_TIME_UNITS
Out[249]: 0.07579508012820513
use above code and confirmed the overflow problem
@chxt @AndyA there is some problems with DWM1004C’s stm32L0 handling uint64_t, I just avoid using uint64_t now
Now I have problem calculate the TDoA time, cause the when the Anchor send blink frame in the same time, the tag will loose messages, so I set fix delay time to Anchor with times of its anchor id, so when I look into the api document, it shows 0x17CDC00 is for adding 100ms, but
0x17CDC00 * 512/(499.2e6*128) is actually 0.2, so is the example wrong?
In [350]: 0x17CDC00 * 512/(499.2e6*128)
Out[350]: 0.2
Nowhere in the documentation does it say that the start time register is in units of 512/(4992.6e6*128) seconds (~8ns).
It says that since the least significant bit of the register is ignored that available the resolution becomes ~8ns. That would indicate that the actual units of the register are half of that size.
Or to look at it a different way the native time units of the DW1000 are (1/499.2e6 * 128) to 40 bit resolution. This is the high 32 bits of that 40 bit time which makes the units 2^8 * (1/499.2e6 * 128) seconds
@AndyA When I compare the time difference half of that delay uint make the data reasonable, I use same length cable to connect Anchor together and passing 5Hz signal to Anchor’stm32 gpio as interrupt, when interrupt trigger read dw1000 system time and set blink frame tx delay, when I put the anchor close and the distance difference should under 10cm, but in the tag is more than 30m, So I don’t know which part I raise the error
30 m of range error represents around 100 ns of time error.
From your description it sounds like you’re using the processor to set the zero point.
What’s the interrupt response time of your processor? For STM32 processors it’s normally measured in the 100’s of nanoseconds.
If you want any sort of accuracy you can’t have a processor in the loop for any of the timing critical parts of the system.
@AndyA there is no code running in Anchor’s stm32f103 main loop, and is there the processor time should be same with each Anchor, so it can be minus in time difference?
If you want any sort of accuracy you can’t have a processor in the loop for any of the timing critical parts of the system.
It doesn’t matter what the main loop is doing. It doesn’t matter if it’s the same processor running the same code. It doesn’t matter if it’s the highest priority interrupt there is. It doesn’t matter how fast the processor is.
If you had processor that was running at 2 GHz and responded to the interrupt instantly in a completely deterministic way there would still be a +/- 1/ (2 GHz) = 500ps = 15 cm variability between two systems due to the phase of the CPU clock.
So even with a far faster and unrealistically deterministic CPU the CPU would still be the largest source of error in the system.
If you want to synchronize the clocks between two DW1000s then you need to do it without having a processor in the loop.
@AndyA How cloud I reduce the processor in loop, since I have to control dw1000 via spi interface, or how to get the processor clock offset
You can control it over SPI with a processor. You just can’t use the processor for any timing critical parts of the clock synchronization routine.
You set up the registers using the processor but the actual synchronization must be done using the sync pin which needs to be controlled by hardware not by a CPU IO pin.