Introduction: JARVAS Indoor Positioning System

JARVAS (Just A Rather Very Average System) is an indoor positioning system, in which a wearable tag communicates with multiple stationary anchors to determine its position. Building one of these probably will interest you if you're Amazon, need to provide your institution (museum, hospital, etc.) with contextual information, or if you want to beef up your personal living space with automaticity.

Step 1: Technical Overview

The anchors and tag communicate using ultra-wideband via DWM1000 chips. The DWM1000 chips provide range information between each anchor and the tag. The tag filters the ranges and uses linear least squares estimation to calculate (x, y) location in meters. Then, the DWM1000 chip on the tag communicates the (x, y) location to the WiFi anchor. The WiFi anchor is equipped with an ESP8266 chip which forwards the location to a server via WiFi. Then, any internet-connected device can have access to the tag's location!

This Instructable is aimed at teaching you how to build the project. If you're interested in diving into the details of the design, check out the documentation in the JARVAS repository.

Step 2: Gather the Materials

You will need the following materials:

* Parts for 3 Anchor PCBs. You can place a DigiKey order using the BOM (bill of materials) here: https://github.com/derindutz/jarvas-indoor-positionin...

* Parts for at least one Tag PCB. You can place a DigiKey order using the BOM here: https://github.com/derindutz/jarvas-indoor-positionin...

* At least 3 copies of the Anchor PCB and at least 1 copy of the Tag PCB from OSHPark. You can order the Anchor PCBs here: https://oshpark.com/shared_projects/S7J6GKik and the Tag PCBs here: https://oshpark.com/shared_projects/1JeCBav4

* An AVR ICSP programmer (You can buy the newest versions here: http://www.atmel.com/tools/atatmel-ice.aspx?tab=overview)

* At least 4 single cell Li-Ion or LiPo batteries (such as: https://www.sparkfun.com/products/341)

You can also improve the location accuracy and range of JARVAS by adding more anchors. As you will also discover in the next step, any beacon board can act either as an anchor or a tag, so if you may replace the "1 tag PCB" with another beacon PCB.

Step 3: Download the Software

For this project, you will need to install:

Arduino (for programming the boards)

* Install the most recent version of Arduino here: https://www.arduino.cc/en/Main/Software

AVRDUDE (for programming the Arduino firmware onto the tags)

* Install from your favorite package manager or download here: http://download.savannah.gnu.org/releases/avrdude/

Heroku (for hosting the web servers)

* Sign up for a free Heroku account here: https://www.heroku.com/

* Download the most recent version of the Heroku Command Line Interface by following the steps here: https://devcenter.heroku.com/articles/getting-star...

JARVAS Project Code

* Download the project GitHub repository by clicking "Clone or Download" and then "Download ZIP" here: https://github.com/derindutz/jarvas-indoor-positionin...

* Add the JARVAS custom DW1000 library to Arduino. Use the library in the project above (at https://github.com/derindutz/jarvas-indoor-positionin...). If you haven't added a custom library to Arduino before, follow the steps here: https://www.arduino.cc/en/Guide/Libraries

Step 4: Build the Anchors

The JARVAS anchor board is a multipurpose board that hosts a SparkFun Arduino Pro Micro, a DWM1000 module, and an ESP8266 WiFi module. You can use this board as either an anchor or a tag, however it's much larger than the dedicated tag module.

1. Order the board from a PCB fab using the jarvas_anchor_gerbers.zip file here: https://github.com/derindutz/jarvas-indoor-positioning-system/tree/master/hardware/jarvas_anchor.

The boards in the pictures were produced by Bay Area Circuits (http://bayareacircuits.com); if you have time to wait, you can likely get cheaper boards from OSHPark (https://oshpark.com). The easiest option is to just click the link below to buy from OSHPark: https://oshpark.com/shared_projects/S7J6GKik.

You don't need Altium Designer to get copies of any of the boards made; however, the full Altium design files are available in the GitHub repository in case you want to make some modifications.

2. (Recommended) Order a stencil to more easily apply solder paste with the .GTP file from the above zip folder. OSHStencils (https://www.oshstencils.com) is a good choice for this.

3. Order components for the boards according to the bill of materials (BOM) Excel file: https://github.com/derindutz/jarvas-indoor-positioning-system/blob/master/hardware/jarvas_anchor/jarvas_anchor_bom.xlsx

If you're buying on DigiKey, you can upload the file directly to your cart and order everything in one go.

4. Once you have the above materials, assemble the board according to the schematic: https://github.com/derindutz/jarvas-indoor-positioning-system/blob/master/hardware/jarvas_anchor/jarvas_anchor_schematics.pdf

Assembling a surface-mount PCB is outside the scope of this guide, so please see the following extremely comprehensive tutorials:

* A SparkFun tutorial: https://www.sparkfun.com/tutorials/59

* A vast library of advice for surface mount soldering: https://www.sparkfun.com/tutorials/category/2

Step 5: Build the Tag

The tag is simply a smaller, cheaper, sleeker version of the anchor board without the WiFi -- so it shares the same building process as the anchor board in the previous step. Here are all the relevant files: https://github.com/derindutz/jarvas-indoor-positioning-system/tree/master/hardware/jarvas_tag

Again, you can easily order copies of this board from OSHPark:

https://oshpark.com/shared_projects/1JeCBav4

Schematic: https://github.com/derindutz/jarvas-indoor-positioning-system/blob/master/hardware/jarvas_tag/jarvas_tag_schematic.pdf

Since the board is so tiny, there are no component designators on the silkscreen of the board. Instead, here's an assembly PDF that shows the location of each component: https://github.com/derindutz/jarvas-indoor-positioning-system/blob/master/hardware/jarvas_tag/jarvas_assembly_drawing.PDF

NOTE: This board needs a bootloader programmed into it before you can program it with the Arduino IDE. The next step will guide you through this.

Step 6: Flash the Tag Bootloader

To breathe your JARVAS Arduino tag to life, you'll need an ICSP programmer. The following instructions use the AVR JTAGICE3, but any other standard programmer will work just as well (although you'll need to specify the correct programmer in the commands below).

1. To use JTAGICE3 on Linux, create a /etc/udev/rules.d/98-local-jtagice3.rules file with the following line:

SUBSYSTEM=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2140", GROUP="dialout"

2. Connect your programmer to the programming header on the JARVAS tag according to the pinout of your programmer. Please refer to the pictures above as a guide!

3. Finally, connect a battery to the tag to power it. If you're using JTAGICE3, you should now see both the green and red lights illuminated.

4. To confirm that you are correctly connected, read the fuse bits off of the board by executing the command below:

avrdude -v -pm32u4 -cjtag3isp -Pusb -B22 -U efuse:r:efuse.hex:h -U hfuse:r:hfuse.hex:h -U lfuse:r:lfuse.hex:h

This will create 3 text files each with one hex value such as "0xff". It's not too important right now what those values are, just that this command runs without error.

5. Download the Caterina bootloader from the JARVAS repository (https://github.com/derindutz/jarvas-indoor-positioning-system/blob/master/hardware/Caterina-promicro8.hex) and then run the following command:

avrdude -v -pm32u4 -cjtag3isp -Pusb -B22 -U flash:w:Caterina-promicro8.hex -U hfuse:w:0xd8:m -U lfuse:w:0xff:m -U efuse:w:0xfe:m

You may get an error that the efuse could not be set. Answer 'y' if it asks to retry. Don't worry if setting the efuse fails.

6. You are now ready to plug in your tag over USB and program it! Make sure the battery is still connected.

Step 7: Set Up the Servers

Now, you will be adding an API (Application Programming Interface) server and an optional front-end server. The API server receives information from the WiFi anchor and opens up the location as a public API. The front-end server provides a nice visualization by using this public API to display the tag's location.

First, sign in to your heroku account and create two apps, one for the API server and one for the front end. There should be a dropdown on the right side of the logged-in dashboard with an option for “create a new app”. Give each app a name, for example “jarvas-api-server” and “jarvas-frontend”. You will need these names for later setup.

Now that you’ve created two apps, open up a terminal. Type in “heroku login” and follow the instructions to log into heroku through the command line (it should ask for your heroku email and password). Now you're ready to start running the servers. Move to the JARVAS repository you downloaded earlier from the command line by typing “cd [path to indoor-positioning-system]".

Now, you will be uploading the API server to heroku. Before you do this, you need a plugin to allow you to upload apps to heroku. In terminal, enter “heroku plugins:install heroku-builds” to install the plugin. Now, type in “cd api-server”. Remember the name you gave to your heroku app for the api server? In this example, we’ll say it was “jarvas-api-server”. Type in “heroku builds:create -a jarvas-api-server.” Once this command is finished running, the api server will be up in the cloud! To confirm, you can check https://dashboard.heroku.com/apps/jarvas-api-serv... where "jarvas-api-server" is the name you selected. The “Latest activity” section on the right should indicate that the app has been deployed.

Now for the front-end server. Type in “cd ../front-end-server” to switch to the correct directory. Recall the heroku app you created for the front-end; for example, let’s say it was called “jarvas-frontend”. Before you upload the front-end, you need to make two small changes to the source code. Open up client.js in your favorite text editor. On lines 32 and 53, you should see a string saying “https://jarvas-api.herokuapp.com/beacons” and “https://jarvas-api.herokuapp.com/location” respectively. Replace the “jarvas-api” with the name of your heroku api-server app above (“jarvas-api-server” in our example). Save the file. Now, return to your terminal and type in the command “heroku builds:create -a jarvas-frontend”. Once this command is complete, you can go to jarvas-frontend.herokuapp.com to see a visualization of the tag's location!

To test that the servers are set up correctly, enter the following into terminal:

curl -X POST '<a href="http://jarvas-api.herokuapp.com/beacons" rel="nofollow">jarvas-api.herokuapp.com/beacons</a>' -H 'Content-Type: application/json' -d '{"beacons": [{"id": "a", "location": [10, 0]}, {"id": "b", "location": [0, 10]}, {"id": "c", "location": [0, 0]} ]}'

You should see 3 beacons appear in the front-end visualization. If you see an error returned in your terminal, it means that there was some problem setting up the API server. Check through the steps above to make sure you haven't missed anything. If you don't see an error but don't see the 3 beacons appear in the visualization, there was some problem setting up the front-end server.

You can also test that setting the location works properly. Enter the following into terminal:

curl -X POST '<a href="http://jarvas-api.herokuapp.com/location?x=1.0&y=0.5" rel="nofollow">jarvas-api.herokuapp.com/location?x=1.0&y=0.5</a>'

The locations in the visualization are in meters and when you enter the code above, you should see the tag move to x = 1.0 and y = 0.5. Feel free to play around with the 1.0 and 0.5 values above and move the tag to different places.

Step 8: Program the Tag

The tag communicates ranging information with all of the anchors. The tag then filters the ranges and runs a localization algorithm that takes in 3 ranges and outputs an (x, y) distance in meters.

To set up the tag:

1. Open the .ino file at: https://github.com/derindutz/jarvas-indoor-positioni... in the Arduino app.

2. Upload the code to the tag.

If you are curious about some technical details on what the code on the tag does, check out the documentation page on localization and filtering.

Step 9: Program the Non-WiFi Anchors

The non-WiFi anchors serve only as anchors: they calculate ranging information between themselves and the tag.

To program both of the non-wifi anchors:

1. Open the .ino file at: https://github.com/derindutz/jarvas-indoor-positioni... in the Arduino IDE.

2. For one of the anchors, edit line 16 of anchor.ino, "DW1000Ranging.startAsAnchor("XX:XX:1A:1A:1A:1A:1A:1A", DW1000.MODE_LONGDATA_RANGE_ACCURACY);" by replacing the "XX:XX" with "2A:1A".

3. For another anchor, edit that line by replacing the "XX:XX" with "3A:1A".

4. Upload the code to the two non-wifi anchors by pressing the upload button in the Arduino IDE.

Step 10: Program the WiFi Anchor

The WiFi anchor serves both as an anchor and as a relay. It's an anchor since it calculates ranging information between itself and the tag, and it's a relay since it receives location (x, y) information in meters from the tag and forwards that information to the server.

First, you're going to set up the ESP8266 WiFi module:

1. Connect the WiFi anchor to your computer.

2. Open the .ino file at: https://github.com/derindutz/jarvas-indoor-positioni... in the Arduino app.

3. Click the upload button in Arduino.

4. Once the code is uploaded, open the Serial Monitor.

5. Type AT into the Serial Monitor. You should see OK returned. If not, there is likely something wrong with your ESP8266 module. Check your connections to make sure the module is hooked up properly.

6. Type AT+CWMODE=1 into Serial. You will see OK returned.

7. Type AT+CWLAP into Serial. You will see a list of access points. Pick one that you want to use and not its ssid.

8. Type AT+CWJAP="ssid","pwd" where ssid is the one you want to use and pwd is the corresponding password.

9. Once you've recieved an IP, type AT+CIFSR. You should see a valid IP address returned. If not, start anew from step 5.

Now, you're ready to program the WiFi anchor:

1. Open the .ino file at: https://github.com/derindutz/jarvas-indoor-positionin... in the Arduino app.

2. Upload the code to the board. If everything's working correctly, you should see little blue lights flickering on the DWM1000 module every so often.

Everything is now set up and ready to go! If you think you may be having issues communicating with the other anchors and the tag, uncomment line 54 of wifi-anchor.ino and re-upload the WiFi anchor. Open up the Serial Monitor in Arduino and ensure that you're receiving location information properly. If you're not, you should be able to tell which anchor is causing the problem. If you think you may be having issues communicating over WiFi, uncomment lines 39-41 of wifi-anchor.ino, re-upload the WiFi anchor, and open Serial Monitor. You should see a stream of information that is coming from the ESP8266 module. If you see errors, go through the ESP8266 module setup steps above.

Step 11: Calibrate the Tag

In order to use your positioning system, you will have to calibrate the tag so it knows the correct distances to the anchors. Simply follow these instructions:

1. Open up tag.ino in the Arduino IDE.

2. Connect a battery to the tag, and connect it to your computer via USB.

3. Make sure you know which anchors have which addresses. If you followed the previous steps, the WiFi anchor should be 1A:1A, and the others should be 2A:1A and 3A:1A.

4. Set CALIBRATION_FIRST to true and upload the code to the tag.

5. Open up the Serial Monitor on your computer to see the distances from each anchor.

6. Walk over to each anchor and stop when the tag is 2 meters away.

7. Record each of the anchor's distance values, and record them in BEACON_N_FIRSTDIST.

8. Repeat this process, but at 5 meters away from each tag, and record the values in BEACON_N_SECONDDIST.

9. Set CALIBRATION_FIRST to false and re-upload the code to the tag.

10. Your tag is now calibrated!

Step 12: Print and Mount Tags/Anchors in Cases

As a fun optional step, you can mount the tags and anchors in cases to better protect them. 3D printing is out of the scope of this Instructable, so if you don't have much experience, check out the tutorials here: http://www.shapeways.com/tutorials/.

1. Download 3D Files from the Github repository. The files are: jarvas_box.stl, jarvas_lid.stl, jarvas_stand.stl.

2. Print on a 3D Printer - if you don't have one, check out Shapeways or 3D Hubs. The specific settings used in the picture are:

* Printer: Robo R1+

* Print speed: 53mm/s everything

* Material: PLA

* Temperature: 210 C

* Infill: 15%

* Outlines: 3 layers

* Layer height: 0.3mm

4. Mount the anchor as shown in picture.

5. Mount the tag in the case however you wish; the standard configuration is with antenna nearest the keychain loop.

6. Use 2 M2.5x4mm screws to screw the lid onto the box.

Step 13: Putting Everything Together

Congratulations! Everything should now be working properly. As you move around with the tag, you should see the location live in the web application. Now it's up to you to extend this project in all kinds of ways! If you end up doing something especially cool we'd love to hear about it :)