Last active
May 4, 2020 16:58
-
-
Save bprobbins/d1f3b160add0e64ce0f5f8a3a55a36a9 to your computer and use it in GitHub Desktop.
Arduino code for Adafruit M0 radio
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
/* | |
Basic client for Adafruit Feather LoRa radios. | |
This is based on the RadioHead library for RF95, but has all | |
the required pins and setup for Feather LoRa's. | |
NOTE: You need to select a unique radio address for this to work | |
*/ | |
#include <Adafruit_GPS.h> | |
#include <RHReliableDatagram.h> | |
#include <RH_RF95.h> | |
#include <SPI.h> | |
#include <avr/dtostrf.h> //REQUIRED to enable use of dtostrf for SAMD | |
// Unique client address can be any number from 0-255 (as HEX) | |
#define CLIENT_ADDRESS 1 | |
#define SERVER_ADDRESS 2 | |
//below is for Feather M0 | |
#define RFM95_CS 8 | |
#define RFM95_RST 4 | |
#define RFM95_INT 3 // Feather LoRa M0 = 3, Feather LoRa 32U4 = 7 | |
#define RF95_FREQ 915.0 | |
#define VBATPIN A7 //AKA D9 | |
// Singleton instance of the radio driver | |
RH_RF95 driver(RFM95_CS, RFM95_INT); | |
// Class to manage message delivery and receipt, using the driver declared above | |
RHReliableDatagram manager(driver, CLIENT_ADDRESS); | |
// what's the name of the hardware serial port? | |
#define GPSSerial Serial1 | |
// Connect to the GPS on the hardware port | |
Adafruit_GPS GPS(&GPSSerial); | |
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console | |
// Set to 'true' if you want to debug and listen to the raw GPS sentences | |
#define GPSECHO false | |
uint32_t timer = millis(); | |
char data[20]; | |
// Dont put this on the stack: | |
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN]; | |
void setup() | |
{ | |
pinMode(VBATPIN,INPUT); | |
pinMode(RFM95_RST, OUTPUT); | |
digitalWrite(RFM95_RST, HIGH); | |
Serial.begin(115200) ; //9600); | |
// manual reset | |
digitalWrite(RFM95_RST, LOW); | |
delay(10); | |
digitalWrite(RFM95_RST, HIGH); | |
delay(10); | |
while (!manager.init()) { | |
Serial.println("Datagram init failed"); | |
while (1); | |
} | |
Serial.println("Datagram init OK!"); | |
if (!driver.setFrequency(RF95_FREQ)) { | |
Serial.println("setFrequency failed"); | |
while (1); | |
} | |
Serial.print("Set Freq to: "); Serial.println(RF95_FREQ); | |
// The default transmitter power is 13dBm, using PA_BOOST. | |
driver.setTxPower(23, false); | |
// 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800 | |
GPS.begin(9600); | |
// uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude | |
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); | |
// uncomment this line to turn on only the "minimum recommended" data | |
//GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY); | |
// For parsing data, we don't suggest using anything but either RMC only or RMC+GGA since | |
// the parser doesn't care about other sentences at this time | |
// Set the update rate | |
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate | |
// For the parsing code to work nicely and have time to sort thru the data, and | |
// print it out we don't suggest using anything higher than 1 Hz | |
// Request updates on antenna status, comment out to keep quiet | |
// GPS.sendCommand(PGCMD_ANTENNA); | |
delay(1000); | |
// Ask for firmware version | |
GPSSerial.println(PMTK_Q_RELEASE); | |
}//setup | |
unsigned long packetnum = 0; // packet counter, we increment per xmission | |
char BATstr[11]; | |
char LATstr[12]; | |
char LONstr[12]; | |
char ALTstr[12]; | |
byte sendLen; | |
char radiopacket[100]; | |
double myfLAT; | |
double myfLON; | |
void loop() | |
{ | |
// read data from the GPS in the 'main loop' | |
char c = GPS.read(); | |
// if you want to debug, this is a good time to do it! | |
if (GPSECHO) | |
if (c) Serial.print(c); | |
// if a sentence is received, we can check the checksum, parse it... | |
if (GPS.newNMEAreceived()) { | |
// a tricky thing here is if we print the NMEA sentence, or data | |
// we end up not listening and catching other sentences! | |
// so be very wary if using OUTPUT_ALLDATA and trying to print out data | |
Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false | |
if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false | |
return; // we can fail to parse a sentence in which case we should just wait for another | |
} | |
// if millis() or timer wraps around, we'll just reset it | |
if (timer > millis()) timer = millis(); | |
// approximately every 2 seconds or so, print out the current stats | |
if (millis() - timer >10000) { //2000 | |
timer = millis(); // reset the timer | |
/* | |
Serial.print("\nTime: "); | |
if (GPS.hour < 10) { Serial.print('0'); } | |
Serial.print(GPS.hour, DEC); Serial.print(':'); | |
if (GPS.minute < 10) { Serial.print('0'); } | |
Serial.print(GPS.minute, DEC); Serial.print(':'); | |
if (GPS.seconds < 10) { Serial.print('0'); } | |
Serial.print(GPS.seconds, DEC); Serial.print('.'); | |
if (GPS.milliseconds < 10) { | |
Serial.print("00"); | |
} else if (GPS.milliseconds > 9 && GPS.milliseconds < 100) { | |
Serial.print("0"); | |
} | |
Serial.println(GPS.milliseconds); | |
Serial.print("Date: "); | |
Serial.print(GPS.day, DEC); Serial.print('/'); | |
Serial.print(GPS.month, DEC); Serial.print("/20"); | |
Serial.println(GPS.year, DEC); | |
Serial.print("Fix: "); Serial.print((int)GPS.fix); | |
Serial.print(" quality: "); Serial.println((int)GPS.fixquality); | |
*/ | |
if (GPS.fix) { | |
Serial.print("Location: "); | |
Serial.print(GPS.latitude, 4); Serial.print(GPS.lat); | |
Serial.print(", "); | |
Serial.print(GPS.longitude, 4); Serial.println(GPS.lon); | |
Serial.print("Speed (knots): "); Serial.println(GPS.speed); | |
Serial.print("Angle: "); Serial.println(GPS.angle); | |
Serial.print("Altitude: "); Serial.println(GPS.altitude); | |
Serial.print("Satellites: "); Serial.println((int)GPS.satellites); | |
packetnum++; | |
float measuredvbat = analogRead(VBATPIN); | |
measuredvbat *= 2; // we divided by 2, so multiply back | |
measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage | |
measuredvbat /= 1024; // convert to voltage | |
dtostrf(GPS.latitudeDegrees,4,6, LATstr); | |
dtostrf(GPS.longitudeDegrees,4,6, LONstr); | |
dtostrf(measuredvbat,3,2, BATstr); | |
dtostrf(GPS.altitude * 3.2808,4,4, ALTstr); //for alt in feet | |
Serial.print("LATstr"); Serial.println(LATstr); | |
Serial.print("LONstr"); Serial.println(LONstr); | |
snprintf(radiopacket, sizeof(radiopacket), | |
"vBAT:,%s,LAT:,%s,%c,LON:,%s,%c,SATS:,%i,ALT:,%s,%u", | |
BATstr, LATstr, GPS.lat, LONstr, GPS.lon, (int)GPS.satellites, ALTstr, packetnum); | |
sendLen = strlen(radiopacket); | |
if (manager.sendtoWait((uint8_t*)radiopacket, sizeof(radiopacket), SERVER_ADDRESS)) | |
{ | |
// Now wait for a reply from the server | |
uint8_t len = sizeof(buf); | |
uint8_t from; | |
if (manager.recvfromAckTimeout(buf, &len, 2000,&from)) | |
{ | |
Serial.print("got reply from : 0x"); | |
Serial.print(from, HEX); | |
Serial.print(": "); | |
Serial.println((char*)buf); | |
} | |
else | |
{ | |
Serial.println("No reply, is rf95_reliable_datagram_server running?"); | |
} | |
// Take a random break | |
delayMicroseconds( random(300) ); | |
} | |
else | |
Serial.println("sendtoWait failed"); | |
}//if (GPS.fix) | |
}//if (millis() - timer > 2000) | |
}//loop |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment