In this post, we will explain set up a ranging application for the Raspberry Pi to display the distances between two DWM1000 modules.
First of all, we will need to have python installed (cf. paragraph 2 and 3 of the cheat sheet) and we will need to have access to a remote terminal: either directly or via SSH (cf. paragraph 1 of the cheat sheet). In this article, we will be using a SSH connection for the setup.
The DWM1000 is connected to the Raspberry Pi via a SPI connection, so we must make sure this interface is also enabled at the software level. Paragraph 4 of this article explains how to activate it. We must also install the spidev library to communicate with the module from the Raspberry Pi.
Note: all that follow was tested with Raspberry Pi 2.
The DWM1000 module must be connected to the SPI interface of the Raspberry Pi. Check the following picture to know where to connect SPI pins MOSI, MISO,CLK (respectively GPIO10, GPIO9 and GPIO11).
We also need to connect the chip select pin to either GPIO8, GPIO7 or GPIO16. Finally, we need to connect the interrupt pin to any unused GPIO. Remember the GPIO number for these two pins, since we will need to change the code accordingly. In our case, the chip select is GPIO16 and the IRQ pin is GPIO19.
If you would rather avoid messy wires and use a fully integrated prototype board instead, check out our automated design and prototyping service that takes care of everything for you.
The Python library we developed for the DWM1000 module requires some external libraries we will need to install to make it fully functional. As we said above, spidev is mandatory so install it if it is not done already. Next, we need to install RPi.GPIO to enable the control of GPIOs especially regarding the interrupt and chip select To do that, simply enter the following command:
sudo apt-get install RPi.GPIO
Finally, we need to install the monotonic library. This is a library providing a function which returns the value of a clock that never goes backward. It is used in the ranging scripts to check for the module’s inactivity. This library does not need to be installed if you have Python3, since the integrated time module provides a monotonic() function. However, you will need to perform a little change in the script, which we will explain later. If you don’t have python3 installed, follow these instructions:
If git package is not installed on the Raspberry Pi, run:
sudo apt-get install git (if you are not sure, run the command anyway since there is no harm in doing so)
Clone the monotonic github repository to the Raspberry Pi:
git clone https://github.com/atdt/monotonic
Move to the new folder:
Install the library:
sudo python setup.py install
We now have installed all the tools necessary to make our library work so it is time to use it!
B/ Downloading the library
Similarly to the Arduino library, we have created a library to control a DWM1000 with Python from the Raspberry Pi. You can clone its repository directly on the Rasperry Pi, by running:
git clone https://github.com/ThingType/DW1000_Raspi_Python_library
Move to the created folder:
The folder contains several Python files:
- DW1000.py: The core of this folder. This is the library containing low level functions allowing the communication between the Raspberry Pi and the DWM1000 module using SPI transactions
- DW1000Constants.py: This is the python module containing the relevant constants used by this library and its scripts
- Receiver.py and Transmitter.py: These are two scripts that must be run together. The Transmitter sends a message to the receiver every 2 seconds and the Receiver displays the data received on the terminal
- PingPong.py: This script needs to be run on two devices, with one of them having trxToggle as RECEIVER and the other as SENDER (changed in the scripts). It enables a “ping-pong” like transmission between the two modules
- DW1000RangingAnchor.py and DW1000RangingTag.py: This is the ranging scripts used to display the distance separating the two modules. We will explain how to execute them
As per our previous article, we need to have at least one anchor and one tag to have an active ranging application. We will begin by going through the Anchor script.
The Anchor is the stationary module and will be responsible for calculating the distance using the recorded timestamps. Before executing the script, we need to make some changes inside the code. Open the script in any editor (nano for instance):
sudo nano DW1000RangingAnchor.py
The file can also be edited on a computer and then transferred to the Raspberry Pi as we explained in Python programming in our cheat sheet.
If you use Python3, replace the import monotonic line by import time and monotonic.monotonic() by time.monotonic(). Otherwise, ignore this step.
Next, we might need to change the value assigned to PIN_IRQ and PIN_SS. We must replace the number depending on which pin we used for the connection in Hardware: wiring. In our case, since we connected the interrupt pin to GPIO19, PIN_IRQ is set to 19. Similarly, we chose GPIO16 for the chip select so PIN_SS is set to 16. After saving these changes, we can execute the script. Run:
On the terminal screen, the device informations should be displayed. If they are all written as 0, then it probably means that we chose the wrong chip select number. If the device is operational, we should see the unique ID as written in the script: 82:17:5B:D5:A9:9A:E2:9C and the PAN as DECA. The terminal should also be printing “reset inactive” at a regular pace. Here is what the terminal looks like after following these steps (short address is generated randomly so don’t worry if it is different everytime).
The script will run until a KeyboardInterrupt is detected. So we need to manually stop it by typing Ctrl + C on the keyboard.
The Tag is the moving module of the system. It will help in creating and saving the timestamps used to process the distance. Like we did with the Anchor script, we need to modify the value assigned to the interrupt and the chip select pins. After applying these changes, you can start the ranging tag script by running:
The terminal should look like this:
3/ Displaying the distance and calibrating the module for better accuracy
If both of the scripts are running, the distance between the two modules should be displayed on the Anchor terminal:
If it is not accurate enough for the range order you are trying to measure, this can be tweaked a little by changing the Antenna Delay . The Antenna Delay is the delay between the time a signal arrives at the receiving antenna and the time the arriving message is time-stamped inside the DW1000. This value will vary slightly between different units of the DW1000 and can be changed to affect precision. Note that distances are not really accurate above 70 meters and below 45 centimeters and if we try to measure outside this span, we might see incorrect values. We need to change this value in the DW1000Constants.py module. By default, it is set to 16390 but this can be changed and tested progressively to match the desired precision.
Instead of using, a Raspberry Pi as the host, you can also use an Arduino board like in this article. Mixing the hosts is possible: for instance, you can use an Arduino board as the Tag and a Raspberry Pi as the Anchor, like in this geofencing example.