
Todays work was to make a simple GPS tracker communicating over LoRaWAN to check the coverage of my LoRaWan gateway in the city. Basically this tracker reports a position per minute to the network. If coverage is good, position will be recorded in the backend. That’s all !
This post details how to do it easily with the low cost and common components : Arduino for the master, Microchip RN2483 for LoRaWan communication and L80 for GPS positioning.
Let’s start by a simple circuit :

The RN2483 circuit is connected to the physical UART of my Leonardo board (I assume it would be better to use the softserial for this one but it was already soldered like this before I add the GPS).
The L80 is connected to a Softserial on port 6 and 8.
Port 2 is used to pilot RN2483 reset pin
Port 3 is used to pilot a Led.
Now, here is the Arduino code I used :
#include <TinyGPS++.h> #include <SoftwareSerial.h> #define rxGpsPin 8 #define txGpsPin 6 #define ledPin 3 // ---------------------------------------------- // DEBUG TOOLS #define DEBUG #ifdef DEBUG void trace(String str) { Serial.println(str); } #else #define trace(x) #endif // ---------------------------------------------- // GLOBALS String str; bool cnxStatus; SoftwareSerial mySerial2 = SoftwareSerial(rxGpsPin,txGpsPin); SoftwareSerial fakeSerial2 = SoftwareSerial(9,10); TinyGPSPlus gps; long lastMinute; // ---------------------------------------------- // SETUP void setup() { // put your setup code here, to run once: #ifdef DEBUG Serial.begin(9600); while (!Serial); #endif Serial1.begin(57600); while (!Serial1); pinMode(rxGpsPin, INPUT); pinMode(txGpsPin, OUTPUT); fakeSerial2.begin(9600); mySerial2.begin(9600); pinMode(ledPin,OUTPUT); digitalWrite(ledPin,HIGH); // reset the module pinMode(2,OUTPUT); digitalWrite(2,LOW); delay(500); digitalWrite(2,HIGH); delay(2000); Serial1.setTimeout(2000); trace("reset"); str = Serial1.readStringUntil('\n'); trace(str); trace("init"); Serial1.println("mac set devaddr 00100001"); str = Serial1.readStringUntil('\n'); trace(str); Serial1.println("mac set appskey AFBXXXXXXXXXXXXXXXXXXXXXXXXXEBDC"); str = Serial1.readStringUntil('\n'); trace(str); Serial1.println("mac set nwkskey AFBXXXXXXXXXXXXXXXXXXXXXXXXXEBDC"); str = Serial1.readStringUntil('\n'); trace(str); Serial1.println("mac save"); str = Serial1.readStringUntil('\n'); trace(str); digitalWrite(ledPin,LOW); cnxStatus = false; // not connected lastMinute = -1; } void loop() { while ( mySerial2.available() ) gps.encode(mySerial2.read()); // ds qu'on a l'heure on joue if ( gps.time.isUpdated() && gps.location.isUpdated() ) { if ( gps.time.minute() != lastMinute ) { fakeSerial2.listen(); lastMinute = gps.time.minute(); long lat = gps.location.rawLat().deg * 1000000; lat += gps.location.rawLat().billionths / 1000; lat += 100000000; long lng = gps.location.rawLng().deg * 1000000; lng += gps.location.rawLng().billionths / 1000; lng += 100000000; String message = "mac tx uncnf 1 "; message += String(lat,HEX); message += String(lng,HEX); trace(message); digitalWrite(ledPin,HIGH); Serial1.println(message); delay(2000); digitalWrite(ledPin,LOW); str = Serial1.readStringUntil('\n'); trace(str); if ( str.startsWith("not_joi") ) { Serial1.println("mac join abp"); delay(3000); str = Serial1.readStringUntil('\n'); str = Serial1.readStringUntil('\n'); trace(str); if ( str.startsWith("acc") ) { digitalWrite(ledPin,HIGH); Serial1.println(message); delay(2000); digitalWrite(ledPin,LOW); str = Serial1.readStringUntil('\n'); trace(str); } } mySerial2.listen(); } }
Some usefull links
- The TinyGPS library : http://arduiniana.org/libraries/tinygpsplus/
- A nice tuto to get start with L80 : http://www.dabax.net/Arduino-GPS/
- A previous post about RN2480
- All about LoRa
Nice work. Very simple, but perfect solution for the job at hand.
I look forward to seeing both the results and the Google Maps mashup code that you put together.
Great article!