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.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // by Matthias Grob & Manuel Stalder - ETH Zürich - 2015
00002 #include "mbed.h"
00003 #include "PC.h"                                     // Serial Port via USB for debugging with Terminal
00004 #include "DW1000.h"                                 // our DW1000 device driver
00005 #include "MM2WayRanging.h"                          // our self developed ranging application
00006 
00007 #define myprintf    pc.printf                       // to make the code adaptable to other outputs that support printf
00008 
00009 PC              pc(USBTX, USBRX, 921600);           // USB UART Terminal
00010 DW1000          dw(PA_7, PA_6, PA_5, PB_6, PB_9);   // Device driver instanceSPI pins: (MOSI, MISO, SCLK, CS, IRQ)
00011 MM2WayRanging   node(dw);                           // Instance of the two way ranging algorithm
00012 
00013 void rangeAndDisplayAll(){
00014     node.requestRangingAll();                       // Request ranging to all anchors
00015     for (int i = 1; i <= 5; i++) {                  // Output Results
00016         myprintf("%f, ", node.distances[i]);
00017         //myprintf("T:%f", node.roundtriptimes[i]);
00018         //myprintf("\r\n");
00019     }
00020     myprintf("\r\n");
00021 }
00022 
00023 void calibrationRanging(int destination){
00024 
00025     const int numberOfRangings = 100;
00026     float rangings[numberOfRangings];
00027     int index = 0;
00028     float mean = 0;
00029     float start, stop;
00030 
00031     Timer localTimer;
00032     localTimer.start();
00033 
00034     start = localTimer.read();
00035 
00036     while (1) {
00037 
00038         node.requestRanging(destination);
00039         if(node.overflow){
00040             myprintf("Overflow! Measured: %f\r\n", node.distances[destination]); // This is the output to see if a timer overflow was corrected by the two way ranging class
00041         }
00042 
00043         if (node.distances[destination] == -1) {
00044             myprintf("Measurement timed out\r\n");
00045             wait(0.001);
00046             continue;
00047         }
00048 
00049         if (node.distances[destination] < 100) {
00050             rangings[index] = node.distances[destination];
00051             //myprintf("%f\r\n", node.distances[destination]);
00052             index++;
00053 
00054             if (index == numberOfRangings) {
00055             stop = localTimer.read();
00056 
00057                 for (int i = 0; i < numberOfRangings - 1; i++)
00058                     rangings[numberOfRangings - 1] += rangings[i];
00059 
00060                 mean = rangings[numberOfRangings - 1] / numberOfRangings;
00061                 myprintf("\r\n\r\nMean %i: %f\r\n", destination, mean);
00062                 myprintf("Elapsed Time for %i: %f\r\n", numberOfRangings, stop - start);
00063 
00064                 mean = 0;
00065                 index = 0;
00066 
00067                 //wait(2);
00068 
00069                 start = localTimer.read();
00070             }
00071         }
00072 
00073         else myprintf("%f\r\n", node.distances[destination]);
00074 
00075     }  
00076     
00077 }    
00078 
00079 struct __attribute__((packed, aligned(1))) DistancesFrame {
00080         uint8_t source;
00081         uint8_t destination;
00082         uint8_t type;
00083         float dist[4];
00084     };
00085     
00086 
00087     
00088 void altCallbackRX();
00089 // -----------------------------------------------------------------------------------------------
00090 
00091 int main() {
00092     pc.printf("\r\nDecaWave 1.0   up and running!\r\n");            // Splashscreen
00093     dw.setEUI(0xFAEDCD01FAEDCD01);                                  // basic methods called to check if we have a working SPI connection
00094     pc.printf("DEVICE_ID register: 0x%X\r\n", dw.getDeviceID());
00095     pc.printf("EUI register: %016llX\r\n", dw.getEUI());
00096     pc.printf("Voltage: %fV\r\n", dw.getVoltage());
00097     
00098     node.isAnchor = true;                       // declare as anchor or beacon
00099     
00100     if (node.isAnchor) {
00101         node.address = 1;
00102         myprintf("This node is Anchor node %d \r\n", node.address);
00103     } else {
00104         node.address = 0;
00105         myprintf("This node is a Beacon. ");
00106     }
00107     
00108     if (node.address == 5){ // the node with address 5 was used as an observer node putting out the results in our test case
00109         dw.setCallbacks(&altCallbackRX, NULL);   
00110     }
00111              
00112     while(1) {
00113         if (!node.isAnchor){
00114             rangeAndDisplayAll();
00115             //calibrationRanging(4);
00116         
00117         } else {
00118             //myprintf("."); // to see if the core and output is working
00119             wait(0.5);
00120         }
00121     }
00122 }
00123 
00124 
00125 void altCallbackRX() { // this callback was used in our verification test case for the observer node which only receives and outputs the resulting data
00126 
00127    DistancesFrame distFrame;
00128    float distances[4];
00129    dw.readRegister(DW1000_RX_BUFFER, 0, (uint8_t*)&distFrame, dw.getFramelength());
00130        
00131     if (distFrame.destination == 5) {
00132         for (int i = 0; i<4; i++){
00133             myprintf("%f, ", distFrame.dist[i]);  
00134         } 
00135             
00136         myprintf("\r\n");
00137     }
00138     dw.startRX();
00139 }