-
-
Save nobodyguy/7920482dd00f300b973126f9d7188db4 to your computer and use it in GitHub Desktop.
#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); | |
} | |
} |
Are you interessted to make a project in this context together? I want to make a replacement of the old APRS over HAM Radios. LoRa is cheaper and in comparision to RF output got more possible distance.
Nice, thanks for sharing.
Sure, no problem. What problem does your project solve?
My use case is pretty straightforward:
General GPS tracker as small as possible. My plan is to use it for tracking my dog or bike. GPS should be powered off when I don't need it (and can be enabled via web interface).
I have a working prototype (including web interface where you can see map with position checkpoints and configuration interface for enabling GPS, changing reporting interval, etc.), but I'm struggling with a few weird bugs of local LoRaWAN network (Czech Republic). Right now I'm testing a few Sigfox and old fashioned GPRS modules.
Mine is not so different. I also want to make everything small as possible to be able to put it in everything.
(Funny idea to track an animal, maybe i could figure out where my cat goes in the night Oo)
But my main goal is to build dropable sensors to meassure tide information on lakes, temp, salt and water height.
Im really interessted in your web interface! My current progress is just to log the positions to a .gpx file... (With horrible bugs, but you cant expect from a E-ing high quality java code, but im future using aprs solves all my problems because then im using excisting APRS software)
But if we implement APRS we could use Software like SARTrack to collect gps location information, weather, etc. Pls check out http://www.cbaprs.de/
You can simply push data to cbaprs using telnet. Im trying to implement telnet in this project:
https://github.com/CongducPham/LowCostLoRaGw
I think APRS is excactly what we both want.
Interesting (and lowtech) project @nobodyguy
Would you be like sharing the circuit connections between board,gps and RNJ2483 as well by any chance?
(I would love to try to replicate to train on ARDUINO).
Interesting (and lowtech) project @nobodyguy
Would you be like sharing the circuit connections between board,gps and RNJ2483 as well by any chance?
(I would love to try to replicate to train on ARDUINO).
Bonjour Jean, I don't really have the project assembled anymore, but I'm sure it was heavily inspired by these resources: https://www.disk91.com/2016/technology/internet-of-things-technology/simple-lora-gps-tracker-based-on-rn2483-and-l80/
https://github.com/hidnseek/hidnseek
https://github.com/ttnmapper/ttntrackernode
Děkuji !
I start reading those links with much interest.
Thank you very much for sharing. As id saw, id always missunderstood sprintf.
Im using SPI to communicate with my LoRa module.