-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMMRanging.ino
103 lines (92 loc) · 3.74 KB
/
MMRanging.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "MMRanging.h"
MMRanging::MMRanging(DW1000& DW) : dw(DW) {
event_i = 0;
counter = 0;
dw.setCallbacks(this, &MMRanging::callbackRX, &MMRanging::callbackTX);
dw.setCallbacks(&MMRanging::callbackRX, &MMRanging::callbackTX);
for (int i = 0; i < 10; i++) {
acknowledgement[i] = true;
distances[i] = -1;
}
//LocalTimer.start();
dw.startRX();
}
void MMRanging::callbackRX() {
rangingframe RX;
dw.readRegister(DW1000_RX_BUFFER, 0, (uint8_t*)&RX, dw.getFramelength()); // get data from buffer
if (RX.destination == address) // only if received packet is for me
switch (RX.type) {
case 1:
rangingtimingsReceiver[RX.source][0] = dw.getRXTimestamp();
sendRangingframe(RX.source, RX.sequence_number, 2, 0);
break;
case 2:
rangingtimingsSender[RX.source][1] = dw.getRXTimestamp();
sendRangingframe(RX.source, counter, 3, 0);
counter++;
break;
case 3:
sendRangingframe(RX.source, RX.sequence_number, 4, timeDifference40Bit(rangingtimingsReceiver[RX.source][0], rangingtimingsReceiver[RX.source][1]));
break;
case 4:
tofs[RX.source] = timeDifference40Bit(rangingtimingsSender[RX.source][0], rangingtimingsSender[RX.source][1]) - RX.time_difference_receiver;
acknowledgement[RX.source] = true;
break;
default : break;
}
#ifdef EVENTS
sprintf(event[event_i], "!R %d>%d / %d %d", RX.source, RX.destination, RX.sequence_number, RX.type);
if (event_i == 8)
event_i = 0;
else
event_i++;
#endif
dw.startRX();
}
void MMRanging::callbackTX() {
switch (TX.type) {
case 1:
rangingtimingsSender[TX.destination][0] = dw.getTXTimestamp();
break;
case 2:
rangingtimingsReceiver[TX.destination][1] = dw.getTXTimestamp();
break;
default: break;
}
#ifdef EVENTS
sprintf(event[event_i], "!S %d>%d / %d %d", TX.source, TX.destination, TX.sequence_number, TX.type);
if (event_i == 8)
event_i = 0;
else
event_i++;
#endif
}
void MMRanging::requestRanging(uint8_t destination) {
acknowledgement[destination] = false;
float time_before = micros();
sendRangingframe(destination, counter, 1, 0);
while(!acknowledgement[destination] && (micros() < time_before + 0.5f)); // wait for succeeding ranging or timeout
roundtriptimes[destination] = micros() - time_before;
distances[destination] = (tofs[destination] * 300 / MMRANGING_TIMEUNIT_US / 2);
}
void MMRanging::requestRangingAll() {
for (int i = 1; i <= 4; i++) { // Request ranging to all anchors
requestRanging(i);
}
}
void MMRanging::sendRangingframe(uint8_t destination, uint8_t sequence_number, uint8_t type, uint64_t time_difference_receiver) {
TX.source = address;
TX.destination = destination;
TX.sequence_number = sequence_number;
TX.type = type;
TX.time_difference_receiver = time_difference_receiver;
dw.sendFrame((uint8_t*)&TX, sizeof(TX));
}
uint64_t MMRanging::timeDifference40Bit(uint64_t early, uint64_t late) {
int64_t difference = late - early;
if ((difference < -MMRANGING_2POWER40+10000000000) && (difference > -MMRANGING_2POWER40-10000000000)) // if the timestamps differ a negative word length +- ~1sec that was potentially measured, correct it
return difference + MMRANGING_2POWER40;
if ((difference < 0) || (difference > 10000000000))
return 10000000000;
return (uint64_t)difference;
}