From 43e6ec0cb673176945bdd6e2fd966c9f34e4f1f5 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Wed, 26 Jan 2022 14:57:35 +0100 Subject: [PATCH 01/60] if482.cpp: fixes after removal of eztime --- src/if482.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/if482.cpp b/src/if482.cpp index 37c12c38..81add69a 100644 --- a/src/if482.cpp +++ b/src/if482.cpp @@ -86,18 +86,19 @@ static const char TAG[] = __FILE__; String IF482_Frame(time_t t) { - char mon, out[IF482_FRAME_SIZE + 1]; + char mon, out[IF482_FRAME_SIZE + 1], buf[IF482_FRAME_SIZE - 3]; if (sntp_get_sync_status() == SNTP_SYNC_STATUS_IN_PROGRESS) mon = 'M'; // time had been set but sync not completed else mon = 'A'; // time has been set and was recently synced - // generate IF482 telegram - // snprintf(out, sizeof(out), "O%cL%s\r", mon, myTZ.dateTime(t, UTC_TIME, - // "ymdwHis").c_str()); - - // ESP_LOGD(TAG, "[%s] IF482 date/time: %s", ctime(time(NULL), out); + // generate IF482 telegram for local time + struct tm tt; + localtime_r(&t, &tt); + mktime(&tt); + strftime(buf, sizeof(buf), "%y%m%d%u%H%M%S", &tt); + snprintf(out, sizeof(out), "O%cL%s\r", mon, buf); return out; } From af01537a95de4ce84da8957b910fdbd8f67c6a79 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Wed, 26 Jan 2022 16:21:44 +0100 Subject: [PATCH 02/60] improve RTC accuracy --- include/globals.h | 1 - include/rtctime.h | 2 +- include/timekeeper.h | 6 +++--- src/main.cpp | 35 +++++++++++++++----------------- src/rtctime.cpp | 20 ++++++++++++------ src/timekeeper.cpp | 48 +++++++++++++++++++++++--------------------- 6 files changed, 59 insertions(+), 53 deletions(-) diff --git a/include/globals.h b/include/globals.h index a3a60341..fb2e773e 100644 --- a/include/globals.h +++ b/include/globals.h @@ -111,6 +111,5 @@ typedef struct { } sdsStatus_t; extern char clientId[20]; // unique clientID -extern time_t _COMPILETIME; // epoch build time #endif \ No newline at end of file diff --git a/include/rtctime.h b/include/rtctime.h index d4d64935..3f75eb37 100644 --- a/include/rtctime.h +++ b/include/rtctime.h @@ -12,7 +12,7 @@ extern RtcDS3231 Rtc; // make RTC instance globally available uint8_t rtc_init(void); uint8_t set_rtctime(time_t t); void sync_rtctime(void); -time_t get_rtctime(void); +time_t get_rtctime(uint16_t *msec); float get_rtctemp(void); #endif // _RTCTIME_H \ No newline at end of file diff --git a/include/timekeeper.h b/include/timekeeper.h index 8eb184b4..956595df 100644 --- a/include/timekeeper.h +++ b/include/timekeeper.h @@ -10,8 +10,8 @@ #include "dcf77.h" #include "esp_sntp.h" -#define SECS_YR_2000 (946684800UL) // the time at the start of y2k -#define GPS_UTC_DIFF 315964800UL // seconds diff between gps and utc epoch +#define SECS_YR_2000 (946684800UL) // the time at the start of y2k +#define GPS_UTC_DIFF 315964800UL // seconds diff between gps and utc epoch #define LEAP_SECS_SINCE_GPSEPOCH 18UL // state of 2021 enum timesource_t { _gps, _rtc, _lora, _unsynced, _set }; @@ -33,7 +33,7 @@ bool timeIsValid(time_t const t); void calibrateTime(void); void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, timesource_t mytimesource); -time_t compileTime(const String compile_date); +time_t compileTime(void); time_t mkgmtime(const struct tm *ptm); TickType_t tx_Ticks(uint32_t framesize, unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPins); diff --git a/src/main.cpp b/src/main.cpp index fda59d8e..a2b2cc1a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,26 +25,24 @@ licenses. Refer to LICENSE.txt file in repository for more details. // Tasks and timers: -Task Core Prio Purpose +Task Core Prio Purpose ------------------------------------------------------------------------------- -ledloop 0 3 blinks LEDs -spiloop 0 2 reads/writes data on spi interface -IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer +ledloop* 0 3 blinks LEDs +spiloop# 0 2 reads/writes data on spi interface +lmictask* 1 2 MCCI LMiC LORAWAN stack +clockloop# 1 4 generates realtime telegrams for external clock +mqttloop# 1 2 reads/writes data on ETH interface +timesync_proc# 1 3 processes realtime time sync requests +irqhandler# 1 2 cyclic tasks (i.e. displayrefresh) triggered by +timers gpsloop* 1 1 reads data from GPS via serial or i2c +lorasendtask# 1 1 feeds data from lora sendqueue to lmcic +rmcd_process# 1 1 Remote command interpreter loop -lmictask 1 2 MCCI LMiC LORAWAN stack -clockloop 1 4 generates realtime telegrams for external clock -mqttloop 1 2 reads/writes data on ETH interface -timesync_proc 1 3 processes realtime time sync requests -irqhandler 1 2 cyclic tasks (i.e. displayrefresh) triggered by timers -gpsloop 1 1 reads data from GPS via serial or i2c -lorasendtask 1 1 feeds data from lora sendqueue to lmcic -rmcd_process 1 1 Remote command interpreter loop -IDLE 1 0 ESP32 arduino scheduler -> runs wifi channel rotator +* spinning task +# blocked/waiting task Low priority numbers denote low priority tasks. - -NOTE: Changing any timings will have impact on time accuracy of whole code. -So don't do it if you do not own a digital oscilloscope. +------------------------------------------------------------------------------- // ESP32 hardware timers ------------------------------------------------------------------------------- @@ -126,7 +124,7 @@ void setup() { snprintf(clientId, 20, "paxcounter_%08x", hashedmac); ESP_LOGI(TAG, "Starting %s v%s (runmode=%d / restarts=%d)", clientId, PROGVERSION, RTC_runmode, RTC_restarts); - ESP_LOGI(TAG, "code build date: %d", _COMPILETIME); + ESP_LOGI(TAG, "code build date: %d", compileTime()); // print chip information on startup if in verbose mode after coldstart #if (VERBOSE) @@ -494,8 +492,7 @@ void setup() { cyclicTimer.attach(HOMECYCLE, setCyclicIRQ); // only if we have a timesource we do timesync -#if ((TIME_SYNC_LORAWAN) || (TIME_SYNC_LORASERVER) || (HAS_GPS) || \ - defined HAS_RTC) +#if ((TIME_SYNC_LORAWAN) || (TIME_SYNC_LORASERVER) || (HAS_GPS) || (HAS_RTC)) #if (defined HAS_IF482 || defined HAS_DCF77) ESP_LOGI(TAG, "Starting Clock Controller..."); diff --git a/src/rtctime.cpp b/src/rtctime.cpp index cb87c9de..eb25698d 100644 --- a/src/rtctime.cpp +++ b/src/rtctime.cpp @@ -25,14 +25,14 @@ uint8_t rtc_init(void) { } #if (TIME_SYNC_COMPILEDATE) - // initialize a blank RTC without battery backup with compiled time + // initialize a blank RTC without battery backup with build time RtcDateTime tt = Rtc.GetDateTime(); time_t t = tt.Epoch32Time(); // sec2000 -> epoch if (!Rtc.IsDateTimeValid() || !timeIsValid(t)) { - ESP_LOGW(TAG, "RTC has no recent time, setting to compiled time"); - Rtc.SetDateTime( - RtcDateTime(_COMPILETIME - SECS_YR_2000)); // epoch -> sec2000 + ESP_LOGW(TAG, "RTC has no recent time, setting to compiletime"); + Rtc.SetDateTime(RtcDateTime(mkgmtime(compileTime()) - + SECS_YR_2000)); // epoch -> sec2000 } #endif @@ -62,15 +62,23 @@ uint8_t set_rtctime(time_t t) { // t is sec epoch time } } // set_rtctime() -time_t get_rtctime(void) { +time_t get_rtctime(uint16_t *msec) { time_t t = 0; + *msec = 0; if (I2C_MUTEX_LOCK()) { if (Rtc.IsDateTimeValid() && Rtc.GetIsRunning()) { RtcDateTime tt = Rtc.GetDateTime(); t = tt.Epoch32Time(); // sec2000 -> epoch } I2C_MUTEX_UNLOCK(); - return timeIsValid(t); +#ifdef RTC_INT + // adjust time to top of next second by waiting TimePulseTick to flip + bool lastTick = TimePulseTick; + while (TimePulseTick == lastTick) { + }; + t++; +#endif + return t; } else { ESP_LOGE(TAG, "RTC get time failure"); return 0; // failure diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index 876bff85..ab686650 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -21,7 +21,6 @@ const char timeSetSymbols[] = {'G', 'R', 'L', '*', '?'}; bool volatile TimePulseTick = false; timesource_t timeSource = _unsynced; -time_t _COMPILETIME = compileTime(__DATE__); TaskHandle_t ClockTask = NULL; hw_timer_t *ppsIRQ = NULL; @@ -40,8 +39,7 @@ Ticker timesyncer; void setTimeSyncIRQ() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); } void calibrateTime(void) { - ESP_LOGD(TAG, "[%0.3f] calibrateTime, timeSource == %d", _seconds(), - timeSource); + time_t t = 0; uint16_t t_msec = 0; @@ -57,7 +55,7 @@ void calibrateTime(void) { // has RTC -> fallback to RTC time #ifdef HAS_RTC - t = get_rtctime(); + t = get_rtctime(&t_msec); // set time from RTC - method will check if time is valid setMyTime((uint32_t)t, t_msec, _rtc); #endif @@ -101,26 +99,27 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, vTaskDelay(pdMS_TO_TICKS(1000 - t_msec % 1000)); } + // from here on we are on top of next second + tv.tv_sec = time_to_set; tv.tv_usec = 0; sntp_sync_time(&tv); ESP_LOGI(TAG, "[%0.3f] UTC time: %d.000 sec", _seconds(), time_to_set); - // if we have a software pps timer, shift it to top of second - if (ppsIRQ != NULL) { - - timerWrite(ppsIRQ, 0); // reset pps timer - CLOCKIRQ(); // fire clock pps, this advances time 1 sec - } - -// if we have got an external timesource, set RTC time and shift RTC_INT pulse -// to top of second + // if we have a precise time timesource, set RTC time and shift RTC_INT + // pulse to top of second #ifdef HAS_RTC if ((mytimesource == _gps) || (mytimesource == _lora)) set_rtctime(time_to_set); #endif + // if we have a software pps timer, shift it to top of second + if (ppsIRQ != NULL) { + timerWrite(ppsIRQ, 0); // reset pps timer + CLOCKIRQ(); // fire clock pps to advance wall clock by 1 sec + } + timeSource = mytimesource; // set global variable timesyncer.attach(TIME_SYNC_INTERVAL * 60, setTimeSyncIRQ); @@ -132,7 +131,7 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, "[%0.3f] Failed to synchronise time from source %c | unix sec " "obtained from source: %d | unix sec at program compilation: %d", _seconds(), timeSetSymbols[mytimesource], time_to_set, - _COMPILETIME); + compileTime()); } } @@ -140,7 +139,7 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, uint8_t timepulse_init() { // set esp-idf API sntp sync mode - //sntp_init(); + // sntp_init(); sntp_set_sync_mode(SNTP_SYNC_MODE_IMMED); // use time pulse from GPS as time base with fixed 1Hz frequency @@ -224,7 +223,9 @@ void IRAM_ATTR CLOCKIRQ(void) { // helper function to check plausibility of a given epoch time bool timeIsValid(time_t const t) { // is t a time in the past? we use compile time to guess - return (t > _COMPILETIME); + // compile time is some local time, but we do not know it's time zone + // thus, we go 1 full day back to be sure to catch a time in the past + return (t > (compileTime() - 86400)); } // helper function to calculate serial transmit time @@ -283,7 +284,7 @@ void clock_loop(void *taskparameter) { // ClockTask // set calendar time for next second of clock output tt = (time_t)(current_time + 1); localtime_r(&tt, &t); - mktime(&t); + tt = mktime(&t); #if defined HAS_IF482 @@ -293,13 +294,13 @@ void clock_loop(void *taskparameter) { // ClockTask if (xTaskNotifyWait(0x00, ULONG_MAX, ¤t_time, txDelay) == pdTRUE) { tt = (time_t)(current_time + 1); localtime_r(&tt, &t); - mktime(&t); + tt = mktime(&t); } // send IF482 telegram - IF482.print(IF482_Frame(t)); // note: telegram is for *next* second + IF482.print(IF482_Frame(tt)); // note: telegram is for *next* second - ESP_LOGD(TAG, "[%0.3f] IF482: %s", _seconds(), IF482_Frame(t)); + ESP_LOGD(TAG, "[%0.3f] IF482: %s", _seconds(), IF482_Frame(tt).c_str()); #elif defined HAS_DCF77 @@ -340,7 +341,7 @@ void clock_loop(void *taskparameter) { // ClockTask } // clock_loop() // we use compile date to create a time_t reference "in the past" -time_t compileTime(const String compile_date) { +time_t compileTime(void) { char s_month[5]; int year; @@ -353,10 +354,11 @@ time_t compileTime(const String compile_date) { if (secs == -1) { // determine date - // we go one day back to bypass unknown timezone of local time - sscanf(compile_date.c_str(), "%s %d %d", s_month, &t.tm_mday - 1, &year); + sscanf(__DATE__, "%s %d %d", s_month, &t.tm_mday, &year); t.tm_mon = (strstr(month_names, s_month) - month_names) / 3; t.tm_year = year - 1900; + // determine time + sscanf(__TIME__, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec); // convert to secs local time secs = mktime(&t); From dc427314a1c13b7623216c87c3b1b0dcb5263922 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Wed, 26 Jan 2022 16:32:54 +0100 Subject: [PATCH 03/60] rework task priorities --- src/lorawan.cpp | 4 ++-- src/main.cpp | 26 +++++++++++++------------- src/mqttclient.cpp | 2 +- src/timekeeper.cpp | 2 +- src/timesync.cpp | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 32f7f1f7..3414bb9e 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -305,7 +305,7 @@ esp_err_t lmic_init(void) { "lmictask", // name of task 4096, // stack size of task (void *)1, // parameter of the task - 2, // priority of the task + 8, // priority of the task &lmicTask, // task handle 1); // CPU core @@ -314,7 +314,7 @@ esp_err_t lmic_init(void) { "lorasendtask", // name of task 3072, // stack size of task (void *)1, // parameter of the task - 1, // priority of the task + 2, // priority of the task &lorasendTask, // task handle 1); // CPU core diff --git a/src/main.cpp b/src/main.cpp index a2b2cc1a..c3c5af5c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,16 +27,16 @@ licenses. Refer to LICENSE.txt file in repository for more details. Task Core Prio Purpose ------------------------------------------------------------------------------- -ledloop* 0 3 blinks LEDs -spiloop# 0 2 reads/writes data on spi interface -lmictask* 1 2 MCCI LMiC LORAWAN stack -clockloop# 1 4 generates realtime telegrams for external clock -mqttloop# 1 2 reads/writes data on ETH interface -timesync_proc# 1 3 processes realtime time sync requests -irqhandler# 1 2 cyclic tasks (i.e. displayrefresh) triggered by -timers gpsloop* 1 1 reads data from GPS via serial or i2c -lorasendtask# 1 1 feeds data from lora sendqueue to lmcic -rmcd_process# 1 1 Remote command interpreter loop +ledloop* 0 1 blinks LEDs +spiloop# 0 2 reads/writes data on spi interface +lmictask* 1 8 MCCI LMiC LORAWAN stack +clockloop# 1 6 generates realtime telegrams for external clock +mqttloop# 1 5 reads/writes data on ETH interface +timesync_proc# 1 7 processes realtime time sync requests +irqhandler# 1 4 cyclic tasks (i.e. displayrefresh) triggered by +gpsloop* 1 3 reads data from GPS via serial or i2c +lorasendtask# 1 2 feeds data from lora sendqueue to lmcic +rmcd_process# 1 1 Remote command interpreter loop * spinning task # blocked/waiting task @@ -242,7 +242,7 @@ void setup() { "ledloop", // name of task 1024, // stack size of task (void *)1, // parameter of the task - 3, // priority of the task + 1, // priority of the task &ledLoopTask, // task handle 0); // CPU core #endif @@ -328,7 +328,7 @@ void setup() { "gpsloop", // name of task 4096, // stack size of task (void *)1, // parameter of the task - 1, // priority of the task + 3, // priority of the task &GpsTask, // task handle 1); // CPU core } @@ -430,7 +430,7 @@ void setup() { "irqhandler", // name of task 4096, // stack size of task (void *)1, // parameter of the task - 2, // priority of the task + 4, // priority of the task &irqHandlerTask, // task handle 1); // CPU core diff --git a/src/mqttclient.cpp b/src/mqttclient.cpp index d7ddb4bf..c8d85ceb 100644 --- a/src/mqttclient.cpp +++ b/src/mqttclient.cpp @@ -37,7 +37,7 @@ esp_err_t mqtt_init(void) { SEND_QUEUE_SIZE * PAYLOAD_BUFFER_SIZE); ESP_LOGI(TAG, "Starting MQTTloop..."); - xTaskCreatePinnedToCore(mqtt_client_task, "mqttloop", 4096, (void *)NULL, 1, + xTaskCreatePinnedToCore(mqtt_client_task, "mqttloop", 4096, (void *)NULL, 5, &mqttTask, 1); return ESP_OK; } diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index ab686650..55ea3d77 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -253,7 +253,7 @@ void clock_init(void) { "clockloop", // name of task 3072, // stack size of task (void *)1, // task parameter - 4, // priority of the task + 6, // priority of the task &ClockTask, // task handle 1); // CPU core diff --git a/src/timesync.cpp b/src/timesync.cpp index aa969897..9b2c5f99 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -34,7 +34,7 @@ void timesync_init(void) { "timesync_proc", // name of task 4096, // stack size of task (void *)1, // task parameter - 3, // priority of the task + 7, // priority of the task &timeSyncProcTask, // task handle 1); // CPU core } From dfa25cd2b40372e8f1efbe04f309036f80f59029 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Wed, 26 Jan 2022 16:58:05 +0100 Subject: [PATCH 04/60] increase delay in gps read spin task --- src/gpsread.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 428604e4..5cb3c170 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -116,9 +116,9 @@ time_t get_gpstime(uint16_t *msec) { gps_tm.tm_mday = atoi(gpsday.value()); // day, 01 to 31 gps_tm.tm_mon = atoi(gpsmonth.value()) - 1; // month, 01 to 12 gps_tm.tm_year = atoi(gpsyear.value()) - 1900; // year, YYYY - + // convert UTC tm to time_t epoch - gps_tm.tm_isdst = 0; // UTC has no DST + gps_tm.tm_isdst = 0; // UTC has no DST time_t t = mkgmtime(&gps_tm); // add protocol delay with millisecond precision @@ -172,7 +172,7 @@ void gps_loop(void *pvParameters) { // gps.passedChecksum(), gps.failedChecksum(), // gps.sentencesWithFix()); - yield(); // yield to CPU + delay(50); } // end of infinite loop From 1ffdbdac3b786580db990c41a93d795b6aa25145 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Wed, 26 Jan 2022 22:44:29 +0100 Subject: [PATCH 05/60] dcf77.cpp: simplyfy parity calculation --- src/dcf77.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/dcf77.cpp b/src/dcf77.cpp index fd59cb51..8b30dcf4 100644 --- a/src/dcf77.cpp +++ b/src/dcf77.cpp @@ -51,18 +51,17 @@ void DCF77_Pulse(uint8_t bit) { // helper function to convert decimal to bcd digit uint64_t dec2bcd(uint8_t const dec, uint8_t const startpos, - uint8_t const endpos, uint8_t *odd_parity) { + uint8_t const endpos, uint8_t *parity) { - uint8_t data = (dec < 10) ? dec : ((dec / 10) << 4) + (dec % 10); + uint8_t data = dec < 10 ? dec : ((dec / 10) << 4) + dec % 10; uint64_t bcd = 0; - *odd_parity = 0; + *parity = 0; for (uint8_t i = startpos; i <= endpos; i++) { - bcd += (data & 1) ? set_dcfbit(i) : 0; - *odd_parity += (data & 1); + bcd += data & 1 ? set_dcfbit(i) : 0; + *parity ^= data & 1; data >>= 1; } - *odd_parity %= 2; return bcd; } @@ -96,14 +95,14 @@ uint64_t DCF77_Frame(const struct tm t) { // DATE (36..58) frame += dec2bcd(t.tm_mday, 36, 41, &parity); - parity_sum += parity; + parity_sum ^= parity; frame += dec2bcd((t.tm_wday == 0) ? 7 : t.tm_wday, 42, 44, &parity); - parity_sum += parity; + parity_sum ^= parity; frame += dec2bcd(t.tm_mon + 1, 45, 49, &parity); - parity_sum += parity; + parity_sum ^= parity; frame += dec2bcd(t.tm_year + 1900 - 2000, 50, 57, &parity); - parity_sum += parity; - frame += parity_sum % 2 ? set_dcfbit(58) : 0; + parity_sum ^= parity; + frame += parity_sum ? set_dcfbit(58) : 0; return frame; From a0ea78844a7e5c6db153577add1a8b740eaafe36 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Wed, 26 Jan 2022 22:45:23 +0100 Subject: [PATCH 06/60] gpsread.cpp: slow down spin loop --- src/gpsread.cpp | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 5cb3c170..86da8fef 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -141,40 +141,35 @@ void gps_loop(void *pvParameters) { while (1) { - if (cfg.payloadmask & GPS_DATA) { + while (cfg.payloadmask & GPS_DATA) { #ifdef GPS_SERIAL // feed GPS decoder with serial NMEA data from GPS device - while (GPS_Serial.available()) { - gps.encode(GPS_Serial.read()); - yield(); - } + while (GPS_Serial.available()) + if (gps.encode(GPS_Serial.read())) + break; // NMEA sentence complete #elif defined GPS_I2C Wire.requestFrom(GPS_ADDR, 32); // caution: this is a blocking call - while (Wire.available()) { - gps.encode(Wire.read()); - delay(2); // 2ms delay according L76 datasheet - yield(); - } + while (Wire.available()) + if (gps.encode(Wire.read())) + break; // NMEA sentence complete #endif // (only) while device time is not set or unsynched, and we have a valid - // GPS time, we trigger a device time update to poll time from GPS + // GPS time, we call calibrateTime to poll time immeditately from GPS if ((timeSource == _unsynced || timeSource == _set) && - (gpstime.isUpdated() && gpstime.isValid() && gpstime.age() < 1000)) { + (gpstime.isUpdated() && gpstime.isValid() && gpstime.age() < 1000)) calibrateTime(); - } - } // if + // show NMEA data, very noisy, useful only for debugging GPS + // ESP_LOGV(TAG, "GPS NMEA data: passed %u / failed: %u / with fix: + // %u", gps.passedChecksum(), gps.failedChecksum(), gps + // .sentencesWithFix()); - // show NMEA data in verbose mode, useful only for debugging GPS, very - // noisy ESP_LOGV(TAG, "GPS NMEA data: passed %u / failed: %u / with fix: - // %u", - // gps.passedChecksum(), gps.failedChecksum(), - // gps.sentencesWithFix()); + delay(2); + } // inner while loop - delay(50); - - } // end of infinite loop + delay(1000); + } // outer while loop } // gps_loop() From 66c321d0e9e6e30c20fafc695b84f068cbb6af2c Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Wed, 26 Jan 2022 22:45:34 +0100 Subject: [PATCH 07/60] led.cpp: slow down spin loop --- src/led.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/led.cpp b/src/led.cpp index b0b302d6..8095a3a9 100644 --- a/src/led.cpp +++ b/src/led.cpp @@ -212,7 +212,7 @@ void ledLoop(void *parameter) { previousLEDState = LEDState; } // give yield to CPU - delay(2); + delay(5); } // while(1) }; // ledloop() From ad027f7e80594e10685e6ab55898d07617dfa47e Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Thu, 27 Jan 2022 18:04:06 +0100 Subject: [PATCH 08/60] DRAM_ATTR for global variable used in ISR --- src/timekeeper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index 55ea3d77..fec827a4 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -19,7 +19,7 @@ static const char TAG[] = __FILE__; // G = GPS / R = RTC / L = LORA / * = no sync / ? = never synced const char timeSetSymbols[] = {'G', 'R', 'L', '*', '?'}; -bool volatile TimePulseTick = false; +DRAM_ATTR bool volatile TimePulseTick = false; timesource_t timeSource = _unsynced; TaskHandle_t ClockTask = NULL; hw_timer_t *ppsIRQ = NULL; From 13eaae74acdcfa00aef2e660e2fe63df64dfeedb Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Thu, 27 Jan 2022 18:04:37 +0100 Subject: [PATCH 09/60] add some task watchdog handling --- include/globals.h | 3 +++ src/gpsread.cpp | 4 +++- src/led.cpp | 2 ++ src/lorawan.cpp | 6 ++++-- src/main.cpp | 4 ++++ 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/include/globals.h b/include/globals.h index fb2e773e..b012dae9 100644 --- a/include/globals.h +++ b/include/globals.h @@ -8,6 +8,9 @@ #include #include +// task watchdog functions +#include + // std::set for unified array functions #include #include diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 86da8fef..ad4d811e 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -138,10 +138,12 @@ time_t get_gpstime(uint16_t *msec) { void gps_loop(void *pvParameters) { _ASSERT((uint32_t)pvParameters == 1); // FreeRTOS check + esp_task_wdt_add(NULL); while (1) { - + esp_task_wdt_reset(); // feed task watchdog while (cfg.payloadmask & GPS_DATA) { + esp_task_wdt_reset(); // feed task watchdog #ifdef GPS_SERIAL // feed GPS decoder with serial NMEA data from GPS device while (GPS_Serial.available()) diff --git a/src/led.cpp b/src/led.cpp index 8095a3a9..083dbcc8 100644 --- a/src/led.cpp +++ b/src/led.cpp @@ -141,7 +141,9 @@ void blink_LED(uint16_t set_color, uint16_t set_blinkduration) { #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) void ledLoop(void *parameter) { + esp_task_wdt_add(NULL); while (1) { + esp_task_wdt_reset(); // feed task watchdog // Custom blink running always have priority other LoRaWAN led // management if (LEDBlinkStarted && LEDBlinkDuration) { diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 3414bb9e..178ff7d7 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -343,9 +343,11 @@ uint32_t lora_queuewaiting(void) { // LMIC loop task void lmictask(void *pvParameters) { _ASSERT((uint32_t)pvParameters == 1); + esp_task_wdt_add(NULL); while (1) { - os_runloop_once(); // execute lmic scheduled jobs and events - delay(2); // yield to CPU + esp_task_wdt_reset(); // feed task watchdog + os_runloop_once(); // execute lmic scheduled jobs and events + delay(2); // yield to CPU } } diff --git a/src/main.cpp b/src/main.cpp index c3c5af5c..4d573df7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -104,6 +104,10 @@ void setup() { (*((uint32_t volatile *)ETS_UNCACHED_ADDR((DR_REG_RTCCNTL_BASE + 0xd4)))) = 0; #endif + // task watchdog configuration + //esp_task_wdt_init(1, true); + esp_task_wdt_deinit(); + // setup debug output or silence device #if (VERBOSE) Serial.begin(115200); From 08a9b8a55749bf4d0e014c84f63dbf5b33ef3213 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Thu, 27 Jan 2022 21:40:25 +0100 Subject: [PATCH 10/60] Revert "add some task watchdog handling" This reverts commit 13eaae74acdcfa00aef2e660e2fe63df64dfeedb. --- include/globals.h | 3 --- src/gpsread.cpp | 4 +--- src/led.cpp | 2 -- src/lorawan.cpp | 6 ++---- src/main.cpp | 4 ---- 5 files changed, 3 insertions(+), 16 deletions(-) diff --git a/include/globals.h b/include/globals.h index b012dae9..fb2e773e 100644 --- a/include/globals.h +++ b/include/globals.h @@ -8,9 +8,6 @@ #include #include -// task watchdog functions -#include - // std::set for unified array functions #include #include diff --git a/src/gpsread.cpp b/src/gpsread.cpp index ad4d811e..86da8fef 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -138,12 +138,10 @@ time_t get_gpstime(uint16_t *msec) { void gps_loop(void *pvParameters) { _ASSERT((uint32_t)pvParameters == 1); // FreeRTOS check - esp_task_wdt_add(NULL); while (1) { - esp_task_wdt_reset(); // feed task watchdog + while (cfg.payloadmask & GPS_DATA) { - esp_task_wdt_reset(); // feed task watchdog #ifdef GPS_SERIAL // feed GPS decoder with serial NMEA data from GPS device while (GPS_Serial.available()) diff --git a/src/led.cpp b/src/led.cpp index 083dbcc8..8095a3a9 100644 --- a/src/led.cpp +++ b/src/led.cpp @@ -141,9 +141,7 @@ void blink_LED(uint16_t set_color, uint16_t set_blinkduration) { #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) void ledLoop(void *parameter) { - esp_task_wdt_add(NULL); while (1) { - esp_task_wdt_reset(); // feed task watchdog // Custom blink running always have priority other LoRaWAN led // management if (LEDBlinkStarted && LEDBlinkDuration) { diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 178ff7d7..3414bb9e 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -343,11 +343,9 @@ uint32_t lora_queuewaiting(void) { // LMIC loop task void lmictask(void *pvParameters) { _ASSERT((uint32_t)pvParameters == 1); - esp_task_wdt_add(NULL); while (1) { - esp_task_wdt_reset(); // feed task watchdog - os_runloop_once(); // execute lmic scheduled jobs and events - delay(2); // yield to CPU + os_runloop_once(); // execute lmic scheduled jobs and events + delay(2); // yield to CPU } } diff --git a/src/main.cpp b/src/main.cpp index 4d573df7..c3c5af5c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -104,10 +104,6 @@ void setup() { (*((uint32_t volatile *)ETS_UNCACHED_ADDR((DR_REG_RTCCNTL_BASE + 0xd4)))) = 0; #endif - // task watchdog configuration - //esp_task_wdt_init(1, true); - esp_task_wdt_deinit(); - // setup debug output or silence device #if (VERBOSE) Serial.begin(115200); From a57730940b312f80060eaa409e482f09686bf08a Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Fri, 28 Jan 2022 10:39:57 +0100 Subject: [PATCH 11/60] increase GPS loop stack size to avoid TG1WDT --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index c3c5af5c..82398073 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -326,7 +326,7 @@ void setup() { ESP_LOGI(TAG, "Starting GPS Feed..."); xTaskCreatePinnedToCore(gps_loop, // task function "gpsloop", // name of task - 4096, // stack size of task + 8192, // stack size of task (void *)1, // parameter of the task 3, // priority of the task &GpsTask, // task handle From 76c465ccb7b05ad953b4c1a825294cc3d7bca3ae Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Fri, 28 Jan 2022 19:51:59 +0100 Subject: [PATCH 12/60] change order of loraykey display for TTNv3 console --- src/lorawan.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 3414bb9e..403cf19f 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -179,10 +179,10 @@ void showLoraKeys(void) { // all EUI buffer so we do it here to a temp // buffer to be able to display them uint8_t buf[32]; - os_getDevEui((u1_t *)buf); - printKey("DevEUI", buf, 8, true); os_getArtEui((u1_t *)buf); printKey("AppEUI", buf, 8, true); + os_getDevEui((u1_t *)buf); + printKey("DevEUI", buf, 8, true); os_getDevKey((u1_t *)buf); printKey("AppKey", buf, 16, false); } From 854480a051a791a9972a0bd1451b6b3140f39077 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Fri, 28 Jan 2022 20:57:31 +0100 Subject: [PATCH 13/60] sdcard: timestamp in iso8601 format --- README.md | 12 ++++++------ include/sdcard.h | 2 +- src/sdcard.cpp | 21 +++++++++------------ src/senddata.cpp | 23 ++++++++++------------- 4 files changed, 26 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 1cf6607c..dc9bae6c 100644 --- a/README.md +++ b/README.md @@ -256,12 +256,12 @@ The data is written to the card and after 3 write-operations the data is flushed And finally: this is the data written to the disk: - date, time, wifi, bluet - 00.00.1970,00:01:09,2,0 - 00.00.1970,00:02:09,1,0 - 00.00.1970,00:03:09,2,0 - -Format of the data is CSV, which can easily imported into LibreOffice, Excel, ..... + timestamp, wifi, ble + 2022-01-28T19:36:35Z,17,48 + 2022-01-28T19:37:35Z,21,52 + 2022-01-28T19:38:35Z,14,49 + +Format of the data is CSV, timestamp is ISO8601, which can easily imported into LibreOffice, Excel, Influx, etc. If you want to change this please look into src/sdcard.cpp and include/sdcard.h. diff --git a/include/sdcard.h b/include/sdcard.h index 5c34dc11..8d20ced5 100644 --- a/include/sdcard.h +++ b/include/sdcard.h @@ -55,7 +55,7 @@ #endif #define SDCARD_FILE_NAME "/paxcount.%02d" -#define SDCARD_FILE_HEADER "date, time, wifi, bluet" +#define SDCARD_FILE_HEADER "timestamp, wifi, ble" #if (COUNT_ENS) #define SDCARD_FILE_HEADER_CWA ",cwa" diff --git a/src/sdcard.cpp b/src/sdcard.cpp index 925ab207..783cf657 100644 --- a/src/sdcard.cpp +++ b/src/sdcard.cpp @@ -42,11 +42,10 @@ bool sdcard_init() { void sdcardWriteData(uint16_t noWifi, uint16_t noBle, __attribute__((unused)) uint16_t noBleCWA) { static int counterWrites = 0; - char tempBuffer[12 + 1]; + char tempBuffer[20 + 1]; time_t t = time(NULL); struct tm tt; - localtime_r(&t, &tt); - mktime(&tt); + gmtime_r(&t, &tt); // make UTC timestamp #if (HAS_SDS011) sdsStatus_t sds; @@ -56,19 +55,17 @@ void sdcardWriteData(uint16_t noWifi, uint16_t noBle, return; ESP_LOGD(TAG, "writing to SD-card"); - strftime(tempBuffer, sizeof(tempBuffer), "%d.%m.%Y", &tt); + strftime(tempBuffer, sizeof(tempBuffer), "%FT%TZ", &tt); fileSDCard.print(tempBuffer); - strftime(tempBuffer, sizeof(tempBuffer), "%H.%M.%S", &tt); - fileSDCard.print(tempBuffer); - sprintf(tempBuffer, "%d,%d", noWifi, noBle); + snprintf(tempBuffer, sizeof(tempBuffer), ",%d,%d", noWifi, noBle); fileSDCard.print(tempBuffer); #if (COUNT_ENS) - sprintf(tempBuffer, ",%d", noBleCWA); + snprintf(tempBuffer, sizeof(tempBuffer), ",%d", noBleCWA); fileSDCard.print(tempBuffer); #endif #if (HAS_SDS011) sds011_store(&sds); - sprintf(tempBuffer, ",%5.1f,%4.1f", sds.pm10, sds.pm25); + snprintf(tempBuffer, sizeof(tempBuffer), ",%5.1f,%4.1f", sds.pm10, sds.pm25); fileSDCard.print(tempBuffer); #endif fileSDCard.println(); @@ -88,7 +85,7 @@ void createFile(void) { for (int i = 0; i < 100; i++) { sprintf(bufferFilename, SDCARD_FILE_NAME, i); - // ESP_LOGD(TAG, "SD: looking for file <%s>", bufferFilename); + ESP_LOGD(TAG, "SD: looking for file <%s>", bufferFilename); #if HAS_SDCARD == 1 bool fileExists = SD.exists(bufferFilename); @@ -97,7 +94,7 @@ void createFile(void) { #endif if (!fileExists) { - // ESP_LOGD(TAG, "SD: file does not exist: opening"); + ESP_LOGD(TAG, "SD: file does not exist: creating"); #if HAS_SDCARD == 1 fileSDCard = SD.open(bufferFilename, FILE_WRITE); @@ -106,7 +103,7 @@ void createFile(void) { #endif if (fileSDCard) { - ESP_LOGD(TAG, "SD: name opened: <%s>", bufferFilename); + ESP_LOGD(TAG, "SD: file opened: <%s>", bufferFilename); fileSDCard.print(SDCARD_FILE_HEADER); #if (COUNT_ENS) fileSDCard.print(SDCARD_FILE_HEADER_CWA); // for Corona-data (CWA) diff --git a/src/senddata.cpp b/src/senddata.cpp index 5a310761..fce1d325 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -65,18 +65,6 @@ void SendPayload(uint8_t port) { mqtt_enqueuedata(&SendBuffer); #endif -// write data to sdcard, if present -#if (HAS_SDCARD) - if (port == COUNTERPORT) { - sdcardWriteData(libpax_macs_wifi, libpax_macs_ble -#if (COUNT_ENS) - , - cwa_report() -#endif - ); - } -#endif - } // SendPayload // interrupt triggered function to prepare payload to send @@ -130,7 +118,16 @@ void sendData() { #ifdef HAS_DISPLAY dp_plotCurve(libpax_macs_ble + libpax_macs_wifi, true); #endif - break; +#if (HAS_SDCARD) + sdcardWriteData(libpax_macs_wifi, libpax_macs_ble +#if (COUNT_ENS) + , + cwa_report() +#endif + ); +#endif // HAS_SDCARD + + break; // case COUNTDATA #endif #if (HAS_BME) From c4ec21d0554b358d6b410cfd8a13a37e37d73179 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Fri, 28 Jan 2022 21:41:55 +0100 Subject: [PATCH 14/60] sdcard logging: add voltage, remove cwa --- README.md | 5 +++-- include/sdcard.h | 6 +++--- src/sdcard.cpp | 10 +++++----- src/senddata.cpp | 4 ++-- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index dc9bae6c..e8ad0b69 100644 --- a/README.md +++ b/README.md @@ -252,16 +252,17 @@ These cheap devices often handle SD-cards up to 32GB, not bigger ones. They can The software included here writes data in a file named PAXCOUNT.xx, where xx can range from 00 to 99. The software starts with 00, checks to see if such a file already exists and if yes it will continue with the next number (up to 99 - in this case it will return no sd-card). So an existing file will not be overwritten. -The data is written to the card and after 3 write-operations the data is flushed to the disk. So maybe the last 3 minutes of data get lost when you disconnect the PAXCOUNTER from power. +The data is written to the card and after 3 write-operations the data is flushed to the disk. Thus, up to the last 3 records of data will get lost when the PAXCOUNTER looses power. And finally: this is the data written to the disk: - timestamp, wifi, ble + timestamp,wifi,ble[,voltage] 2022-01-28T19:36:35Z,17,48 2022-01-28T19:37:35Z,21,52 2022-01-28T19:38:35Z,14,49 Format of the data is CSV, timestamp is ISO8601, which can easily imported into LibreOffice, Excel, Influx, etc. +Voltage is logged, if the device has a battery voltage sensor (to be configure in board hal file). If you want to change this please look into src/sdcard.cpp and include/sdcard.h. diff --git a/include/sdcard.h b/include/sdcard.h index 8d20ced5..4d04f3ab 100644 --- a/include/sdcard.h +++ b/include/sdcard.h @@ -55,10 +55,10 @@ #endif #define SDCARD_FILE_NAME "/paxcount.%02d" -#define SDCARD_FILE_HEADER "timestamp, wifi, ble" +#define SDCARD_FILE_HEADER "timestamp,wifi,ble" -#if (COUNT_ENS) -#define SDCARD_FILE_HEADER_CWA ",cwa" +#if (defined BAT_MEASURE_ADC || defined HAS_PMU) +#define SDCARD_FILE_HEADER_VOLTAGE ",voltage" #endif bool sdcard_init(void); diff --git a/src/sdcard.cpp b/src/sdcard.cpp index 783cf657..396f5257 100644 --- a/src/sdcard.cpp +++ b/src/sdcard.cpp @@ -40,7 +40,7 @@ bool sdcard_init() { } void sdcardWriteData(uint16_t noWifi, uint16_t noBle, - __attribute__((unused)) uint16_t noBleCWA) { + __attribute__((unused)) uint16_t voltage) { static int counterWrites = 0; char tempBuffer[20 + 1]; time_t t = time(NULL); @@ -59,8 +59,8 @@ void sdcardWriteData(uint16_t noWifi, uint16_t noBle, fileSDCard.print(tempBuffer); snprintf(tempBuffer, sizeof(tempBuffer), ",%d,%d", noWifi, noBle); fileSDCard.print(tempBuffer); -#if (COUNT_ENS) - snprintf(tempBuffer, sizeof(tempBuffer), ",%d", noBleCWA); +#if (defined BAT_MEASURE_ADC || defined HAS_PMU) + snprintf(tempBuffer, sizeof(tempBuffer), ",%d", voltage); fileSDCard.print(tempBuffer); #endif #if (HAS_SDS011) @@ -105,8 +105,8 @@ void createFile(void) { if (fileSDCard) { ESP_LOGD(TAG, "SD: file opened: <%s>", bufferFilename); fileSDCard.print(SDCARD_FILE_HEADER); -#if (COUNT_ENS) - fileSDCard.print(SDCARD_FILE_HEADER_CWA); // for Corona-data (CWA) +#if (defined BAT_MEASURE_ADC || defined HAS_PMU) + fileSDCard.print(SDCARD_FILE_HEADER_VOLTAGE); // for battery level data #endif #if (HAS_SDS011) fileSDCard.print(SDCARD_FILE_HEADER_SDS011); diff --git a/src/senddata.cpp b/src/senddata.cpp index fce1d325..bc9ee702 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -120,9 +120,9 @@ void sendData() { #endif #if (HAS_SDCARD) sdcardWriteData(libpax_macs_wifi, libpax_macs_ble -#if (COUNT_ENS) +#if (defined BAT_MEASURE_ADC || defined HAS_PMU) , - cwa_report() + read_voltage() #endif ); #endif // HAS_SDCARD From aea6dc88c69a4e6fa15a99c3fa7926b7e0b99840 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Fri, 28 Jan 2022 21:43:59 +0100 Subject: [PATCH 15/60] for user joseph --- platformio_orig.ini | 8 ++++---- src/hal/ttgov21new.h | 7 ++++--- src/paxcounter_orig.conf | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/platformio_orig.ini b/platformio_orig.ini index 100ede8a..507058a6 100644 --- a/platformio_orig.ini +++ b/platformio_orig.ini @@ -16,10 +16,10 @@ ;halfile = ttgov1.h ;halfile = ttgov2.h ;halfile = ttgov21old.h -;halfile = ttgov21new.h +halfile = ttgov21new.h ;halfile = ttgofox.h ;halfile = ttgobeam.h -halfile = ttgobeam10.h +;halfile = ttgobeam10.h ;halfile = ttgotdisplay.h ;halfile = ttgotwristband.h ;halfile = fipy.h @@ -48,7 +48,7 @@ description = Paxcounter is a device for metering passenger flows in realtime. I [common] ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" -release_version = 3.1.0 +release_version = 3.1.1 ; 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 debug_level = 3 @@ -56,7 +56,7 @@ extra_scripts = pre:build.py otakeyfile = ota.conf lorakeyfile = loraconf.h lmicconfigfile = lmic_config.h -platform_espressif32 = espressif32@3.4.0 +platform_espressif32 = espressif32@3.5.0 monitor_speed = 115200 upload_speed = 115200 ; set by build.py and taken from hal file display_library = ; set by build.py and taken from hal file diff --git a/src/hal/ttgov21new.h b/src/hal/ttgov21new.h index 71c22bca..5e0d0dd9 100644 --- a/src/hal/ttgov21new.h +++ b/src/hal/ttgov21new.h @@ -16,10 +16,11 @@ #define CFG_sx1276_radio 1 // HPD13A LoRa SoC // enable only if you want to store a local paxcount table on the device -#define HAS_SDCARD 2 // // this board has a SDMMC card-reader/writer +#define HAS_SDCARD 2 // this board has a SDMMC card-reader/writer -#define HAS_DISPLAY 1 -#define HAS_LED (25) // green on board LED +//#define HAS_DISPLAY 1 +//#define HAS_LED (25) // green on board LED +#define HAS_LED NOT_A_PIN #define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 #define BAT_VOLTAGE_DIVIDER 2 // voltage divider 100k/100k on board diff --git a/src/paxcounter_orig.conf b/src/paxcounter_orig.conf index 0fe927b9..ede57963 100644 --- a/src/paxcounter_orig.conf +++ b/src/paxcounter_orig.conf @@ -14,7 +14,7 @@ // Payload send cycle and encoding #define SENDCYCLE 30 // payload send cycle [seconds/2], 0 .. 255 -#define SLEEPCYCLE 0 // sleep time after a send cycle [seconds/10], 0 .. 65535; 0 means no sleep [default = 0] +#define SLEEPCYCLE 1800 // sleep time after a send cycle [seconds/10], 0 .. 65535; 0 means no sleep [default = 0] #define PAYLOAD_ENCODER 2 // payload encoder: 1=Plain, 2=Packed, 3=Cayenne LPP dynamic, 4=Cayenne LPP packed #define COUNTERMODE 0 // 0=cyclic, 1=cumulative, 2=cyclic confirmed From 150eb720699e53b5c88ea5c3b80a32ac655638b6 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Fri, 28 Jan 2022 21:50:48 +0100 Subject: [PATCH 16/60] update comments in board hal files --- src/hal/heltec.h | 2 +- src/hal/heltecv2.h | 2 +- src/hal/heltecv21.h | 2 +- src/hal/lolin32lite.h | 2 +- src/hal/lolin32litelora.h | 2 +- src/hal/ttgov1.h | 2 +- src/hal/ttgov21new.h | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hal/heltec.h b/src/hal/heltec.h index 47877577..55f7332a 100644 --- a/src/hal/heltec.h +++ b/src/hal/heltec.h @@ -18,7 +18,7 @@ #define CFG_sx1276_radio 1 #define HAS_DISPLAY 1 // OLED-Display on board -#define HAS_LED LED_BUILTIN // white LED on board +#define HAS_LED LED_BUILTIN // white LED on board (set to NOT_A_PIN to disable) #define HAS_BUTTON KEY_BUILTIN // button "PROG" on board // Pins for I2C interface of OLED Display diff --git a/src/hal/heltecv2.h b/src/hal/heltecv2.h index b33863ff..b6aab088 100644 --- a/src/hal/heltecv2.h +++ b/src/hal/heltecv2.h @@ -20,7 +20,7 @@ #define CFG_sx1276_radio 1 #define HAS_DISPLAY 1 // OLED-Display on board -#define HAS_LED LED_BUILTIN // white LED on board +#define HAS_LED LED_BUILTIN // white LED on board (set to NOT_A_PIN to disable) #define HAS_BUTTON KEY_BUILTIN // button "PROG" on board #define BAT_MEASURE_ADC ADC2_GPIO13_CHANNEL // battery probe GPIO pin diff --git a/src/hal/heltecv21.h b/src/hal/heltecv21.h index 9586edfd..a24d875a 100644 --- a/src/hal/heltecv21.h +++ b/src/hal/heltecv21.h @@ -20,7 +20,7 @@ #define CFG_sx1276_radio 1 #define HAS_DISPLAY 1 // OLED-Display on board -#define HAS_LED LED_BUILTIN // white LED on board +#define HAS_LED LED_BUILTIN // white LED on board (set to NOT_A_PIN to disable) #define HAS_BUTTON KEY_BUILTIN // button "PROG" on board #define BAT_MEASURE_ADC ADC1_GPIO37_CHANNEL // battery probe GPIO pin diff --git a/src/hal/lolin32lite.h b/src/hal/lolin32lite.h index 1c860393..3f9f9fe0 100644 --- a/src/hal/lolin32lite.h +++ b/src/hal/lolin32lite.h @@ -10,7 +10,7 @@ // Hardware related definitions for lolin32lite (without LoRa shield) #define HAS_LED LED_BUILTIN // on board LED on GPIO5 -#define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW +#define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW (set to NOT_A_PIN to disable) #define MY_SDA SDA #define MY_SCL SCL diff --git a/src/hal/lolin32litelora.h b/src/hal/lolin32litelora.h index f0b99250..d3ae2133 100644 --- a/src/hal/lolin32litelora.h +++ b/src/hal/lolin32litelora.h @@ -15,7 +15,7 @@ #define HAS_DISPLAY 1 // OLED-Display on board //#define MY_DISPLAY_FLIP 1 // uncomment this for rotated display -#define HAS_LED 22 // ESP32 GPIO12 (pin22) On Board LED +#define HAS_LED 22 // ESP32 GPIO12 (pin22) On Board LED (set to NOT_A_PIN to disable) #define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW #define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_13) // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED #define HAS_BUTTON 15 // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield diff --git a/src/hal/ttgov1.h b/src/hal/ttgov1.h index bb1b63e7..cc0493c8 100644 --- a/src/hal/ttgov1.h +++ b/src/hal/ttgov1.h @@ -14,7 +14,7 @@ #define HAS_DISPLAY 1 // OLED-Display on board //#define MY_DISPLAY_FLIP 1 // uncomment this for rotated display -#define HAS_LED LED_BUILTIN +#define HAS_LED LED_BUILTIN // set to NOT_A_PIN to disable #define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW #define HAS_BUTTON KEY_BUILTIN diff --git a/src/hal/ttgov21new.h b/src/hal/ttgov21new.h index 71c22bca..5c531423 100644 --- a/src/hal/ttgov21new.h +++ b/src/hal/ttgov21new.h @@ -16,10 +16,10 @@ #define CFG_sx1276_radio 1 // HPD13A LoRa SoC // enable only if you want to store a local paxcount table on the device -#define HAS_SDCARD 2 // // this board has a SDMMC card-reader/writer +#define HAS_SDCARD 2 // this board has a SDMMC card-reader/writer #define HAS_DISPLAY 1 -#define HAS_LED (25) // green on board LED +#define HAS_LED (25) // green on board LED (set to NOT_A_PIN to disable) #define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 #define BAT_VOLTAGE_DIVIDER 2 // voltage divider 100k/100k on board From db60afe05d0ecb8f2568383d82e63e4725f94fe0 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Fri, 28 Jan 2022 22:17:17 +0100 Subject: [PATCH 17/60] remove unused ENS/CWA code --- README.md | 20 ++----- include/corona.h | 16 ------ include/display.h | 4 -- include/globals.h | 1 - include/main.h | 1 - include/senddata.h | 4 -- src/TTN/packed_decoder.js | 5 -- src/TTNv3/packed_decodeUplink.js | 5 -- src/TTNv3/plain_decodeUplink.js | 7 --- src/configmanager.cpp | 1 - src/corona.cpp | 54 ------------------- src/display.cpp | 14 +---- .../opensource/esp32-paxcounter-packed.js | 7 +-- src/main.cpp | 6 --- src/paxcounter_orig.conf | 4 -- src/rcommand.cpp | 11 +--- src/senddata.cpp | 4 -- src/sensor.cpp | 12 ----- 18 files changed, 9 insertions(+), 167 deletions(-) delete mode 100644 include/corona.h delete mode 100644 src/corona.cpp diff --git a/README.md b/README.md index e8ad0b69..a61d400a 100644 --- a/README.md +++ b/README.md @@ -216,15 +216,6 @@ Paxcounter can be used to sync a wall clock which has a DCF77 or IF482 time tele This describes how to set up a mobile PaxCounter:
Follow all steps so far for preparing the device, selecting the packed payload format. In `paxcounter.conf` set PAYLOAD_OPENSENSEBOX to 1. Register a new sensebox on https://opensensemap.org/. In the sensor configuration select "TheThingsNetwork" and set decoding profile to "LoRa serialization". Enter your TTN Application and Device ID. Setup decoding option using `[{"decoder":"latLng"},{"decoder":"uint16",sensor_id":"yoursensorid"}]` -# Covid-19 Exposure Notification System beacon detection (currently NOT working with v3.0.x, use v2.4.x for this feature) - -Bluetooth low energy service UUID 0xFD6F, used by Google/Apple COVID-19 Exposure Notification System, can be monitored and counted. By comparing with the total number of observed devices this gives an indication how many people staying in proximity are using Apps for tracing COVID-19 exposures, e.g. in Germany the "Corona Warn App". To achive best results with this funcion, use following settings in `paxcounter.conf`: - - #define COUNT_ENS 1 // enable ENS monitoring function - #define BLECOUNTER 1 // enable bluetooth sniffing - #define WIFICOUNTER 0 // disable wifi sniffing (improves BLE scan speed) - #define HAS_SENSOR_1 1 // optional, in board's hal file: transmit ENS counter data to server - # SD-card Data can be stored on an SD-card if one is availabe. Simply choose the file in src/hal and add the following lines to your hal-file: @@ -384,7 +375,7 @@ Hereafter described is the default *plain* format, which uses MSB bit numbering. **Ports #10, #11, #12:** User sensor data - Format is specified by user in function `sensor_read(uint8_t sensor)`, see `src/sensor.cpp`. Port #10 is also used for ENS counter (2 bytes = 16 bit), if ENS is compiled AND ENS data transfer is enabled + Format is specified by user in function `sensor_read(uint8_t sensor)`, see `src/sensor.cpp`. # Remote control @@ -504,7 +495,7 @@ Send for example `83` `86` as Downlink on Port 2 to get battery status and time/ 0x02 = RESERVED_DATA 0x04 = MEMS_DATA 0x08 = GPS_DATA - 0x10 = SENSOR_1_DATA (also ENS counter) + 0x10 = SENSOR_1_DATA 0x20 = SENSOR_2_DATA 0x40 = SENSOR_3_DATA 0x80 = BATT_DATA @@ -525,10 +516,9 @@ Send for example `83` `86` as Downlink on Port 2 to get battery status and time/ 0 = disabled 1 = enabled [default] -0x18 set ENS counter on/off +0x18 reserved - 0 = disabled [default] - 1 = enabled + unused, does nothing 0x19 set sleep cycle @@ -622,4 +612,4 @@ Thanks to - [terrillmoore](https://github.com/mcci-catena) for maintaining the LMIC for arduino LoRaWAN stack - [sbamueller](https://github.com/sbamueller) for writing the tutorial in Make Magazine - [Stefan](https://github.com/nerdyscout) for paxcounter opensensebox integration -- [August Quint](https://github.com/AugustQu) for adding SD card data logger, SDS011 and ENS support +- [August Quint](https://github.com/AugustQu) for adding SD card data logger and SDS011 support diff --git a/include/corona.h b/include/corona.h deleted file mode 100644 index 9af0d314..00000000 --- a/include/corona.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _CORONA_h -#define _CORONA_H - -// inspired by https://github.com/kmetz/BLEExposureNotificationBeeper -// (c) by Kaspar Metz -// modified for use in the Paxcounter by AQ - -#include "globals.h" -#include - -bool cwa_init(void); -void cwa_mac_add(uint16_t hashedmac); -void cwa_clear(void); -uint16_t cwa_report(void); - -#endif diff --git a/include/display.h b/include/display.h index 2b00aa44..62cdf363 100644 --- a/include/display.h +++ b/include/display.h @@ -6,10 +6,6 @@ #include "qrcode.h" #include "power.h" -#if (COUNT_ENS) -#include "corona.h" -#endif - #if (HAS_DISPLAY) == 1 #include #elif (HAS_DISPLAY) == 2 diff --git a/include/globals.h b/include/globals.h index fb2e773e..9b141b09 100644 --- a/include/globals.h +++ b/include/globals.h @@ -71,7 +71,6 @@ typedef struct __attribute__((packed)) { uint8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4) uint8_t rgblum; // RGB Led luminosity (0..100%) uint8_t payloadmask; // bitswitches for payload data - uint8_t enscount; // 0=disabled 1= enabled #ifdef HAS_BME680 uint8_t diff --git a/include/main.h b/include/main.h index a0772b03..6fa72b11 100644 --- a/include/main.h +++ b/include/main.h @@ -18,7 +18,6 @@ #include "sensor.h" #include "lorawan.h" #include "timekeeper.h" -#include "corona.h" #include "boot.h" #include "libpax_helpers.h" #include "power.h" diff --git a/include/senddata.h b/include/senddata.h index 4ae83018..6c44dfa7 100644 --- a/include/senddata.h +++ b/include/senddata.h @@ -10,10 +10,6 @@ #include "display.h" #include "sdcard.h" -#if (COUNT_ENS) -#include "corona.h" -#endif - extern struct count_payload_t count_from_libpax; void SendPayload(uint8_t port); diff --git a/src/TTN/packed_decoder.js b/src/TTN/packed_decoder.js index f338e6df..7230fb46 100644 --- a/src/TTN/packed_decoder.js +++ b/src/TTN/packed_decoder.js @@ -84,11 +84,6 @@ function Decoder(bytes, port) { } } - if (port === 10) { - // ENS count - return decode(bytes, [uint16], ['ens']); - } - } diff --git a/src/TTNv3/packed_decodeUplink.js b/src/TTNv3/packed_decodeUplink.js index a010f3dc..94c1ec8b 100644 --- a/src/TTNv3/packed_decodeUplink.js +++ b/src/TTNv3/packed_decodeUplink.js @@ -90,11 +90,6 @@ function decodeUplink(input) { data = decode(input.bytes, [uint32, uint8], ['time', 'timestatus']); } } - - if (input.fPort === 10) { - // ENS count - data = decode(input.bytes, [uint16], ['ens']); - } data.bytes = input.bytes; // comment out if you do not want to include the original payload data.port = input.fPort; // comment out if you do not want to inlude the port diff --git a/src/TTNv3/plain_decodeUplink.js b/src/TTNv3/plain_decodeUplink.js index d19feb48..0b1b8c23 100644 --- a/src/TTNv3/plain_decodeUplink.js +++ b/src/TTNv3/plain_decodeUplink.js @@ -84,13 +84,6 @@ function decodeUplink(input) { } } - if (input.fPort === 10) { - var i = 0; - if (input.bytes.length >= 2) { - data.ens = (input.bytes[i++] << 8) | input.bytes[i++]; - } - } - if (data.hdop) { data.hdop /= 100; data.latitude /= 1000000; diff --git a/src/configmanager.cpp b/src/configmanager.cpp index 7de8d127..256c9f2d 100644 --- a/src/configmanager.cpp +++ b/src/configmanager.cpp @@ -57,7 +57,6 @@ static void defaultConfig(configData_t *myconfig) { myconfig->wifiant = 0; // 0=internal, 1=external (for LoPy/LoPy4) myconfig->rgblum = RGBLUMINOSITY; // RGB Led luminosity (0..100%) myconfig->payloadmask = PAYLOADMASK; // payloads as defined in default - myconfig->enscount = COUNT_ENS; // 0=disabled, 1=enabled #ifdef HAS_BME680 // initial BSEC state for BME680 sensor diff --git a/src/corona.cpp b/src/corona.cpp deleted file mode 100644 index bd20fb17..00000000 --- a/src/corona.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// routines for counting the number of devices which advertise Exposure -// Notification Service e.g. "Corona Warn App" in Germany - -// copied from https://github.com/kmetz/BLEExposureNotificationBeeper -// (c) by Kaspar Metz -// modified for use in the Paxcounter by AQ - -#if (COUNT_ENS) && !(BLECOUNTER) -#warning ENS-Counter needs Bluetooth, but Bluetooth compile option is disabled -#endif - -#if (COUNT_ENS) - -// Local logging tag -static const char TAG[] = __FILE__; - -#define BT_BD_ADDR_HEX(addr) \ - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] - -#include "corona.h" - -// When to forget old senders ** currently not used ** -#define FORGET_AFTER_MINUTES 2 - -// array of timestamps for seen notifiers: hash -> timestamp[ms] -static std::map cwaSeenNotifiers; - -// Remove notifiers last seen over FORGET_AFTER_MINUTES ago. -void cwa_clear() { -#ifdef VERBOSE - ESP_LOGV(TAG, "CWA: forget old notifier: %d", cwaSeenNotifiers.size()); - for (auto const ¬ifier : cwaSeenNotifiers) { - ESP_LOGD(TAG, "CWA forget <%04X>", notifier.first); - // } - } -#endif - // clear everything, otherwise we would count the same device again, as in the - // next cycle it likely will advertise with a different hash-value - cwaSeenNotifiers.clear(); -} - -// return the total number of devices seen advertising ENS -uint16_t cwa_report(void) { return cwaSeenNotifiers.size(); } - -bool cwa_init(void) { - ESP_LOGD(TAG, "init BLE-scanner for ENS"); - return true; -} - -void cwa_mac_add(uint16_t hashedmac) { - cwaSeenNotifiers[hashedmac] = millis(); // hash last seen at .... -} - -#endif diff --git a/src/display.cpp b/src/display.cpp index fdf70904..10722fa3 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -268,12 +268,7 @@ void dp_drawPage(bool nextpage) { else dp_printf("WIFI:off"); if (cfg.blescan) -#if (COUNT_ENS) - if (cfg.enscount) - dp_printf(" CWA:%-5d", cwa_report()); - else -#endif - dp_printf("BLTH:%-5d", count_from_libpax.ble_count); + dp_printf("BLTH:%-5d", count_from_libpax.ble_count); else dp_printf(" BLTH:off"); #elif ((WIFICOUNTER) && (!BLECOUNTER)) @@ -284,12 +279,7 @@ void dp_drawPage(bool nextpage) { #elif ((!WIFICOUNTER) && (BLECOUNTER)) if (cfg.blescan) dp_printf("BLTH:%-5d", count_from_libpax.ble_count); -#if (COUNT_ENS) - if (cfg.enscount) - dp_printf("(CWA:%d)", cwa_report()); - else -#endif - dp_printf("BLTH:off"); + dp_printf("BLTH:off"); #else dp_printf("Sniffer disabled"); #endif diff --git a/src/lorawan-devices-repo/vendor/opensource/esp32-paxcounter-packed.js b/src/lorawan-devices-repo/vendor/opensource/esp32-paxcounter-packed.js index d82e56e9..b9fc15a1 100644 --- a/src/lorawan-devices-repo/vendor/opensource/esp32-paxcounter-packed.js +++ b/src/lorawan-devices-repo/vendor/opensource/esp32-paxcounter-packed.js @@ -90,12 +90,7 @@ function decodeUplink(input) { data = decode(input.bytes, [uint32, uint8], ['time', 'timestatus']); } } - - if (input.fPort === 10) { - // ENS count - data = decode(input.bytes, [uint16], ['ens']); - } - + data.bytes = input.bytes; // comment out if you do not want to include the original payload data.port = input.fPort; // comment out if you do not want to inlude the port diff --git a/src/main.cpp b/src/main.cpp index 82398073..4bc007ab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -337,15 +337,9 @@ void setup() { // initialize sensors #if (HAS_SENSORS) #if (HAS_SENSOR_1) -#if (COUNT_ENS) - ESP_LOGI(TAG, "init CWA-counter"); - if (cwa_init()) - strcat_P(features, " CWA"); -#else strcat_P(features, " SENS(1)"); sensor_init(); #endif -#endif #if (HAS_SENSOR_2) strcat_P(features, " SENS(2)"); sensor_init(); diff --git a/src/paxcounter_orig.conf b/src/paxcounter_orig.conf index 0fe927b9..a96a8c53 100644 --- a/src/paxcounter_orig.conf +++ b/src/paxcounter_orig.conf @@ -27,10 +27,6 @@ #define BLESCANWINDOW 80 // [milliseconds] scan window, see below, 3 .. 10240, default 80ms #define BLESCANINTERVAL 80 // [illiseconds] scan interval, see below, 3 .. 10240, default 80ms = 100% duty cycle -// Corona Exposure Notification Service(ENS) counter -#define COUNT_ENS 0 // count found number of devices which advertise Exposure Notification Service - // set to 1 if you want to enable this function [default=0] - /* Note: guide for setting bluetooth parameters * * |< Scan Window > |< Scan Window > | ... |< Scan Window > | diff --git a/src/rcommand.cpp b/src/rcommand.cpp index 08c7618d..ecaadca7 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -397,15 +397,6 @@ void set_flush(uint8_t val[]) { // used to open receive window on LoRaWAN class a nodes }; -void set_enscount(uint8_t val[]) { - ESP_LOGI(TAG, "Remote command: set ENS_COUNT to %s", val[0] ? "on" : "off"); - cfg.enscount = val[0] ? 1 : 0; - if (val[0]) - cfg.payloadmask |= (uint8_t)SENSOR1_DATA; - else - cfg.payloadmask &= (uint8_t)~SENSOR1_DATA; -} - void set_loadconfig(uint8_t val[]) { ESP_LOGI(TAG, "Remote command: load config from NVRAM"); loadConfig(); @@ -430,7 +421,7 @@ static const cmd_t table[] = { {0x10, set_rgblum, 1}, {0x13, set_sensor, 2}, {0x14, set_payloadmask, 1}, {0x15, set_bme, 1}, {0x16, set_batt, 1}, {0x17, set_wifiscan, 1}, - {0x18, set_enscount, 1}, {0x19, set_sleepcycle, 2}, + {0x18, set_flush, 0}, {0x19, set_sleepcycle, 2}, {0x20, set_loadconfig, 0}, {0x21, set_saveconfig, 0}, {0x80, get_config, 0}, {0x81, get_status, 0}, {0x83, get_batt, 0}, {0x84, get_gps, 0}, diff --git a/src/senddata.cpp b/src/senddata.cpp index bc9ee702..9b7a5e57 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -159,10 +159,6 @@ void sendData() { payload.reset(); payload.addSensor(sensor_read(1)); SendPayload(SENSOR1PORT); -#if (COUNT_ENS) - if (cfg.countermode != 1) - cwa_clear(); -#endif break; #endif #if (HAS_SENSOR_2) diff --git a/src/sensor.cpp b/src/sensor.cpp index 21f212f5..2d077175 100644 --- a/src/sensor.cpp +++ b/src/sensor.cpp @@ -2,12 +2,6 @@ #include "globals.h" #include "sensor.h" -#if (COUNT_ENS) -#include "payload.h" -#include "corona.h" -extern PayloadConvert payload; -#endif - // Local logging tag static const char TAG[] = __FILE__; @@ -53,16 +47,10 @@ uint8_t *sensor_read(uint8_t sensor) { case 1: // insert user specific sensor data frames here - // note: Sensor1 fields are used for ENS count, if ENS detection enabled -#if (COUNT_ENS) - if (cfg.enscount) - payload.addCount(cwa_report(), MAC_SNIFF_BLE_ENS); -#else buf[0] = length; buf[1] = 0x01; buf[2] = 0x02; buf[3] = 0x03; -#endif break; case 2: From 51c6a41180040a3498e422a98e5dc14e883d536b Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sat, 29 Jan 2022 13:47:59 +0100 Subject: [PATCH 18/60] flush to sd card before sleep --- include/reset.h | 1 + include/sdcard.h | 3 ++- src/reset.cpp | 5 +++++ src/sdcard.cpp | 8 +++++++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/reset.h b/include/reset.h index bffff1bc..64d25437 100644 --- a/include/reset.h +++ b/include/reset.h @@ -8,6 +8,7 @@ #include "lorawan.h" #include "display.h" #include "power.h" +#include "sdcard.h" void reset_rtc_vars(void); void do_reset(bool warmstart); diff --git a/include/sdcard.h b/include/sdcard.h index 4d04f3ab..6718616b 100644 --- a/include/sdcard.h +++ b/include/sdcard.h @@ -61,7 +61,8 @@ #define SDCARD_FILE_HEADER_VOLTAGE ",voltage" #endif -bool sdcard_init(void); +bool sdcard_init(bool create = true); +bool sdcard_close(void); void sdcardWriteData(uint16_t, uint16_t, uint16_t = 0); #endif // _SDCARD_H diff --git a/src/reset.cpp b/src/reset.cpp index d21a042d..b67d8dae 100644 --- a/src/reset.cpp +++ b/src/reset.cpp @@ -126,6 +126,11 @@ void enter_deepsleep(const uint64_t wakeup_sec, gpio_num_t wakeup_gpio) { sds011_sleep(); #endif +// flush & close sd card, if we have +#if (HAS_SDCARD) + sdcard_close(); +#endif + // wait a while (max 100 sec) to clear send queues ESP_LOGI(TAG, "Waiting until send queues are empty..."); for (i = 100; i > 0; i--) { diff --git a/src/sdcard.cpp b/src/sdcard.cpp index 396f5257..da204982 100644 --- a/src/sdcard.cpp +++ b/src/sdcard.cpp @@ -13,7 +13,13 @@ static void createFile(void); File fileSDCard; -bool sdcard_init() { +bool sdcard_close(void) { + ESP_LOGD(TAG, "unmounting SD-card"); + fileSDCard.flush(); + fileSDCard.end(); +} + +bool sdcard_init(bool create) { ESP_LOGI(TAG, "looking for SD-card..."); // for usage of SD drivers on ESP32 platform see From d97f57faa07b5262c2dc58e9cf08cc129ee41fe5 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sat, 29 Jan 2022 13:49:12 +0100 Subject: [PATCH 19/60] reset.h: add missing forward declaration sds011 --- include/reset.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/reset.h b/include/reset.h index 64d25437..6ce2661e 100644 --- a/include/reset.h +++ b/include/reset.h @@ -9,6 +9,7 @@ #include "display.h" #include "power.h" #include "sdcard.h" +#include "sds011read.h" void reset_rtc_vars(void); void do_reset(bool warmstart); From 581a3aafa5efdcd52b4b2cd058792dfdae83a262 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sat, 29 Jan 2022 19:22:16 +0100 Subject: [PATCH 20/60] sdcard.cpp: bugfix file end -> close --- src/sdcard.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sdcard.cpp b/src/sdcard.cpp index da204982..e19630c2 100644 --- a/src/sdcard.cpp +++ b/src/sdcard.cpp @@ -16,7 +16,8 @@ File fileSDCard; bool sdcard_close(void) { ESP_LOGD(TAG, "unmounting SD-card"); fileSDCard.flush(); - fileSDCard.end(); + fileSDCard.close(); +return true; } bool sdcard_init(bool create) { From dffb5dee751529525ff2e708f3594814a38e9e5c Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 30 Jan 2022 15:25:16 +0100 Subject: [PATCH 21/60] move payloadmask define to paxcounter.conf --- src/configmanager.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/configmanager.cpp b/src/configmanager.cpp index 256c9f2d..6112444d 100644 --- a/src/configmanager.cpp +++ b/src/configmanager.cpp @@ -6,12 +6,6 @@ // Local logging tag static const char TAG[] = __FILE__; -// default settings for device data to be sent -#define PAYLOADMASK \ - ((GPS_DATA | MEMS_DATA | COUNT_DATA | SENSOR1_DATA | SENSOR2_DATA | \ - SENSOR3_DATA) & \ - (~BATT_DATA) & (~RESERVED_DATA)) - // namespace for device runtime preferences #define DEVCONFIG "paxcntcfg" From bce80542a84fec67b8a29fd289d4c6c5336d73f7 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 30 Jan 2022 15:25:46 +0100 Subject: [PATCH 22/60] change CD logging to single file --- include/sdcard.h | 8 ++-- src/sdcard.cpp | 115 +++++++++++++++++++++++++++++------------------ 2 files changed, 77 insertions(+), 46 deletions(-) diff --git a/include/sdcard.h b/include/sdcard.h index 6718616b..5a88ea5d 100644 --- a/include/sdcard.h +++ b/include/sdcard.h @@ -1,15 +1,17 @@ #ifndef _SDCARD_H #define _SDCARD_H -#include +#include "globals.h" #include #include #if (HAS_SDCARD) #if HAS_SDCARD == 1 #include +#define MYSD SD #elif HAS_SDCARD == 2 #include +#define MYSD SD_MMC #else #error HAS_SDCARD unknown card reader value, must be either 1 or 2 #endif @@ -54,7 +56,7 @@ #define SDCARD_DATA3 13 #endif -#define SDCARD_FILE_NAME "/paxcount.%02d" +#define SDCARD_FILE_NAME clientId #define SDCARD_FILE_HEADER "timestamp,wifi,ble" #if (defined BAT_MEASURE_ADC || defined HAS_PMU) @@ -62,7 +64,7 @@ #endif bool sdcard_init(bool create = true); -bool sdcard_close(void); +void sdcard_close(void); void sdcardWriteData(uint16_t, uint16_t, uint16_t = 0); #endif // _SDCARD_H diff --git a/src/sdcard.cpp b/src/sdcard.cpp index da204982..476e4037 100644 --- a/src/sdcard.cpp +++ b/src/sdcard.cpp @@ -1,4 +1,7 @@ // routines for writing data to an SD-card, if present +// use FAT32 formatted card +// check whether your card reader supports SPI oder SDMMC and select appropriate +// SD low level driver in board hal file // Local logging tag static const char TAG[] = __FILE__; @@ -7,19 +10,16 @@ static const char TAG[] = __FILE__; #ifdef HAS_SDCARD -static bool useSDCard; - -static void createFile(void); +static bool useSDCard = false; +static void openFile(void); File fileSDCard; -bool sdcard_close(void) { - ESP_LOGD(TAG, "unmounting SD-card"); - fileSDCard.flush(); - fileSDCard.end(); -} - bool sdcard_init(bool create) { + + uint8_t cardType; + uint64_t cardSize; + ESP_LOGI(TAG, "looking for SD-card..."); // for usage of SD drivers on ESP32 platform see @@ -27,22 +27,51 @@ bool sdcard_init(bool create) { // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdmmc_host.html #if HAS_SDCARD == 1 // use SD SPI host driver - useSDCard = SD.begin(SDCARD_CS, SDCARD_MOSI, SDCARD_MISO, SDCARD_SCLK); + useSDCard = MYSD.begin(SDCARD_CS, SDCARD_MOSI, SDCARD_MISO, SDCARD_SCLK); #elif HAS_SDCARD == 2 // use SD MMC host driver // enable internal pullups of sd-data lines gpio_set_pull_mode(gpio_num_t(SDCARD_DATA0), GPIO_PULLUP_ONLY); gpio_set_pull_mode(gpio_num_t(SDCARD_DATA1), GPIO_PULLUP_ONLY); gpio_set_pull_mode(gpio_num_t(SDCARD_DATA2), GPIO_PULLUP_ONLY); gpio_set_pull_mode(gpio_num_t(SDCARD_DATA3), GPIO_PULLUP_ONLY); - useSDCard = SD_MMC.begin(); + useSDCard = MYSD.begin(); #endif if (useSDCard) { ESP_LOGI(TAG, "SD-card found"); - createFile(); - } else + cardType = MYSD.cardType(); + cardSize = MYSD.cardSize() / (1024 * 1024); + } else { ESP_LOGI(TAG, "SD-card not found"); - return useSDCard; + return false; + } + + if (cardType == CARD_NONE) { + ESP_LOGI(TAG, "No SD card attached"); + return false; + } + + if (cardType == CARD_MMC) { + ESP_LOGI(TAG, "SD Card type: MMC"); + } else if (cardType == CARD_SD) { + ESP_LOGI(TAG, "SD Card type: SDSC"); + } else if (cardType == CARD_SDHC) { + ESP_LOGI(TAG, "SD Card type: SDHC"); + } else { + ESP_LOGI(TAG, "SD Card type: UNKNOWN"); + } + + ESP_LOGI(TAG, "SD Card Size: %lluMB\n", cardSize); + + openFile(); + + return true; +} + +void sdcard_close(void) { + ESP_LOGI(TAG, "closing SD-card"); + fileSDCard.flush(); + fileSDCard.close(); } void sdcardWriteData(uint16_t noWifi, uint16_t noBle, @@ -60,7 +89,7 @@ void sdcardWriteData(uint16_t noWifi, uint16_t noBle, if (!useSDCard) return; - ESP_LOGD(TAG, "writing to SD-card"); + ESP_LOGI(TAG, "SD: writing data"); strftime(tempBuffer, sizeof(tempBuffer), "%FT%TZ", &tt); fileSDCard.print(tempBuffer); snprintf(tempBuffer, sizeof(tempBuffer), ",%d,%d", noWifi, noBle); @@ -78,51 +107,51 @@ void sdcardWriteData(uint16_t noWifi, uint16_t noBle, if (++counterWrites > 2) { // force writing to SD-card - ESP_LOGD(TAG, "flushing data to card"); + ESP_LOGI(TAG, "SD: flushing data"); fileSDCard.flush(); counterWrites = 0; } } -void createFile(void) { - char bufferFilename[8 + 1 + 3 + 1]; +void openFile(void) { + char bufferFilename[30]; useSDCard = false; - for (int i = 0; i < 100; i++) { - sprintf(bufferFilename, SDCARD_FILE_NAME, i); - ESP_LOGD(TAG, "SD: looking for file <%s>", bufferFilename); + snprintf(bufferFilename, sizeof(bufferFilename), "/%s.csv", SDCARD_FILE_NAME); + ESP_LOGI(TAG, "SD: looking for file <%s>", bufferFilename); -#if HAS_SDCARD == 1 - bool fileExists = SD.exists(bufferFilename); -#elif HAS_SDCARD == 2 - bool fileExists = SD_MMC.exists(bufferFilename); -#endif + /* + if (MYSD.exists(bufferFilename)) { + if (MYSD.open(bufferFilename, FILE_APPEND)) + useSDCard = true; + } else { + ESP_LOGI(TAG, "SD: file does not exist, creating it"); + if (MYSD.open(bufferFilename, FILE_WRITE)) + useSDCard = true; + } + */ - if (!fileExists) { - ESP_LOGD(TAG, "SD: file does not exist: creating"); + if (!MYSD.exists(bufferFilename)) + ESP_LOGI(TAG, "SD: file does not exist, creating it"); -#if HAS_SDCARD == 1 - fileSDCard = SD.open(bufferFilename, FILE_WRITE); -#elif HAS_SDCARD == 2 - fileSDCard = SD_MMC.open(bufferFilename, FILE_WRITE); -#endif + if (MYSD.open(bufferFilename, FILE_WRITE)) + useSDCard = true; - if (fileSDCard) { - ESP_LOGD(TAG, "SD: file opened: <%s>", bufferFilename); - fileSDCard.print(SDCARD_FILE_HEADER); + if (useSDCard) { + ESP_LOGI(TAG, "SD: file opened: <%s>", bufferFilename); + fileSDCard.print(SDCARD_FILE_HEADER); #if (defined BAT_MEASURE_ADC || defined HAS_PMU) - fileSDCard.print(SDCARD_FILE_HEADER_VOLTAGE); // for battery level data + fileSDCard.print(SDCARD_FILE_HEADER_VOLTAGE); // for battery level data #endif #if (HAS_SDS011) - fileSDCard.print(SDCARD_FILE_HEADER_SDS011); + fileSDCard.print(SDCARD_FILE_HEADER_SDS011); #endif - fileSDCard.println(); - useSDCard = true; - break; - } - } + fileSDCard.println(); + } else { + ESP_LOGE(TAG, "SD: file not opened error"); } + return; } From d2ee10f40a0afe78d1eecc410abdf068144cac11 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 30 Jan 2022 15:29:52 +0100 Subject: [PATCH 23/60] update paxcounter_orig.conf --- src/paxcounter_orig.conf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/paxcounter_orig.conf b/src/paxcounter_orig.conf index ecd4f948..ee6584d2 100644 --- a/src/paxcounter_orig.conf +++ b/src/paxcounter_orig.conf @@ -18,6 +18,11 @@ #define PAYLOAD_ENCODER 2 // payload encoder: 1=Plain, 2=Packed, 3=Cayenne LPP dynamic, 4=Cayenne LPP packed #define COUNTERMODE 0 // 0=cyclic, 1=cumulative, 2=cyclic confirmed +// default settings for transmission of sensor data (first list = data on / second line = data off) +#define PAYLOADMASK \ + ((GPS_DATA | MEMS_DATA | COUNT_DATA | SENSOR1_DATA | SENSOR2_DATA | SENSOR3_DATA) \ + & (~BATT_DATA) & (~RESERVED_DATA)) + // MAC sniffing parameters #define BLECOUNTER 1 // set to 0 if you do not want to install the BLE sniffer #define WIFICOUNTER 1 // set to 0 if you do not want to install the WIFI sniffer From d4f5f4ea8219a934e5b286cf6dd6b51337455f5b Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 30 Jan 2022 15:30:35 +0100 Subject: [PATCH 24/60] update platformio_orig.ini --- platformio_orig.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platformio_orig.ini b/platformio_orig.ini index 507058a6..c70bbd9e 100644 --- a/platformio_orig.ini +++ b/platformio_orig.ini @@ -16,10 +16,10 @@ ;halfile = ttgov1.h ;halfile = ttgov2.h ;halfile = ttgov21old.h -halfile = ttgov21new.h +;halfile = ttgov21new.h ;halfile = ttgofox.h ;halfile = ttgobeam.h -;halfile = ttgobeam10.h +halfile = ttgobeam10.h ;halfile = ttgotdisplay.h ;halfile = ttgotwristband.h ;halfile = fipy.h @@ -48,7 +48,7 @@ description = Paxcounter is a device for metering passenger flows in realtime. I [common] ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" -release_version = 3.1.1 +release_version = 3.1.2 ; 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 debug_level = 3 From 09d29c1d1f08491966d7451ba2bb8c4274ff0e7c Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 30 Jan 2022 15:32:14 +0100 Subject: [PATCH 25/60] Update paxcounter_orig.conf --- src/paxcounter_orig.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/paxcounter_orig.conf b/src/paxcounter_orig.conf index ee6584d2..f273cdd4 100644 --- a/src/paxcounter_orig.conf +++ b/src/paxcounter_orig.conf @@ -20,8 +20,8 @@ // default settings for transmission of sensor data (first list = data on / second line = data off) #define PAYLOADMASK \ - ((GPS_DATA | MEMS_DATA | COUNT_DATA | SENSOR1_DATA | SENSOR2_DATA | SENSOR3_DATA) \ - & (~BATT_DATA) & (~RESERVED_DATA)) + ((GPS_DATA | MEMS_DATA | COUNT_DATA | SENSOR1_DATA | SENSOR2_DATA | SENSOR3_DATA | BATT_DATA) \ + & (~RESERVED_DATA)) // MAC sniffing parameters #define BLECOUNTER 1 // set to 0 if you do not want to install the BLE sniffer From 2b9c7c8804d82a1d25e5ccbe6dbc1ff87ea0ef31 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 30 Jan 2022 15:32:43 +0100 Subject: [PATCH 26/60] Update platformio_orig.ini --- platformio_orig.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platformio_orig.ini b/platformio_orig.ini index c70bbd9e..58491357 100644 --- a/platformio_orig.ini +++ b/platformio_orig.ini @@ -16,10 +16,10 @@ ;halfile = ttgov1.h ;halfile = ttgov2.h ;halfile = ttgov21old.h -;halfile = ttgov21new.h +halfile = ttgov21new.h ;halfile = ttgofox.h ;halfile = ttgobeam.h -halfile = ttgobeam10.h +;halfile = ttgobeam10.h ;halfile = ttgotdisplay.h ;halfile = ttgotwristband.h ;halfile = fipy.h @@ -133,4 +133,4 @@ upload_protocol = esptool [env:dev] upload_protocol = esptool build_type = debug -platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-upstream \ No newline at end of file +platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-upstream From d45c96e5449b38354bbb8c898f16c32f6e5f5e17 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 30 Jan 2022 21:53:11 +0100 Subject: [PATCH 27/60] sdcard bugfixes --- include/sdcard.h | 2 -- src/sdcard.cpp | 77 ++++++++++++++++++++++++++++++------------------ 2 files changed, 48 insertions(+), 31 deletions(-) diff --git a/include/sdcard.h b/include/sdcard.h index 5a88ea5d..1dfb5f2d 100644 --- a/include/sdcard.h +++ b/include/sdcard.h @@ -8,10 +8,8 @@ #if (HAS_SDCARD) #if HAS_SDCARD == 1 #include -#define MYSD SD #elif HAS_SDCARD == 2 #include -#define MYSD SD_MMC #else #error HAS_SDCARD unknown card reader value, must be either 1 or 2 #endif diff --git a/src/sdcard.cpp b/src/sdcard.cpp index 476e4037..9f7737dd 100644 --- a/src/sdcard.cpp +++ b/src/sdcard.cpp @@ -10,7 +10,7 @@ static const char TAG[] = __FILE__; #ifdef HAS_SDCARD -static bool useSDCard = false; +static bool useSDCard; static void openFile(void); File fileSDCard; @@ -27,20 +27,25 @@ bool sdcard_init(bool create) { // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdmmc_host.html #if HAS_SDCARD == 1 // use SD SPI host driver - useSDCard = MYSD.begin(SDCARD_CS, SDCARD_MOSI, SDCARD_MISO, SDCARD_SCLK); + useSDCard = SD.begin(SDCARD_CS, SDCARD_MOSI, SDCARD_MISO, SDCARD_SCLK); #elif HAS_SDCARD == 2 // use SD MMC host driver // enable internal pullups of sd-data lines gpio_set_pull_mode(gpio_num_t(SDCARD_DATA0), GPIO_PULLUP_ONLY); gpio_set_pull_mode(gpio_num_t(SDCARD_DATA1), GPIO_PULLUP_ONLY); gpio_set_pull_mode(gpio_num_t(SDCARD_DATA2), GPIO_PULLUP_ONLY); gpio_set_pull_mode(gpio_num_t(SDCARD_DATA3), GPIO_PULLUP_ONLY); - useSDCard = MYSD.begin(); + useSDCard = SD_MMC.begin(); #endif if (useSDCard) { ESP_LOGI(TAG, "SD-card found"); - cardType = MYSD.cardType(); - cardSize = MYSD.cardSize() / (1024 * 1024); +#if HAS_SDCARD == 1 + cardType = SD.cardType(); + cardSize = SD.cardSize() / (1024 * 1024); +#elif HAS_SDCARD == 2 + cardType = SD_MMC.cardType(); + cardSize = SD_MMC.cardSize() / (1024 * 1024); +#endif } else { ESP_LOGI(TAG, "SD-card not found"); return false; @@ -60,8 +65,7 @@ bool sdcard_init(bool create) { } else { ESP_LOGI(TAG, "SD Card type: UNKNOWN"); } - - ESP_LOGI(TAG, "SD Card Size: %lluMB\n", cardSize); + ESP_LOGI(TAG, "SD Card Size: %lluMB", cardSize); openFile(); @@ -121,35 +125,50 @@ void openFile(void) { snprintf(bufferFilename, sizeof(bufferFilename), "/%s.csv", SDCARD_FILE_NAME); ESP_LOGI(TAG, "SD: looking for file <%s>", bufferFilename); - /* - if (MYSD.exists(bufferFilename)) { - if (MYSD.open(bufferFilename, FILE_APPEND)) - useSDCard = true; - } else { - ESP_LOGI(TAG, "SD: file does not exist, creating it"); - if (MYSD.open(bufferFilename, FILE_WRITE)) - useSDCard = true; - } - */ +#if HAS_SDCARD == 1 + bool fileExists = SD.exists(bufferFilename); +#elif HAS_SDCARD == 2 + bool fileExists = SD_MMC.exists(bufferFilename); +#endif - if (!MYSD.exists(bufferFilename)) - ESP_LOGI(TAG, "SD: file does not exist, creating it"); + // file not exists, create it + if (!fileExists) { + ESP_LOGD(TAG, "SD: file not found, creating..."); - if (MYSD.open(bufferFilename, FILE_WRITE)) - useSDCard = true; +#if HAS_SDCARD == 1 + fileSDCard = SD.open(bufferFilename, FILE_WRITE); +#elif HAS_SDCARD == 2 + fileSDCard = SD_MMC.open(bufferFilename, FILE_WRITE); +#endif - if (useSDCard) { - ESP_LOGI(TAG, "SD: file opened: <%s>", bufferFilename); - fileSDCard.print(SDCARD_FILE_HEADER); + if (fileSDCard) { + ESP_LOGD(TAG, "SD: name opened: <%s>", bufferFilename); + fileSDCard.print(SDCARD_FILE_HEADER); #if (defined BAT_MEASURE_ADC || defined HAS_PMU) - fileSDCard.print(SDCARD_FILE_HEADER_VOLTAGE); // for battery level data + fileSDCard.print(SDCARD_FILE_HEADER_VOLTAGE); // for battery level data #endif #if (HAS_SDS011) - fileSDCard.print(SDCARD_FILE_HEADER_SDS011); + fileSDCard.print(SDCARD_FILE_HEADER_SDS011); #endif - fileSDCard.println(); - } else { - ESP_LOGE(TAG, "SD: file not opened error"); + fileSDCard.println(); + useSDCard = true; + } + } + + // file exists, append data + else { + ESP_LOGD(TAG, "SD: file found, opening..."); + +#if HAS_SDCARD == 1 + fileSDCard = SD.open(bufferFilename, FILE_APPEND); +#elif HAS_SDCARD == 2 + fileSDCard = SD_MMC.open(bufferFilename, FILE_APPEND); +#endif + + if (fileSDCard) { + ESP_LOGD(TAG, "SD: name opened: <%s>", bufferFilename); + useSDCard = true; + } } return; From d6385f1f70d96e7f709457a6004d7b7157e4cb3e Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 30 Jan 2022 22:12:26 +0100 Subject: [PATCH 28/60] further sdcard fixes --- src/sdcard.cpp | 35 +++-------------------------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/src/sdcard.cpp b/src/sdcard.cpp index 9f7737dd..59d194d6 100644 --- a/src/sdcard.cpp +++ b/src/sdcard.cpp @@ -17,15 +17,11 @@ File fileSDCard; bool sdcard_init(bool create) { - uint8_t cardType; - uint64_t cardSize; - - ESP_LOGI(TAG, "looking for SD-card..."); - // for usage of SD drivers on ESP32 platform see // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdspi_host.html // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdmmc_host.html + ESP_LOGI(TAG, "looking for SD-card..."); #if HAS_SDCARD == 1 // use SD SPI host driver useSDCard = SD.begin(SDCARD_CS, SDCARD_MOSI, SDCARD_MISO, SDCARD_SCLK); #elif HAS_SDCARD == 2 // use SD MMC host driver @@ -39,37 +35,12 @@ bool sdcard_init(bool create) { if (useSDCard) { ESP_LOGI(TAG, "SD-card found"); -#if HAS_SDCARD == 1 - cardType = SD.cardType(); - cardSize = SD.cardSize() / (1024 * 1024); -#elif HAS_SDCARD == 2 - cardType = SD_MMC.cardType(); - cardSize = SD_MMC.cardSize() / (1024 * 1024); -#endif + openFile(); + return true; } else { ESP_LOGI(TAG, "SD-card not found"); return false; } - - if (cardType == CARD_NONE) { - ESP_LOGI(TAG, "No SD card attached"); - return false; - } - - if (cardType == CARD_MMC) { - ESP_LOGI(TAG, "SD Card type: MMC"); - } else if (cardType == CARD_SD) { - ESP_LOGI(TAG, "SD Card type: SDSC"); - } else if (cardType == CARD_SDHC) { - ESP_LOGI(TAG, "SD Card type: SDHC"); - } else { - ESP_LOGI(TAG, "SD Card type: UNKNOWN"); - } - ESP_LOGI(TAG, "SD Card Size: %lluMB", cardSize); - - openFile(); - - return true; } void sdcard_close(void) { From 353e55f0c230799e31082854515b23437f7574fc Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 30 Jan 2022 23:27:28 +0100 Subject: [PATCH 29/60] remove esp32-micro-sdcard library --- include/sdcard.h | 2 +- platformio_orig.ini | 5 ++--- src/sdcard.cpp | 9 ++++++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/sdcard.h b/include/sdcard.h index 1dfb5f2d..25fcf2c4 100644 --- a/include/sdcard.h +++ b/include/sdcard.h @@ -7,7 +7,7 @@ #if (HAS_SDCARD) #if HAS_SDCARD == 1 -#include +#include #elif HAS_SDCARD == 2 #include #else diff --git a/platformio_orig.ini b/platformio_orig.ini index 58491357..0fea3a83 100644 --- a/platformio_orig.ini +++ b/platformio_orig.ini @@ -16,10 +16,10 @@ ;halfile = ttgov1.h ;halfile = ttgov2.h ;halfile = ttgov21old.h -halfile = ttgov21new.h +;halfile = ttgov21new.h ;halfile = ttgofox.h ;halfile = ttgobeam.h -;halfile = ttgobeam10.h +halfile = ttgobeam10.h ;halfile = ttgotdisplay.h ;halfile = ttgotwristband.h ;halfile = fipy.h @@ -85,7 +85,6 @@ lib_deps_basic = makuna/RTC @ ^2.3.5 spacehuhn/SimpleButton lewisxhe/AXP202X_Library @ ^1.1.3 - geeksville/esp32-micro-sdcard @ ^0.1.1 256dpi/MQTT @ ^2.4.8 lib_deps_all = ${common.lib_deps_basic} diff --git a/src/sdcard.cpp b/src/sdcard.cpp index 59d194d6..72af507e 100644 --- a/src/sdcard.cpp +++ b/src/sdcard.cpp @@ -15,6 +15,10 @@ static void openFile(void); File fileSDCard; +#if HAS_SDCARD == 1 +SPIClass sd_spi; +#endif + bool sdcard_init(bool create) { // for usage of SD drivers on ESP32 platform see @@ -23,7 +27,10 @@ bool sdcard_init(bool create) { ESP_LOGI(TAG, "looking for SD-card..."); #if HAS_SDCARD == 1 // use SD SPI host driver - useSDCard = SD.begin(SDCARD_CS, SDCARD_MOSI, SDCARD_MISO, SDCARD_SCLK); + digitalWrite(SDCARD_CS, HIGH); + sd_spi.begin(SDCARD_SCLK, SDCARD_MISO, SDCARD_MOSI, SDCARD_CS); + digitalWrite(SDCARD_CS, LOW); + useSDCard = SD.begin(SDCARD_CS, sd_spi); #elif HAS_SDCARD == 2 // use SD MMC host driver // enable internal pullups of sd-data lines gpio_set_pull_mode(gpio_num_t(SDCARD_DATA0), GPIO_PULLUP_ONLY); From 746cb0ede21a23a0853c08b46848846b9e8f4549 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 30 Jan 2022 23:32:09 +0100 Subject: [PATCH 30/60] paxcounter_orig.conf set back to defaults --- src/paxcounter_orig.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/paxcounter_orig.conf b/src/paxcounter_orig.conf index f273cdd4..143d3d21 100644 --- a/src/paxcounter_orig.conf +++ b/src/paxcounter_orig.conf @@ -14,14 +14,14 @@ // Payload send cycle and encoding #define SENDCYCLE 30 // payload send cycle [seconds/2], 0 .. 255 -#define SLEEPCYCLE 1800 // sleep time after a send cycle [seconds/10], 0 .. 65535; 0 means no sleep [default = 0] +#define SLEEPCYCLE 0 // sleep time after a send cycle [seconds/10], 0 .. 65535; 0 means no sleep [default = 0] #define PAYLOAD_ENCODER 2 // payload encoder: 1=Plain, 2=Packed, 3=Cayenne LPP dynamic, 4=Cayenne LPP packed #define COUNTERMODE 0 // 0=cyclic, 1=cumulative, 2=cyclic confirmed // default settings for transmission of sensor data (first list = data on / second line = data off) #define PAYLOADMASK \ - ((GPS_DATA | MEMS_DATA | COUNT_DATA | SENSOR1_DATA | SENSOR2_DATA | SENSOR3_DATA | BATT_DATA) \ - & (~RESERVED_DATA)) + ((GPS_DATA | MEMS_DATA | COUNT_DATA | SENSOR1_DATA | SENSOR2_DATA | SENSOR3_DATA) & \ + & (~BATT_DATA) & (~RESERVED_DATA)) // MAC sniffing parameters #define BLECOUNTER 1 // set to 0 if you do not want to install the BLE sniffer From a4133d6e0ab001b69862ce5a4afb2710d80f4ac1 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Mon, 31 Jan 2022 09:24:47 +0100 Subject: [PATCH 31/60] correction in paxcounter_orig.conf --- src/paxcounter_orig.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/paxcounter_orig.conf b/src/paxcounter_orig.conf index 143d3d21..e0f0eb11 100644 --- a/src/paxcounter_orig.conf +++ b/src/paxcounter_orig.conf @@ -21,7 +21,7 @@ // default settings for transmission of sensor data (first list = data on / second line = data off) #define PAYLOADMASK \ ((GPS_DATA | MEMS_DATA | COUNT_DATA | SENSOR1_DATA | SENSOR2_DATA | SENSOR3_DATA) & \ - & (~BATT_DATA) & (~RESERVED_DATA)) + (~BATT_DATA) & (~RESERVED_DATA)) // MAC sniffing parameters #define BLECOUNTER 1 // set to 0 if you do not want to install the BLE sniffer From e6f4e26d736d7d6ad45b673af5cd9b699c079833 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Mon, 31 Jan 2022 11:03:22 +0100 Subject: [PATCH 32/60] readme.md: update section SD card --- README.md | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index a61d400a..6cb527ec 100644 --- a/README.md +++ b/README.md @@ -218,7 +218,7 @@ This describes how to set up a mobile PaxCounter:
Follow all steps so far fo # SD-card -Data can be stored on an SD-card if one is availabe. Simply choose the file in src/hal and add the following lines to your hal-file: +Data can be stored on an SD-card if the board has SD-card slot. To enable this feature, specify the board's SD interface and it's pins in the board's hal file (src/hal/): #define HAS_SDCARD 1 // SD-card-reader/writer, using SPI interface OR @@ -230,31 +230,22 @@ Data can be stored on an SD-card if one is availabe. Simply choose the file in s #define SDCARD_MISO (2) #define SDCARD_SCLK (14) -Please choose the correct number for the connection of the reader/writer. - This is an example of a board with SD-card: https://www.aliexpress.com/item/32990008126.html -In this case you take the file src/hal/ttgov21new.h and add the lines given above (numbers given are for this board). +For this board use file src/hal/ttgov21new.h and add the lines given above. Another approach would be this tiny board: https://www.aliexpress.com/item/32424558182.html (needs 5V). In this case you choose the correct file for your ESP32-board in the src/hal-directory and add the lines given above to the correct h-file. Please correct the numbers given in the example to the numbers used corresponding to your wiring. -Some hints: -These cheap devices often handle SD-cards up to 32GB, not bigger ones. They can handle files in the old DOS-way, to say the filenames are in the 8.3-format. And they often cannot handle subdirectories. +Data is written to a single file and after 3 write-operations the data is flushed to the disk to minimize flash write cycles. Thus, up to the last 3 records of data will get lost when the PAXCOUNTER looses power. -The software included here writes data in a file named PAXCOUNT.xx, where xx can range from 00 to 99. The software starts with 00, checks to see if such a file already exists and if yes it will continue with the next number (up to 99 - in this case it will return no sd-card). So an existing file will not be overwritten. - -The data is written to the card and after 3 write-operations the data is flushed to the disk. Thus, up to the last 3 records of data will get lost when the PAXCOUNTER looses power. - -And finally: this is the data written to the disk: +Format of the file is CSV, thus easy import in LibreOffice, Excel, Influx, etc. Each record contains timestamp (ISO8601), paxcount (wifi and ble) and battery voltage (optional). Voltage is logged, if the device has a battery voltage sensor (to be configure in board hal file). timestamp,wifi,ble[,voltage] - 2022-01-28T19:36:35Z,17,48 - 2022-01-28T19:37:35Z,21,52 - 2022-01-28T19:38:35Z,14,49 + 2022-01-30T21:12:41Z,11,25[,4100] + 2022-01-30T21:14:24Z,10,21[,4070] + 2022-01-30T21:16:08Z,12,26[,4102] + 2022-01-30T21:17:52Z,11,26[,4076] -Format of the data is CSV, timestamp is ISO8601, which can easily imported into LibreOffice, Excel, Influx, etc. -Voltage is logged, if the device has a battery voltage sensor (to be configure in board hal file). - If you want to change this please look into src/sdcard.cpp and include/sdcard.h. # Integration into "The Things Stack Community Edition" aka "The Things Stack V3" From 01745f00497e726c0968b406c751477efee6b9f9 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Mon, 31 Jan 2022 22:28:39 +0100 Subject: [PATCH 33/60] polish readme.md --- README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 6cb527ec..9d4fe759 100644 --- a/README.md +++ b/README.md @@ -218,11 +218,11 @@ This describes how to set up a mobile PaxCounter:
Follow all steps so far fo # SD-card -Data can be stored on an SD-card if the board has SD-card slot. To enable this feature, specify the board's SD interface and it's pins in the board's hal file (src/hal/): +Data can be stored on SD-card if the board provides an SD card interface, either with SPI or MMC mode. To enable this feature, specify interface mode and hardware pins in board's hal file (src/hal/): - #define HAS_SDCARD 1 // SD-card-reader/writer, using SPI interface + #define HAS_SDCARD 1 // SD-card interface, using SPI mode OR - #define HAS_SDCARD 2 // SD-card-reader/writer, using SDMMC interface + #define HAS_SDCARD 2 // SD-card interface, using MMC mode // Pins for SPI interface #define SDCARD_CS (13) // fill in the correct numbers for your board @@ -230,15 +230,16 @@ Data can be stored on an SD-card if the board has SD-card slot. To enable this f #define SDCARD_MISO (2) #define SDCARD_SCLK (14) -This is an example of a board with SD-card: https://www.aliexpress.com/item/32990008126.html -For this board use file src/hal/ttgov21new.h and add the lines given above. +This is an example of a board with MMC SD-card interface: https://www.aliexpress.com/item/32915894264.html. For this board use file src/hal/ttgov21new.h and add the lines given above. Another approach would be this tiny board: https://www.aliexpress.com/item/32424558182.html (needs 5V). -In this case you choose the correct file for your ESP32-board in the src/hal-directory and add the lines given above to the correct h-file. Please correct the numbers given in the example to the numbers used corresponding to your wiring. +In this case you choose the correct file for your ESP32-board in the src/hal-directory and add the lines given above. Edit the pin numbers given in the example, according to your wiring. -Data is written to a single file and after 3 write-operations the data is flushed to the disk to minimize flash write cycles. Thus, up to the last 3 records of data will get lost when the PAXCOUNTER looses power. +Data is written on SD-card to a single file. After 3 write operations the data is flushed to the disk to minimize flash write cycles. Thus, up to the last 3 records of data will get lost when the PAXCOUNTER looses power during operation. -Format of the file is CSV, thus easy import in LibreOffice, Excel, Influx, etc. Each record contains timestamp (ISO8601), paxcount (wifi and ble) and battery voltage (optional). Voltage is logged, if the device has a battery voltage sensor (to be configure in board hal file). +Format of the resulting file is CSV, thus easy import in LibreOffice, Excel, Influx, etc. Each record contains timestamp (in ISO8601 format), paxcount (wifi and ble) and battery voltage (optional). Voltage is logged if the device has a battery voltage sensor (to be configured in board hal file). + +File contents example: timestamp,wifi,ble[,voltage] 2022-01-30T21:12:41Z,11,25[,4100] @@ -246,7 +247,7 @@ Format of the file is CSV, thus easy import in LibreOffice, Excel, Influx, etc. 2022-01-30T21:16:08Z,12,26[,4102] 2022-01-30T21:17:52Z,11,26[,4076] -If you want to change this please look into src/sdcard.cpp and include/sdcard.h. +If you want to change this, modify src/sdcard.cpp and include/sdcard.h. # Integration into "The Things Stack Community Edition" aka "The Things Stack V3" From a447aaafb9ebb7dc6d3a4419ca7296b9a00c087d Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Tue, 1 Feb 2022 22:25:35 +0100 Subject: [PATCH 34/60] readme.md edits --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d4fe759..4cdf2f2d 100644 --- a/README.md +++ b/README.md @@ -202,7 +202,7 @@ Output of sensor and peripheral data is internally switched by a bitmask registe # Power saving mode -Paxcounter supports a battery friendly power saving mode. In this mode the device enters deep sleep, after all data is polled from all sensors and the dataset is completeley sent through all user configured channels (LORAWAN / SPI / MQTT). Set *#define SLEEPCYCLE* in paxcounter.conf to enable power saving mode and to specify the duration of a sleep cycle. Power consumption in deep sleep mode depends on your hardware, i.e. if on board peripherals can be switched off or set to a chip specific sleep mode either by MCU or by power management unit (PMU) as found on TTGO T-BEAM v1.0/V1.1. See *power.cpp* for power management, and *reset.cpp* for sleep and wakeup logic. +Paxcounter supports a battery friendly power saving mode. In this mode the device enters deep sleep, after all data is polled from all sensors and the dataset is completeley sent through all user configured channels (LORAWAN / SPI / MQTT / SD-Card). Set *#define SLEEPCYCLE* in paxcounter.conf to enable power saving mode and to specify the duration of a sleep cycle. Power consumption in deep sleep mode depends on your hardware, i.e. if on board peripherals can be switched off or set to a chip specific sleep mode either by MCU or by power management unit (PMU) as found on TTGO T-BEAM v1.0/V1.1. See *power.cpp* for power management, and *reset.cpp* for sleep and wakeup logic. # Time sync From 296194875964a39aca1e43c55ff24fcb4da57367 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 6 Feb 2022 18:29:30 +0100 Subject: [PATCH 35/60] improve ublox gps chip init --- include/gpsread.h | 6 +- src/gpsread.cpp | 187 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 173 insertions(+), 20 deletions(-) diff --git a/include/gpsread.h b/include/gpsread.h index fe204bea..1025065d 100644 --- a/include/gpsread.h +++ b/include/gpsread.h @@ -9,7 +9,11 @@ #include #endif -#define NMEA_FRAME_SIZE 82 // NEMA has a maxium of 82 bytes per record +#ifndef GPS_BAUDRATE +#define GPS_BAUDRATE 115200 +#endif + +#define NMEA_FRAME_SIZE 82 // NEMA has a maxium of 82 bytes per record #define NMEA_COMPENSATION_FACTOR 480 // empiric for Ublox Neo 6M extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 86da8fef..0405522e 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -27,17 +27,176 @@ static uint16_t nmea_txDelay_ms = static uint16_t nmea_txDelay_ms = 0; #endif +// helper functions to send UBX commands to ublox gps chip + +// Send the packet specified to the receiver. +void sendPacket(byte *packet, byte len) { + + uint8_t CK_A = 0; + uint8_t CK_B = 0; + + for (int i = 0; i < len; i++) { +#ifdef GPS_SERIAL + GPS_Serial.write(packet[i]); +#elif defined GPS_I2C + Wire.write(packet[i]); +#endif + } + + // calculate Fletcher checksum + for (int i = 2; i < len; i++) { + CK_A += packet[i]; + CK_B += CK_A; + } + +// send checksum +#ifdef GPS_SERIAL + GPS_Serial.write(CK_A); + GPS_Serial.write(CK_B); +#elif defined GPS_I2C + Wire.write(CK_A); + Wire.write(CK_B); +#endif +} + +// Send a packet to the receiver to restore default configuration. +void restoreDefaults() { + // CFG-CFG packet. + byte packet[] = { + 0xB5, // sync char 1 + 0x62, // sync char 2 + 0x06, // class + 0x09, // id + 0x0D, // length + 0x00, // length + 0b00011111, // clearmask + 0b00000110, // clearmask + 0x00, // clearmask + 0x00, // clearmask + 0x00, // savemask + 0x00, // savemask + 0x00, // savemask + 0x00, // savemask + 0b00011111, // loadmask + 0b00000110, // loadmask + 0x00, // loadmask + 0x00, // loadmask + 0b00010001 // devicemask + }; + + sendPacket(packet, sizeof(packet)); +} + +// Send a set of packets to the receiver to disable NMEA messages. +void disableNmea() { + + // for tinygps++ we need only $GPGGA and $GPRMC + // for time we use $GPZDA + // we disable all others + + // Array of two bytes for CFG-MSG packets payload. + byte messages[][2] = {{0xF0, 0x01}, {0xF0, 0x02}, {0xF0, 0x03}, {0xF0, 0x05}, + {0xF0, 0x06}, {0xF0, 0x07}, {0xF0, 0x09}, {0xF0, 0x0A}, + {0xF0, 0x0E}, {0xF1, 0x00}, {0xF1, 0x03}, {0xF1, 0x04}, + {0xF1, 0x05}, {0xF1, 0x06}}; + + // CFG-MSG packet buffer. + byte packet[] = { + 0xB5, // sync char 1 + 0x62, // sync char 2 + 0x06, // class + 0x01, // id + 0x03, // length + 0x00, // length + 0x00, // payload (first byte from messages array element) + 0x00, // payload (second byte from messages array element) + 0x00 // payload (zero to disable message) + }; + + byte packetSize = sizeof(packet); + + // Offset to the place where payload starts. + byte payloadOffset = 6; + + // Iterate over the messages array. + for (byte i = 0; i < sizeof(messages) / sizeof(*messages); i++) { + // Copy two bytes of payload to the packet buffer. + for (byte j = 0; j < sizeof(*messages); j++) { + packet[payloadOffset + j] = messages[i][j]; + } + sendPacket(packet, packetSize); + } +} + +// Send a packet to the receiver to change baudrate to 115200. +void changeBaudrate(uint32_t baudRate) { + // CFG-PRT packet. + byte packet[] = { + 0xB5, // sync char 1 + 0x62, // sync char 2 + 0x06, // class + 0x00, // id + 0x14, // length + 0x00, // length + 0x01, // portID (UART 1) + 0x00, // reserved + 0x00, // reserved + 0x00, // reserved + 0b11010000, // UART mode: 8bit + 0b00001000, // UART mode: No Parity, 1 Stopbit + 0x00, // UART mode + 0x00, // UART mode + (byte)baudRate, // baudrate (4 bytes) + (byte)(baudRate >> 4), // . + (byte)(baudRate >> 8), // . + (byte)(baudRate >> 12), // . + 0b00000011, // input protocols: NMEA + UBX + 0b00000000, // input protocols + 0b00000010, // output protocols: NMEA + 0x00000000, // output protocols + 0x00, // reserved + 0x00, // reserved + 0x00, // reserved + 0x00 // reserved + }; + + sendPacket(packet, sizeof(packet)); +} + +// Send a packet to the receiver to change frequency to 100 ms. +void changeFrequency() { + // CFG-RATE packet. + byte packet[] = { + 0xB5, // sync char 1 + 0x62, // sync char 2 + 0x06, // class + 0x08, // id + 0x06, // length + 0x00, // length + 0x64, // Measurement rate 100ms + 0x00, // Measurement rate + 0x01, // Measurement cycles + 0x00, // Measurement cycles + 0x01, // Alignment to reference time: GPS time + 0x00 // payload + }; + + sendPacket(packet, sizeof(packet)); +} + // initialize and configure GPS int gps_init(void) { - if (!gps_config()) { - ESP_LOGE(TAG, "GPS chip initializiation error"); - return 0; - } + restoreDefaults(); #ifdef GPS_SERIAL ESP_LOGI(TAG, "Opening serial GPS"); GPS_Serial.begin(GPS_SERIAL); + changeBaudrate(GPS_BAUDRATE); + delay(100); + GPS_Serial.flush(); + GPS_Serial.updateBaudRate(GPS_BAUDRATE); + #elif defined GPS_I2C ESP_LOGI(TAG, "Opening I2C GPS"); Wire.begin(GPS_I2C, 400000); // I2C connect to GPS device with 400 KHz @@ -50,24 +209,14 @@ int gps_init(void) { ESP_LOGI(TAG, "Quectel L76 GPS chip found"); #endif + disableNmea(); + changeFrequency(); + // enableNavTimeUTC(); + return 1; + } // gps_init() -// detect gps chipset type and configure it with device specific settings -int gps_config() { - int rslt = 1; // success -#if defined GPS_SERIAL - - /* insert user configuration here, if needed */ - -#elif defined GPS_I2C - - /* insert user configuration here, if needed */ - -#endif - return rslt; -} - // store current GPS location data in struct void gps_storelocation(gpsStatus_t *gps_store) { if (gps.location.isUpdated() && gps.location.isValid() && From 02c29afca60be9cb8af335dc6d1abd7f817120b7 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 6 Feb 2022 18:33:17 +0100 Subject: [PATCH 36/60] remove incompleted I2C gps support --- src/gpsread.cpp | 44 ++------------------------------------------ src/hal/lopy.h | 5 ----- src/hal/lopy4.h | 5 ----- 3 files changed, 2 insertions(+), 52 deletions(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 0405522e..2d0ebf4b 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -19,13 +19,9 @@ TinyGPSCustom gpsyear(gps, "GPZDA", 4); // field 4 = year (4-digit) static const String ZDA_Request = "$EIGPQ,ZDA*39\r\n"; TaskHandle_t GpsTask; -#ifdef GPS_SERIAL HardwareSerial GPS_Serial(1); // use UART #1 static uint16_t nmea_txDelay_ms = (tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL) / portTICK_PERIOD_MS); -#else -static uint16_t nmea_txDelay_ms = 0; -#endif // helper functions to send UBX commands to ublox gps chip @@ -35,28 +31,16 @@ void sendPacket(byte *packet, byte len) { uint8_t CK_A = 0; uint8_t CK_B = 0; - for (int i = 0; i < len; i++) { -#ifdef GPS_SERIAL + for (int i = 0; i < len; i++) GPS_Serial.write(packet[i]); -#elif defined GPS_I2C - Wire.write(packet[i]); -#endif - } - // calculate Fletcher checksum + // calculate and send Fletcher checksum for (int i = 2; i < len; i++) { CK_A += packet[i]; CK_B += CK_A; } - -// send checksum -#ifdef GPS_SERIAL GPS_Serial.write(CK_A); GPS_Serial.write(CK_B); -#elif defined GPS_I2C - Wire.write(CK_A); - Wire.write(CK_B); -#endif } // Send a packet to the receiver to restore default configuration. @@ -189,7 +173,6 @@ int gps_init(void) { restoreDefaults(); -#ifdef GPS_SERIAL ESP_LOGI(TAG, "Opening serial GPS"); GPS_Serial.begin(GPS_SERIAL); changeBaudrate(GPS_BAUDRATE); @@ -197,18 +180,6 @@ int gps_init(void) { GPS_Serial.flush(); GPS_Serial.updateBaudRate(GPS_BAUDRATE); -#elif defined GPS_I2C - ESP_LOGI(TAG, "Opening I2C GPS"); - Wire.begin(GPS_I2C, 400000); // I2C connect to GPS device with 400 KHz - Wire.beginTransmission(GPS_ADDR); - Wire.write(0x00); // dummy write - if (Wire.endTransmission()) { - ESP_LOGE(TAG, "Quectel L76 GPS chip not found"); - return 0; - } else - ESP_LOGI(TAG, "Quectel L76 GPS chip found"); -#endif - disableNmea(); changeFrequency(); // enableNavTimeUTC(); @@ -242,13 +213,9 @@ bool gps_hasfix() { time_t get_gpstime(uint16_t *msec) { // poll NMEA ZDA sentence -#ifdef GPS_SERIAL GPS_Serial.print(ZDA_Request); // wait for gps NMEA answer // vTaskDelay(tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL)); -#elif defined GPS_I2C - Wire.print(ZDA_Request); -#endif // did we get a current date & time? if (gpstime.isValid()) { @@ -291,17 +258,10 @@ void gps_loop(void *pvParameters) { while (1) { while (cfg.payloadmask & GPS_DATA) { -#ifdef GPS_SERIAL // feed GPS decoder with serial NMEA data from GPS device while (GPS_Serial.available()) if (gps.encode(GPS_Serial.read())) break; // NMEA sentence complete -#elif defined GPS_I2C - Wire.requestFrom(GPS_ADDR, 32); // caution: this is a blocking call - while (Wire.available()) - if (gps.encode(Wire.read())) - break; // NMEA sentence complete -#endif // (only) while device time is not set or unsynched, and we have a valid // GPS time, we call calibrateTime to poll time immeditately from GPS diff --git a/src/hal/lopy.h b/src/hal/lopy.h index 733eb603..e196ee1a 100644 --- a/src/hal/lopy.h +++ b/src/hal/lopy.h @@ -20,11 +20,6 @@ #define HAS_ANTENNA_SWITCH (16) // pin for switching wifi antenna #define WIFI_ANTENNA 0 // 0 = internal, 1 = external -// uncomment this only if your LoPy runs on a PYTRACK BOARD -#define HAS_GPS 1 -#define GPS_I2C GPIO_NUM_25, GPIO_NUM_26 // SDA (P22), SCL (P21) -#define GPS_ADDR 0x10 - // uncomment this only if your LoPy runs on a EXPANSION BOARD //#define HAS_LED (12) // use if LoPy is on Expansion Board, this has a user LED //#define LED_ACTIVE_LOW 1 // use if LoPy is on Expansion Board, this has a user LED diff --git a/src/hal/lopy4.h b/src/hal/lopy4.h index fd99a7d7..0c5999f0 100644 --- a/src/hal/lopy4.h +++ b/src/hal/lopy4.h @@ -30,11 +30,6 @@ #define HAS_ANTENNA_SWITCH (21) // pin for switching wifi antenna (P12) #define WIFI_ANTENNA 0 // 0 = internal, 1 = external -// uncomment defines in this section ONLY if your LoPy lives on a PYTRACK BOARD -//#define HAS_GPS 1 -//#define GPS_I2C GPIO_NUM_25, GPIO_NUM_26 // SDA (P22), SCL (P21) -//#define GPS_ADDR 0x10 - // uncomment defines in this section ONLY if your LoPy lives on a EXPANSION BOARD //#define HAS_LED (12) // use if LoPy is on Expansion Board, this has a user LED //#define LED_ACTIVE_LOW 1 // use if LoPy is on Expansion Board, this has a user LED From ef15fa2d2a7f2635f2a9901a37636a1c1083e219 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 6 Feb 2022 20:23:08 +0100 Subject: [PATCH 37/60] cyclic.cpp: task errorhandling added --- src/cyclic.cpp | 55 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/src/cyclic.cpp b/src/cyclic.cpp index d197e234..45bac2f2 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -22,44 +22,55 @@ void doHousekeeping() { if ((RTC_runmode == RUNMODE_UPDATE) || (RTC_runmode == RUNMODE_MAINTENANCE)) do_reset(true); // warmstart - // heap and task storage debugging + // print heap and task storage information ESP_LOGD(TAG, "Heap: Free:%d, Min:%d, Size:%d, Alloc:%d, StackHWM:%d", ESP.getFreeHeap(), ESP.getMinFreeHeap(), ESP.getHeapSize(), ESP.getMaxAllocHeap(), uxTaskGetStackHighWaterMark(NULL)); - ESP_LOGD(TAG, "IRQhandler %d bytes left | Taskstate = %d", - uxTaskGetStackHighWaterMark(irqHandlerTask), - eTaskGetState(irqHandlerTask)); - ESP_LOGD(TAG, "Rcommand interpreter %d bytes left | Taskstate = %d", - uxTaskGetStackHighWaterMark(rcmdTask), eTaskGetState(rcmdTask)); + + if (irqHandlerTask != NULL) + ESP_LOGD(TAG, "IRQhandler %d bytes left | Taskstate = %d", + uxTaskGetStackHighWaterMark(irqHandlerTask), + eTaskGetState(irqHandlerTask)); + if (rcmdTask != NULL) + ESP_LOGD(TAG, "Rcommand interpreter %d bytes left | Taskstate = %d", + uxTaskGetStackHighWaterMark(rcmdTask), eTaskGetState(rcmdTask)); #if (HAS_LORA) - ESP_LOGD(TAG, "LMiCtask %d bytes left | Taskstate = %d", - uxTaskGetStackHighWaterMark(lmicTask), eTaskGetState(lmicTask)); - ESP_LOGD(TAG, "Lorasendtask %d bytes left | Taskstate = %d", - uxTaskGetStackHighWaterMark(lorasendTask), - eTaskGetState(lorasendTask)); + if (lmicTask != NULL) + ESP_LOGD(TAG, "LMiCtask %d bytes left | Taskstate = %d", + uxTaskGetStackHighWaterMark(lmicTask), eTaskGetState(lmicTask)); + if (lorasendTask != NULL) + ESP_LOGD(TAG, "Lorasendtask %d bytes left | Taskstate = %d", + uxTaskGetStackHighWaterMark(lorasendTask), + eTaskGetState(lorasendTask)); #endif #if (HAS_GPS) - ESP_LOGD(TAG, "Gpsloop %d bytes left | Taskstate = %d", - uxTaskGetStackHighWaterMark(GpsTask), eTaskGetState(GpsTask)); + if (GpsTask != NULL) + ESP_LOGD(TAG, "Gpsloop %d bytes left | Taskstate = %d", + uxTaskGetStackHighWaterMark(GpsTask), eTaskGetState(GpsTask)); #endif #ifdef HAS_SPI - ESP_LOGD(TAG, "spiloop %d bytes left | Taskstate = %d", - uxTaskGetStackHighWaterMark(spiTask), eTaskGetState(spiTask)); + if (spiTask != NULL) + ESP_LOGD(TAG, "spiloop %d bytes left | Taskstate = %d", + uxTaskGetStackHighWaterMark(spiTask), eTaskGetState(spiTask)); #endif + #ifdef HAS_MQTT - ESP_LOGD(TAG, "MQTTloop %d bytes left | Taskstate = %d", - uxTaskGetStackHighWaterMark(mqttTask), eTaskGetState(mqttTask)); + if (mqttTask != NULL) + ESP_LOGD(TAG, "MQTTloop %d bytes left | Taskstate = %d", + uxTaskGetStackHighWaterMark(mqttTask), eTaskGetState(mqttTask)); #endif #if (defined HAS_DCF77 || defined HAS_IF482) - ESP_LOGD(TAG, "Clockloop %d bytes left | Taskstate = %d", - uxTaskGetStackHighWaterMark(ClockTask), eTaskGetState(ClockTask)); + if (ClockTask != NULL) + ESP_LOGD(TAG, "Clockloop %d bytes left | Taskstate = %d", + uxTaskGetStackHighWaterMark(ClockTask), eTaskGetState(ClockTask)); #endif #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) - ESP_LOGD(TAG, "LEDloop %d bytes left | Taskstate = %d", - uxTaskGetStackHighWaterMark(ledLoopTask), - eTaskGetState(ledLoopTask)); + if (ledLoopTask != NULL) + ESP_LOGD(TAG, "LEDloop %d bytes left | Taskstate = %d", + uxTaskGetStackHighWaterMark(ledLoopTask), + eTaskGetState(ledLoopTask)); #endif // read battery voltage into global variable From babfe4b245e3f49e0a2c58de627fa82076926bfe Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 6 Feb 2022 20:23:34 +0100 Subject: [PATCH 38/60] UBX commands bugfix baudrate --- src/gpsread.cpp | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 2d0ebf4b..f7dd1167 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -25,6 +25,18 @@ static uint16_t nmea_txDelay_ms = // helper functions to send UBX commands to ublox gps chip +/* +// Print the UBX packet for debugging +void printPacket(byte *packet, byte len) { + char temp[3]; + + for (byte i = 0; i < len; i++) { + sprintf(temp, "%.2X", packet[i]); + ESP_LOGD(TAG, "%s", temp); + } +} +*/ + // Send the packet specified to the receiver. void sendPacket(byte *packet, byte len) { @@ -75,8 +87,8 @@ void restoreDefaults() { void disableNmea() { // for tinygps++ we need only $GPGGA and $GPRMC - // for time we use $GPZDA - // we disable all others + // for getting time we use $GPZDA + // we disable all other NMEA messages // Array of two bytes for CFG-MSG packets payload. byte messages[][2] = {{0xF0, 0x01}, {0xF0, 0x02}, {0xF0, 0x03}, {0xF0, 0x05}, @@ -124,20 +136,20 @@ void changeBaudrate(uint32_t baudRate) { 0x00, // length 0x01, // portID (UART 1) 0x00, // reserved - 0x00, // reserved - 0x00, // reserved + 0x00, // txReady + 0x00, // . 0b11010000, // UART mode: 8bit 0b00001000, // UART mode: No Parity, 1 Stopbit - 0x00, // UART mode - 0x00, // UART mode + 0x00, // . + 0x00, // . (byte)baudRate, // baudrate (4 bytes) - (byte)(baudRate >> 4), // . (byte)(baudRate >> 8), // . - (byte)(baudRate >> 12), // . + (byte)(baudRate >> 16), // . + (byte)(baudRate >> 24), // . 0b00000011, // input protocols: NMEA + UBX - 0b00000000, // input protocols + 0b00000000, // . 0b00000010, // output protocols: NMEA - 0x00000000, // output protocols + 0x00000000, // . 0x00, // reserved 0x00, // reserved 0x00, // reserved @@ -161,7 +173,7 @@ void changeFrequency() { 0x00, // Measurement rate 0x01, // Measurement cycles 0x00, // Measurement cycles - 0x01, // Alignment to reference time: GPS time + 0x00, // Alignment to reference time: UTC time 0x00 // payload }; @@ -171,10 +183,10 @@ void changeFrequency() { // initialize and configure GPS int gps_init(void) { - restoreDefaults(); - ESP_LOGI(TAG, "Opening serial GPS"); GPS_Serial.begin(GPS_SERIAL); + restoreDefaults(); + changeBaudrate(GPS_BAUDRATE); delay(100); GPS_Serial.flush(); From c41d44bd7d8d7cee26ab9c74f985e36003f2bc23 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Mon, 7 Feb 2022 15:35:25 +0100 Subject: [PATCH 39/60] gps ubx fixes --- src/gpsread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index f7dd1167..aecef475 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -289,7 +289,7 @@ void gps_loop(void *pvParameters) { delay(2); } // inner while loop - delay(1000); + delay(2); } // outer while loop } // gps_loop() From 69da95cd665dfbdc149ef04bb3341ade7ee25b43 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Mon, 7 Feb 2022 15:38:15 +0100 Subject: [PATCH 40/60] sanitize ISR IRAM_ATTR and global vars --- include/display.h | 1 + include/irqhandler.h | 2 +- include/timekeeper.h | 3 ++- src/display.cpp | 4 +++- src/main.cpp | 42 ++++++++++++++++++------------------------ src/timekeeper.cpp | 8 ++++++-- 6 files changed, 31 insertions(+), 29 deletions(-) diff --git a/include/display.h b/include/display.h index 62cdf363..70187893 100644 --- a/include/display.h +++ b/include/display.h @@ -5,6 +5,7 @@ #include "cyclic.h" #include "qrcode.h" #include "power.h" +#include "timekeeper.h" #if (HAS_DISPLAY) == 1 #include diff --git a/include/irqhandler.h b/include/irqhandler.h index 8b14b293..eacbd35f 100644 --- a/include/irqhandler.h +++ b/include/irqhandler.h @@ -24,7 +24,7 @@ void irqHandler(void *pvParameters); void mask_user_IRQ(); void unmask_user_IRQ(); -void doIRQ(int irq); +void IRAM_ATTR doIRQ(int irq); extern TaskHandle_t irqHandlerTask; diff --git a/include/timekeeper.h b/include/timekeeper.h index 956595df..88084916 100644 --- a/include/timekeeper.h +++ b/include/timekeeper.h @@ -20,8 +20,9 @@ extern const char timeSetSymbols[]; extern Ticker timesyncer; extern timesource_t timeSource; extern TaskHandle_t ClockTask; -extern bool volatile TimePulseTick; // 1sec pps flag set by GPS or RTC +extern DRAM_ATTR bool TimePulseTick; // 1sec pps flag set by GPS or RTC extern hw_timer_t *ppsIRQ; +extern portMUX_TYPE mux; void IRAM_ATTR CLOCKIRQ(void); void clock_init(void); diff --git a/src/display.cpp b/src/display.cpp index 10722fa3..e41dea81 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -317,7 +317,9 @@ void dp_drawPage(bool nextpage) { #if (TIME_SYNC_INTERVAL) timeState = TimePulseTick ? ' ' : timeSetSymbols[timeSource]; - TimePulseTick = false; + portENTER_CRITICAL(&mux); + TimePulseTick = false; // flip global variable pulse ticker + portEXIT_CRITICAL(&mux); time(&now); localtime_r(&now, &timeinfo); strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo); diff --git a/src/main.cpp b/src/main.cpp index 4bc007ab..9cd922fc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,37 +48,31 @@ Low priority numbers denote low priority tasks. ------------------------------------------------------------------------------- 0 displayIRQ -> display refresh -> 40ms (DISPLAYREFRESH_MS) 1 ppsIRQ -> pps clock irq -> 1sec +2 (unused) 3 MatrixDisplayIRQ -> matrix mux cycle -> 0,5ms (MATRIX_DISPLAY_SCAN_US) -// Interrupt routines -------------------------------------------------------------------------------- - -irqHandlerTask (Core 1), see irqhandler.cpp - -fired by hardware -DisplayIRQ -> esp32 timer 0 -CLOCKIRQ -> esp32 timer 1 or external GPIO (RTC_INT or GPS_INT) -MatrixDisplayIRQ-> esp32 timer 3 -ButtonIRQ -> external GPIO -PMUIRQ -> PMU chip GPIO - -fired by software -TIMESYNC_IRQ -> setTimeSyncIRQ() -> Ticker.h -CYCLIC_IRQ -> setCyclicIRQ() -> Ticker.h -SENDCYCLE_IRQ -> setSendIRQ() -> xTimer -BME_IRQ -> setBMEIRQ() -> Ticker.h - -ClockTask (Core 1), see timekeeper.cpp - -fired by hardware -CLOCKIRQ -> esp32 timer 1 - - // External RTC timer (if present) ------------------------------------------------------------------------------- triggers pps 1 sec impulse + +// Interrupt routines +------------------------------------------------------------------------------- + +ISRs fired by CPU or GPIO: +DisplayIRQ <- esp32 timer 0 +CLOCKIRQ <- esp32 timer 1 or GPIO (RTC_INT or GPS_INT) +MatrixDisplayIRQ<- esp32 timer 3 +ButtonIRQ <- GPIO <- Button +PMUIRQ <- GPIO <- PMU chip + +Application IRQs fired by software: +TIMESYNC_IRQ <- setTimeSyncIRQ() <- Ticker.h +CYCLIC_IRQ <- setCyclicIRQ() <- Ticker.h +SENDCYCLE_IRQ <- setSendIRQ() <- xTimer +BME_IRQ <- setBMEIRQ() <- Ticker.h + */ // Basic Config diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index fec827a4..84445e77 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -19,7 +19,9 @@ static const char TAG[] = __FILE__; // G = GPS / R = RTC / L = LORA / * = no sync / ? = never synced const char timeSetSymbols[] = {'G', 'R', 'L', '*', '?'}; -DRAM_ATTR bool volatile TimePulseTick = false; +portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; + +DRAM_ATTR bool TimePulseTick = false; timesource_t timeSource = _unsynced; TaskHandle_t ClockTask = NULL; hw_timer_t *ppsIRQ = NULL; @@ -211,7 +213,9 @@ void IRAM_ATTR CLOCKIRQ(void) { // flip time pulse ticker, if needed #ifdef HAS_DISPLAY #if (defined GPS_INT || defined RTC_INT) - TimePulseTick = !TimePulseTick; // flip pulse ticker + portENTER_CRITICAL(&mux); + TimePulseTick = !TimePulseTick; // flip global variable pulse ticker + portEXIT_CRITICAL(&mux); #endif #endif From 01011013fc0659ed3b9f0201edd39e3fa46110f1 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Wed, 9 Feb 2022 12:24:11 +0100 Subject: [PATCH 41/60] adjust task prios & delays & time cal cycle --- src/cyclic.cpp | 8 ++++++++ src/gpsread.cpp | 12 +++--------- src/lorawan.cpp | 2 +- src/main.cpp | 10 +++++----- src/rcommand.cpp | 2 +- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/cyclic.cpp b/src/cyclic.cpp index 45bac2f2..42556acf 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -34,6 +34,7 @@ void doHousekeeping() { if (rcmdTask != NULL) ESP_LOGD(TAG, "Rcommand interpreter %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(rcmdTask), eTaskGetState(rcmdTask)); + #if (HAS_LORA) if (lmicTask != NULL) ESP_LOGD(TAG, "LMiCtask %d bytes left | Taskstate = %d", @@ -43,11 +44,18 @@ void doHousekeeping() { uxTaskGetStackHighWaterMark(lorasendTask), eTaskGetState(lorasendTask)); #endif + #if (HAS_GPS) if (GpsTask != NULL) ESP_LOGD(TAG, "Gpsloop %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(GpsTask), eTaskGetState(GpsTask)); + // (only) while device time is not set or unsynched, and we have a valid + // GPS time, we call calibrateTime to poll time immeditately from GPS + if ((timeSource == _unsynced || timeSource == _set) && + (gpstime.isUpdated() && gpstime.isValid() && gpstime.age() < 1000)) + calibrateTime(); #endif + #ifdef HAS_SPI if (spiTask != NULL) ESP_LOGD(TAG, "spiloop %d bytes left | Taskstate = %d", diff --git a/src/gpsread.cpp b/src/gpsread.cpp index aecef475..6aef95b0 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -273,23 +273,17 @@ void gps_loop(void *pvParameters) { // feed GPS decoder with serial NMEA data from GPS device while (GPS_Serial.available()) if (gps.encode(GPS_Serial.read())) - break; // NMEA sentence complete - - // (only) while device time is not set or unsynched, and we have a valid - // GPS time, we call calibrateTime to poll time immeditately from GPS - if ((timeSource == _unsynced || timeSource == _set) && - (gpstime.isUpdated() && gpstime.isValid() && gpstime.age() < 1000)) - calibrateTime(); + break; // leave encode loop after each NMEA complete sentence // show NMEA data, very noisy, useful only for debugging GPS // ESP_LOGV(TAG, "GPS NMEA data: passed %u / failed: %u / with fix: // %u", gps.passedChecksum(), gps.failedChecksum(), gps // .sentencesWithFix()); - delay(2); + delay(5); } // inner while loop - delay(2); + delay(1000); } // outer while loop } // gps_loop() diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 403cf19f..ab5b2fe7 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -305,7 +305,7 @@ esp_err_t lmic_init(void) { "lmictask", // name of task 4096, // stack size of task (void *)1, // parameter of the task - 8, // priority of the task + 1, // priority of the task &lmicTask, // task handle 1); // CPU core diff --git a/src/main.cpp b/src/main.cpp index 9cd922fc..b1d12fbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,16 +29,16 @@ Task Core Prio Purpose ------------------------------------------------------------------------------- ledloop* 0 1 blinks LEDs spiloop# 0 2 reads/writes data on spi interface -lmictask* 1 8 MCCI LMiC LORAWAN stack +lmictask* 1 1 MCCI LMiC LORAWAN stack clockloop# 1 6 generates realtime telegrams for external clock mqttloop# 1 5 reads/writes data on ETH interface timesync_proc# 1 7 processes realtime time sync requests -irqhandler# 1 4 cyclic tasks (i.e. displayrefresh) triggered by -gpsloop* 1 3 reads data from GPS via serial or i2c +irqhandler# 1 4 application IRQ (i.e. displayrefresh) +gpsloop* 1 1 reads data from GPS via serial or i2c lorasendtask# 1 2 feeds data from lora sendqueue to lmcic rmcd_process# 1 1 Remote command interpreter loop -* spinning task +* spinning task, always ready # blocked/waiting task Low priority numbers denote low priority tasks. @@ -322,7 +322,7 @@ void setup() { "gpsloop", // name of task 8192, // stack size of task (void *)1, // parameter of the task - 3, // priority of the task + 1, // priority of the task &GpsTask, // task handle 1); // CPU core } diff --git a/src/rcommand.cpp b/src/rcommand.cpp index ecaadca7..fe333b1f 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -484,7 +484,7 @@ void rcmd_process(void *pvParameters) { rcmd_execute(RcmdBuffer.cmd, RcmdBuffer.cmdLen); } - delay(2); // yield to CPU + delay(5); // yield to CPU } // rcmd_process() // enqueue remote command From 817f7793c4b8279f321e154c3a7d5b6ebe6df347 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Wed, 9 Feb 2022 12:36:45 +0100 Subject: [PATCH 42/60] fix cyclic time sync when no timesource seen yet --- src/cyclic.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/cyclic.cpp b/src/cyclic.cpp index 42556acf..33a0022d 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -22,6 +22,10 @@ void doHousekeeping() { if ((RTC_runmode == RUNMODE_UPDATE) || (RTC_runmode == RUNMODE_MAINTENANCE)) do_reset(true); // warmstart + // try to get time if we don't yet have a recent timesource + if (timeSource == _unsynced || timeSource == _set) + calibrateTime(); + // print heap and task storage information ESP_LOGD(TAG, "Heap: Free:%d, Min:%d, Size:%d, Alloc:%d, StackHWM:%d", ESP.getFreeHeap(), ESP.getMinFreeHeap(), ESP.getHeapSize(), @@ -49,11 +53,6 @@ void doHousekeeping() { if (GpsTask != NULL) ESP_LOGD(TAG, "Gpsloop %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(GpsTask), eTaskGetState(GpsTask)); - // (only) while device time is not set or unsynched, and we have a valid - // GPS time, we call calibrateTime to poll time immeditately from GPS - if ((timeSource == _unsynced || timeSource == _set) && - (gpstime.isUpdated() && gpstime.isValid() && gpstime.age() < 1000)) - calibrateTime(); #endif #ifdef HAS_SPI From a71a7e08a4480d94a50bc102a41e0fa456c2031c Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sat, 12 Feb 2022 16:26:41 +0100 Subject: [PATCH 43/60] getting time from GPS reworked --- include/gpsread.h | 9 +- include/timekeeper.h | 5 +- src/display.cpp | 3 - src/gpsread.cpp | 200 ++++++++++++++++++++----------------------- src/main.cpp | 5 +- src/timekeeper.cpp | 62 +++++++------- 6 files changed, 128 insertions(+), 156 deletions(-) diff --git a/include/gpsread.h b/include/gpsread.h index 1025065d..95cd1afa 100644 --- a/include/gpsread.h +++ b/include/gpsread.h @@ -5,17 +5,10 @@ #include #include "timekeeper.h" -#ifdef GPS_I2C // Needed for reading from I2C Bus -#include -#endif - #ifndef GPS_BAUDRATE -#define GPS_BAUDRATE 115200 +#define GPS_BAUDRATE 115200UL #endif -#define NMEA_FRAME_SIZE 82 // NEMA has a maxium of 82 bytes per record -#define NMEA_COMPENSATION_FACTOR 480 // empiric for Ublox Neo 6M - extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe extern TaskHandle_t GpsTask; diff --git a/include/timekeeper.h b/include/timekeeper.h index 88084916..bb97a043 100644 --- a/include/timekeeper.h +++ b/include/timekeeper.h @@ -21,13 +21,13 @@ extern Ticker timesyncer; extern timesource_t timeSource; extern TaskHandle_t ClockTask; extern DRAM_ATTR bool TimePulseTick; // 1sec pps flag set by GPS or RTC +extern DRAM_ATTR unsigned long lastPPS; extern hw_timer_t *ppsIRQ; -extern portMUX_TYPE mux; void IRAM_ATTR CLOCKIRQ(void); +void IRAM_ATTR GPSIRQ(void); void clock_init(void); void clock_loop(void *pvParameters); -void timepulse_start(void); void setTimeSyncIRQ(void); uint8_t timepulse_init(void); bool timeIsValid(time_t const t); @@ -38,5 +38,4 @@ time_t compileTime(void); time_t mkgmtime(const struct tm *ptm); TickType_t tx_Ticks(uint32_t framesize, unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPins); - #endif // _timekeeper_H \ No newline at end of file diff --git a/src/display.cpp b/src/display.cpp index e41dea81..7fab780e 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -317,9 +317,6 @@ void dp_drawPage(bool nextpage) { #if (TIME_SYNC_INTERVAL) timeState = TimePulseTick ? ' ' : timeSetSymbols[timeSource]; - portENTER_CRITICAL(&mux); - TimePulseTick = false; // flip global variable pulse ticker - portEXIT_CRITICAL(&mux); time(&now); localtime_r(&now, &timeinfo); strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo); diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 6aef95b0..dac8e4d6 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -6,38 +6,12 @@ // Local logging tag static const char TAG[] = __FILE__; -// we use NMEA ZDA sentence field 1 for time synchronization -// ZDA gives time for preceding pps pulse -// downsight is that it does not have a constant offset -// thus precision is only +/- 1 second - TinyGPSPlus gps; -TinyGPSCustom gpstime(gps, "GPZDA", 1); // field 1 = UTC time (hhmmss.ss) -TinyGPSCustom gpsday(gps, "GPZDA", 2); // field 2 = day (01..31) -TinyGPSCustom gpsmonth(gps, "GPZDA", 3); // field 3 = month (01..12) -TinyGPSCustom gpsyear(gps, "GPZDA", 4); // field 4 = year (4-digit) -static const String ZDA_Request = "$EIGPQ,ZDA*39\r\n"; TaskHandle_t GpsTask; - HardwareSerial GPS_Serial(1); // use UART #1 -static uint16_t nmea_txDelay_ms = - (tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL) / portTICK_PERIOD_MS); // helper functions to send UBX commands to ublox gps chip -/* -// Print the UBX packet for debugging -void printPacket(byte *packet, byte len) { - char temp[3]; - - for (byte i = 0; i < len; i++) { - sprintf(temp, "%.2X", packet[i]); - ESP_LOGD(TAG, "%s", temp); - } -} -*/ - -// Send the packet specified to the receiver. void sendPacket(byte *packet, byte len) { uint8_t CK_A = 0; @@ -55,55 +29,85 @@ void sendPacket(byte *packet, byte len) { GPS_Serial.write(CK_B); } -// Send a packet to the receiver to restore default configuration. void restoreDefaults() { - // CFG-CFG packet. + // UBX CFG-CFG packet byte packet[] = { 0xB5, // sync char 1 0x62, // sync char 2 0x06, // class 0x09, // id 0x0D, // length - 0x00, // length + 0x00, // . 0b00011111, // clearmask - 0b00000110, // clearmask - 0x00, // clearmask - 0x00, // clearmask - 0x00, // savemask - 0x00, // savemask - 0x00, // savemask + 0b00000110, // . + 0x00, // . + 0x00, // . 0x00, // savemask + 0x00, // . + 0x00, // . + 0x00, // . 0b00011111, // loadmask - 0b00000110, // loadmask - 0x00, // loadmask - 0x00, // loadmask + 0b00000110, // . + 0x00, // . + 0x00, // . 0b00010001 // devicemask }; sendPacket(packet, sizeof(packet)); } -// Send a set of packets to the receiver to disable NMEA messages. +void setTimePulse() { + // UBX TIM-TP packet + byte packet[] = { + 0xB5, // sync char 1 + 0x62, // sync char 2 + 0x06, // class + 0x07, // id + 0x14, // length + 0x40, // time interval for time pulse [us] + 0x42, // -> 1 sec = 1000000us + 0x0F, // . + 0x00, // . + 0xE8, // length of time pulse [us] + 0x03, // -> 1000us + 0x00, // . + 0x00, // . + 0x01, // status -> positive edge + 0x00, // timeRef -> UTC + 0b00000001, // syncMode asynchronized + 0x00, // reserved + 0x00, // antenna cable delay [ns] + 0x00, // . + 0x00, // receiver rf group delay [ns] + 0x00, // . + 0x00, // user time function delay [ns] + 0x00, // . + 0x00, // . + 0x00 // . + }; + + sendPacket(packet, sizeof(packet)); +} + void disableNmea() { // for tinygps++ we need only $GPGGA and $GPRMC - // for getting time we use $GPZDA - // we disable all other NMEA messages + // thus, we disable all other NMEA messages // Array of two bytes for CFG-MSG packets payload. byte messages[][2] = {{0xF0, 0x01}, {0xF0, 0x02}, {0xF0, 0x03}, {0xF0, 0x05}, - {0xF0, 0x06}, {0xF0, 0x07}, {0xF0, 0x09}, {0xF0, 0x0A}, - {0xF0, 0x0E}, {0xF1, 0x00}, {0xF1, 0x03}, {0xF1, 0x04}, - {0xF1, 0x05}, {0xF1, 0x06}}; + {0xF0, 0x06}, {0xF0, 0x07}, {0xF0, 0x08}, {0xF0, 0x09}, + {0xF0, 0x0A}, {0xF0, 0x0E}, {0xF1, 0x00}, {0xF1, 0x03}, + {0xF1, 0x04}, {0xF1, 0x05}, {0xF1, 0x06}}; - // CFG-MSG packet buffer. + // UBX CFG-MSG packet byte packet[] = { 0xB5, // sync char 1 0x62, // sync char 2 0x06, // class 0x01, // id 0x03, // length - 0x00, // length + 0x00, // . 0x00, // payload (first byte from messages array element) 0x00, // payload (second byte from messages array element) 0x00 // payload (zero to disable message) @@ -124,25 +128,24 @@ void disableNmea() { } } -// Send a packet to the receiver to change baudrate to 115200. void changeBaudrate(uint32_t baudRate) { - // CFG-PRT packet. + // UBX CFG-PRT packet byte packet[] = { 0xB5, // sync char 1 0x62, // sync char 2 0x06, // class 0x00, // id 0x14, // length - 0x00, // length + 0x00, // . 0x01, // portID (UART 1) 0x00, // reserved 0x00, // txReady 0x00, // . - 0b11010000, // UART mode: 8bit - 0b00001000, // UART mode: No Parity, 1 Stopbit + 0b11010000, // UART mode: 8N1 + 0b00001000, // . 0x00, // . 0x00, // . - (byte)baudRate, // baudrate (4 bytes) + (byte)baudRate, // baudrate (byte)(baudRate >> 8), // . (byte)(baudRate >> 16), // . (byte)(baudRate >> 24), // . @@ -151,30 +154,9 @@ void changeBaudrate(uint32_t baudRate) { 0b00000010, // output protocols: NMEA 0x00000000, // . 0x00, // reserved - 0x00, // reserved - 0x00, // reserved - 0x00 // reserved - }; - - sendPacket(packet, sizeof(packet)); -} - -// Send a packet to the receiver to change frequency to 100 ms. -void changeFrequency() { - // CFG-RATE packet. - byte packet[] = { - 0xB5, // sync char 1 - 0x62, // sync char 2 - 0x06, // class - 0x08, // id - 0x06, // length - 0x00, // length - 0x64, // Measurement rate 100ms - 0x00, // Measurement rate - 0x01, // Measurement cycles - 0x00, // Measurement cycles - 0x00, // Alignment to reference time: UTC time - 0x00 // payload + 0x00, // . + 0x00, // . + 0x00 // . }; sendPacket(packet, sizeof(packet)); @@ -184,8 +166,11 @@ void changeFrequency() { int gps_init(void) { ESP_LOGI(TAG, "Opening serial GPS"); + GPS_Serial.begin(GPS_SERIAL); + restoreDefaults(); + delay(100); changeBaudrate(GPS_BAUDRATE); delay(100); @@ -193,8 +178,7 @@ int gps_init(void) { GPS_Serial.updateBaudRate(GPS_BAUDRATE); disableNmea(); - changeFrequency(); - // enableNavTimeUTC(); + setTimePulse(); return 1; @@ -224,40 +208,38 @@ bool gps_hasfix() { // function to poll UTC time from GPS NMEA data; note: this is costly time_t get_gpstime(uint16_t *msec) { - // poll NMEA ZDA sentence - GPS_Serial.print(ZDA_Request); - // wait for gps NMEA answer - // vTaskDelay(tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL)); + *msec = 0; // did we get a current date & time? - if (gpstime.isValid()) { + if (gps.time.isValid() && gps.date.isValid() && gps.time.age() < 1000) { - uint32_t delay_ms = - gpstime.age() + nmea_txDelay_ms + NMEA_COMPENSATION_FACTOR; - uint32_t zdatime = atof(gpstime.value()); - - // convert UTC time from gps NMEA ZDA sentence to tm format + // convert tinygps time format to struct tm format struct tm gps_tm = {0}; - gps_tm.tm_sec = zdatime % 100; // second (UTC) - gps_tm.tm_min = (zdatime / 100) % 100; // minute (UTC) - gps_tm.tm_hour = zdatime / 10000; // hour (UTC) - gps_tm.tm_mday = atoi(gpsday.value()); // day, 01 to 31 - gps_tm.tm_mon = atoi(gpsmonth.value()) - 1; // month, 01 to 12 - gps_tm.tm_year = atoi(gpsyear.value()) - 1900; // year, YYYY + gps_tm.tm_sec = gps.time.second(); + gps_tm.tm_min = gps.time.minute(); + gps_tm.tm_hour = gps.time.hour(); + gps_tm.tm_mday = gps.date.day(); + gps_tm.tm_mon = gps.date.month() - 1; // 1-12 -> 0-11 + gps_tm.tm_year = gps.date.year() - 1900; // 2000+ -> years since 1900 // convert UTC tm to time_t epoch gps_tm.tm_isdst = 0; // UTC has no DST time_t t = mkgmtime(&gps_tm); - // add protocol delay with millisecond precision - t += (time_t)(delay_ms / 1000); - *msec = delay_ms % 1000; // fractional seconds +#ifdef GPS_INT + // if we have a recent GPS PPS pulse, sync on top of next second + if (millis() - lastPPS < 1000) + *msec = (uint16_t)(millis() - lastPPS); + else { + ESP_LOGD(TAG, "no PPS from GPS"); + return 0; + } +#endif return t; } ESP_LOGD(TAG, "no valid GPS time"); - return 0; } // get_gpstime() @@ -271,20 +253,24 @@ void gps_loop(void *pvParameters) { while (cfg.payloadmask & GPS_DATA) { // feed GPS decoder with serial NMEA data from GPS device - while (GPS_Serial.available()) - if (gps.encode(GPS_Serial.read())) - break; // leave encode loop after each NMEA complete sentence + while (GPS_Serial.available()) { + if (gps.encode(GPS_Serial.read())) { - // show NMEA data, very noisy, useful only for debugging GPS - // ESP_LOGV(TAG, "GPS NMEA data: passed %u / failed: %u / with fix: - // %u", gps.passedChecksum(), gps.failedChecksum(), gps - // .sentencesWithFix()); + // show NMEA data, very noisy, for debugging GPS + // ESP_LOGV( + // TAG, + // "GPS NMEA data: chars %u / passed %u / failed: %u / with fix: + // %u", gps.charsProcessed(), gps.passedChecksum(), + // gps.failedChecksum(), gps.sentencesWithFix()); + delay(5); // yield after each sentence to crack NMEA burst + } + } // read from serial buffer loop delay(5); - } // inner while loop + } delay(1000); - } // outer while loop + } // infinite while loop } // gps_loop() diff --git a/src/main.cpp b/src/main.cpp index b1d12fbb..b4b780af 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -62,7 +62,7 @@ triggers pps 1 sec impulse ISRs fired by CPU or GPIO: DisplayIRQ <- esp32 timer 0 -CLOCKIRQ <- esp32 timer 1 or GPIO (RTC_INT or GPS_INT) +CLOCKIRQ <- esp32 timer 1 or GPIO (RTC_INT) MatrixDisplayIRQ<- esp32 timer 3 ButtonIRQ <- GPIO <- Button PMUIRQ <- GPIO <- PMU chip @@ -492,8 +492,7 @@ void setup() { #endif ESP_LOGI(TAG, "Starting Timekeeper..."); - _ASSERT(timepulse_init()); // setup pps timepulse - timepulse_start(); // starts pps and cyclic time sync + _ASSERT(timepulse_init()); // starts pps and cyclic time sync strcat_P(features, " TIME"); #endif // timesync diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index 84445e77..6a4d2904 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -19,9 +19,8 @@ static const char TAG[] = __FILE__; // G = GPS / R = RTC / L = LORA / * = no sync / ? = never synced const char timeSetSymbols[] = {'G', 'R', 'L', '*', '?'}; -portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; - DRAM_ATTR bool TimePulseTick = false; +DRAM_ATTR unsigned long lastPPS = millis(); timesource_t timeSource = _unsynced; TaskHandle_t ClockTask = NULL; hw_timer_t *ppsIRQ = NULL; @@ -144,26 +143,23 @@ uint8_t timepulse_init() { // sntp_init(); sntp_set_sync_mode(SNTP_SYNC_MODE_IMMED); -// use time pulse from GPS as time base with fixed 1Hz frequency +// if we have, use PPS time pulse from GPS for syncing time on top of second #ifdef GPS_INT - - // setup external interupt pin for rising edge GPS INT + // setup external interupt pin for rising edge of GPS PPS pinMode(GPS_INT, INPUT_PULLDOWN); - // setup external rtc 1Hz clock as pulse per second clock - ESP_LOGI(TAG, "Timepulse: external (GPS)"); - return 1; // success + attachInterrupt(digitalPinToInterrupt(GPS_INT), GPSIRQ, RISING); +#endif -// use pulse from on board RTC chip as time base with fixed frequency -#elif defined RTC_INT +// if we have, use pulse from on board RTC chip as time base for calendar time +#if defined RTC_INT - // setup external interupt pin for falling edge RTC INT - pinMode(RTC_INT, INPUT_PULLUP); - - // setup external rtc 1Hz clock as pulse per second clock + // setup external rtc 1Hz clock pulse if (I2C_MUTEX_LOCK()) { Rtc.SetSquareWavePinClockFrequency(DS3231SquareWaveClock_1Hz); Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeClock); I2C_MUTEX_UNLOCK(); + pinMode(RTC_INT, INPUT_PULLUP); + attachInterrupt(digitalPinToInterrupt(RTC_INT), CLOCKIRQ, FALLING); ESP_LOGI(TAG, "Timepulse: external (RTC)"); return 1; // success } else { @@ -173,33 +169,39 @@ uint8_t timepulse_init() { return 1; // success #else - // use ESP32 hardware timer as time base with adjustable frequency + // use ESP32 hardware timer as time base for calendar time ppsIRQ = timerBegin(1, 8000, true); // set 80 MHz prescaler to 1/10000 sec timerAlarmWrite(ppsIRQ, 10000, true); // 1000ms + timerAttachInterrupt(ppsIRQ, &CLOCKIRQ, true); + timerAlarmEnable(ppsIRQ); ESP_LOGI(TAG, "Timepulse: internal (ESP32 hardware timer)"); return 1; // success #endif -} // timepulse_init -void timepulse_start(void) { -#ifdef GPS_INT // start external clock gps pps line - attachInterrupt(digitalPinToInterrupt(GPS_INT), CLOCKIRQ, RISING); -#elif defined RTC_INT // start external clock rtc - attachInterrupt(digitalPinToInterrupt(RTC_INT), CLOCKIRQ, FALLING); -#else // start internal clock esp32 hardware timer - timerAttachInterrupt(ppsIRQ, &CLOCKIRQ, true); - timerAlarmEnable(ppsIRQ); -#endif + // start cyclic time sync + timesyncer.attach(TIME_SYNC_INTERVAL * 60, setTimeSyncIRQ); // get time if we don't have one if (timeSource != _set) setTimeSyncIRQ(); // init systime by RTC or GPS or LORA - // start cyclic time sync - timesyncer.attach(TIME_SYNC_INTERVAL * 60, setTimeSyncIRQ); + +} // timepulse_init + +// interrupt service routine triggered by GPS PPS +void IRAM_ATTR GPSIRQ(void) { + + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + // take timestamp + lastPPS = millis(); // last time of pps + + // yield only if we should + if (xHigherPriorityTaskWoken) + portYIELD_FROM_ISR(); } -// interrupt service routine triggered by either pps or esp32 hardware timer +// interrupt service routine triggered by esp32 hardware timer void IRAM_ATTR CLOCKIRQ(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; @@ -212,11 +214,7 @@ void IRAM_ATTR CLOCKIRQ(void) { // flip time pulse ticker, if needed #ifdef HAS_DISPLAY -#if (defined GPS_INT || defined RTC_INT) - portENTER_CRITICAL(&mux); TimePulseTick = !TimePulseTick; // flip global variable pulse ticker - portEXIT_CRITICAL(&mux); -#endif #endif // yield only if we should From bc4f2fbb95be0e5fb85ff92545c36c275f120d9f Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sat, 12 Feb 2022 16:27:21 +0100 Subject: [PATCH 44/60] move led loop from core0 to core1 --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b4b780af..f3bd3e8a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,7 +27,7 @@ licenses. Refer to LICENSE.txt file in repository for more details. Task Core Prio Purpose ------------------------------------------------------------------------------- -ledloop* 0 1 blinks LEDs +ledloop* 1 1 blinks LEDs spiloop# 0 2 reads/writes data on spi interface lmictask* 1 1 MCCI LMiC LORAWAN stack clockloop# 1 6 generates realtime telegrams for external clock @@ -238,7 +238,7 @@ void setup() { (void *)1, // parameter of the task 1, // priority of the task &ledLoopTask, // task handle - 0); // CPU core + 1); // CPU core #endif // initialize wifi antenna From 2d786967ea6ca2ddc55ab20bf66115bb0911a789 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sat, 12 Feb 2022 18:15:19 +0100 Subject: [PATCH 45/60] gpsread.cpp: fix centiseconds if no PPS present --- src/gpsread.cpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index dac8e4d6..2fc23ccf 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -91,7 +91,7 @@ void setTimePulse() { void disableNmea() { - // for tinygps++ we need only $GPGGA and $GPRMC + // tinygps++ processes only $GPGGA/$GNGGA and $GPRMC/$GNRMC // thus, we disable all other NMEA messages // Array of two bytes for CFG-MSG packets payload. @@ -234,6 +234,9 @@ time_t get_gpstime(uint16_t *msec) { ESP_LOGD(TAG, "no PPS from GPS"); return 0; } +#else + // best guess top of second + *msec = gps.time.age() + gps.time.centisecond() * 10; #endif return t; @@ -249,26 +252,15 @@ void gps_loop(void *pvParameters) { _ASSERT((uint32_t)pvParameters == 1); // FreeRTOS check + // feed GPS decoder with serial NMEA data from GPS device while (1) { - while (cfg.payloadmask & GPS_DATA) { - // feed GPS decoder with serial NMEA data from GPS device - while (GPS_Serial.available()) { - if (gps.encode(GPS_Serial.read())) { - // show NMEA data, very noisy, for debugging GPS - // ESP_LOGV( - // TAG, - // "GPS NMEA data: chars %u / passed %u / failed: %u / with fix: - // %u", gps.charsProcessed(), gps.passedChecksum(), - // gps.failedChecksum(), gps.sentencesWithFix()); + while (GPS_Serial.available()) + gps.encode(GPS_Serial.read()); - delay(5); // yield after each sentence to crack NMEA burst - } - } // read from serial buffer loop delay(5); } - delay(1000); } // infinite while loop From 2dd9a4701b1b4be99381dd29d02f830d95647ce1 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 13 Feb 2022 15:41:42 +0100 Subject: [PATCH 46/60] rework ublox gps init --- src/gpsread.cpp | 251 +++++++++++++++++++++++++----------------------- 1 file changed, 129 insertions(+), 122 deletions(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 2fc23ccf..7856013e 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -10,6 +10,121 @@ TinyGPSPlus gps; TaskHandle_t GpsTask; HardwareSerial GPS_Serial(1); // use UART #1 +// Ublox UBX packet data + +// UBX CFG-PRT packet +byte CFG_PRT[] = { + 0xB5, // sync char 1 + 0x62, // sync char 2 + 0x06, // class + 0x00, // id + 0x14, // length + 0x00, // . + 0x01, // portID (UART 1) + 0x00, // reserved + 0x00, // txReady + 0x00, // . + 0b11010000, // UART mode: 8N1 + 0b00001000, // . + 0x00, // . + 0x00, // . + (byte)GPS_BAUDRATE, // baudrate + (byte)(GPS_BAUDRATE >> 8), // . + (byte)(GPS_BAUDRATE >> 16), // . + (byte)(GPS_BAUDRATE >> 24), // . + 0b00000011, // input protocols: NMEA + UBX + 0b00000000, // . + 0b00000010, // output protocols: NMEA + 0x00000000, // . + 0x00, // reserved + 0x00, // . + 0x00, // . + 0x00 // . +}; + +// Array of two bytes for CFG-MSG packets payload. +byte CFG_MSG_CID[][2] = { + {0xF0, 0x01}, {0xF0, 0x02}, {0xF0, 0x03}, {0xF0, 0x05}, {0xF0, 0x06}, + {0xF0, 0x07}, {0xF0, 0x08}, {0xF0, 0x09}, {0xF0, 0x0A}, {0xF0, 0x0E}, + {0xF1, 0x00}, {0xF1, 0x03}, {0xF1, 0x04}, {0xF1, 0x05}, {0xF1, 0x06}}; + +// UBX CFG-MSG packet +byte CFG_MSG[] = { + 0xB5, // sync char 1 + 0x62, // sync char 2 + 0x06, // class + 0x01, // id + 0x03, // length + 0x00, // . + 0x00, // payload (first byte from messages array element) + 0x00, // payload (second byte from messages array element) + 0x00 // payload (zero to disable message) +}; + +// UBX TIM-TP5 packet +byte TIM_TP5[] = { + 0xB5, // sync char 1 + 0x62, // sync char 2 + 0x06, // class + 0x31, // id + 0x20, // length + 0x00, // time pulse index + 0x00, // reserved + 0x00, // reserved + 0x00, // . + 0x00, // antenna cable delay [ns] + 0x00, // . + 0x00, // receiver rf group delay [ns] + 0x00, // . + 0x00, // frequency unlocked + 0x00, // -> no signal + 0x00, // . + 0x00, // . + 0x01, // frequency locked + 0x00, // -> 1Hz + 0x00, // . + 0x00, // . + 0x00, // pulse length unlocked + 0x00, // -> no pulse + 0x00, // . + 0x00, // . + 0xE8, // pulse length locked + 0x03, // -> 1000us = 1ms + 0x00, // . + 0x00, // . + 0x00, // user delay + 0x00, // . + 0x00, // . + 0x00, // . + 0b01111111, // flags + 0b00000000, // -> UTC time grid + 0b00000000, // . + 0b00000000 // . +}; + +// UBX CFG-CFG packet +byte CFG_CFG[] = { + 0xB5, // sync char 1 + 0x62, // sync char 2 + 0x06, // class + 0x09, // id + 0x0D, // length + 0x00, // . + 0b00011111, // clearmask + 0b00000110, // . + 0x00, // . + 0x00, // . + 0x00, // savemask + 0x00, // . + 0x00, // . + 0x00, // . + 0b00011111, // loadmask + 0b00000110, // . + 0x00, // . + 0x00, // . + 0b00010001 // devicemask +}; + // helper functions to send UBX commands to ublox gps chip void sendPacket(byte *packet, byte len) { @@ -29,139 +144,30 @@ void sendPacket(byte *packet, byte len) { GPS_Serial.write(CK_B); } -void restoreDefaults() { - // UBX CFG-CFG packet - byte packet[] = { - 0xB5, // sync char 1 - 0x62, // sync char 2 - 0x06, // class - 0x09, // id - 0x0D, // length - 0x00, // . - 0b00011111, // clearmask - 0b00000110, // . - 0x00, // . - 0x00, // . - 0x00, // savemask - 0x00, // . - 0x00, // . - 0x00, // . - 0b00011111, // loadmask - 0b00000110, // . - 0x00, // . - 0x00, // . - 0b00010001 // devicemask - }; - - sendPacket(packet, sizeof(packet)); -} - -void setTimePulse() { - // UBX TIM-TP packet - byte packet[] = { - 0xB5, // sync char 1 - 0x62, // sync char 2 - 0x06, // class - 0x07, // id - 0x14, // length - 0x40, // time interval for time pulse [us] - 0x42, // -> 1 sec = 1000000us - 0x0F, // . - 0x00, // . - 0xE8, // length of time pulse [us] - 0x03, // -> 1000us - 0x00, // . - 0x00, // . - 0x01, // status -> positive edge - 0x00, // timeRef -> UTC - 0b00000001, // syncMode asynchronized - 0x00, // reserved - 0x00, // antenna cable delay [ns] - 0x00, // . - 0x00, // receiver rf group delay [ns] - 0x00, // . - 0x00, // user time function delay [ns] - 0x00, // . - 0x00, // . - 0x00 // . - }; - - sendPacket(packet, sizeof(packet)); -} +void restoreDefaults() { sendPacket(CFG_CFG, sizeof(CFG_CFG)); } +void changeBaudrate() { sendPacket(CFG_PRT, sizeof(CFG_PRT)); } +void setTimePulse() { sendPacket(TIM_TP5, sizeof(TIM_TP5)); } void disableNmea() { // tinygps++ processes only $GPGGA/$GNGGA and $GPRMC/$GNRMC // thus, we disable all other NMEA messages - // Array of two bytes for CFG-MSG packets payload. - byte messages[][2] = {{0xF0, 0x01}, {0xF0, 0x02}, {0xF0, 0x03}, {0xF0, 0x05}, - {0xF0, 0x06}, {0xF0, 0x07}, {0xF0, 0x08}, {0xF0, 0x09}, - {0xF0, 0x0A}, {0xF0, 0x0E}, {0xF1, 0x00}, {0xF1, 0x03}, - {0xF1, 0x04}, {0xF1, 0x05}, {0xF1, 0x06}}; - - // UBX CFG-MSG packet - byte packet[] = { - 0xB5, // sync char 1 - 0x62, // sync char 2 - 0x06, // class - 0x01, // id - 0x03, // length - 0x00, // . - 0x00, // payload (first byte from messages array element) - 0x00, // payload (second byte from messages array element) - 0x00 // payload (zero to disable message) - }; - - byte packetSize = sizeof(packet); + byte packetSize = sizeof(CFG_MSG); // Offset to the place where payload starts. byte payloadOffset = 6; // Iterate over the messages array. - for (byte i = 0; i < sizeof(messages) / sizeof(*messages); i++) { + for (byte i = 0; i < sizeof(CFG_MSG_CID) / sizeof(*CFG_MSG_CID); i++) { // Copy two bytes of payload to the packet buffer. - for (byte j = 0; j < sizeof(*messages); j++) { - packet[payloadOffset + j] = messages[i][j]; + for (byte j = 0; j < sizeof(*CFG_MSG_CID); j++) { + CFG_MSG[payloadOffset + j] = CFG_MSG_CID[i][j]; } - sendPacket(packet, packetSize); + sendPacket(CFG_MSG, packetSize); } } -void changeBaudrate(uint32_t baudRate) { - // UBX CFG-PRT packet - byte packet[] = { - 0xB5, // sync char 1 - 0x62, // sync char 2 - 0x06, // class - 0x00, // id - 0x14, // length - 0x00, // . - 0x01, // portID (UART 1) - 0x00, // reserved - 0x00, // txReady - 0x00, // . - 0b11010000, // UART mode: 8N1 - 0b00001000, // . - 0x00, // . - 0x00, // . - (byte)baudRate, // baudrate - (byte)(baudRate >> 8), // . - (byte)(baudRate >> 16), // . - (byte)(baudRate >> 24), // . - 0b00000011, // input protocols: NMEA + UBX - 0b00000000, // . - 0b00000010, // output protocols: NMEA - 0x00000000, // . - 0x00, // reserved - 0x00, // . - 0x00, // . - 0x00 // . - }; - - sendPacket(packet, sizeof(packet)); -} - // initialize and configure GPS int gps_init(void) { @@ -172,7 +178,7 @@ int gps_init(void) { restoreDefaults(); delay(100); - changeBaudrate(GPS_BAUDRATE); + changeBaudrate(); delay(100); GPS_Serial.flush(); GPS_Serial.updateBaudRate(GPS_BAUDRATE); @@ -206,12 +212,13 @@ bool gps_hasfix() { } // function to poll UTC time from GPS NMEA data; note: this is costly -time_t get_gpstime(uint16_t *msec) { +time_t get_gpstime(uint16_t *msec = 0) { - *msec = 0; + const uint16_t txDelay = + 70 * 1000 / (GPS_BAUDRATE / 9); // serial tx of 70 NMEA chars // did we get a current date & time? - if (gps.time.isValid() && gps.date.isValid() && gps.time.age() < 1000) { + if (gps.time.age() < 1000) { // convert tinygps time format to struct tm format struct tm gps_tm = {0}; @@ -236,7 +243,7 @@ time_t get_gpstime(uint16_t *msec) { } #else // best guess top of second - *msec = gps.time.age() + gps.time.centisecond() * 10; + *msec = gps.time.centisecond() * 10 + txDelay; #endif return t; From 8e4fe93069d50f18142a82d0a595bc852202fc23 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 13 Feb 2022 16:00:01 +0100 Subject: [PATCH 47/60] sanitze libpax integration (volatile vars removed) --- include/libpax_helpers.h | 2 +- include/main.h | 3 ++- include/rcommand.h | 1 + include/senddata.h | 2 +- src/libpax_helpers.cpp | 11 +---------- src/rcommand.cpp | 1 - src/senddata.cpp | 25 +++++++++++++++---------- 7 files changed, 21 insertions(+), 24 deletions(-) diff --git a/include/libpax_helpers.h b/include/libpax_helpers.h index 74be26a4..aee1e1c4 100644 --- a/include/libpax_helpers.h +++ b/include/libpax_helpers.h @@ -8,6 +8,6 @@ void init_libpax(void); -extern uint16_t volatile libpax_macs_ble, libpax_macs_wifi; // libpax values +extern struct count_payload_t count_from_libpax; // libpax count storage #endif \ No newline at end of file diff --git a/include/main.h b/include/main.h index 6fa72b11..824b020e 100644 --- a/include/main.h +++ b/include/main.h @@ -7,6 +7,8 @@ #include // needed for coex version display #include // needed for wifi init / deinit +#include + #include "globals.h" #include "reset.h" #include "i2c.h" @@ -19,7 +21,6 @@ #include "lorawan.h" #include "timekeeper.h" #include "boot.h" -#include "libpax_helpers.h" #include "power.h" #include "antenna.h" diff --git a/include/rcommand.h b/include/rcommand.h index 0cdb23c6..d842fdef 100644 --- a/include/rcommand.h +++ b/include/rcommand.h @@ -3,6 +3,7 @@ #include +#include "libpax_helpers.h" #include "senddata.h" #include "cyclic.h" #include "configmanager.h" diff --git a/include/senddata.h b/include/senddata.h index 6c44dfa7..94392c42 100644 --- a/include/senddata.h +++ b/include/senddata.h @@ -1,7 +1,6 @@ #ifndef _SENDDATA_H #define _SENDDATA_H -#include "libpax_helpers.h" #include "spislave.h" #include "mqttclient.h" #include "cyclic.h" @@ -18,6 +17,7 @@ void checkSendQueues(void); void flushQueues(void); bool allQueuesEmtpy(void); void setSendIRQ(TimerHandle_t xTimer = NULL); +void setSendIRQ(void); void initSendDataTimer(uint8_t sendcycle); #endif // _SENDDATA_H_ diff --git a/src/libpax_helpers.cpp b/src/libpax_helpers.cpp index 9883648c..937dfd04 100644 --- a/src/libpax_helpers.cpp +++ b/src/libpax_helpers.cpp @@ -5,18 +5,9 @@ static const char TAG[] = __FILE__; // libpax payload struct count_payload_t count_from_libpax; -uint16_t volatile libpax_macs_ble, libpax_macs_wifi; - -void process_count(void) { - ESP_LOGD(TAG, "pax: %d / %d / %d", count_from_libpax.pax, - count_from_libpax.wifi_count, count_from_libpax.ble_count); - libpax_macs_ble = count_from_libpax.ble_count; - libpax_macs_wifi = count_from_libpax.wifi_count; - setSendIRQ(); -} void init_libpax(void) { - libpax_counter_init(process_count, &count_from_libpax, cfg.sendcycle * 2, + libpax_counter_init(setSendIRQ, &count_from_libpax, cfg.sendcycle * 2, cfg.countermode); libpax_counter_start(); } \ No newline at end of file diff --git a/src/rcommand.cpp b/src/rcommand.cpp index fe333b1f..71c6f453 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -1,7 +1,6 @@ // Basic Config #include "globals.h" #include "rcommand.h" -#include "libpax_helpers.h" // Local logging tag static const char TAG[] = __FILE__; diff --git a/src/senddata.cpp b/src/senddata.cpp index 9b7a5e57..0016f11b 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -5,6 +5,10 @@ void setSendIRQ(TimerHandle_t xTimer) { xTaskNotify(irqHandlerTask, SENDCYCLE_IRQ, eSetBits); } +#if ((WIFICOUNTER) || (BLECOUNTER)) +void setSendIRQ(void) { setSendIRQ(NULL); } +#endif + void initSendDataTimer(uint8_t sendcycle) { static TimerHandle_t SendDataTimer = NULL; @@ -79,6 +83,10 @@ void sendData() { sdsStatus_t sds_status; #endif + ESP_LOGD(TAG, "Sending count results: pax=%d / wifi=%d / ble=%d", + count_from_libpax.pax, count_from_libpax.wifi_count, + count_from_libpax.ble_count); + while (bitmask) { switch (bitmask & mask) { @@ -86,11 +94,9 @@ void sendData() { case COUNT_DATA: payload.reset(); #if !(PAYLOAD_OPENSENSEBOX) - ESP_LOGI(TAG, "Sending libpax wifi count: %d", libpax_macs_wifi); - payload.addCount(libpax_macs_wifi, MAC_SNIFF_WIFI); + payload.addCount(count_from_libpax.wifi_count, MAC_SNIFF_WIFI); if (cfg.blescan) { - ESP_LOGI(TAG, "Sending libpax ble count: %d", libpax_macs_ble); - payload.addCount(libpax_macs_ble, MAC_SNIFF_BLE); + payload.addCount(count_from_libpax.ble_count, MAC_SNIFF_BLE); } #endif #if (HAS_GPS) @@ -104,11 +110,9 @@ void sendData() { } #endif #if (PAYLOAD_OPENSENSEBOX) - ESP_LOGI(TAG, "Sending libpax wifi count: %d", libpax_macs_wifi); - payload.addCount(libpax_macs_wifi, MAC_SNIFF_WIFI); + payload.addCount(count_from_libpax.wifi_count, MAC_SNIFF_WIFI); if (cfg.blescan) { - ESP_LOGI(TAG, "Sending libpax ble count: %d", libpax_macs_ble); - payload.addCount(libpax_macs_ble, MAC_SNIFF_BLE); + payload.addCount(count_from_libpax.ble_count, MAC_SNIFF_BLE); #endif #if (HAS_SDS011) sds011_store(&sds_status); @@ -116,10 +120,11 @@ void sendData() { #endif SendPayload(COUNTERPORT); #ifdef HAS_DISPLAY - dp_plotCurve(libpax_macs_ble + libpax_macs_wifi, true); + dp_plotCurve(count_from_libpax.pax, true); #endif #if (HAS_SDCARD) - sdcardWriteData(libpax_macs_wifi, libpax_macs_ble + sdcardWriteData(count_from_libpax.wifi_count, + count_from_libpax.ble_count #if (defined BAT_MEASURE_ADC || defined HAS_PMU) , read_voltage() From 88efd5dd4d86c94bea21100f906ed73a93118386 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 13 Feb 2022 17:43:05 +0100 Subject: [PATCH 48/60] senddata.cpp sanitized --- include/senddata.h | 2 +- src/main.cpp | 2 +- src/senddata.cpp | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/include/senddata.h b/include/senddata.h index 94392c42..3f269447 100644 --- a/include/senddata.h +++ b/include/senddata.h @@ -16,7 +16,7 @@ void sendData(void); void checkSendQueues(void); void flushQueues(void); bool allQueuesEmtpy(void); -void setSendIRQ(TimerHandle_t xTimer = NULL); +void setSendIRQ(TimerHandle_t xTimer); void setSendIRQ(void); void initSendDataTimer(uint8_t sendcycle); diff --git a/src/main.cpp b/src/main.cpp index f3bd3e8a..dcec92e9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -70,7 +70,7 @@ PMUIRQ <- GPIO <- PMU chip Application IRQs fired by software: TIMESYNC_IRQ <- setTimeSyncIRQ() <- Ticker.h CYCLIC_IRQ <- setCyclicIRQ() <- Ticker.h -SENDCYCLE_IRQ <- setSendIRQ() <- xTimer +SENDCYCLE_IRQ <- setSendIRQ() <- xTimer or libpax callback BME_IRQ <- setBMEIRQ() <- Ticker.h */ diff --git a/src/senddata.cpp b/src/senddata.cpp index 0016f11b..bca6e235 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -5,9 +5,7 @@ void setSendIRQ(TimerHandle_t xTimer) { xTaskNotify(irqHandlerTask, SENDCYCLE_IRQ, eSetBits); } -#if ((WIFICOUNTER) || (BLECOUNTER)) void setSendIRQ(void) { setSendIRQ(NULL); } -#endif void initSendDataTimer(uint8_t sendcycle) { static TimerHandle_t SendDataTimer = NULL; @@ -71,7 +69,7 @@ void SendPayload(uint8_t port) { } // SendPayload -// interrupt triggered function to prepare payload to send +// timer triggered function to prepare payload to send void sendData() { uint8_t bitmask = cfg.payloadmask; From 8f98a9bdde49cc452f7cb5d3e3c7d7875dbf3a44 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 13 Feb 2022 18:41:22 +0100 Subject: [PATCH 49/60] gps fixes (TIM-TP5 removed again) --- src/gpsread.cpp | 61 ++++++++----------------------------------------- 1 file changed, 10 insertions(+), 51 deletions(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 7856013e..6c628782 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -43,10 +43,10 @@ byte CFG_PRT[] = { }; // Array of two bytes for CFG-MSG packets payload. -byte CFG_MSG_CID[][2] = { - {0xF0, 0x01}, {0xF0, 0x02}, {0xF0, 0x03}, {0xF0, 0x05}, {0xF0, 0x06}, - {0xF0, 0x07}, {0xF0, 0x08}, {0xF0, 0x09}, {0xF0, 0x0A}, {0xF0, 0x0E}, - {0xF1, 0x00}, {0xF1, 0x03}, {0xF1, 0x04}, {0xF1, 0x05}, {0xF1, 0x06}}; +byte CFG_MSG_CID[][2] = {{0xF0, 0x01}, {0xF0, 0x02}, {0xF0, 0x03}, {0xF0, 0x05}, + {0xF0, 0x06}, {0xF0, 0x07}, {0xF0, 0x08}, {0xF0, 0x09}, + {0xF0, 0x0A}, {0xF0, 0x0E}, {0xF1, 0x00}, {0xF1, 0x03}, + {0xF1, 0x04}, {0xF1, 0x05}, {0xF1, 0x06}}; // UBX CFG-MSG packet byte CFG_MSG[] = { @@ -61,47 +61,6 @@ byte CFG_MSG[] = { 0x00 // payload (zero to disable message) }; -// UBX TIM-TP5 packet -byte TIM_TP5[] = { - 0xB5, // sync char 1 - 0x62, // sync char 2 - 0x06, // class - 0x31, // id - 0x20, // length - 0x00, // time pulse index - 0x00, // reserved - 0x00, // reserved - 0x00, // . - 0x00, // antenna cable delay [ns] - 0x00, // . - 0x00, // receiver rf group delay [ns] - 0x00, // . - 0x00, // frequency unlocked - 0x00, // -> no signal - 0x00, // . - 0x00, // . - 0x01, // frequency locked - 0x00, // -> 1Hz - 0x00, // . - 0x00, // . - 0x00, // pulse length unlocked - 0x00, // -> no pulse - 0x00, // . - 0x00, // . - 0xE8, // pulse length locked - 0x03, // -> 1000us = 1ms - 0x00, // . - 0x00, // . - 0x00, // user delay - 0x00, // . - 0x00, // . - 0x00, // . - 0b01111111, // flags - 0b00000000, // -> UTC time grid - 0b00000000, // . - 0b00000000 // . -}; - // UBX CFG-CFG packet byte CFG_CFG[] = { 0xB5, // sync char 1 @@ -184,7 +143,6 @@ int gps_init(void) { GPS_Serial.updateBaudRate(GPS_BAUDRATE); disableNmea(); - setTimePulse(); return 1; @@ -215,7 +173,7 @@ bool gps_hasfix() { time_t get_gpstime(uint16_t *msec = 0) { const uint16_t txDelay = - 70 * 1000 / (GPS_BAUDRATE / 9); // serial tx of 70 NMEA chars + 70U * 1000 / (GPS_BAUDRATE / 9); // serial tx of 70 NMEA chars // did we get a current date & time? if (gps.time.age() < 1000) { @@ -235,15 +193,16 @@ time_t get_gpstime(uint16_t *msec = 0) { #ifdef GPS_INT // if we have a recent GPS PPS pulse, sync on top of next second - if (millis() - lastPPS < 1000) - *msec = (uint16_t)(millis() - lastPPS); + uint16_t ppsDiff = millis() - lastPPS; + if (ppsDiff < 1000) + *msec = ppsDiff; else { ESP_LOGD(TAG, "no PPS from GPS"); return 0; } #else - // best guess top of second - *msec = gps.time.centisecond() * 10 + txDelay; + // best guess for sync on top of next second + *msec = gps.time.centisecond() * 10U + txDelay; #endif return t; From 4d48b14b88c419ac370b320d03ae44b4f5bf495a Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 13 Feb 2022 18:41:43 +0100 Subject: [PATCH 50/60] increase lmic task prio --- src/lorawan.cpp | 2 +- src/main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lorawan.cpp b/src/lorawan.cpp index ab5b2fe7..299481fc 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -305,7 +305,7 @@ esp_err_t lmic_init(void) { "lmictask", // name of task 4096, // stack size of task (void *)1, // parameter of the task - 1, // priority of the task + 2, // priority of the task &lmicTask, // task handle 1); // CPU core diff --git a/src/main.cpp b/src/main.cpp index dcec92e9..2e20fb76 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,7 +29,7 @@ Task Core Prio Purpose ------------------------------------------------------------------------------- ledloop* 1 1 blinks LEDs spiloop# 0 2 reads/writes data on spi interface -lmictask* 1 1 MCCI LMiC LORAWAN stack +lmictask* 1 2 MCCI LMiC LORAWAN stack clockloop# 1 6 generates realtime telegrams for external clock mqttloop# 1 5 reads/writes data on ETH interface timesync_proc# 1 7 processes realtime time sync requests From 274b8525f68639818d179beafaf48b34643117cb Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Mon, 14 Feb 2022 16:23:26 +0100 Subject: [PATCH 51/60] Update ttgov21new.h --- src/hal/ttgov21new.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hal/ttgov21new.h b/src/hal/ttgov21new.h index f72b7369..fbaae22b 100644 --- a/src/hal/ttgov21new.h +++ b/src/hal/ttgov21new.h @@ -18,9 +18,9 @@ // enable only if you want to store a local paxcount table on the device #define HAS_SDCARD 2 // this board has a SDMMC card-reader/writer -//#define HAS_DISPLAY 1 -//#define HAS_LED (25) // green on board LED -#define HAS_LED NOT_A_PIN +#define HAS_DISPLAY 1 +#define HAS_LED (25) // green on board LED +//#define HAS_LED NOT_A_PIN #define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 #define BAT_VOLTAGE_DIVIDER 2 // voltage divider 100k/100k on board From 45f531ccfbba19cecd8a2d62caafe63a49b70d1b Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Mon, 14 Feb 2022 17:31:14 +0100 Subject: [PATCH 52/60] ttgov21new.h: correction display --- src/hal/ttgov21new.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hal/ttgov21new.h b/src/hal/ttgov21new.h index f72b7369..fbaae22b 100644 --- a/src/hal/ttgov21new.h +++ b/src/hal/ttgov21new.h @@ -18,9 +18,9 @@ // enable only if you want to store a local paxcount table on the device #define HAS_SDCARD 2 // this board has a SDMMC card-reader/writer -//#define HAS_DISPLAY 1 -//#define HAS_LED (25) // green on board LED -#define HAS_LED NOT_A_PIN +#define HAS_DISPLAY 1 +#define HAS_LED (25) // green on board LED +//#define HAS_LED NOT_A_PIN #define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 #define BAT_VOLTAGE_DIVIDER 2 // voltage divider 100k/100k on board From eeed8b7bfefa466c3ca027e1e7e0e7a1fdb39595 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Mon, 14 Feb 2022 17:32:46 +0100 Subject: [PATCH 53/60] sds011: change device driver library (initial) --- include/sds011read.h | 4 +++- platformio_orig.ini | 2 +- src/cyclic.cpp | 4 ---- src/sds011read.cpp | 34 +++++++++++++++++++--------------- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/include/sds011read.h b/include/sds011read.h index f49c34f0..db651ebf 100644 --- a/include/sds011read.h +++ b/include/sds011read.h @@ -1,11 +1,13 @@ #ifndef _SDS011READ_H #define _SDS011READ_H -#include +#include #include "globals.h" #define SDCARD_FILE_HEADER_SDS011 ", PM10,PM25" +extern bool isSDS011Active; + bool sds011_init(); void sds011_loop(); void sds011_sleep(void); diff --git a/platformio_orig.ini b/platformio_orig.ini index 0fea3a83..632ef7e8 100644 --- a/platformio_orig.ini +++ b/platformio_orig.ini @@ -77,7 +77,7 @@ lib_deps_sensors = adafruit/Adafruit BME280 Library @ ^2.2.1 adafruit/Adafruit BMP085 Library @ ^1.2.0 boschsensortec/BSEC Software Library @ 1.6.1480 - https://github.com/ricki-z/SDS011.git + https://github.com/cyberman54/sds-dust-sensors-arduino-library.git lib_deps_basic = https://github.com/dbSuS/libpax.git @ ^1.0.0 https://github.com/SukkoPera/Arduino-Rokkit-Hash.git diff --git a/src/cyclic.cpp b/src/cyclic.cpp index 33a0022d..67d21262 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -9,10 +9,6 @@ static const char TAG[] = __FILE__; Ticker cyclicTimer; -#if (HAS_SDS011) -extern boolean isSDS011Active; -#endif - void setCyclicIRQ() { xTaskNotify(irqHandlerTask, CYCLIC_IRQ, eSetBits); } // do all housekeeping diff --git a/src/sds011read.cpp b/src/sds011read.cpp index a693f651..76719d42 100644 --- a/src/sds011read.cpp +++ b/src/sds011read.cpp @@ -10,35 +10,41 @@ static const char TAG[] = __FILE__; #if (HAS_IF482) #error cannot use IF482 together with SDS011 (both use UART#2) #endif -// UART(2) is unused in this project -static HardwareSerial sdsSerial(2); // so we use it here -static SDS011 sdsSensor; // fine dust sensor + +// sds011 connected to UART(2) +static SdsDustSensor sdsSensor(Serial2); // the results of the sensor: static float pm10, pm25; -boolean isSDS011Active; +bool isSDS011Active = false; // init bool sds011_init() { pm25 = pm10 = 0.0; - sdsSensor.begin(&sdsSerial, SDS_RX, SDS_TX); + sdsSensor.begin(); + + String version = sdsSensor.queryFirmwareVersion().toString(); + ESP_LOGI(TAG, "SDS011 firmware version %s", version); + sdsSensor.setQueryReportingMode(); sds011_sleep(); // we do sleep/wakup by ourselves + return true; } // reading data: void sds011_loop() { if (isSDS011Active) { - int sdsErrorCode = sdsSensor.read(&pm25, &pm10); - if (sdsErrorCode) { + PmResult pm = sdsSensor.queryPm(); + if (!pm.isOk()) { pm25 = pm10 = 0.0; - ESP_LOGI(TAG, "SDS011 error: %d", sdsErrorCode); + ESP_LOGE(TAG, "SDS011 query error"); } else { + pm25 = pm.pm25; + pm10 = pm.pm10; ESP_LOGI(TAG, "fine-dust-values: %5.1f,%4.1f", pm10, pm25); } sds011_sleep(); } - return; } // retrieving stored data: @@ -49,17 +55,15 @@ void sds011_store(sdsStatus_t *sds_store) { // putting the SDS-sensor to sleep void sds011_sleep(void) { - sdsSensor.sleep(); - isSDS011Active = false; + WorkingStateResult state = sdsSensor.sleep(); + isSDS011Active = state.isWorking(); } // start the SDS-sensor // needs 30 seconds for warming up void sds011_wakeup() { - if (!isSDS011Active) { - sdsSensor.wakeup(); - isSDS011Active = true; - } + WorkingStateResult state = sdsSensor.wakeup(); + isSDS011Active = state.isWorking(); } #endif // HAS_SDS011 From 736d51a142b23f56e9b7085a6ff0c72fd44b9283 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Mon, 14 Feb 2022 20:49:23 +0100 Subject: [PATCH 54/60] gpsread.cpp: fix removal TIM_TP5 --- src/gpsread.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 6c628782..3f1e0acd 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -105,7 +105,6 @@ void sendPacket(byte *packet, byte len) { void restoreDefaults() { sendPacket(CFG_CFG, sizeof(CFG_CFG)); } void changeBaudrate() { sendPacket(CFG_PRT, sizeof(CFG_PRT)); } -void setTimePulse() { sendPacket(TIM_TP5, sizeof(TIM_TP5)); } void disableNmea() { From a1461be403a481a3db77eb1c2029e05104c51754 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Mon, 14 Feb 2022 21:34:19 +0100 Subject: [PATCH 55/60] make libpax count_payload_t varables local --- include/senddata.h | 2 -- src/display.cpp | 15 ++++++++------- src/ledmatrixdisplay.cpp | 15 ++++++++------- src/senddata.cpp | 35 ++++++++++++++++++++++------------- 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/include/senddata.h b/include/senddata.h index 3f269447..ff0a382b 100644 --- a/include/senddata.h +++ b/include/senddata.h @@ -9,8 +9,6 @@ #include "display.h" #include "sdcard.h" -extern struct count_payload_t count_from_libpax; - void SendPayload(uint8_t port); void sendData(void); void checkSendQueues(void); diff --git a/src/display.cpp b/src/display.cpp index 7fab780e..1cfff3e4 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -43,6 +43,7 @@ uint8_t DisplayIsOn = 0; uint8_t displaybuf[MY_DISPLAY_WIDTH * MY_DISPLAY_HEIGHT / 8] = {0}; static uint8_t plotbuf[MY_DISPLAY_WIDTH * MY_DISPLAY_HEIGHT / 8] = {0}; static int dp_row = 0, dp_col = 0, dp_font = 0; +static struct count_payload_t count; // libpax count storage hw_timer_t *displayIRQ = NULL; @@ -175,14 +176,14 @@ void dp_init(bool verbose) { void dp_refresh(bool nextPage) { // update counter values from libpax - libpax_counter_count(&count_from_libpax); + libpax_counter_count(&count); #ifndef HAS_BUTTON static uint32_t framecounter = 0; #endif // update histogram - dp_plotCurve(count_from_libpax.pax, false); + dp_plotCurve(count.pax, false); // if display is switched off we don't refresh it to relax cpu if (!DisplayIsOn && (DisplayIsOn == cfg.screenon)) @@ -240,7 +241,7 @@ void dp_drawPage(bool nextpage) { // display number of unique macs total Wifi + BLE if (DisplayPage < 5) { dp_setFont(MY_FONT_STRETCHED); - dp_printf("%-5d", count_from_libpax.pax); + dp_printf("%-5d", count.pax); } switch (DisplayPage) { @@ -264,21 +265,21 @@ void dp_drawPage(bool nextpage) { #if ((WIFICOUNTER) && (BLECOUNTER)) if (cfg.wifiscan) - dp_printf("WIFI:%-5d", count_from_libpax.wifi_count); + dp_printf("WIFI:%-5d", count.wifi_count); else dp_printf("WIFI:off"); if (cfg.blescan) - dp_printf("BLTH:%-5d", count_from_libpax.ble_count); + dp_printf("BLTH:%-5d", count.ble_count); else dp_printf(" BLTH:off"); #elif ((WIFICOUNTER) && (!BLECOUNTER)) if (cfg.wifiscan) - dp_printf("WIFI:%-5d", count_from_libpax.wifi_count); + dp_printf("WIFI:%-5d", count.wifi_count); else dp_printf("WIFI:off"); #elif ((!WIFICOUNTER) && (BLECOUNTER)) if (cfg.blescan) - dp_printf("BLTH:%-5d", count_from_libpax.ble_count); + dp_printf("BLTH:%-5d", count.ble_count); dp_printf("BLTH:off"); #else dp_printf("Sniffer disabled"); diff --git a/src/ledmatrixdisplay.cpp b/src/ledmatrixdisplay.cpp index e6b1d070..8940d6ec 100644 --- a/src/ledmatrixdisplay.cpp +++ b/src/ledmatrixdisplay.cpp @@ -13,6 +13,7 @@ uint8_t MatrixDisplayIsOn = 0; static uint8_t displaybuf[LED_MATRIX_WIDTH * LED_MATRIX_HEIGHT / 8] = {0}; static unsigned long ulLastNumMacs = 0; static time_t ulLastTime = time(NULL); +static struct count_payload_t count; // libpax count storage hw_timer_t *matrixDisplayIRQ = NULL; @@ -76,12 +77,12 @@ void refreshTheMatrixDisplay(bool nextPage) { case 0: // update counter values from libpax - libpax_counter_count(&count_from_libpax); + libpax_counter_count(&count); if (cfg.countermode == 1) { // cumulative counter mode -> display total number of pax - if (ulLastNumMacs != count_from_libpax.pax) { - ulLastNumMacs = count_from_libpax.pax; + if (ulLastNumMacs != count.pax) { + ulLastNumMacs = count.pax; matrix.clear(); DrawNumber(String(ulLastNumMacs)); } @@ -89,10 +90,10 @@ void refreshTheMatrixDisplay(bool nextPage) { else { // cyclic counter mode -> plot a line diagram - if (ulLastNumMacs != count_from_libpax.pax) { + if (ulLastNumMacs != count.pax) { // next count cycle? - if (count_from_libpax.pax == 0) { + if (count.pax == 0) { // matrix full? then scroll left 1 dot, else increment column if (col < (LED_MATRIX_WIDTH - 1)) @@ -104,7 +105,7 @@ void refreshTheMatrixDisplay(bool nextPage) { matrix.drawPoint(col, row, 0); // clear current dot // scale and set new dot - ulLastNumMacs = count_from_libpax.pax; + ulLastNumMacs = count.pax; level = ulLastNumMacs / LINE_DIAGRAM_DIVIDER; row = level <= LED_MATRIX_HEIGHT ? LED_MATRIX_HEIGHT - 1 - level % LED_MATRIX_HEIGHT @@ -120,7 +121,7 @@ void refreshTheMatrixDisplay(bool nextPage) { if (ulLastTime != t) { ulLastTime = t; matrix.clear(); - //DrawNumber(myTZ.dateTime("H:i:s").c_str()); + // DrawNumber(myTZ.dateTime("H:i:s").c_str()); } break; diff --git a/src/senddata.cpp b/src/senddata.cpp index bca6e235..fedee7da 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -74,16 +74,19 @@ void sendData() { uint8_t bitmask = cfg.payloadmask; uint8_t mask = 1; + #if (HAS_GPS) gpsStatus_t gps_status; #endif #if (HAS_SDS011) sdsStatus_t sds_status; #endif - - ESP_LOGD(TAG, "Sending count results: pax=%d / wifi=%d / ble=%d", - count_from_libpax.pax, count_from_libpax.wifi_count, - count_from_libpax.ble_count); +#if ((WIFICOUNTER) || (BLECOUNTER)) + struct count_payload_t count = + count_from_libpax; // copy values from global libpax var + ESP_LOGD(TAG, "Sending count results: pax=%d / wifi=%d / ble=%d", count.pax, + count.wifi_count, count.ble_count); +#endif while (bitmask) { switch (bitmask & mask) { @@ -91,12 +94,14 @@ void sendData() { #if ((WIFICOUNTER) || (BLECOUNTER)) case COUNT_DATA: payload.reset(); + #if !(PAYLOAD_OPENSENSEBOX) - payload.addCount(count_from_libpax.wifi_count, MAC_SNIFF_WIFI); + payload.addCount(count.wifi_count, MAC_SNIFF_WIFI); if (cfg.blescan) { - payload.addCount(count_from_libpax.ble_count, MAC_SNIFF_BLE); + payload.addCount(count.ble_count, MAC_SNIFF_BLE); } #endif + #if (HAS_GPS) if (GPSPORT == COUNTERPORT) { // send GPS position only if we have a fix @@ -107,22 +112,24 @@ void sendData() { ESP_LOGD(TAG, "No valid GPS position"); } #endif + #if (PAYLOAD_OPENSENSEBOX) - payload.addCount(count_from_libpax.wifi_count, MAC_SNIFF_WIFI); + payload.addCount(count.wifi_count, MAC_SNIFF_WIFI); if (cfg.blescan) { - payload.addCount(count_from_libpax.ble_count, MAC_SNIFF_BLE); + payload.addCount(count.ble_count, MAC_SNIFF_BLE); #endif + #if (HAS_SDS011) sds011_store(&sds_status); payload.addSDS(sds_status); #endif - SendPayload(COUNTERPORT); + #ifdef HAS_DISPLAY - dp_plotCurve(count_from_libpax.pax, true); + dp_plotCurve(count.pax, true); #endif + #if (HAS_SDCARD) - sdcardWriteData(count_from_libpax.wifi_count, - count_from_libpax.ble_count + sdcardWriteData(count.wifi_count, count.ble_count #if (defined BAT_MEASURE_ADC || defined HAS_PMU) , read_voltage() @@ -130,8 +137,10 @@ void sendData() { ); #endif // HAS_SDCARD + SendPayload(COUNTERPORT); break; // case COUNTDATA -#endif + +#endif // ((WIFICOUNTER) || (BLECOUNTER)) #if (HAS_BME) case MEMS_DATA: From 641b0ad7a230c48d2cd58821faafbd644a285c38 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Tue, 15 Feb 2022 21:58:20 +0100 Subject: [PATCH 56/60] bugfix curve plotter zero drops --- src/display.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/display.cpp b/src/display.cpp index 1cfff3e4..692b352d 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -43,7 +43,6 @@ uint8_t DisplayIsOn = 0; uint8_t displaybuf[MY_DISPLAY_WIDTH * MY_DISPLAY_HEIGHT / 8] = {0}; static uint8_t plotbuf[MY_DISPLAY_WIDTH * MY_DISPLAY_HEIGHT / 8] = {0}; static int dp_row = 0, dp_col = 0, dp_font = 0; -static struct count_payload_t count; // libpax count storage hw_timer_t *displayIRQ = NULL; @@ -175,16 +174,10 @@ void dp_init(bool verbose) { void dp_refresh(bool nextPage) { - // update counter values from libpax - libpax_counter_count(&count); - #ifndef HAS_BUTTON static uint32_t framecounter = 0; #endif - // update histogram - dp_plotCurve(count.pax, false); - // if display is switched off we don't refresh it to relax cpu if (!DisplayIsOn && (DisplayIsOn == cfg.screenon)) return; @@ -208,7 +201,6 @@ void dp_refresh(bool nextPage) { #endif dp_drawPage(nextPage); - dp_dump(displaybuf); I2C_MUTEX_UNLOCK(); // release i2c bus access @@ -220,6 +212,7 @@ void dp_drawPage(bool nextpage) { // write display content to display buffer // nextpage = true -> flip 1 page + struct count_payload_t count; // libpax count storage static uint8_t DisplayPage = 0; char timeState, strftime_buf[64]; time_t now; @@ -234,6 +227,9 @@ void dp_drawPage(bool nextpage) { dp_clear(); } + // update counter values from libpax + libpax_counter_count(&count); + // cursor home dp_setTextCursor(0, 0); @@ -345,6 +341,8 @@ void dp_drawPage(bool nextpage) { dp_printf("%-4s", getSfName(updr2rps(LMIC.datarate))); dp_setFont(MY_FONT_SMALL, 0); #endif // HAS_LORA + + dp_dump(displaybuf); break; // ---------- page 1: lorawan parameters ---------- @@ -370,6 +368,8 @@ void dp_drawPage(bool nextpage) { LMIC.seqnoDn ? LMIC.seqnoDn - 1 : 0); dp_println(); dp_printf("SNR:%-5d RSSI:%-5d", (LMIC.snr + 2) / 4, LMIC.rssi); + + dp_dump(displaybuf); break; #else // flip page if we are unattended DisplayPage++; @@ -402,6 +402,8 @@ void dp_drawPage(bool nextpage) { dp_printf("No fix"); wasnofix = true; } + + dp_dump(displaybuf); break; #else // flip page if we are unattended DisplayPage++; @@ -425,10 +427,12 @@ void dp_drawPage(bool nextpage) { #ifdef HAS_BME680 // line 6-7: IAQ dp_printf("IAQ:%-3.0f", bme_status.iaq); -#else // is BME280 or BMP180 +#else // is BME280 or BMP180 // line 6-7: Pre dp_printf("PRE:%-2.1f", bme_status.pressure); -#endif // HAS_BME680 +#endif // HAS_BME680 + + dp_dump(displaybuf); break; // page 3 #else // flip page if we are unattended DisplayPage++; @@ -443,14 +447,15 @@ void dp_drawPage(bool nextpage) { localtime_r(&now, &timeinfo); strftime(strftime_buf, sizeof(strftime_buf), "%T", &timeinfo); dp_printf("%.8s", strftime_buf); + + dp_dump(displaybuf); break; // ---------- page 5: pax graph ---------- case 5: - dp_setFont(MY_FONT_NORMAL); - dp_setTextCursor(0, 0); - dp_printf("Pax graph"); + // update histogram + dp_plotCurve(count.pax, false); dp_dump(plotbuf); break; From 9dc3f03b62bca6a8044b8ac7331eaddbec484dea Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Wed, 16 Feb 2022 00:07:41 +0100 Subject: [PATCH 57/60] sds011 cleanups after moving to new lib --- src/sds011read.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sds011read.cpp b/src/sds011read.cpp index 76719d42..b8a0188b 100644 --- a/src/sds011read.cpp +++ b/src/sds011read.cpp @@ -11,8 +11,7 @@ static const char TAG[] = __FILE__; #error cannot use IF482 together with SDS011 (both use UART#2) #endif -// sds011 connected to UART(2) -static SdsDustSensor sdsSensor(Serial2); +SdsDustSensor sds(Serial2); // the results of the sensor: static float pm10, pm25; @@ -21,11 +20,12 @@ bool isSDS011Active = false; // init bool sds011_init() { pm25 = pm10 = 0.0; - sdsSensor.begin(); - String version = sdsSensor.queryFirmwareVersion().toString(); + sds.begin(9600, SERIAL_8N1, 12, 35); + + String version = sds.queryFirmwareVersion().toString(); ESP_LOGI(TAG, "SDS011 firmware version %s", version); - sdsSensor.setQueryReportingMode(); + sds.setQueryReportingMode(); sds011_sleep(); // we do sleep/wakup by ourselves return true; @@ -34,7 +34,7 @@ bool sds011_init() { // reading data: void sds011_loop() { if (isSDS011Active) { - PmResult pm = sdsSensor.queryPm(); + PmResult pm = sds.queryPm(); if (!pm.isOk()) { pm25 = pm10 = 0.0; ESP_LOGE(TAG, "SDS011 query error"); @@ -55,14 +55,14 @@ void sds011_store(sdsStatus_t *sds_store) { // putting the SDS-sensor to sleep void sds011_sleep(void) { - WorkingStateResult state = sdsSensor.sleep(); + WorkingStateResult state = sds.sleep(); isSDS011Active = state.isWorking(); } // start the SDS-sensor // needs 30 seconds for warming up void sds011_wakeup() { - WorkingStateResult state = sdsSensor.wakeup(); + WorkingStateResult state = sds.wakeup(); isSDS011Active = state.isWorking(); } From f8d3780b2cdad7c422bf8efb1a3bfb314655d03b Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Wed, 16 Feb 2022 00:47:17 +0100 Subject: [PATCH 58/60] sds011 more cleanups --- include/sds011read.h | 9 ++++++++- src/sds011read.cpp | 16 ++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/include/sds011read.h b/include/sds011read.h index db651ebf..f1b874d3 100644 --- a/include/sds011read.h +++ b/include/sds011read.h @@ -6,6 +6,14 @@ #define SDCARD_FILE_HEADER_SDS011 ", PM10,PM25" +// use original pins from HardwareSerial if none defined +#ifndef SDS_TX +#define SDS_TX -1 +#endif +#ifndef SDS_RX +#define SDS_RX -1 +#endif + extern bool isSDS011Active; bool sds011_init(); @@ -13,5 +21,4 @@ void sds011_loop(); void sds011_sleep(void); void sds011_wakeup(void); void sds011_store(sdsStatus_t *sds_store); - #endif // _SDS011READ_H diff --git a/src/sds011read.cpp b/src/sds011read.cpp index b8a0188b..c8c754f3 100644 --- a/src/sds011read.cpp +++ b/src/sds011read.cpp @@ -13,16 +13,12 @@ static const char TAG[] = __FILE__; SdsDustSensor sds(Serial2); -// the results of the sensor: -static float pm10, pm25; bool isSDS011Active = false; +static float pm10 = 0.0, pm25 = 0.0; // init bool sds011_init() { - pm25 = pm10 = 0.0; - - sds.begin(9600, SERIAL_8N1, 12, 35); - + sds.begin(9600, SERIAL_8N1, SDS_RX, SDS_TX); String version = sds.queryFirmwareVersion().toString(); ESP_LOGI(TAG, "SDS011 firmware version %s", version); sds.setQueryReportingMode(); @@ -36,12 +32,12 @@ void sds011_loop() { if (isSDS011Active) { PmResult pm = sds.queryPm(); if (!pm.isOk()) { - pm25 = pm10 = 0.0; - ESP_LOGE(TAG, "SDS011 query error"); + ESP_LOGE(TAG, "SDS011 query error %s", pm.statusToString()); + pm10 = pm25 = 0.0; } else { - pm25 = pm.pm25; + ESP_LOGI(TAG, "SDS011: %s", pm.toString()); pm10 = pm.pm10; - ESP_LOGI(TAG, "fine-dust-values: %5.1f,%4.1f", pm10, pm25); + pm25 = pm.pm25; } sds011_sleep(); } From e4d6aea3622fbdaa2098e3302a8fe4a257dd2a89 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Wed, 16 Feb 2022 17:40:40 +0100 Subject: [PATCH 59/60] sds011 final fixes for new lib --- src/cyclic.cpp | 2 -- src/sdcard.cpp | 3 ++- src/sds011read.cpp | 11 ++++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cyclic.cpp b/src/cyclic.cpp index 67d21262..385f9afe 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -120,10 +120,8 @@ void doHousekeeping() { #if (HAS_SDS011) if (isSDS011Active) { - ESP_LOGD(TAG, "SDS011: go to sleep"); sds011_loop(); } else { - ESP_LOGD(TAG, "SDS011: wakeup"); sds011_wakeup(); } #endif diff --git a/src/sdcard.cpp b/src/sdcard.cpp index 72af507e..c8696bb1 100644 --- a/src/sdcard.cpp +++ b/src/sdcard.cpp @@ -82,7 +82,8 @@ void sdcardWriteData(uint16_t noWifi, uint16_t noBle, #endif #if (HAS_SDS011) sds011_store(&sds); - snprintf(tempBuffer, sizeof(tempBuffer), ",%5.1f,%4.1f", sds.pm10, sds.pm25); + snprintf(tempBuffer, sizeof(tempBuffer), ",%5.1f,%4.1f", sds.pm10 / 10, + sds.pm25 / 10); fileSDCard.print(tempBuffer); #endif fileSDCard.println(); diff --git a/src/sds011read.cpp b/src/sds011read.cpp index c8c754f3..b1f4d4b0 100644 --- a/src/sds011read.cpp +++ b/src/sds011read.cpp @@ -19,10 +19,9 @@ static float pm10 = 0.0, pm25 = 0.0; // init bool sds011_init() { sds.begin(9600, SERIAL_8N1, SDS_RX, SDS_TX); - String version = sds.queryFirmwareVersion().toString(); - ESP_LOGI(TAG, "SDS011 firmware version %s", version); + sds011_wakeup(); + ESP_LOGI(TAG, "SDS011: %s", sds.queryFirmwareVersion().toString().c_str()); sds.setQueryReportingMode(); - sds011_sleep(); // we do sleep/wakup by ourselves return true; } @@ -32,13 +31,14 @@ void sds011_loop() { if (isSDS011Active) { PmResult pm = sds.queryPm(); if (!pm.isOk()) { - ESP_LOGE(TAG, "SDS011 query error %s", pm.statusToString()); + ESP_LOGE(TAG, "SDS011: query error %s", pm.statusToString().c_str()); pm10 = pm25 = 0.0; } else { - ESP_LOGI(TAG, "SDS011: %s", pm.toString()); + ESP_LOGI(TAG, "SDS011: %s", pm.toString().c_str()); pm10 = pm.pm10; pm25 = pm.pm25; } + ESP_LOGD(TAG, "SDS011: go to sleep"); sds011_sleep(); } } @@ -60,6 +60,7 @@ void sds011_sleep(void) { void sds011_wakeup() { WorkingStateResult state = sds.wakeup(); isSDS011Active = state.isWorking(); + ESP_LOGD(TAG, "SDS011: %s", state.toString().c_str()); } #endif // HAS_SDS011 From 64eaf537dad555799004f6a9eea31f5281f80789 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Wed, 16 Feb 2022 21:06:37 +0100 Subject: [PATCH 60/60] bump to v3.2.0 --- platformio_orig.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio_orig.ini b/platformio_orig.ini index 632ef7e8..6baf22c9 100644 --- a/platformio_orig.ini +++ b/platformio_orig.ini @@ -48,7 +48,7 @@ description = Paxcounter is a device for metering passenger flows in realtime. I [common] ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" -release_version = 3.1.2 +release_version = 3.2.0 ; 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 debug_level = 3