mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-24 17:32:18 +00:00
WIP on #124
This commit is contained in:
parent
101eef5495
commit
c2be6c4068
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -52,6 +52,7 @@
|
|||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"Blox",
|
"Blox",
|
||||||
"Meshtastic",
|
"Meshtastic",
|
||||||
|
"NEMAGPS",
|
||||||
"Ublox",
|
"Ublox",
|
||||||
"descs",
|
"descs",
|
||||||
"protobufs"
|
"protobufs"
|
||||||
|
@ -24,6 +24,7 @@ Minimum items needed to make sure hardware is good.
|
|||||||
|
|
||||||
Needed to be fully functional at least at the same level of the ESP32 boards. At this point users would probably want them.
|
Needed to be fully functional at least at the same level of the ESP32 boards. At this point users would probably want them.
|
||||||
|
|
||||||
|
- stop polling for GPS characters, instead stay blocked on read in a thread
|
||||||
- increase preamble length? - will break other clients? so all devices must update
|
- increase preamble length? - will break other clients? so all devices must update
|
||||||
- enable BLE DFU somehow
|
- enable BLE DFU somehow
|
||||||
- set appversion/hwversion
|
- set appversion/hwversion
|
||||||
|
@ -74,6 +74,7 @@ lib_deps =
|
|||||||
https://github.com/meshtastic/arduino-fsm.git
|
https://github.com/meshtastic/arduino-fsm.git
|
||||||
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git
|
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git
|
||||||
https://github.com/meshtastic/RadioLib.git
|
https://github.com/meshtastic/RadioLib.git
|
||||||
|
https://github.com/meshtastic/TinyGPSPlus.git
|
||||||
|
|
||||||
; Common settings for ESP targes, mixin with extends = esp32_base
|
; Common settings for ESP targes, mixin with extends = esp32_base
|
||||||
[esp32_base]
|
[esp32_base]
|
||||||
|
@ -50,6 +50,24 @@ void perhapsSetRTC(const struct timeval *tv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void perhapsSetRTC(struct tm &t)
|
||||||
|
{
|
||||||
|
/* 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).
|
||||||
|
*/
|
||||||
|
time_t res = mktime(&t);
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = res;
|
||||||
|
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
|
||||||
|
|
||||||
|
DEBUG_MSG("Got time from GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec);
|
||||||
|
if (t.tm_year < 0 || t.tm_year >= 300)
|
||||||
|
DEBUG_MSG("Ignoring invalid GPS time\n");
|
||||||
|
else
|
||||||
|
perhapsSetRTC(&tv);
|
||||||
|
}
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
uint32_t getTime()
|
uint32_t getTime()
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
|
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
|
||||||
void perhapsSetRTC(const struct timeval *tv);
|
void perhapsSetRTC(const struct timeval *tv);
|
||||||
|
void perhapsSetRTC(struct tm &t);
|
||||||
|
|
||||||
/// Return time since 1970 in secs. Until we have a GPS lock we will be returning time based at zero
|
/// Return time since 1970 in secs. Until we have a GPS lock we will be returning time based at zero
|
||||||
uint32_t getTime();
|
uint32_t getTime();
|
||||||
@ -37,7 +38,10 @@ class GPS : public Observable<void *>
|
|||||||
/**
|
/**
|
||||||
* Returns true if we succeeded
|
* Returns true if we succeeded
|
||||||
*/
|
*/
|
||||||
virtual bool setup() = 0;
|
virtual bool setup() { return true; }
|
||||||
|
|
||||||
|
/// A loop callback for subclasses that need it. FIXME, instead just block on serial reads
|
||||||
|
virtual void loop() {}
|
||||||
|
|
||||||
/// Returns ture if we have acquired GPS lock.
|
/// Returns ture if we have acquired GPS lock.
|
||||||
bool hasLock() const { return hasValidLocation; }
|
bool hasLock() const { return hasValidLocation; }
|
||||||
|
56
src/gps/NEMAGPS.cpp
Normal file
56
src/gps/NEMAGPS.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include "NEMAGPS.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NEMAGPS::loop()
|
||||||
|
{
|
||||||
|
while (_serial_gps.available() > 0) {
|
||||||
|
int c = _serial_gps.read();
|
||||||
|
Serial.write(c);
|
||||||
|
reader.encode(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reader.altitude.isUpdated() || reader.location.isUpdated()) { // probably get updated at the same time
|
||||||
|
if (reader.altitude.isValid())
|
||||||
|
altitude = reader.altitude.meters();
|
||||||
|
|
||||||
|
auto loc = reader.location;
|
||||||
|
if (loc.isValid()) {
|
||||||
|
latitude = toDegInt(loc.rawLat());
|
||||||
|
longitude = toDegInt(loc.rawLng());
|
||||||
|
}
|
||||||
|
|
||||||
|
// expect gps pos lat=37.520825, lon=-122.309162, alt=158
|
||||||
|
DEBUG_MSG("new NEMA GPS pos lat=%f, lon=%f, alt=%d\n", latitude * 1e-7, longitude * 1e-7, altitude);
|
||||||
|
|
||||||
|
hasValidLocation = (latitude != 0) || (longitude != 0); // bogus lat lon is reported as 0,0
|
||||||
|
if (hasValidLocation)
|
||||||
|
notifyObservers(NULL);
|
||||||
|
}
|
||||||
|
}
|
19
src/gps/NEMAGPS.h
Normal file
19
src/gps/NEMAGPS.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GPS.h"
|
||||||
|
#include "Observer.h"
|
||||||
|
#include "PeriodicTask.h"
|
||||||
|
#include "TinyGPS++.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A gps class thatreads from a NEMA GPS stream (and FIXME - eventually keeps the gps powered down except when reading)
|
||||||
|
*
|
||||||
|
* When new data is available it will notify observers.
|
||||||
|
*/
|
||||||
|
class NEMAGPS : public GPS
|
||||||
|
{
|
||||||
|
TinyGPSPlus reader;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void loop();
|
||||||
|
};
|
@ -9,8 +9,6 @@ UBloxGPS::UBloxGPS() : PeriodicTask()
|
|||||||
|
|
||||||
bool UBloxGPS::setup()
|
bool UBloxGPS::setup()
|
||||||
{
|
{
|
||||||
PeriodicTask::setup();
|
|
||||||
|
|
||||||
#ifdef GPS_RX_PIN
|
#ifdef GPS_RX_PIN
|
||||||
_serial_gps.begin(GPS_BAUDRATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
|
_serial_gps.begin(GPS_BAUDRATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
|
||||||
#else
|
#else
|
||||||
@ -30,18 +28,18 @@ bool UBloxGPS::setup()
|
|||||||
if (isConnected) {
|
if (isConnected) {
|
||||||
DEBUG_MSG("Connected to UBLOX GPS successfully\n");
|
DEBUG_MSG("Connected to UBLOX GPS successfully\n");
|
||||||
|
|
||||||
bool factoryReset = false;
|
bool factoryReset = true;
|
||||||
bool ok;
|
bool ok;
|
||||||
if (factoryReset) {
|
if (factoryReset) {
|
||||||
// It is useful to force back into factory defaults (9600baud, NEMA to test the behavior of boards that don't have
|
// It is useful to force back into factory defaults (9600baud, NEMA to test the behavior of boards that don't have
|
||||||
// GPS_TX connected)
|
// GPS_TX connected)
|
||||||
ublox.factoryReset();
|
ublox.factoryReset();
|
||||||
delay(2000);
|
delay(3000);
|
||||||
isConnected = ublox.begin(_serial_gps);
|
isConnected = ublox.begin(_serial_gps);
|
||||||
DEBUG_MSG("Factory reset success=%d\n", isConnected);
|
DEBUG_MSG("Factory reset success=%d\n", isConnected);
|
||||||
if (isConnected) {
|
ok = ublox.saveConfiguration(3000);
|
||||||
ublox.assumeAutoPVT(true, true); // Just parse NEMA for now
|
assert(ok);
|
||||||
}
|
return false;
|
||||||
} else {
|
} else {
|
||||||
ok = ublox.setUART1Output(COM_TYPE_UBX, 500); // Use native API
|
ok = ublox.setUART1Output(COM_TYPE_UBX, 500); // Use native API
|
||||||
assert(ok);
|
assert(ok);
|
||||||
@ -57,12 +55,10 @@ bool UBloxGPS::setup()
|
|||||||
ok = ublox.saveConfiguration(3000);
|
ok = ublox.saveConfiguration(3000);
|
||||||
assert(ok);
|
assert(ok);
|
||||||
|
|
||||||
|
PeriodicTask::setup(); // We don't start our periodic task unless we actually found the device
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all. Just
|
|
||||||
// assume NEMA at 9600 baud.
|
|
||||||
DEBUG_MSG("ERROR: No bidirectional GPS found, hoping that it still might work\n");
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,26 +76,24 @@ void UBloxGPS::doTask()
|
|||||||
{
|
{
|
||||||
uint8_t fixtype = 3; // If we are only using the RX pin, assume we have a 3d fix
|
uint8_t fixtype = 3; // If we are only using the RX pin, assume we have a 3d fix
|
||||||
|
|
||||||
if (isConnected) {
|
assert(isConnected);
|
||||||
// Consume all characters that have arrived
|
|
||||||
|
|
||||||
// getPVT automatically calls checkUblox
|
// Consume all characters that have arrived
|
||||||
ublox.checkUblox(); // See if new data is available. Process bytes as they come in.
|
|
||||||
|
|
||||||
// If we don't have a fix (a quick check), don't try waiting for a solution)
|
// getPVT automatically calls checkUblox
|
||||||
// Hmmm my fix type reading returns zeros for fix, which doesn't seem correct, because it is still sptting out positions
|
ublox.checkUblox(); // See if new data is available. Process bytes as they come in.
|
||||||
// turn off for now
|
|
||||||
// fixtype = ublox.getFixType();
|
// If we don't have a fix (a quick check), don't try waiting for a solution)
|
||||||
DEBUG_MSG("fix type %d\n", fixtype);
|
// Hmmm my fix type reading returns zeros for fix, which doesn't seem correct, because it is still sptting out positions
|
||||||
}
|
// turn off for now
|
||||||
|
// fixtype = ublox.getFixType();
|
||||||
|
DEBUG_MSG("fix type %d\n", fixtype);
|
||||||
|
|
||||||
// DEBUG_MSG("sec %d\n", ublox.getSecond());
|
// DEBUG_MSG("sec %d\n", ublox.getSecond());
|
||||||
// DEBUG_MSG("lat %d\n", ublox.getLatitude());
|
// DEBUG_MSG("lat %d\n", ublox.getLatitude());
|
||||||
|
|
||||||
// any fix that has time
|
// any fix that has time
|
||||||
if (ublox.getT()) {
|
if (ublox.getT()) {
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
/* Convert to unix time
|
/* 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
|
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).
|
(midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
|
||||||
@ -112,15 +106,7 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
|
|||||||
t.tm_mon = ublox.getMonth() - 1;
|
t.tm_mon = ublox.getMonth() - 1;
|
||||||
t.tm_year = ublox.getYear() - 1900;
|
t.tm_year = ublox.getYear() - 1900;
|
||||||
t.tm_isdst = false;
|
t.tm_isdst = false;
|
||||||
time_t res = mktime(&t);
|
perhapsSetRTC(t);
|
||||||
tv.tv_sec = res;
|
|
||||||
tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
|
|
||||||
|
|
||||||
DEBUG_MSG("Got time from GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec);
|
|
||||||
if (t.tm_year < 0 || t.tm_year >= 300)
|
|
||||||
DEBUG_MSG("Ignoring invalid GPS time\n");
|
|
||||||
else
|
|
||||||
perhapsSetRTC(&tv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fixtype >= 3 && fixtype <= 4) && ublox.getP()) // rd fixes only
|
if ((fixtype >= 3 && fixtype <= 4) && ublox.getP()) // rd fixes only
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "MeshRadio.h"
|
#include "MeshRadio.h"
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
|
#include "NEMAGPS.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "Periodic.h"
|
#include "Periodic.h"
|
||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
@ -193,7 +194,12 @@ void setup()
|
|||||||
// Init GPS - first try ublox
|
// Init GPS - first try ublox
|
||||||
gps = new UBloxGPS();
|
gps = new UBloxGPS();
|
||||||
if (!gps->setup()) {
|
if (!gps->setup()) {
|
||||||
// FIXME - fallback to NEMA
|
// Some boards might have only the TX line from the GPS connected, in that case, we can't configure it at all. Just
|
||||||
|
// assume NEMA at 9600 baud.
|
||||||
|
DEBUG_MSG("ERROR: No UBLOX GPS found, hoping that NEMA might work\n");
|
||||||
|
delete gps;
|
||||||
|
gps = new NEMAGPS();
|
||||||
|
gps->setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
service.init();
|
service.init();
|
||||||
@ -263,6 +269,7 @@ void loop()
|
|||||||
{
|
{
|
||||||
uint32_t msecstosleep = 1000 * 30; // How long can we sleep before we again need to service the main loop?
|
uint32_t msecstosleep = 1000 * 30; // How long can we sleep before we again need to service the main loop?
|
||||||
|
|
||||||
|
gps->loop(); // FIXME, remove from main, instead block on read
|
||||||
router.loop();
|
router.loop();
|
||||||
powerFSM.run_machine();
|
powerFSM.run_machine();
|
||||||
service.loop();
|
service.loop();
|
||||||
|
Loading…
Reference in New Issue
Block a user