Skip to content

Instantly share code, notes, and snippets.

@nobodyguy
Last active September 21, 2022 03:13
Show Gist options
  • Save nobodyguy/7920482dd00f300b973126f9d7188db4 to your computer and use it in GitHub Desktop.
Save nobodyguy/7920482dd00f300b973126f9d7188db4 to your computer and use it in GitHub Desktop.
GpsLoRaWANTracker using Arduino, RN2483 and L86/neo-m8n GPS module
#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);
}
}
@Jeannotisintheplace
Copy link

Děkuji !

I start reading those links with much interest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment