Added NMEA passthrough for GPS attached to marauder to be available on serial port, such as to flipper apps that use UART GPS, as long as they do 115200.

This commit is contained in:
Kragg Malak
2023-11-26 11:26:18 -07:00
parent 7a79860b17
commit c4af8003de
6 changed files with 310 additions and 7 deletions

View File

@@ -2,6 +2,8 @@
#ifdef HAS_GPS
extern GpsInterface gps_obj;
char nmeaBuffer[100];
MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer));
@@ -33,6 +35,170 @@ void GpsInterface::begin() {
while (Serial2.available())
Serial2.read();
}
this->queue_enabled_flag=0;
this->queue=NULL;
this->new_queue();
nmea.setUnknownSentenceHandler(gps_nmea_notimp);
}
//passthrough for other objects
void gps_nmea_notimp(MicroNMEA& nmea){
gps_obj.enqueue(nmea);
}
void GpsInterface::enqueue(MicroNMEA& nmea){
String nmea_sentence = String(nmea.getSentence());
if(nmea_sentence != ""){
this->notimp_nmea_sentence = nmea_sentence;
if(this->queue_enabled_flag){
if(!this->queue) this->new_queue();
this->queue->add(String(nmea_sentence));
}
}
}
void GpsInterface::enable_queue(){
this->flush_queue();
this->queue_enabled_flag=1;
}
void GpsInterface::disable_queue(){
this->queue_enabled_flag=0;
this->flush_queue();
}
bool GpsInterface::queue_enabled(){
return this->queue_enabled_flag;
}
LinkedList<String>* GpsInterface::get_queue(){
return this->queue;
}
void GpsInterface::new_queue(){
this->queue=new LinkedList<String>;
}
void GpsInterface::flush_queue(){
if(this->queue) delete this->queue;
this->new_queue();
}
void GpsInterface::sendSentence(const char* sentence){
MicroNMEA::sendSentence(Serial2, sentence);
}
void GpsInterface::sendSentence(Stream &s, const char* sentence){
MicroNMEA::sendSentence(s, sentence);
}
void GpsInterface::setType(String t){
if(t == "gps")
this->type_flag=GPSTYPE_GPS;
else if(t == "glonass")
this->type_flag=GPSTYPE_GLONASS;
else if(t == "galileo")
this->type_flag=GPSTYPE_GALILEO;
else
this->type_flag=GPSTYPE_ALL;
}
const char* GpsInterface::generateGXgga(){
String msg_type="$G";
if(this->type_flag == GPSTYPE_GPS)
msg_type+='P';
else if(this->type_flag == GPSTYPE_GLONASS)
msg_type+='L';
else if(this->type_flag == GPSTYPE_GALILEO)
msg_type+='A';
else
msg_type+='N';
msg_type+="GGA,";
char timeStr[8];
sprintf(timeStr, "%02d%02d%02d,", (int)(nmea.getHour()), (int)(nmea.getMinute()), (int)(nmea.getSecond()));
long lat = nmea.getLatitude();
char latDir = lat < 0 ? 'S' : 'N';
lat = abs(lat);
char latStr[12];
sprintf(latStr, "%02ld%08.5f,", lat / 1000000, ((lat % 1000000)*60) / 1000000.0);
long lon = nmea.getLongitude();
char lonDir = lon < 0 ? 'W' : 'E';
lon = abs(lon);
char lonStr[13];
sprintf(lonStr, "%03ld%08.5f,", lon / 1000000, ((lon % 1000000)*60) / 1000000.0);
int fixQuality = nmea.isValid() ? 1 : 0;
char fixStr[3];
sprintf(fixStr, "%01d,", fixQuality);
int numSatellites = nmea.getNumSatellites();
char satStr[4];
sprintf(satStr, "%02d,", numSatellites);
unsigned long hdop = nmea.getHDOP();
char hdopStr[14];
sprintf(hdopStr, "%01.2f,", 2.5 * (((float)(hdop))/10));
long altitude;
if(!nmea.getAltitude(altitude)) altitude=0;
char altStr[14];
sprintf(altStr, "%01.1f,", altitude/1000.0);
String message = msg_type + timeStr + latStr + latDir + "," + lonStr + lonDir +
"," + fixStr + satStr + hdopStr + altStr + "M,,M,,";
return message.c_str();
}
const char* GpsInterface::generateGXrmc(){
String msg_type="$G";
if(this->type_flag == GPSTYPE_GPS)
msg_type+='P';
else if(this->type_flag == GPSTYPE_GLONASS)
msg_type+='L';
else if(this->type_flag == GPSTYPE_GALILEO)
msg_type+='A';
else
msg_type+='N';
msg_type+="RMC,";
char timeStr[8];
sprintf(timeStr, "%02d%02d%02d,", (int)(nmea.getHour()), (int)(nmea.getMinute()), (int)(nmea.getSecond()));
char dateStr[8];
sprintf(dateStr, "%02d%02d%02d,", (int)(nmea.getDay()), (int)(nmea.getMonth()), (int)(nmea.getYear()%100));
char status = nmea.isValid() ? 'A' : 'V';
char mode = nmea.isValid() ? 'A' : 'N';
long lat = nmea.getLatitude();
char latDir = lat < 0 ? 'S' : 'N';
lat = abs(lat);
char latStr[12];
sprintf(latStr, "%02ld%08.5f,", lat / 1000000, ((lat % 1000000)*60) / 1000000.0);
long lon = nmea.getLongitude();
char lonDir = lon < 0 ? 'W' : 'E';
lon = abs(lon);
char lonStr[13];
sprintf(lonStr, "%03ld%08.5f,", lon / 1000000, ((lon % 1000000)*60) / 1000000.0);
char speedStr[14];
sprintf(speedStr, "%01.1f,", nmea.getSpeed() / 1000.0);
char courseStr[14];
sprintf(courseStr, "%01.1f,", nmea.getCourse() / 1000.0);
String message = msg_type + timeStr + status + "," + latStr + latDir + "," +
lonStr + lonDir + "," + speedStr + courseStr + dateStr + ",," + mode;
return message.c_str();
}
// Thanks JosephHewitt
@@ -56,6 +222,9 @@ String GpsInterface::dt_string_from_gps(){
}
void GpsInterface::setGPSInfo() {
String nmea_sentence = String(nmea.getSentence());
if(nmea_sentence != "") this->nmea_sentence = nmea_sentence;
this->good_fix = nmea.isValid();
this->num_sats = nmea.getNumSatellites();
@@ -113,6 +282,14 @@ bool GpsInterface::getGpsModuleStatus() {
return this->gps_enabled;
}
String GpsInterface::getNmea() {
return this->nmea_sentence;
}
String GpsInterface::getNmeaNotimp() {
return this->notimp_nmea_sentence;
}
void GpsInterface::main() {
while (Serial2.available()) {
//Fetch the character one by one