In this tutorial, we will use the MKR GPS Shield to record the longitude and latitude, and transmit it to another board using LoRa® technology. This setup can be very useful for scenarios involving remote areas, where tracking location might be essential.
Special thanks to Sandeep Mistry for creating the LoRa library.
The goals of this project are:
The GPS is an incredible technology that is used to pinpoint an exact location. Even more interesting, it uses a series of satellites orbiting the Earth to do so. Basically, a satellite in orbit continuously sends signals towards the Earth, which are picked up by GPS receivers, that exist in e.g. smartphones. As the satellite has a positioning system, it knows where it is, relative to the Earth. But this signal can only pinpoint that you are in a certain part of the world, e.g. in the Atlantic Ocean or Asia. For more accuracy, data from other satellites are also used, where for every satellite the accuracy increases.
It is quite spectacular, that something 20.000 kilometers above the Earth can pinpoint your exact location. What is even more interesting, is that we can create our own projects using this technology. The MKR GPS shield can get extremely accurate readings on where we are in the world. This can be used to first locate where we are in the world, but we can also use it to record for example speed.
There is, of course, much more behind the GPS technology. If we want to read more, why not start at NASA's own article on how GPS works.
We will now go through a series of step by steps, to set up our GPS + LoRa® device.
Before starting, we will need to make sure that we have all the dependencies. For this setup, we are using two MKR WAN 1310 boards, two antennas and one MKR GPS Shield. We will also need to install the Arduino_MKRGPS library, the LoRa library. The latter can be downloaded from the LoRa® repository, where you can install it by navigating to Sketch > Include Library > Add .ZIP Library... in the offline IDE.
Since we are using two boards, we will also need to program them separately.
We will first need to program the board that will have the GPS shield attached to it. In this program, we will be using the Arduino_MKRGPS library, which is used to record various GPS data, such as longitude, latitude, number of satellites reached and speed. We will record all of them, but we will only send the longitude and latitude. This will be done using the LoRa library.
Some of the main functions of this sketch are listed below:
byte localAddress = 0xBB;
- create a local address for our board.byte destination = 0xFF;
- create a destination address we will send our data to. LoRa.begin(868E6)
- initializes the LoRa® module to operate on 868 MHz frequency (European, for American, change to 915E6).GPS.begin
- initializes the GPS library.GPS.latitude()
- records latitude.GPS.longitude()
- records longitude.LoRa.beginPacket()
- creates a LoRa® packet.LoRa.print()
- prints data to the LoRa® packet.LoRa.endPacket()
- sends the LoRa® packet.We can now upload the code below to the MKR WAN 1310 board that has the GPS shield connected to it.
1#include <SPI.h>2#include <LoRa.h>3#include <Arduino_MKRGPS.h>4
5float latitude;6float longitude;7float altitude;8float speed;9float satellites;10
11byte localAddress = 0xBB; //address of this device12byte destination = 0xFF; //where we are sending data to13
14void setup() {15
16 // initialize serial communications and wait for port to open:17 Serial.begin(9600);18
19 while (!Serial)20 if (!LoRa.begin(868E6)) {21 Serial.println("Starting LoRa failed!");22 while (1);23 }24
25 if (!GPS.begin()) {26 Serial.println("Failed to initialize GPS!");27 while (1);28 }29}30
31void loop() {32 // check if there is new GPS data available33 if (GPS.available()) {34
35 // read GPS values36 latitude = GPS.latitude();37 longitude = GPS.longitude();38 altitude = GPS.altitude();39 speed = GPS.speed();40 satellites = GPS.satellites();41
42 // print GPS values43 printValues();44 45 // Create and send LoRa packet46 LoRa_send();47 }48 delay(1);49}50
51//function to send information over LoRa network52void LoRa_send() {53 LoRa.beginPacket(); //creates a LoRa packet54 LoRa.write(destination); //destination address55 LoRa.print("LAT: ");56 LoRa.print(latitude);57 LoRa.print(" LONG: ");58 LoRa.print(longitude);59 LoRa.endPacket(); //sends the LoRa packet60 delay(10000); //a 10 second delay to limit the amount of packets sent61}62
63//function that prints all readings in the Serial Monitor64void printValues() {65 Serial.print("Location: ");66 Serial.print(latitude, 7);67 Serial.print(", ");68 Serial.println(longitude, 7);69 Serial.print("Altitude: ");70 Serial.print(altitude);71 Serial.println("m");72 Serial.print("Ground speed: ");73 Serial.print(speed);74 Serial.println(" km/h");75 Serial.print("Number of satellites: ");76 Serial.println(satellites);77 Serial.println();78}
Now that we have successfully uploaded the code to the first board (the sender), we can move on to configure the second board.
First, it is a good idea to use two computers if possible, otherwise, we will have to manually change between ports. It is important now to keep track on which board you are uploading to, as if accidentally upload the same sketch to both boards, it won't work.
The second sketch we need to upload is a bit more basic. It basically only listens for incoming messages, and if we receive a message from the other board, we print it in the Serial Monitor. Some of the core functions of this sketch are:
byte localAddress = 0xFF;
- create a local address. LoRa.available()
- checks if there's any available data.LoRa.parsePacket()
- parses the incoming data.LoRa.read()
- reads the incoming data.LoRa.packetRssi()
- signal strength from packet sender.We can now copy and paste the code from below and upload it to the second MKR WAN 1310 board. Make sure we have selected the right MKR WAN 1310 board to upload to.
1#include <SPI.h>2#include <LoRa.h>3
4String message;5
6byte localAddress = 0xFF; 7
8
9void setup() {10 Serial.begin(9600);11 while (!Serial);12 Serial.println("LoRa GPS data receiver");13 if (!LoRa.begin(868E6)) {14 Serial.println("Starting LoRa failed!");15 while (1);16 }17 delay(1000);18}19void loop() {20
21 onReceive(LoRa.parsePacket());22}23
24void onReceive(int packetSize) {25 if (packetSize == 0) return; // if there's no packet, return26
27 int recipient = LoRa.read();28 String incoming = "";29
30 while (LoRa.available()) {31 incoming += (char)LoRa.read();32 }33
34 if (recipient != localAddress && recipient != 0xFF) {35 Serial.println("This message is not for me.");36 return; // skip rest of function37 }38
39 Serial.print(incoming);40 Serial.print(" || RSSI: ");41 Serial.println(LoRa.packetRssi());42 Serial.println();43}
Now the two MKR WAN 1310s have two unique sketches uploaded to each board. We will begin by initializing the first board (the sender) and then initialize the second board (the receiver).
delay(10000)
in the sketch after each packet is sent.
Congratulations, you have now managed to combine the tracking of GPS signals, and transfer the coordinates over LoRa, to another board. This setup can be extremely useful for remote areas, where we for example need to send an emergency signal to notify our location.
This tutorial combines both the use of LoRa® and GPS technologies, but you can of course explore them separately as well. The GPS shield can for example be used for more than just positioning, it can also be used to measure speed, for example how fast we are traveling by bike.
If the code is not working, there are some common issues we can troubleshoot:
This tutorial combines both the LoRa® and GPS technologies, but you can of course explore them separately as well. The MKR GPS Shield can for example be used for more than just positioning, it can also be used to measure speed, for example how fast we are traveling by bike.