mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-25 17:42:48 +00:00
commit
32ea11d2af
@ -1,3 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
export VERSION=1.1.1
|
export VERSION=1.1.2
|
@ -1,4 +1,4 @@
|
|||||||
gps todo - bug 376
|
You probably don't care about this ugly file of personal notes ;-)
|
||||||
|
|
||||||
for taiwan region:
|
for taiwan region:
|
||||||
bin/run.sh --set region 8
|
bin/run.sh --set region 8
|
||||||
@ -6,40 +6,12 @@ bin/run.sh --set region 8
|
|||||||
time only mode
|
time only mode
|
||||||
./bin/run.sh --set gps_operation 3
|
./bin/run.sh --set gps_operation 3
|
||||||
|
|
||||||
increase acquisition time until ublox power management can be improved see 9.3.1
|
|
||||||
|
|
||||||
ublox parsing failure
|
ublox parsing failure
|
||||||
|
|
||||||
record power measurements and update spreadsheet
|
record power measurements and update spreadsheet
|
||||||
|
|
||||||
fix has_gps based on new logic
|
|
||||||
|
|
||||||
make sure we are turning off lora radio in deep sleep
|
|
||||||
|
|
||||||
don't send locations if the user has forbidden that (lie to phone so phone won't either)
|
|
||||||
|
|
||||||
have loop methods return allowable sleep time (from their perspective)
|
have loop methods return allowable sleep time (from their perspective)
|
||||||
increase main cpu sleep time
|
increase main cpu sleep time
|
||||||
|
|
||||||
add set router mode in python tool - it will also set GPS to stationary
|
|
||||||
make sure location still gets set once per boot and stays marked as valid on the gui
|
|
||||||
send position updates super rarely
|
|
||||||
turn off checking for usb power and forcing always on
|
|
||||||
(which will shrink DARK and NB period to zero and
|
|
||||||
make light_sleep very long)
|
|
||||||
|
|
||||||
warn people about crummy gps antennas - add to faq
|
warn people about crummy gps antennas - add to faq
|
||||||
|
|
||||||
|
|
||||||
gps states
|
|
||||||
|
|
||||||
Active - for gps_attempt_time seconds
|
|
||||||
Sleeping - for (gps_update_rate or sleep forever) seconds
|
|
||||||
ForcedSleep - PowerFSM says we don't want to use GPS right now
|
|
||||||
(no need for sleep forever state)
|
|
||||||
|
|
||||||
gps triggers
|
|
||||||
GPS_TRIG_FORCE_SLEEP - from powerfsm
|
|
||||||
GPS_TRIG_FORCE_WAKE - from powerfsm
|
|
||||||
GPS_SETTINGS - if GPS settings changed, reset params and possibly become active
|
|
||||||
|
|
||||||
|
@ -62,8 +62,8 @@ lib_deps =
|
|||||||
1260 ; OneButton library for non-blocking button debounce
|
1260 ; OneButton library for non-blocking button debounce
|
||||||
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
|
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
|
||||||
https://github.com/meshtastic/arduino-fsm.git
|
https://github.com/meshtastic/arduino-fsm.git
|
||||||
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#cb8353dfddd1b0e205098f5e70d5f2a5f74b4838
|
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
|
||||||
https://github.com/meshtastic/RadioLib.git#1083c2e76f9906c5f80dfec726facebf8413eef0
|
https://github.com/meshtastic/RadioLib.git#8657380241bce681c33aab46598bbf13b11f876c
|
||||||
https://github.com/meshtastic/TinyGPSPlus.git
|
https://github.com/meshtastic/TinyGPSPlus.git
|
||||||
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
|
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
|
||||||
https://github.com/meshtastic/esp32_https_server.git
|
https://github.com/meshtastic/esp32_https_server.git
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
#include "GPS.h"
|
#include "GPS.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
|
#include "RTC.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
// If we have a serial GPS port it will not be null
|
// If we have a serial GPS port it will not be null
|
||||||
#ifdef GPS_RX_PIN
|
#ifdef GPS_RX_PIN
|
||||||
@ -23,76 +23,8 @@ uint8_t GPS::i2cAddress = GPS_I2C_ADDRESS;
|
|||||||
uint8_t GPS::i2cAddress = 0;
|
uint8_t GPS::i2cAddress = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool timeSetFromGPS; // We try to set our time from GPS each time we wake from sleep
|
|
||||||
|
|
||||||
GPS *gps;
|
GPS *gps;
|
||||||
|
|
||||||
// stuff that really should be in in the instance instead...
|
|
||||||
static uint32_t
|
|
||||||
timeStartMsec; // Once we have a GPS lock, this is where we hold the initial msec clock that corresponds to that time
|
|
||||||
static uint64_t zeroOffsetSecs; // GPS based time in secs since 1970 - only updated once on initial lock
|
|
||||||
|
|
||||||
void readFromRTC()
|
|
||||||
{
|
|
||||||
struct timeval tv; /* btw settimeofday() is helpfull here too*/
|
|
||||||
|
|
||||||
if (!gettimeofday(&tv, NULL)) {
|
|
||||||
uint32_t now = millis();
|
|
||||||
|
|
||||||
DEBUG_MSG("Read RTC time as %ld (cur millis %u) valid=%d\n", tv.tv_sec, now, timeSetFromGPS);
|
|
||||||
timeStartMsec = now;
|
|
||||||
zeroOffsetSecs = tv.tv_sec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
|
|
||||||
bool perhapsSetRTC(const struct timeval *tv)
|
|
||||||
{
|
|
||||||
if (!timeSetFromGPS) {
|
|
||||||
timeSetFromGPS = true;
|
|
||||||
DEBUG_MSG("Setting RTC %ld secs\n", tv->tv_sec);
|
|
||||||
#ifndef NO_ESP32
|
|
||||||
settimeofday(tv, NULL);
|
|
||||||
#else
|
|
||||||
DEBUG_MSG("ERROR TIME SETTING NOT IMPLEMENTED!\n");
|
|
||||||
#endif
|
|
||||||
readFromRTC();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool 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 month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return perhapsSetRTC(&tv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t getTime()
|
|
||||||
{
|
|
||||||
return ((millis() - timeStartMsec) / 1000) + zeroOffsetSecs;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t getValidTime()
|
|
||||||
{
|
|
||||||
return timeSetFromGPS ? getTime() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GPS::setup()
|
bool GPS::setup()
|
||||||
{
|
{
|
||||||
setAwake(true); // Wake GPS power before doing any init
|
setAwake(true); // Wake GPS power before doing any init
|
||||||
@ -151,7 +83,7 @@ uint32_t GPS::getWakeTime() const
|
|||||||
return t; // already maxint
|
return t; // already maxint
|
||||||
|
|
||||||
if (t == 0)
|
if (t == 0)
|
||||||
t = 5 * 60; // Allow up to 5 mins for each attempt (probably will be much less if we can find sats)
|
t = 15 * 60; // Allow up to 5 mins for each attempt (probably will be much less if we can find sats)
|
||||||
|
|
||||||
t *= 1000; // msecs
|
t *= 1000; // msecs
|
||||||
|
|
||||||
@ -165,7 +97,8 @@ uint32_t GPS::getSleepTime() const
|
|||||||
uint32_t t = radioConfig.preferences.gps_update_interval;
|
uint32_t t = radioConfig.preferences.gps_update_interval;
|
||||||
|
|
||||||
auto op = getGpsOp();
|
auto op = getGpsOp();
|
||||||
if ((timeSetFromGPS && op == GpsOperation_GpsOpTimeOnly) || (op == GpsOperation_GpsOpDisabled))
|
bool gotTime = (getRTCQuality() >= RTCQualityGPS);
|
||||||
|
if ((gotTime && op == GpsOperation_GpsOpTimeOnly) || (op == GpsOperation_GpsOpDisabled))
|
||||||
t = UINT32_MAX; // Sleep forever now
|
t = UINT32_MAX; // Sleep forever now
|
||||||
|
|
||||||
if (t == UINT32_MAX)
|
if (t == UINT32_MAX)
|
||||||
@ -208,13 +141,13 @@ void GPS::loop()
|
|||||||
// While we are awake
|
// While we are awake
|
||||||
if (isAwake) {
|
if (isAwake) {
|
||||||
// DEBUG_MSG("looking for location\n");
|
// DEBUG_MSG("looking for location\n");
|
||||||
if ((now - lastWhileActiveMsec) > 1000) {
|
if ((now - lastWhileActiveMsec) > 5000) {
|
||||||
lastWhileActiveMsec = now;
|
lastWhileActiveMsec = now;
|
||||||
whileActive();
|
whileActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we've already set time from the GPS, no need to ask the GPS
|
// If we've already set time from the GPS, no need to ask the GPS
|
||||||
bool gotTime = timeSetFromGPS || lookForTime();
|
bool gotTime = (getRTCQuality() >= RTCQualityGPS) || lookForTime();
|
||||||
bool gotLoc = lookForLocation();
|
bool gotLoc = lookForLocation();
|
||||||
|
|
||||||
// We've been awake too long - force sleep
|
// We've been awake too long - force sleep
|
||||||
@ -224,7 +157,7 @@ void GPS::loop()
|
|||||||
// Once we get a location we no longer desperately want an update
|
// Once we get a location we no longer desperately want an update
|
||||||
// or if we got a time and we are in GpsOpTimeOnly mode
|
// or if we got a time and we are in GpsOpTimeOnly mode
|
||||||
// DEBUG_MSG("gotLoc %d, tooLong %d, gotTime %d\n", gotLoc, tooLong, gotTime);
|
// DEBUG_MSG("gotLoc %d, tooLong %d, gotTime %d\n", gotLoc, tooLong, gotTime);
|
||||||
if (gotLoc || tooLong || (gotTime && getGpsOp() == GpsOperation_GpsOpTimeOnly)) {
|
if ((gotLoc && gotTime) || tooLong || (gotTime && getGpsOp() == GpsOperation_GpsOpTimeOnly)) {
|
||||||
if (gotLoc)
|
if (gotLoc)
|
||||||
hasValidLocation = true;
|
hasValidLocation = true;
|
||||||
|
|
||||||
@ -247,7 +180,10 @@ void GPS::forceWake(bool on)
|
|||||||
wakeAllowed = true;
|
wakeAllowed = true;
|
||||||
} else {
|
} else {
|
||||||
wakeAllowed = false;
|
wakeAllowed = false;
|
||||||
setAwake(false);
|
|
||||||
|
// Note: if the gps was already awake, we DO NOT shut it down, because we want to allow it to complete its lock
|
||||||
|
// attempt even if we are in light sleep. Once the attempt succeeds (or times out) we'll then shut it down.
|
||||||
|
// setAwake(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,25 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../concurrency/PeriodicTask.h"
|
|
||||||
#include "GPSStatus.h"
|
#include "GPSStatus.h"
|
||||||
#include "Observer.h"
|
#include "Observer.h"
|
||||||
#include "sys/time.h"
|
|
||||||
|
|
||||||
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
|
|
||||||
bool perhapsSetRTC(const struct timeval *tv);
|
|
||||||
bool perhapsSetRTC(struct tm &t);
|
|
||||||
|
|
||||||
// Generate a string representation of DOP
|
// Generate a string representation of DOP
|
||||||
const char *getDOPString(uint32_t dop);
|
const char *getDOPString(uint32_t dop);
|
||||||
|
|
||||||
/// Return time since 1970 in secs. Until we have a GPS lock we will be returning time based at zero
|
|
||||||
uint32_t getTime();
|
|
||||||
|
|
||||||
/// Return time since 1970 in secs. If we don't have a GPS lock return zero
|
|
||||||
uint32_t getValidTime();
|
|
||||||
|
|
||||||
void readFromRTC();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A gps class that only reads from the GPS periodically (and FIXME - eventually keeps the gps powered down except when reading)
|
* A gps class that only reads from the GPS periodically (and FIXME - eventually keeps the gps powered down except when reading)
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "NMEAGPS.h"
|
#include "NMEAGPS.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
#include "RTC.h"
|
||||||
|
|
||||||
static int32_t toDegInt(RawDegrees d)
|
static int32_t toDegInt(RawDegrees d)
|
||||||
{
|
{
|
||||||
@ -44,7 +45,7 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
|
|||||||
t.tm_mon = d.month() - 1;
|
t.tm_mon = d.month() - 1;
|
||||||
t.tm_year = d.year() - 1900;
|
t.tm_year = d.year() - 1900;
|
||||||
t.tm_isdst = false;
|
t.tm_isdst = false;
|
||||||
perhapsSetRTC(t);
|
perhapsSetRTC(RTCQualityGPS, t);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else
|
} else
|
||||||
|
77
src/gps/RTC.cpp
Normal file
77
src/gps/RTC.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#include "RTC.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
static RTCQuality currentQuality = RTCQualityNone;
|
||||||
|
|
||||||
|
RTCQuality getRTCQuality()
|
||||||
|
{
|
||||||
|
return currentQuality;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stuff that really should be in in the instance instead...
|
||||||
|
static uint32_t
|
||||||
|
timeStartMsec; // Once we have a GPS lock, this is where we hold the initial msec clock that corresponds to that time
|
||||||
|
static uint64_t zeroOffsetSecs; // GPS based time in secs since 1970 - only updated once on initial lock
|
||||||
|
|
||||||
|
void readFromRTC()
|
||||||
|
{
|
||||||
|
struct timeval tv; /* btw settimeofday() is helpfull here too*/
|
||||||
|
|
||||||
|
if (!gettimeofday(&tv, NULL)) {
|
||||||
|
uint32_t now = millis();
|
||||||
|
|
||||||
|
DEBUG_MSG("Read RTC time as %ld (cur millis %u) quality=%d\n", tv.tv_sec, now, currentQuality);
|
||||||
|
timeStartMsec = now;
|
||||||
|
zeroOffsetSecs = tv.tv_sec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
|
||||||
|
bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
||||||
|
{
|
||||||
|
if (q > currentQuality) {
|
||||||
|
currentQuality = q;
|
||||||
|
DEBUG_MSG("Setting RTC %ld secs\n", tv->tv_sec);
|
||||||
|
#ifndef NO_ESP32
|
||||||
|
settimeofday(tv, NULL);
|
||||||
|
#else
|
||||||
|
DEBUG_MSG("ERROR TIME SETTING NOT IMPLEMENTED!\n");
|
||||||
|
#endif
|
||||||
|
readFromRTC();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool perhapsSetRTC(RTCQuality q, 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 month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return perhapsSetRTC(q, &tv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getTime()
|
||||||
|
{
|
||||||
|
return ((millis() - timeStartMsec) / 1000) + zeroOffsetSecs;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getValidTime(RTCQuality minQuality)
|
||||||
|
{
|
||||||
|
return (currentQuality >= minQuality) ? getTime() : 0;
|
||||||
|
}
|
30
src/gps/RTC.h
Normal file
30
src/gps/RTC.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
|
#include "sys/time.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
enum RTCQuality {
|
||||||
|
/// We haven't had our RTC set yet
|
||||||
|
RTCQualityNone = 0,
|
||||||
|
|
||||||
|
/// Some other node gave us a time we can use
|
||||||
|
RTCQualityFromNet = 1,
|
||||||
|
|
||||||
|
/// Our time is based on our own GPS
|
||||||
|
RTCQualityGPS = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
RTCQuality getRTCQuality();
|
||||||
|
|
||||||
|
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
|
||||||
|
bool perhapsSetRTC(RTCQuality q, const struct timeval *tv);
|
||||||
|
bool perhapsSetRTC(RTCQuality q, struct tm &t);
|
||||||
|
|
||||||
|
/// Return time since 1970 in secs. While quality is RTCQualityNone we will be returning time based at zero
|
||||||
|
uint32_t getTime();
|
||||||
|
|
||||||
|
/// Return time since 1970 in secs. If quality is RTCQualityNone return zero
|
||||||
|
uint32_t getValidTime(RTCQuality minQuality);
|
||||||
|
|
||||||
|
void readFromRTC();
|
@ -1,4 +1,5 @@
|
|||||||
#include "UBloxGPS.h"
|
#include "UBloxGPS.h"
|
||||||
|
#include "RTC.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -32,7 +33,7 @@ bool UBloxGPS::setupGPS()
|
|||||||
_serial_gps->begin(GPS_BAUDRATE);
|
_serial_gps->begin(GPS_BAUDRATE);
|
||||||
#endif
|
#endif
|
||||||
#ifndef NO_ESP32
|
#ifndef NO_ESP32
|
||||||
_serial_gps->setRxBufferSize(1024); // the default is 256
|
_serial_gps->setRxBufferSize(2048); // the default is 256
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +127,7 @@ void UBloxGPS::whileActive()
|
|||||||
// Update fixtype
|
// Update fixtype
|
||||||
if (ublox.moduleQueried.fixType) {
|
if (ublox.moduleQueried.fixType) {
|
||||||
fixType = ublox.getFixType(0);
|
fixType = ublox.getFixType(0);
|
||||||
DEBUG_MSG("GPS fix type %d\n", fixType);
|
DEBUG_MSG("GPS fix type %d, numSats %d\n", fixType, numSatellites);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,23 +139,21 @@ void UBloxGPS::whileActive()
|
|||||||
*/
|
*/
|
||||||
bool UBloxGPS::lookForTime()
|
bool UBloxGPS::lookForTime()
|
||||||
{
|
{
|
||||||
if (fixType >= 2) {
|
if (ublox.moduleQueried.gpsSecond) {
|
||||||
if (ublox.moduleQueried.gpsSecond) {
|
/* 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
|
||||||
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).
|
||||||
1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
|
*/
|
||||||
*/
|
struct tm t;
|
||||||
struct tm t;
|
t.tm_sec = ublox.getSecond(0);
|
||||||
t.tm_sec = ublox.getSecond(0);
|
t.tm_min = ublox.getMinute(0);
|
||||||
t.tm_min = ublox.getMinute(0);
|
t.tm_hour = ublox.getHour(0);
|
||||||
t.tm_hour = ublox.getHour(0);
|
t.tm_mday = ublox.getDay(0);
|
||||||
t.tm_mday = ublox.getDay(0);
|
t.tm_mon = ublox.getMonth(0) - 1;
|
||||||
t.tm_mon = ublox.getMonth(0) - 1;
|
t.tm_year = ublox.getYear(0) - 1900;
|
||||||
t.tm_year = ublox.getYear(0) - 1900;
|
t.tm_isdst = false;
|
||||||
t.tm_isdst = false;
|
perhapsSetRTC(RTCQualityGPS, t);
|
||||||
perhapsSetRTC(t);
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -170,6 +169,12 @@ bool UBloxGPS::lookForLocation()
|
|||||||
{
|
{
|
||||||
bool foundLocation = false;
|
bool foundLocation = false;
|
||||||
|
|
||||||
|
if (ublox.moduleQueried.SIV)
|
||||||
|
numSatellites = ublox.getSIV(0);
|
||||||
|
|
||||||
|
if (ublox.moduleQueried.pDOP)
|
||||||
|
dop = ublox.getPDOP(0); // PDOP (an accuracy metric) is reported in 10^2 units so we have to scale down when we use it
|
||||||
|
|
||||||
// we only notify if position has changed due to a new fix
|
// we only notify if position has changed due to a new fix
|
||||||
if ((fixType >= 3 && fixType <= 4)) {
|
if ((fixType >= 3 && fixType <= 4)) {
|
||||||
if (ublox.moduleQueried.latitude) // rd fixes only
|
if (ublox.moduleQueried.latitude) // rd fixes only
|
||||||
@ -177,12 +182,10 @@ bool UBloxGPS::lookForLocation()
|
|||||||
latitude = ublox.getLatitude(0);
|
latitude = ublox.getLatitude(0);
|
||||||
longitude = ublox.getLongitude(0);
|
longitude = ublox.getLongitude(0);
|
||||||
altitude = ublox.getAltitudeMSL(0) / 1000; // in mm convert to meters
|
altitude = ublox.getAltitudeMSL(0) / 1000; // in mm convert to meters
|
||||||
dop = ublox.getPDOP(0); // PDOP (an accuracy metric) is reported in 10^2 units so we have to scale down when we use it
|
|
||||||
|
|
||||||
// Note: heading is only currently implmented in the ublox for the 8m chipset - therefore
|
// Note: heading is only currently implmented in the ublox for the 8m chipset - therefore
|
||||||
// don't read it here - it will generate an ignored getPVT command on the 6ms
|
// don't read it here - it will generate an ignored getPVT command on the 6ms
|
||||||
// heading = ublox.getHeading(0);
|
// heading = ublox.getHeading(0);
|
||||||
numSatellites = ublox.getSIV(0);
|
|
||||||
|
|
||||||
// bogus lat lon is reported as 0 or 0 (can be bogus just for one)
|
// bogus lat lon is reported as 0 or 0 (can be bogus just for one)
|
||||||
// Also: apparently when the GPS is initially reporting lock it can output a bogus latitude > 90 deg!
|
// Also: apparently when the GPS is initially reporting lock it can output a bogus latitude > 90 deg!
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
// #include "rom/rtc.h"
|
// #include "rom/rtc.h"
|
||||||
#include "DSRRouter.h"
|
#include "DSRRouter.h"
|
||||||
// #include "debug.h"
|
// #include "debug.h"
|
||||||
|
#include "RTC.h"
|
||||||
#include "SPILock.h"
|
#include "SPILock.h"
|
||||||
#include "graphics/Screen.h"
|
#include "graphics/Screen.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
@ -151,6 +152,8 @@ void userButtonPressedLong()
|
|||||||
screen.adjustBrightness();
|
screen.adjustBrightness();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RadioInterface *rIf = NULL;
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
#ifdef USE_SEGGER
|
#ifdef USE_SEGGER
|
||||||
@ -298,8 +301,7 @@ void setup()
|
|||||||
digitalWrite(SX1262_ANT_SW, 1);
|
digitalWrite(SX1262_ANT_SW, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// MUST BE AFTER service.init, so we have our radio config settings (from nodedb init)
|
// radio init MUST BE AFTER service.init, so we have our radio config settings (from nodedb init)
|
||||||
RadioInterface *rIf = NULL;
|
|
||||||
|
|
||||||
#if defined(RF95_IRQ)
|
#if defined(RF95_IRQ)
|
||||||
if (!rIf) {
|
if (!rIf) {
|
||||||
@ -406,6 +408,9 @@ void loop()
|
|||||||
|
|
||||||
loopWifi();
|
loopWifi();
|
||||||
|
|
||||||
|
// For debugging
|
||||||
|
// if (rIf) ((RadioLibInterface *)rIf)->isActivelyReceiving();
|
||||||
|
|
||||||
// Show boot screen for first 3 seconds, then switch to normal operation.
|
// Show boot screen for first 3 seconds, then switch to normal operation.
|
||||||
static bool showingBootScreen = true;
|
static bool showingBootScreen = true;
|
||||||
if (showingBootScreen && (millis() > 3000)) {
|
if (showingBootScreen && (millis() > 3000)) {
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
|
#include "RTC.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
@ -139,7 +140,7 @@ void MeshService::handleIncomingPosition(const MeshPacket *mp)
|
|||||||
tv.tv_sec = secs;
|
tv.tv_sec = secs;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
perhapsSetRTC(&tv);
|
perhapsSetRTC(RTCQualityFromNet, &tv);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DEBUG_MSG("Ignoring incoming packet - not a position\n");
|
DEBUG_MSG("Ignoring incoming packet - not a position\n");
|
||||||
@ -150,12 +151,8 @@ int MeshService::handleFromRadio(const MeshPacket *mp)
|
|||||||
{
|
{
|
||||||
powerFSM.trigger(EVENT_RECEIVED_PACKET); // Possibly keep the node from sleeping
|
powerFSM.trigger(EVENT_RECEIVED_PACKET); // Possibly keep the node from sleeping
|
||||||
|
|
||||||
// If it is a position packet, perhaps set our clock (if we don't have a GPS of our own, otherwise wait for that to work)
|
// If it is a position packet, perhaps set our clock - this must be before nodeDB.updateFrom
|
||||||
if (!gps->isConnected)
|
handleIncomingPosition(mp);
|
||||||
handleIncomingPosition(mp);
|
|
||||||
else {
|
|
||||||
DEBUG_MSG("Ignoring incoming time, because we have a GPS\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mp->which_payload == MeshPacket_decoded_tag && mp->decoded.which_payload == SubPacket_user_tag) {
|
if (mp->which_payload == MeshPacket_decoded_tag && mp->decoded.which_payload == SubPacket_user_tag) {
|
||||||
mp = handleFromRadioUser(mp);
|
mp = handleFromRadioUser(mp);
|
||||||
@ -229,7 +226,7 @@ void MeshService::handleToRadio(MeshPacket &p)
|
|||||||
if (p.id == 0)
|
if (p.id == 0)
|
||||||
p.id = generatePacketId(); // If the phone didn't supply one, then pick one
|
p.id = generatePacketId(); // If the phone didn't supply one, then pick one
|
||||||
|
|
||||||
p.rx_time = getValidTime(); // Record the time the packet arrived from the phone
|
p.rx_time = getValidTime(RTCQualityFromNet); // Record the time the packet arrived from the phone
|
||||||
// (so we update our nodedb for the local node)
|
// (so we update our nodedb for the local node)
|
||||||
|
|
||||||
// Send the packet into the mesh
|
// Send the packet into the mesh
|
||||||
@ -288,7 +285,7 @@ void MeshService::sendOurPosition(NodeNum dest, bool wantReplies)
|
|||||||
p->decoded.which_payload = SubPacket_position_tag;
|
p->decoded.which_payload = SubPacket_position_tag;
|
||||||
p->decoded.position = node->position;
|
p->decoded.position = node->position;
|
||||||
p->decoded.want_response = wantReplies;
|
p->decoded.want_response = wantReplies;
|
||||||
p->decoded.position.time = getValidTime(); // This nodedb timestamp might be stale, so update it if our clock is valid.
|
p->decoded.position.time = getValidTime(RTCQualityGPS); // This nodedb timestamp might be stale, so update it if our clock is valid.
|
||||||
sendToMesh(p);
|
sendToMesh(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,9 +303,10 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *unused)
|
|||||||
pos.altitude = gps->altitude;
|
pos.altitude = gps->altitude;
|
||||||
pos.latitude_i = gps->latitude;
|
pos.latitude_i = gps->latitude;
|
||||||
pos.longitude_i = gps->longitude;
|
pos.longitude_i = gps->longitude;
|
||||||
pos.time = getValidTime();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pos.time = getValidTime(RTCQualityGPS);
|
||||||
|
|
||||||
// Include our current battery voltage in our position announcement
|
// Include our current battery voltage in our position announcement
|
||||||
pos.battery_level = powerStatus->getBatteryChargePercent();
|
pos.battery_level = powerStatus->getBatteryChargePercent();
|
||||||
updateBatteryLevel(pos.battery_level);
|
updateBatteryLevel(pos.battery_level);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "PacketHistory.h"
|
#include "PacketHistory.h"
|
||||||
#include "PowerFSM.h"
|
#include "PowerFSM.h"
|
||||||
|
#include "RTC.h"
|
||||||
#include "Router.h"
|
#include "Router.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
@ -414,10 +415,10 @@ void NodeDB::updateFrom(const MeshPacket &mp)
|
|||||||
|
|
||||||
switch (p.which_payload) {
|
switch (p.which_payload) {
|
||||||
case SubPacket_position_tag: {
|
case SubPacket_position_tag: {
|
||||||
// we carefully preserve the old time, because we always trust our local timestamps more
|
// we always trust our local timestamps more
|
||||||
uint32_t oldtime = info->position.time;
|
|
||||||
info->position = p.position;
|
info->position = p.position;
|
||||||
info->position.time = oldtime;
|
if (mp.rx_time)
|
||||||
|
info->position.time = mp.rx_time;
|
||||||
info->has_position = true;
|
info->has_position = true;
|
||||||
updateGUIforNode = info;
|
updateGUIforNode = info;
|
||||||
notifyObservers(true); // Force an update whether or not our node counts have changed
|
notifyObservers(true); // Force an update whether or not our node counts have changed
|
||||||
|
@ -109,7 +109,11 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_SEND_MY_INFO:
|
case STATE_SEND_MY_INFO:
|
||||||
myNodeInfo.has_gps = gps && gps->isConnected; // Update with latest GPS connect info
|
// If the user has specified they don't want our node to share its location, make sure to tell the phone
|
||||||
|
// app not to send locations on our behalf.
|
||||||
|
myNodeInfo.has_gps = (radioConfig.preferences.location_share == LocationSharing_LocDisabled)
|
||||||
|
? true
|
||||||
|
: (gps && gps->isConnected); // Update with latest GPS connect info
|
||||||
fromRadioScratch.which_variant = FromRadio_my_info_tag;
|
fromRadioScratch.which_variant = FromRadio_my_info_tag;
|
||||||
fromRadioScratch.variant.my_info = myNodeInfo;
|
fromRadioScratch.variant.my_info = myNodeInfo;
|
||||||
state = STATE_SEND_RADIO;
|
state = STATE_SEND_RADIO;
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#define MAX_POWER 20
|
#define MAX_POWER 20
|
||||||
// if we use 20 we are limited to 1% duty cycle or hw might overheat. For continuous operation set a limit of 17
|
// if we use 20 we are limited to 1% duty cycle or hw might overheat. For continuous operation set a limit of 17
|
||||||
|
// In theory up to 27 dBm is possible, but the modules installed in most radios can cope with a max of 20. So BIG WARNING
|
||||||
|
// if you set power to something higher than 17 or 20 you might fry your board.
|
||||||
|
|
||||||
#define POWER_DEFAULT 17 // How much power to use if the user hasn't set a power level
|
#define POWER_DEFAULT 17 // How much power to use if the user hasn't set a power level
|
||||||
|
|
||||||
|
@ -137,6 +137,11 @@ class RadioLibInterface : public RadioInterface, private concurrency::PeriodicTa
|
|||||||
*/
|
*/
|
||||||
virtual void startReceive() = 0;
|
virtual void startReceive() = 0;
|
||||||
|
|
||||||
|
/** are we actively receiving a packet (only called during receiving state)
|
||||||
|
* This method is only public to facilitate debugging. Do not call.
|
||||||
|
*/
|
||||||
|
virtual bool isActivelyReceiving() = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** if we have something waiting to send, start a short random timer so we can come check for collision before actually doing
|
/** if we have something waiting to send, start a short random timer so we can come check for collision before actually doing
|
||||||
* the transmit
|
* the transmit
|
||||||
@ -176,9 +181,6 @@ class RadioLibInterface : public RadioInterface, private concurrency::PeriodicTa
|
|||||||
/** Could we send right now (i.e. either not actively receiving or transmitting)? */
|
/** Could we send right now (i.e. either not actively receiving or transmitting)? */
|
||||||
virtual bool canSendImmediately();
|
virtual bool canSendImmediately();
|
||||||
|
|
||||||
/** are we actively receiving a packet (only called during receiving state) */
|
|
||||||
virtual bool isActivelyReceiving() = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Raw ISR handler that just calls our polymorphic method
|
* Raw ISR handler that just calls our polymorphic method
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "Router.h"
|
#include "Router.h"
|
||||||
#include "CryptoEngine.h"
|
#include "CryptoEngine.h"
|
||||||
#include "GPS.h"
|
#include "RTC.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "mesh-pb-constants.h"
|
#include "mesh-pb-constants.h"
|
||||||
#include <NodeDB.h>
|
#include <NodeDB.h>
|
||||||
@ -89,7 +89,7 @@ MeshPacket *Router::allocForSending()
|
|||||||
p->to = NODENUM_BROADCAST;
|
p->to = NODENUM_BROADCAST;
|
||||||
p->hop_limit = HOP_RELIABLE;
|
p->hop_limit = HOP_RELIABLE;
|
||||||
p->id = generatePacketId();
|
p->id = generatePacketId();
|
||||||
p->rx_time = getValidTime(); // Just in case we process the packet locally - make sure it has a valid timestamp
|
p->rx_time = getValidTime(RTCQualityFromNet); // Just in case we process the packet locally - make sure it has a valid timestamp
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -198,9 +198,8 @@ NodeNum Router::getNodeNum()
|
|||||||
*/
|
*/
|
||||||
void Router::handleReceived(MeshPacket *p)
|
void Router::handleReceived(MeshPacket *p)
|
||||||
{
|
{
|
||||||
// FIXME, this class shouldn't EVER need to know about the GPS, move getValidTime() into a non gps dependent function
|
|
||||||
// Also, we should set the time from the ISR and it should have msec level resolution
|
// Also, we should set the time from the ISR and it should have msec level resolution
|
||||||
p->rx_time = getValidTime(); // store the arrival timestamp for the phone
|
p->rx_time = getValidTime(RTCQualityFromNet); // store the arrival timestamp for the phone
|
||||||
|
|
||||||
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
// Take those raw bytes and convert them back into a well structured protobuf we can understand
|
||||||
if (perhapsDecode(p)) {
|
if (perhapsDecode(p)) {
|
||||||
|
@ -179,16 +179,18 @@ void SX1262Interface::startReceive()
|
|||||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
||||||
bool SX1262Interface::isActivelyReceiving()
|
bool SX1262Interface::isActivelyReceiving()
|
||||||
{
|
{
|
||||||
// The IRQ status will be cleared when we start our read operation. Check if we've started a preamble, but haven't yet
|
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
|
||||||
// received and handled the interrupt for reading the packet/handling errors.
|
// received and handled the interrupt for reading the packet/handling errors.
|
||||||
|
// FIXME: it would be better to check for preamble, but we currently have our ISR not set to fire for packets that
|
||||||
|
// never even get a valid header, so we don't want preamble to get set and stay set due to noise on the network.
|
||||||
|
|
||||||
uint16_t irq = lora.getIrqStatus();
|
uint16_t irq = lora.getIrqStatus();
|
||||||
bool hasPreamble = (irq & SX126X_IRQ_PREAMBLE_DETECTED);
|
bool hasPreamble = (irq & SX126X_IRQ_HEADER_VALID);
|
||||||
|
|
||||||
// this is not correct - often always true - need to add an extra conditional
|
// this is not correct - often always true - need to add an extra conditional
|
||||||
// size_t bytesPending = lora.getPacketLength();
|
// size_t bytesPending = lora.getPacketLength();
|
||||||
|
|
||||||
// if (hasPreamble || bytesPending) DEBUG_MSG("rx hasPre %d, bytes %d\n", hasPreamble, bytesPending);
|
// if (hasPreamble) DEBUG_MSG("rx hasPreamble\n");
|
||||||
return hasPreamble;
|
return hasPreamble;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,17 +170,18 @@ void doDeepSleep(uint64_t msecToWake)
|
|||||||
|
|
||||||
#ifdef TBEAM_V10
|
#ifdef TBEAM_V10
|
||||||
if (axp192_found) {
|
if (axp192_found) {
|
||||||
|
// Obsolete comment: from back when we we used to receive lora packets while CPU was in deep sleep.
|
||||||
|
// We no longer do that, because our light-sleep current draws are low enough and it provides fast start/low cost
|
||||||
|
// wake. We currently use deep sleep only for 'we want our device to actually be off - because our battery is
|
||||||
|
// critically low'. So in deep sleep we DO shut down power to LORA (and when we boot later we completely reinit it)
|
||||||
|
//
|
||||||
// No need to turn this off if the power draw in sleep mode really is just 0.2uA and turning it off would
|
// No need to turn this off if the power draw in sleep mode really is just 0.2uA and turning it off would
|
||||||
// leave floating input for the IRQ line
|
// leave floating input for the IRQ line
|
||||||
|
|
||||||
// If we want to leave the radio receving in would be 11.5mA current draw, but most of the time it is just waiting
|
// If we want to leave the radio receving in would be 11.5mA current draw, but most of the time it is just waiting
|
||||||
// in its sequencer (true?) so the average power draw should be much lower even if we were listinging for packets
|
// in its sequencer (true?) so the average power draw should be much lower even if we were listinging for packets
|
||||||
// all the time.
|
// all the time.
|
||||||
|
|
||||||
// axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF); // LORA radio
|
axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF); // LORA radio
|
||||||
|
|
||||||
// now done by UBloxGPS.cpp
|
|
||||||
// setGPSPower(false);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user