Last active
September 21, 2022 03:13
-
-
Save nobodyguy/7920482dd00f300b973126f9d7188db4 to your computer and use it in GitHub Desktop.
GpsLoRaWANTracker using Arduino, RN2483 and L86/neo-m8n GPS module
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <TinyGPS++.h> | |
#include <SoftwareSerial.h> | |
#include <avr/sleep.h> | |
#include <avr/power.h> | |
// ---------------------------------------------- | |
// DEFINES | |
// ---------------------------------------------- | |
#define rxGpsPin 10 | |
#define txGpsPin 11 | |
#define ledPin 6 | |
#define loraResetPin 4 | |
#define loraTxPin 8 | |
#define loraRxPin 7 | |
#define wakePin 2 | |
#define sleepTime 60000 // 1 minute | |
#define minSatelites 8 | |
const String devaddr = "XXXXXXXX"; | |
const String appskey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; | |
const String nwkskey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; | |
// ---------------------------------------------- | |
// DEBUG TOOLS | |
// ---------------------------------------------- | |
#define DEBUG | |
#ifdef DEBUG | |
void trace(String str) { | |
Serial.println(str); | |
} | |
#else | |
#define trace(x) | |
#endif | |
// ---------------------------------------------- | |
// GLOBALS | |
// ---------------------------------------------- | |
String str; | |
SoftwareSerial gpsSerial = SoftwareSerial(rxGpsPin, txGpsPin); | |
SoftwareSerial loraSerial = SoftwareSerial(loraRxPin, loraTxPin); | |
TinyGPSPlus gps; | |
// ---------------------------------------------- | |
// SLEEP FUNCTIONS | |
// ---------------------------------------------- | |
void wakeUpArduino(void) | |
{ | |
/* This will bring us back from sleep. */ | |
/* We detach the interrupt to stop it from | |
* continuously firing while the interrupt pin | |
* is low. | |
*/ | |
detachInterrupt(0); | |
} | |
void sleepArduino(void) | |
{ | |
/* Setup pin2 as an interrupt and attach handler. */ | |
attachInterrupt(0, wakeUpArduino, CHANGE); | |
delay(100); | |
set_sleep_mode(SLEEP_MODE_PWR_DOWN); | |
sleep_enable(); | |
sleep_mode(); | |
/* The program will continue from here. */ | |
/* First thing to do is disable sleep. */ | |
sleep_disable(); | |
} | |
// ---------------------------------------------- | |
// SETUP | |
// ---------------------------------------------- | |
void setup() { | |
// put your setup code here, to run once: | |
#ifdef DEBUG | |
Serial.begin(9600); | |
while (!Serial); | |
#endif | |
loraSerial.begin(57600); | |
while (!loraSerial); | |
//pinMode(rxGpsPin, INPUT); | |
//pinMode(txGpsPin, OUTPUT); | |
gpsSerial.begin(9600); | |
pinMode(wakePin, INPUT); | |
pinMode(ledPin, OUTPUT); | |
digitalWrite(ledPin, HIGH); | |
// reset the module | |
pinMode(loraResetPin, OUTPUT); | |
digitalWrite(loraResetPin, LOW); | |
delay(500); | |
digitalWrite(loraResetPin, HIGH); | |
delay(2000); | |
loraSerial.setTimeout(50000); | |
loraSerial.listen(); | |
trace("reset"); | |
//str = loraSerial.readStringUntil('\n'); | |
//trace(str); | |
trace("init"); | |
loraSerial.println("mac set devaddr " + devaddr); | |
str = loraSerial.readStringUntil('\n'); | |
trace(str); | |
loraSerial.println("mac set appskey " + appskey); | |
str = loraSerial.readStringUntil('\n'); | |
trace(str); | |
loraSerial.println("mac set nwkskey " + nwkskey); | |
str = loraSerial.readStringUntil('\n'); | |
trace(str); | |
//loraSerial.println("mac set dr 5"); | |
//str = loraSerial.readStringUntil('\n'); | |
//trace(str); | |
loraSerial.println("mac save"); | |
delay(2000); | |
str = loraSerial.readStringUntil('\n'); | |
trace(str); | |
loraSerial.println("mac join abp"); | |
delay(2000); | |
str = loraSerial.readStringUntil('\n'); | |
trace(str); | |
str = loraSerial.readStringUntil('\n'); | |
trace(str); | |
digitalWrite(ledPin, LOW); | |
gpsSerial.listen(); | |
trace("GPS listening..."); | |
} | |
double lat; | |
double lng; | |
char latBuffer[20]; | |
char lngBuffer[20]; | |
char payload[100]; | |
// ---------------------------------------------- | |
// MAIN LOOP | |
// ---------------------------------------------- | |
void loop() { | |
while (gpsSerial.available()) | |
{ | |
if (gps.encode(gpsSerial.read())) | |
{ | |
int satellites = gps.satellites.value(); | |
//Serial.print(satellites); | |
if (gps.satellites.isValid() && (satellites >= minSatelites) && ((gps.location.isValid() && gps.location.age() < 2000)) && (gps.location.lat() > 0) && (gps.location.lng() > 0)) { | |
digitalWrite(ledPin, HIGH); | |
lat = gps.location.lat(); | |
lng = gps.location.lng(); | |
dtostrf(lat, 10, 8, latBuffer); | |
dtostrf(lng, 10, 8, lngBuffer); | |
sprintf(payload, "%s,%s,%d", latBuffer, lngBuffer, satellites); | |
gpsSerial.end(); | |
loraSerial.listen(); | |
sendRadioMsgBuffer(payload); | |
str = loraSerial.readStringUntil('\n'); | |
trace(str); | |
if (str.startsWith("ok")) | |
{ | |
str = loraSerial.readStringUntil('\n'); | |
trace(str); | |
if (str.startsWith("not_joi")) { | |
loraSerial.println("mac join abp"); | |
delay(3000); | |
str = loraSerial.readStringUntil('\n'); | |
str = loraSerial.readStringUntil('\n'); | |
trace(str); | |
if (str.startsWith("acc")) { | |
sendRadioMsgBuffer(payload); | |
str = loraSerial.readStringUntil('\n'); | |
trace(str); | |
} | |
} else if (!str.startsWith("mac_tx_ok") && !str.startsWith("mac_rx")) { | |
errorLoop(); | |
} | |
} | |
else | |
{ | |
errorLoop(); | |
} | |
digitalWrite(ledPin, LOW); | |
loraSerial.print("sys sleep "); | |
loraSerial.println(sleepTime); | |
delay(100); | |
trace("Sleeping..."); | |
sleepArduino(); // put arduino into sleep - it will be woken up by lora module | |
gpsSerial.begin(9600); | |
gpsSerial.listen(); | |
} | |
} | |
} | |
} | |
// ---------------------------------------------- | |
// RADIO FUNCTIONS | |
// ---------------------------------------------- | |
void sendRadioMsgBuffer(char* msg) | |
{ | |
size_t len = strlen(msg); | |
loraSerial.print("mac tx cnf 1 "); | |
for (int i = 0; i < len; i++) { | |
loraSerial.print(msg[i], HEX); | |
} | |
loraSerial.println(); | |
Serial.println("Message was sent"); | |
} | |
void sendRadioMsg(String msg) | |
{ | |
char charBuf[200]; | |
msg.toCharArray(charBuf, 200); | |
sendRadioMsgBuffer(charBuf); | |
} | |
void errorLoop() | |
{ | |
while (true) | |
{ | |
digitalWrite(ledPin, HIGH); | |
delay(1000); | |
digitalWrite(ledPin, LOW); | |
delay(1000); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Děkuji !
I start reading those links with much interest.