GPS data handling refactored
This commit is contained in:
parent
359b31e9e9
commit
195661a520
@ -83,7 +83,8 @@ typedef struct {
|
|||||||
uint8_t satellites;
|
uint8_t satellites;
|
||||||
uint16_t hdop;
|
uint16_t hdop;
|
||||||
int16_t altitude;
|
int16_t altitude;
|
||||||
time_t utctime;
|
uint32_t time_age;
|
||||||
|
tmElements_t timedate;
|
||||||
} gpsStatus_t;
|
} gpsStatus_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -18,9 +18,10 @@ extern gpsStatus_t
|
|||||||
extern TaskHandle_t GpsTask;
|
extern TaskHandle_t GpsTask;
|
||||||
|
|
||||||
int gps_init(void);
|
int gps_init(void);
|
||||||
void gps_read(void);
|
void IRAM_ATTR gps_storetime(gpsStatus_t &gps_store);
|
||||||
|
void gps_storelocation(gpsStatus_t &gps_store);
|
||||||
void gps_loop(void *pvParameters);
|
void gps_loop(void *pvParameters);
|
||||||
time_t get_gpstime(void);
|
time_t get_gpstime(gpsStatus_t value);
|
||||||
int gps_config();
|
int gps_config();
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -28,8 +28,6 @@ uint8_t timepulse_init(void);
|
|||||||
time_t timeIsValid(time_t const t);
|
time_t timeIsValid(time_t const t);
|
||||||
time_t timeProvider(void);
|
time_t timeProvider(void);
|
||||||
time_t compiledUTC(void);
|
time_t compiledUTC(void);
|
||||||
time_t tmConvert(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh, uint8_t mm,
|
|
||||||
uint8_t ss);
|
|
||||||
TickType_t tx_Ticks(uint32_t framesize, unsigned long baud, uint32_t config,
|
TickType_t tx_Ticks(uint32_t framesize, unsigned long baud, uint32_t config,
|
||||||
int8_t rxPin, int8_t txPins);
|
int8_t rxPin, int8_t txPins);
|
||||||
time_t TimeSyncAns(uint8_t seqNo, uint64_t unixTime);
|
time_t TimeSyncAns(uint8_t seqNo, uint64_t unixTime);
|
||||||
|
@ -31,10 +31,10 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng
|
|||||||
|
|
||||||
[common]
|
[common]
|
||||||
; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
|
; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
|
||||||
release_version = 1.7.5
|
release_version = 1.7.541
|
||||||
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
|
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
|
||||||
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
|
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
|
||||||
debug_level = 3
|
debug_level = 0
|
||||||
; UPLOAD MODE: select esptool to flash via USB/UART, select custom to upload to cloud for OTA
|
; UPLOAD MODE: select esptool to flash via USB/UART, select custom to upload to cloud for OTA
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
;upload_protocol = custom
|
;upload_protocol = custom
|
||||||
@ -45,8 +45,8 @@ platform_espressif32 = espressif32@1.7.0
|
|||||||
board_build.partitions = min_spiffs.csv
|
board_build.partitions = min_spiffs.csv
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
lib_deps_lora =
|
lib_deps_lora =
|
||||||
;MCCI LoRaWAN LMIC library@>=2.3.2
|
;MCCI LoRaWAN LMIC library@2.3.2
|
||||||
https://github.com/mcci-catena/arduino-lmic.git#e5503ff
|
https://github.com/mcci-catena/arduino-lmic.git#dc18ee9
|
||||||
lib_deps_display =
|
lib_deps_display =
|
||||||
U8g2@>=2.25.7
|
U8g2@>=2.25.7
|
||||||
lib_deps_rgbled =
|
lib_deps_rgbled =
|
||||||
|
@ -65,31 +65,48 @@ int gps_config() {
|
|||||||
return rslt;
|
return rslt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read GPS data and cast to global struct
|
// store current GPS location data in struct
|
||||||
void gps_read() {
|
void gps_storelocation(gpsStatus_t &gps_store) {
|
||||||
gps_status.latitude = (int32_t)(gps.location.lat() * 1e6);
|
gps_store.latitude = (int32_t)(gps.location.lat() * 1e6);
|
||||||
gps_status.longitude = (int32_t)(gps.location.lng() * 1e6);
|
gps_store.longitude = (int32_t)(gps.location.lng() * 1e6);
|
||||||
gps_status.satellites = (uint8_t)gps.satellites.value();
|
gps_store.satellites = (uint8_t)gps.satellites.value();
|
||||||
gps_status.hdop = (uint16_t)gps.hdop.value();
|
gps_store.hdop = (uint16_t)gps.hdop.value();
|
||||||
gps_status.altitude = (int16_t)gps.altitude.meters();
|
gps_store.altitude = (int16_t)gps.altitude.meters();
|
||||||
gps_status.utctime = get_gpstime();
|
|
||||||
|
|
||||||
// show NMEA data in debug mode, useful for debugging GPS
|
|
||||||
ESP_LOGV(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d",
|
|
||||||
gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// function to fetch current time from gps
|
// store current GPS timedate in struct
|
||||||
time_t get_gpstime(void) {
|
void IRAM_ATTR gps_storetime(gpsStatus_t &gps_store) {
|
||||||
|
|
||||||
time_t t = 0;
|
gps_store.time_age = gps.time.age();
|
||||||
uint32_t time_age = gps.time.age();
|
|
||||||
|
|
||||||
if (gps.time.isValid() && gps.date.isValid() && (time_age < 1000))
|
if (gps.time.isValid() && gps.date.isValid() && (gps_store.time_age < 1000)) {
|
||||||
t = tmConvert(gps.date.year(), gps.date.month(), gps.date.day(),
|
gps_store.timedate.Year =
|
||||||
gps.time.hour(), gps.time.minute(), gps.time.second());
|
CalendarYrToTm(gps.date.year()); // year offset from 1970 in microTime.h
|
||||||
|
gps_store.timedate.Month = gps.date.month();
|
||||||
|
gps_store.timedate.Day = gps.date.day();
|
||||||
|
gps_store.timedate.Hour = gps.time.hour();
|
||||||
|
gps_store.timedate.Minute = gps.time.minute();
|
||||||
|
gps_store.timedate.Second = gps.time.second();
|
||||||
|
} else
|
||||||
|
gps_store.timedate = {0};
|
||||||
|
}
|
||||||
|
|
||||||
|
// function to fetch current time from struct; note: this is costly
|
||||||
|
time_t get_gpstime(gpsStatus_t value) {
|
||||||
|
|
||||||
|
time_t t = timeIsValid(makeTime(value.timedate));
|
||||||
|
|
||||||
|
// if (t)
|
||||||
|
// t = value.time_age > nmea_txDelay_ms ? t : t - 1;
|
||||||
|
|
||||||
|
// show NMEA data in verbose mode, useful for debugging GPS
|
||||||
|
ESP_LOGV(
|
||||||
|
TAG,
|
||||||
|
"GPS time: %d | GPS NMEA data: passed %d / failed: %d / with fix: %d", t,
|
||||||
|
gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix());
|
||||||
|
|
||||||
|
return t;
|
||||||
|
|
||||||
return timeIsValid(time_age > nmea_txDelay_ms ? t : t - 1);
|
|
||||||
} // get_gpstime()
|
} // get_gpstime()
|
||||||
|
|
||||||
// GPS serial feed FreeRTos Task
|
// GPS serial feed FreeRTos Task
|
||||||
|
@ -42,7 +42,7 @@ void irqHandler(void *pvParameters) {
|
|||||||
// gps refresh buffer?
|
// gps refresh buffer?
|
||||||
#if (HAS_GPS)
|
#if (HAS_GPS)
|
||||||
if (InterruptStatus & GPS_IRQ)
|
if (InterruptStatus & GPS_IRQ)
|
||||||
gps_read();
|
gps_storelocation(gps_status);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// are cyclic tasks due?
|
// are cyclic tasks due?
|
||||||
|
@ -33,7 +33,7 @@ IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer
|
|||||||
|
|
||||||
clockloop 1 4 generates realtime telegrams for external clock
|
clockloop 1 4 generates realtime telegrams for external clock
|
||||||
timesync_req 1 3 processes realtime time sync requests
|
timesync_req 1 3 processes realtime time sync requests
|
||||||
irqhandler 1 2 display, timesync, etc. tasks triggered by timer
|
irqhandler 1 2 display, timesync, gps, etc. triggered by timers
|
||||||
gpsloop 1 2 reads data from GPS via serial or i2c
|
gpsloop 1 2 reads data from GPS via serial or i2c
|
||||||
bmeloop 1 1 reads data from BME sensor via i2c
|
bmeloop 1 1 reads data from BME sensor via i2c
|
||||||
looptask 1 1 runs the LMIC LoRa stack (arduino loop)
|
looptask 1 1 runs the LMIC LoRa stack (arduino loop)
|
||||||
|
@ -18,6 +18,10 @@ const char timeSetSymbols[] = {'G', 'R', 'L', '?'};
|
|||||||
HardwareSerial IF482(2); // use UART #2 (#1 may be in use for serial GPS)
|
HardwareSerial IF482(2); // use UART #2 (#1 may be in use for serial GPS)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (HAS_GPS)
|
||||||
|
static gpsStatus_t gps_pps_status;
|
||||||
|
#endif
|
||||||
|
|
||||||
Ticker timesyncer;
|
Ticker timesyncer;
|
||||||
|
|
||||||
void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); }
|
void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); }
|
||||||
@ -27,7 +31,8 @@ time_t timeProvider(void) {
|
|||||||
time_t t = 0;
|
time_t t = 0;
|
||||||
|
|
||||||
#if (HAS_GPS)
|
#if (HAS_GPS)
|
||||||
t = gps_pps_time; // fetch recent time from last NEMA record
|
// fetch recent time from last NEMA record
|
||||||
|
t = get_gpstime(gps_pps_status);
|
||||||
if (t) {
|
if (t) {
|
||||||
#ifdef HAS_RTC
|
#ifdef HAS_RTC
|
||||||
set_rtctime(t, do_mutex); // calibrate RTC
|
set_rtctime(t, do_mutex); // calibrate RTC
|
||||||
@ -116,9 +121,9 @@ void timepulse_start(void) {
|
|||||||
timerAlarmEnable(ppsIRQ);
|
timerAlarmEnable(ppsIRQ);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// initialize gps time
|
||||||
#if (HAS_GPS)
|
#if (HAS_GPS)
|
||||||
gps_read();
|
gps_storetime(gps_pps_status);
|
||||||
gps_pps_time = gps_status.utctime;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// start cyclic time sync
|
// start cyclic time sync
|
||||||
@ -134,9 +139,9 @@ void IRAM_ATTR CLOCKIRQ(void) {
|
|||||||
|
|
||||||
SyncToPPS(); // advance systime, see microTime.h
|
SyncToPPS(); // advance systime, see microTime.h
|
||||||
|
|
||||||
// store recent gps time, if we have
|
// store recent gps time, if we have gps
|
||||||
#if (HAS_GPS)
|
#if (HAS_GPS)
|
||||||
gps_pps_time = gps_status.utctime + 1;
|
gps_storetime(gps_pps_status);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// advance wall clock, if we have
|
// advance wall clock, if we have
|
||||||
@ -169,19 +174,6 @@ time_t compiledUTC(void) {
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper function to convert gps date/time into time_t
|
|
||||||
time_t tmConvert(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh, uint8_t mm,
|
|
||||||
uint8_t ss) {
|
|
||||||
tmElements_t tm;
|
|
||||||
tm.Year = CalendarYrToTm(YYYY); // year offset from 1970 in microTime.h
|
|
||||||
tm.Month = MM;
|
|
||||||
tm.Day = DD;
|
|
||||||
tm.Hour = hh;
|
|
||||||
tm.Minute = mm;
|
|
||||||
tm.Second = ss;
|
|
||||||
return makeTime(tm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper function to calculate serial transmit time
|
// helper function to calculate serial transmit time
|
||||||
TickType_t tx_Ticks(uint32_t framesize, unsigned long baud, uint32_t config,
|
TickType_t tx_Ticks(uint32_t framesize, unsigned long baud, uint32_t config,
|
||||||
int8_t rxPin, int8_t txPins) {
|
int8_t rxPin, int8_t txPins) {
|
||||||
|
@ -216,12 +216,12 @@ int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) {
|
|||||||
// adjust system time, calibrate RTC and RTC_INT pps
|
// adjust system time, calibrate RTC and RTC_INT pps
|
||||||
void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec) {
|
void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec) {
|
||||||
|
|
||||||
time_t time_to_set = (time_t)t_sec;
|
// advance time 1 sec wait time
|
||||||
|
time_t time_to_set = (time_t)(t_sec + 1);
|
||||||
|
|
||||||
// advance time 1 sec wait time if we have no pulse clock
|
//#if (!defined GPS_INT && !defined RTC_INT)
|
||||||
#if (!defined GPS_INT) && (!defined RTC_INT)
|
// time_to_set++;
|
||||||
time_to_set++;
|
//#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGD(TAG, "[%0.3f] Calculated UTC epoch time: %d.%03d sec",
|
ESP_LOGD(TAG, "[%0.3f] Calculated UTC epoch time: %d.%03d sec",
|
||||||
millis() / 1000.0, time_to_set, t_msec);
|
millis() / 1000.0, time_to_set, t_msec);
|
||||||
|
Loading…
Reference in New Issue
Block a user