meshtastic-firmware/src/gps/NMEAGPS.cpp

138 wiersze
4.7 KiB
C++
Czysty Zwykły widok Historia

#include "NMEAGPS.h"
2020-05-05 00:39:57 +00:00
#include "configuration.h"
/*
Helpful translations from the Air530 GPS datasheet
Sat acquision mode
@3.3v 42.6 mA
sat tracking mode
@3.3v 36.7 mA
Low power mode
@3.3V 0.85 mA
(:$PGKC051,0)
Super low power mode
@3.3V 31 uA
(:$PGKC105,4)
To exit sleep use WAKE pin
Commands to enter sleep
6Command: 105
Arguments:
Arg1: 0, (normal mode)
1,, WAKE (periodic low power tracking mode - keeps sat positions, use wake to wake up)
2, (periodic low power mode)
4,, WAKE (super low power consumption mode immediately, need WAKE to resume)
8,, (automatic low power mode, wake by sending characters to serial port)
9, , WAKE (automatic low power tracking when possible, need wake pin to resume)
(Arg 2 & 3 only valid if Arg1 is "1" or "2")
Arg2:(), Arg1 12 ,
ON time in msecs
Arg3:(), Arg1 12 ,
Sleep time in msecs
Example:
$PGKC105,8*3F<CR><LF>
This will set automatic low power mode with waking when we send chars to the serial port. Possibly do this as soon as we get a new
location. When we wake again in a minute we send a character to wake up.
*/
2020-05-05 00:39:57 +00:00
static int32_t toDegInt(RawDegrees d)
{
int32_t degMult = 10000000; // 1e7
int32_t r = d.deg * degMult + d.billionths / 100;
if (d.negative)
r *= -1;
return r;
}
2020-09-25 16:14:00 +00:00
bool NMEAGPS::setup()
{
2020-09-26 16:40:48 +00:00
#ifdef PIN_GPS_PPS
// pulse per second
// FIXME - move into shared GPS code
pinMode(PIN_GPS_PPS, INPUT);
#endif
2020-09-25 16:14:00 +00:00
return true;
}
void NMEAGPS::loop()
2020-05-05 00:39:57 +00:00
{
while (_serial_gps->available() > 0) {
int c = _serial_gps->read();
// DEBUG_MSG("%c", c);
bool isValid = reader.encode(c);
// if we have received valid NMEA claim we are connected
if (isValid)
isConnected = true;
2020-05-05 00:39:57 +00:00
}
uint32_t now = millis();
if ((now - lastUpdateMsec) > 20 * 1000) { // Ugly hack for now - limit update checks to once every 20 secs (but still consume
// serial chars at whatever rate)
lastUpdateMsec = now;
2020-05-05 00:39:57 +00:00
auto ti = reader.time;
auto d = reader.date;
if (ti.isUpdated() && ti.isValid() && d.isValid()) {
/* Convert to unix time
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970
(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
*/
struct tm t;
t.tm_sec = ti.second();
t.tm_min = ti.minute();
t.tm_hour = ti.hour();
t.tm_mday = d.day();
t.tm_mon = d.month() - 1;
t.tm_year = d.year() - 1900;
t.tm_isdst = false;
perhapsSetRTC(t);
2020-05-05 00:39:57 +00:00
}
uint8_t fixtype = reader.fixQuality();
hasValidLocation = ((fixtype >= 1) && (fixtype <= 5));
if (reader.location.isUpdated()) {
if (reader.altitude.isValid())
altitude = reader.altitude.meters();
if (reader.location.isValid()) {
auto loc = reader.location.value();
latitude = toDegInt(loc.lat);
longitude = toDegInt(loc.lng);
}
2020-06-21 01:59:41 +00:00
// Diminution of precision (an accuracy metric) is reported in 10^2 units, so we need to scale down when we use it
if (reader.hdop.isValid()) {
2020-06-21 01:59:41 +00:00
dop = reader.hdop.value();
}
if (reader.course.isValid()) {
heading =
reader.course.value() * 1e3; // Scale the heading (in degrees * 10^-2) to match the expected degrees * 10^-5
}
if (reader.satellites.isValid()) {
numSatellites = reader.satellites.value();
}
2020-05-05 00:39:57 +00:00
// expect gps pos lat=37.520825, lon=-122.309162, alt=158
DEBUG_MSG("new NMEA GPS pos lat=%f, lon=%f, alt=%d, hdop=%g, heading=%f\n", latitude * 1e-7, longitude * 1e-7,
altitude, dop * 1e-2, heading * 1e-5);
}
2020-06-29 01:17:52 +00:00
// Notify any status instances that are observing us
const meshtastic::GPSStatus status =
meshtastic::GPSStatus(hasLock(), isConnected, latitude, longitude, altitude, dop, heading, numSatellites);
2020-06-29 01:17:52 +00:00
newStatus.notifyObservers(&status);
2020-05-05 00:39:57 +00:00
}
}