UWB Ranging with the DecaWave DWM1000 - Part II

DecaWave now has a very nice development kit for $240 that includes 12 (twelve!) fully assembled, battery-powered modules you can use as tags, or anchors.  You can configure the system with 4-11 anchors and 1-8 tags.  I highly recommend you consider using this kit rather than using my now, rather primitive hardware design.  For details, see:

  https://www.semiconductorstore.com/cart/pc/viewPrd.asp?idproduct=70928&gclid=EAIaIQobChMIpdOEuJeC3wIVhBx9Ch2IkwXBEAAYASAAEgLh9vD_BwE

Important 10/6/2016 - Since I first published this article (and related videos) the open source Arduino code on which I based my project has evolved and improved.  While I have not had time to digest all the changes, the new code seems to now handle several issues I had problems with, such as using a different interrupt pin for an Arduino Pro Micro.

Important - 12/6/2018 - If you use my PCB, please note that there is an error in the design that some have reported can cause problems.  The DW1000 data sheet says that the RST pin "must not be pulled high by external source" and my PCB does exactly that.  While I did not see problem with this with the boards I built, you may wish to sever this connection.  On the PCB design on this page, this signal is routed though a via near the RST on the DWM1000 module, so one solution is to drill out this via (turning a shape xacto knife in the via hole (see PCB image below) should you decide you want to disconnect this signal.  

Update 4/26/2016 - I got a report of problems when trying to use the adapter board described on this page with an Arduino Pro Micro, which is based ATmega32U4.  After some investigation, I traced the problem to the different interrupt wiring on the two boards.  The code published on GitHub for the arduino-DWM1000 open source project I'm using to drive the DWM1000 module was designed to work with the Arduino Pro Mini and hard coded to use interrupt 0 which, in the Pro Mini, is on pin 2.  However, on the Pro Micro, interrupt 0 is connected to pin 3 and pin 2 uses interrupt 1.  Therefore, to use the Pro Micro, you'll need to change the code in the DWM1000 library use interrupt 1.  To do this, I'll have to assume you know how to locate the folder and/or the .zip file that contains the code for this library.  Inside, you find a folder named "src" and in this folder you see a file named DW1000Ranging.cpp.

Open this file with a text editor that can edit code files, or plain text files and search for a line that reads:

DW1000.begin(0, myRST);

Edit this line to change the lone '0' to a "1" and save the file.  Close the library folder and use the Arduino IDE to recompile the sketch which should, in turn, cause the library code to be recompiled.  The modified library code should then run with the Pro Micro.  However, you'll need to undo this change if you ever want to use it with a Pro Mini.

Update 4/10/2016 - See my new video on how to assemble and solder the surface mount devices (SMD on this PCB.

This article is a continuation of this one, which described my initial experiments with the DecaWave DWM1000 module.  After experimenting with a two PCB solution, one as a breakout board for the DWM1000 and the other as a mother board for both the breakout board and an Arduino Pro Mini, I decided to create a single boar solution, as I had trouble finding sockets and headers for the Arduino Pro Mini that were low profile enough to fit under the breakout board.  My new design puts the Arduino Pro Mini and the DWM100 module on the same PCB and looks like this:

Click for large view

Click for larger view

The PCB board for this design can be ordered here from OSH Park and will cost you $9 for three boards.  The parts needed to build this board are listed below along with links to Mouser and/or Digi-Key to simplify ordering:

The signal connections are the same as the original 2 PCB design so you can use the same Arduino code, unchanged.

Putting the Pieces Together

To finish everything off, I laser cut a backboard for the PCB that includes a hole for a 1/4 inch T-Nut so the backing board can screw into a cheap tripod mount so I can position the anchors stably on the ground.  Here's what the finished result looks like:

Click for larger view

Soldering the SMD Parts on the PCB

Testing and Troubleshooting

1. Before plugging in the Arduino, connect USB power to Mini USB connector (J1) on the PCB.  You should see LED D1 (near the upper left corner) light up.  If not, use a multimeter set to the measure Voltage, check that the 3.3 volt regulator (LDO) is working by touching the black lead to the (-) pin and the red lead to the (+) pin near the lower righthand side of the PCB.  You should read approximately 3.3 volts.  If not, something is wrong with the voltage regulator IC (LDO) or there is a short somewhere.  Check all your soldered connections and look for solder bridges that might create a short.  Also, make sure that the three 6 pin ICs (LVC2G17DBVR) are oriented correctly with pin 1 in the upper left.  Note: it can be difficult to see, but there should be a small dot next to pin 1 on each IC.

2. Next, unplug the cable from the Mini USB connector (J1) and plug in the 16 MHz Arduino Mini, or compatible (NOT an Sparkfun Pro Micro, or similar.)  It's possible to use a Pro Micro, but it requires changes to the software and will not work with the software I referenced in Part I of this article.  As a quick check, if your Arduino board has it's own USB connector, it WILL NOT WORK without modifications to the software.  It's also important that the Arduino Mini you are using has a 16 MHz crystal, not an 8 MHz Crystal.  If everything is correct, proceed to step 3.

3. Once the 16 MHz Arduino Mini is connected, connect a 5 Volt serial programming adapter, such as an FTDI cable, to the 6 pin header on the bottom of the Arduino Mini.  If you're using an serial adapter that can be switched between 5 Volts and 3.3 Volts using a jumper, or a switch, make sure it's set to 5 Volts.   If you've connected the Arduino Mini  correctly, the 6 pin header should be at the same end as the J1 connector on the PCB.  If so, plug the serial programming adapter into your computer. You should then see LED D1 light up again.  If everything is correct, proceed to step 4. 

4. Start the Arduino IDE (latest version recommended and install the arduino-dw1000 library into the Arduino IDE using the Sketch->Include Library->Add .ZIP File selection.  Then, Quit and Restart the Arduino IDE.  Then, using the menu action File->Examples should list a DW1000 library.  As a first test, upload the example sketch File->Examples->DW1000->BasicConnectivityTest to the Arduino Mini.  Then open the Arduino IDE's Serial Monitor and select 9600 baud.  The code should run and output something like this:

DW1000 initialized ...

Committed configuration ...

Device IDDW1000 initialized ...

Committed configuration ...

Device ID: FFFF - model: 255, version: 15, revision: 15

Unique ID: FF:FF:FF:FF:FF:FF:FF:FF

Network ID & Device Address: PAN: FFFF, Short Address: FFFF

Device mode: Data rate: 6800 kb/s, PRF: 16 MHz, Preamble: 128 symbols (code #4), Channel: #5

If not, you'll need to try another board (assuming you assembled more than one, as you'll eventually need at least two to perform ranging.  If the BasicConnectivityTest sketch works, then proceed to step 5. 

5. At this point you'll need two assembled and working PCBs that have both passed the BasicConnectivityTest.  To perform ranging, you'll need to upload the DW1000Ranging_ANCHOR sketch to one PCB and the DW1000Ranging_TAG sketch to the other.  Upload the DW1000Ranging_ANCHOR sketch to one of the PCBs first, then disconnect it from the serial programming adapter and then supply power to it using the Mini USB connector on the PCB.  Then, upload the DW1000Ranging_TAG sketch to the second PCB and start the Arduino Monitor.  If everything is working correctly, you should see the two modules communicating with each other, as displayed on the serial monitor from the viewpoint of the TAG module.