This is the DW1000 driver and our self developed distance measurement application based on it. We do this as a semester thesis at ETH Zürich under the Automatic Control Laboratory in the Department of electrical engineering.
MM2WayRanging.h
00001 // by Matthias Grob & Manuel Stalder - ETH Zürich - 2015 00002 00003 #ifndef MM2WAYRANGING_H 00004 #define MM2WAYRANGING_H 00005 00006 #include "mbed.h" 00007 #include "DW1000.h" 00008 00009 #define TIMEUNITS_TO_US (1/(128*499.2)) // conversion between the decawave timeunits (ca 15.65ps) to microseconds. 00010 #define US_TO_TIMEUNITS (128*499.2) // conversion between microseconds to the decawave timeunits (ca 15.65ps). 00011 #define MMRANGING_2POWER40 1099511627776 // decimal value of 2^40 to correct timeroverflow between timestamps 00012 00013 00014 00015 //Predefined delay for the critical answers in the ranging algorithm 00016 //HAS TO BE BIGGER THAN THE PROCESSING TIME OF THE FRAME ON THE NODE 00017 #define ANSWER_DELAY_US 2500 //2500 works for 110kbps, 900 for 6.8Mbps 00018 #define ANSWER_DELAY_TIMEUNITS ANSWER_DELAY_US * (128*499.2) 00019 00020 class MM2WayRanging { 00021 00022 public: 00023 MM2WayRanging(DW1000& DW); 00024 00025 void requestRanging(uint8_t destination); 00026 void requestRangingAll(); 00027 00028 00029 00030 //TODO: Better capsulation on those? 00031 bool isAnchor; 00032 uint8_t address; // Identifies the nodes as source and destination in rangingframes 00033 00034 //TODO: Make those PRIVATE! 00035 float roundtriptimes[10]; // Array containing the round trip times to the anchors or the timeout which occured 00036 float distances[10]; // Array containing the finally calculated Distances to the anchors 00037 00038 bool overflow; // TRUE if counter overflows while ranging 00039 00040 private: 00041 00042 00043 DW1000& dw; 00044 Timer LocalTimer; 00045 00046 void callbackRX(); 00047 void callbackTX(); 00048 void sendPingFrame(uint8_t destination); 00049 void sendDelayedAnswer(uint8_t destination, uint8_t type, uint64_t rxTimestamp); 00050 void sendTransferFrame(uint8_t destination, int timestamp); 00051 00052 inline float calibratedDistance(uint8_t destination); 00053 00054 /** 00055 * These two functions correct the timestamps if the counter had an overflow between measurements 00056 */ 00057 void correctReceiverTimestamps(uint8_t source); 00058 void correctSenderTimestamps(uint8_t source); 00059 00060 int timediffRec; 00061 int timediffSend; 00062 00063 enum FrameType{ 00064 PING=1, 00065 ANCHOR_RESPONSE, 00066 BEACON_RESPONSE, 00067 TRANSFER_FRAME, 00068 DISTANCES_FRAME 00069 }; 00070 00071 //the packed attribute makes sure the types only use their respective size in memory (8 bit for uint8_t), otherwise they would always use 32 bit 00072 //IT IS A GCC SPECIFIC DIRECTIVE 00073 struct __attribute__((packed, aligned(1))) RangingFrame { 00074 uint8_t source; 00075 uint8_t destination; 00076 uint8_t type; 00077 }; 00078 00079 struct __attribute__((packed, aligned(1))) ExtendedRangingFrame : RangingFrame{ 00080 int signedTime; 00081 }; 00082 00083 00084 RangingFrame rangingFrame; // buffer in class for sending a frame (not made locally because then we can recall in the interrupt what was sent) 00085 ExtendedRangingFrame transferFrame; 00086 ExtendedRangingFrame receivedFrame; 00087 uint64_t rxTimestamp; 00088 uint64_t senderTimestamps[10][3]; 00089 uint64_t receiverTimestamps[10][3]; 00090 bool acknowledgement[10]; // flag to indicate if ranging has succeeded 00091 uint32_t tofs[10]; // Array containing time of flights for each node (index is address of node) 00092 00093 }; 00094 00095 #endif
Generated on Tue Jul 12 2022 15:21:24 by 1.7.2