mirror of
https://github.com/meshtastic/firmware.git
synced 2025-02-02 18:59:56 +00:00
Add NMEA output mode (my own position, and other devices as waypoints) to serial module
This commit is contained in:
parent
44529620ad
commit
d3e9dbf6a9
@ -12,6 +12,7 @@
|
||||
* 4 E or W (East or West)
|
||||
* 5 Waypoint name
|
||||
* 6 Checksum
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
uint printWPL(char *buf, Position &pos, const char *name)
|
||||
@ -24,3 +25,52 @@ uint printWPL(char *buf, Position &pos, const char *name)
|
||||
len += sprintf(buf + len, "*%02X\r\n", chk);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* -------------------------------------------
|
||||
* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
* | | | | | | | | | | | | | | |
|
||||
* $--GGA,hhmmss.ss,ddmm.mm,a,ddmm.mm,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh<CR><LF>
|
||||
*
|
||||
* Field Number:
|
||||
* 1 UTC of this position report, hh is hours, mm is minutes, ss.ss is seconds.
|
||||
* 2 Latitude
|
||||
* 3 N or S (North or South)
|
||||
* 4 Longitude
|
||||
* 5 E or W (East or West)
|
||||
* 6 GPS Quality Indicator (non null)
|
||||
* 7 Number of satellites in use, 00 - 12
|
||||
* 8 Horizontal Dilution of precision (meters)
|
||||
* 9 Antenna Altitude above/below mean-sea-level (geoid) (in meters)
|
||||
* 10 Units of antenna altitude, meters
|
||||
* 11 Geoidal separation, the difference between the WGS-84 earth ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level below ellipsoid
|
||||
* 12 Units of geoidal separation, meters
|
||||
* 13 Age of differential GPS data, time in seconds since last SC104 type 1 or 9 update, null field when DGPS is not used
|
||||
* 14 Differential reference station ID, 0000-1023
|
||||
* 15 Checksum
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
uint printGGA(char *buf, Position &pos)
|
||||
{
|
||||
uint len = sprintf(buf, "$GNGGA,%06d.%03d,%07.2f,%c,%08.2f,%c,%d,%02d,%04d,%04d,%c,%04d,%c,%d,%04d",
|
||||
pos.time / 1000,
|
||||
pos.time % 1000,
|
||||
pos.latitude_i * 1e-5, pos.latitude_i < 0 ? 'S' : 'N',
|
||||
pos.longitude_i * 1e-5, pos.longitude_i < 0 ? 'W' : 'E',
|
||||
pos.fix_type,
|
||||
pos.sats_in_view,
|
||||
pos.HDOP,
|
||||
pos.altitude,
|
||||
'M',
|
||||
pos.altitude_geoidal_separation,
|
||||
'M',
|
||||
0,
|
||||
0);
|
||||
|
||||
uint chk = 0;
|
||||
for (uint i = 1; i < len; i++) {
|
||||
chk ^= buf[i];
|
||||
}
|
||||
len += sprintf(buf + len, "*%02X\r\n", chk);
|
||||
return len;
|
||||
}
|
@ -4,3 +4,4 @@
|
||||
#include "main.h"
|
||||
|
||||
uint printWPL(char *buf, Position &pos, const char *name);
|
||||
uint printGGA(char *buf, Position &pos);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "NMEAWPL.h"
|
||||
#include "Router.h"
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
@ -40,7 +41,7 @@
|
||||
KNOWN PROBLEMS
|
||||
* Until the module is initilized by the startup sequence, the TX pin is in a floating
|
||||
state. Device connected to that pin may see this as "noise".
|
||||
* Will not work on NRF and the Linux device targets.
|
||||
* Will not work on T-Echo and the Linux device targets.
|
||||
|
||||
|
||||
*/
|
||||
@ -62,16 +63,19 @@ char serialStringChar[Constants_DATA_PAYLOAD_LEN];
|
||||
|
||||
SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio")
|
||||
{
|
||||
// restrict to the admin channel for rx
|
||||
boundChannel = Channels::serialChannel;
|
||||
|
||||
switch (moduleConfig.serial.mode)
|
||||
{
|
||||
case ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG:
|
||||
ourPortNum = PortNum_TEXT_MESSAGE_APP;
|
||||
break;
|
||||
case ModuleConfig_SerialConfig_Serial_Mode_NMEA:
|
||||
ourPortNum = PortNum_POSITION_APP;
|
||||
break;
|
||||
default:
|
||||
ourPortNum = PortNum_SERIAL_APP;
|
||||
// restrict to the serial channel for rx
|
||||
boundChannel = Channels::serialChannel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -175,15 +179,25 @@ int32_t SerialModule::runOnce()
|
||||
firstTime = 0;
|
||||
|
||||
} else {
|
||||
String serialString;
|
||||
|
||||
while (Serial2.available()) {
|
||||
serialString = Serial2.readString();
|
||||
serialString.toCharArray(serialStringChar, Constants_DATA_PAYLOAD_LEN);
|
||||
// in NMEA mode send out GGA every 2 seconds, Don't read from Port
|
||||
if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_NMEA) {
|
||||
if (millis() - lastNmeaTime > 2000) {
|
||||
lastNmeaTime = millis();
|
||||
printGGA(outbuf, nodeDB.getNode(myNodeInfo.my_node_num)->position);
|
||||
Serial2.printf("%s", outbuf);
|
||||
}
|
||||
} else {
|
||||
String serialString;
|
||||
|
||||
serialModuleRadio->sendPayload();
|
||||
while (Serial2.available()) {
|
||||
serialString = Serial2.readString();
|
||||
serialString.toCharArray(serialStringChar, Constants_DATA_PAYLOAD_LEN);
|
||||
|
||||
DEBUG_MSG("Received: %s\n", serialStringChar);
|
||||
serialModuleRadio->sendPayload();
|
||||
|
||||
DEBUG_MSG("Received: %s\n", serialStringChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,7 +205,7 @@ int32_t SerialModule::runOnce()
|
||||
} else {
|
||||
DEBUG_MSG("Serial Module Disabled\n");
|
||||
|
||||
return (INT32_MAX);
|
||||
return INT32_MAX;
|
||||
}
|
||||
#else
|
||||
return INT32_MAX;
|
||||
@ -255,6 +269,19 @@ ProcessMessage SerialModuleRadio::handleReceived(const MeshPacket &mp)
|
||||
|
||||
} else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_PROTO) {
|
||||
// TODO this needs to be implemented
|
||||
} else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_NMEA) {
|
||||
// Decode the Payload some more
|
||||
Position scratch;
|
||||
Position *decoded = NULL;
|
||||
if (mp.which_payload_variant == MeshPacket_decoded_tag && mp.decoded.portnum == ourPortNum) {
|
||||
memset(&scratch, 0, sizeof(scratch));
|
||||
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, Position_fields, &scratch)) {
|
||||
decoded = &scratch;
|
||||
}
|
||||
// send position packet as WPL to the serial port
|
||||
printWPL(outbuf, *decoded, nodeDB.getNode(getFrom(&mp))->user.long_name);
|
||||
Serial2.printf("%s", outbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
class SerialModule : private concurrency::OSThread
|
||||
{
|
||||
bool firstTime = 1;
|
||||
unsigned long lastNmeaTime = millis();
|
||||
char outbuf[90] = "";
|
||||
|
||||
public:
|
||||
SerialModule();
|
||||
@ -28,6 +30,7 @@ extern SerialModule *serialModule;
|
||||
class SerialModuleRadio : public MeshModule
|
||||
{
|
||||
uint32_t lastRxID = 0;
|
||||
char outbuf[90] = "";
|
||||
|
||||
public:
|
||||
SerialModuleRadio();
|
||||
|
Loading…
Reference in New Issue
Block a user