#include <SPI.h>
#include <LoRa.h>
#include <Ethernet.h>
#include <NMEAGPS.h>
#define CALLSIGN "YOURCALL"
#define LED 13
#define gpsPort Serial1
// Packet ID counter
byte counter = 0;
NMEAGPS gps; // SPG parsing
gps_fix fix; // Current GPS data
// Current position sent in decimal degrees x 10^7
// East and North are positive
// This fits nicely in a 32-bit signed integer
int32_t lat;
int32_t lon;
unsigned long xmitTime; // Track when we sent a packet
char packet[255]; // Storage to build packet
int pktLen; // packet length in bytes
void setup() {
// Shut off LED to save power
digitalWrite(LED, LOW);
Serial.begin(115200);
// Give usb serial time to start
// delay(5000)
Serial.println("LoRa Sender Starting");
// Setup radio
LoRa.setPins(8,4,3);
// Don't run if LoRa setup fails
if (!LoRa.begin(434E6)) {
Serial.println("Starting LoRa failed!");
// Long blink forever if radio doesn't start
while (1) {
digitalWrite(LED, HIGH);
delay(900);
digitalWrite(LED, LOW);
delay(100);
}
}
// Radio parameters
LoRa.setTxPower(2);
LoRa.setSpreadingFactor(12);
LoRa.setSignalBandwidth(62.5E3);
LoRa.setCodingRate4(5);
//LoRa.setSyncWord(0x12);
//LoRa.enableCrc();
// Setup GPS
Serial.println("GPS starting");
gpsPort.begin(9600);
Serial.println("Ready");
}
void loop() {
// Process any GPS data waiting in buffer
while (gps.available( gpsPort )) {
fix = gps.read();
}
// If we have a valid location fix then transmit it otherwise
// we fall through and the loop will restart immedietly and poll the GPS again.
if ( fix.valid.location ) {
Serial.println();
Serial.print("Lat: ");
Serial.print( fix.latitude(), 6 );
Serial.print(" Lat: ");
Serial.print( fix.longitude(), 6 );
Serial.println();
// Build the (binary) packet
// The callsign is ASCII so we can strncpy() it
// 11 bytes for flags,type,counter,lat,lon
strncpy(packet, CALLSIGN, sizeof(packet)- 11);
int pktLen = strlen(packet);
packet[pktLen++] = 0x00; // flags: end of callsign
packet[pktLen++] = 0x01; // type: position
packet[pktLen++] = counter++; // packet ID
// Convert to network byte order
// TODO: test and only do this when necessary, but on Cortex M0 it is.
lat = __builtin_bswap32(fix.latitudeL());
lon = __builtin_bswap32(fix.longitudeL());
// Insert lan/lon
// TODO: test to make sure there are enough bytes left in packet[]
// although that should never happen unless CALLSIGN is rediculous
memcpy(&packet[pktLen], &lat, 4);
pktLen += 4;
memcpy(&packet[pktLen], &lon, 4);
pktLen += 4;
// Setup FIFO in radio for next packet
LoRa.beginPacket();
LoRa.write((uint8_t *)packet, pktLen);
// Send the packet
// Turn on LED while we transmit
// Timestamps for trasmitter on time
digitalWrite(LED, HIGH);
LoRa.endPacket();
digitalWrite(LED, LOW);
// Put radio into lower power sleep mode
LoRa.sleep();
// Wait 60 sec before we continue.
// This will report position every 60 seconds (at most)
// We can power down radio, deepsleep microcontroller
// and put GPS in low power mode here to save power
// instead of delay()
delay(60000);
}
}
(coming soon)
(coming soon)