From cb7b6001682bfc2c9402422de4577bd618be1ee5 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Mon, 29 Jul 2019 00:24:37 +0200 Subject: [PATCH 01/34] gpsread.cpp: code sanitization --- src/gpsread.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index d746d127..b63be1ab 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -83,13 +83,9 @@ void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store) { if (gps.time.isUpdated() && gps.date.isValid() && (gps.time.age() < 1000)) { // nmea telegram serial delay compensation; not sure if we need this? - /* - if (gps.time.age() > nmea_txDelay_ms) - gps_store->timedate.Second = gps.time.second() + 1; - else - gps_store->timedate.Second = gps.time.second(); - */ - + // if (gps.time.age() > nmea_txDelay_ms) + // gps_store->timedate.Second = gps.time.second() + 1; + // else gps_store->timedate.Second = gps.time.second(); gps_store->timedate.Minute = gps.time.minute(); gps_store->timedate.Hour = gps.time.hour(); From 57d0624fd03c6c454402c7a9fb6c2a82c8e4fb05 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Mon, 29 Jul 2019 10:26:58 +0200 Subject: [PATCH 02/34] removed GPS IRQ, since not really needed --- include/globals.h | 2 +- include/irqhandler.h | 4 ---- src/irqhandler.cpp | 17 ----------------- src/main.cpp | 13 +------------ src/rcommand.cpp | 1 + src/senddata.cpp | 1 + src/timekeeper.cpp | 2 +- 7 files changed, 5 insertions(+), 35 deletions(-) diff --git a/include/globals.h b/include/globals.h index 9e8549e5..20eb6934 100644 --- a/include/globals.h +++ b/include/globals.h @@ -112,7 +112,7 @@ extern uint16_t volatile macs_total, macs_wifi, macs_ble, batt_voltage; // display values extern bool volatile TimePulseTick; // 1sec pps flag set by GPS or RTC extern timesource_t timeSource; -extern hw_timer_t *displayIRQ, *matrixDisplayIRQ, *ppsIRQ, *gpsIRQ; +extern hw_timer_t *displayIRQ, *matrixDisplayIRQ, *ppsIRQ; extern SemaphoreHandle_t I2Caccess; extern TaskHandle_t irqHandlerTask, ClockTask; extern TimerHandle_t WifiChanTimer; diff --git a/include/irqhandler.h b/include/irqhandler.h index 3a06d3da..54b0e1a4 100644 --- a/include/irqhandler.h +++ b/include/irqhandler.h @@ -8,7 +8,6 @@ #define TIMESYNC_IRQ 0x010 #define MASK_IRQ 0x020 #define UNMASK_IRQ 0x040 -#define GPS_IRQ 0x080 #define MATRIX_DISPLAY_IRQ 0x100 #include "globals.h" @@ -32,8 +31,5 @@ void IRAM_ATTR MatrixDisplayIRQ(); void IRAM_ATTR ButtonIRQ(); #endif -#if (HAS_GPS) -void IRAM_ATTR GpsIRQ(); -#endif #endif \ No newline at end of file diff --git a/src/irqhandler.cpp b/src/irqhandler.cpp index 86177a31..6574bbcc 100644 --- a/src/irqhandler.cpp +++ b/src/irqhandler.cpp @@ -45,12 +45,6 @@ void irqHandler(void *pvParameters) { refreshTheMatrixDisplay(); #endif -// gps refresh buffer? -#if (HAS_GPS) - if (InterruptStatus & GPS_IRQ) - gps_storelocation(&gps_status); -#endif - // are cyclic tasks due? if (InterruptStatus & CYCLIC_IRQ) doHousekeeping(); @@ -108,17 +102,6 @@ void IRAM_ATTR ButtonIRQ() { } #endif -#if (HAS_GPS) -void IRAM_ATTR GpsIRQ() { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - - xTaskNotifyFromISR(irqHandlerTask, GPS_IRQ, eSetBits, - &xHigherPriorityTaskWoken); - if (xHigherPriorityTaskWoken) - portYIELD_FROM_ISR(); -} -#endif - void mask_user_IRQ() { xTaskNotify(irqHandlerTask, MASK_IRQ, eSetBits); } void unmask_user_IRQ() { xTaskNotify(irqHandlerTask, UNMASK_IRQ, eSetBits); } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index f97ca72d..34787246 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,7 +48,6 @@ So don't do it if you do not own a digital oscilloscope. ------------------------------------------------------------------------------- 0 displayIRQ -> display refresh -> 40ms (DISPLAYREFRESH_MS) 1 ppsIRQ -> pps clock irq -> 1sec -2 gpsIRQ -> gps store data -> 300ms 3 MatrixDisplayIRQ -> matrix mux cycle -> 0,5ms (MATRIX_DISPLAY_SCAN_US) @@ -58,7 +57,6 @@ So don't do it if you do not own a digital oscilloscope. fired by hardware DisplayIRQ -> esp32 timer 0 -> irqHandlerTask (Core 1) CLOCKIRQ -> esp32 timer 1 -> ClockTask (Core 1) -GpsIRQ -> esp32 timer 2 -> irqHandlerTask (Core 1) ButtonIRQ -> external gpio -> irqHandlerTask (Core 1) fired by software (Ticker.h) @@ -82,8 +80,7 @@ uint8_t volatile channel = 0; // channel rotation counter uint16_t volatile macs_total = 0, macs_wifi = 0, macs_ble = 0, batt_voltage = 0; // globals for display -hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL, *matrixDisplayIRQ = NULL, - *gpsIRQ = NULL; +hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL, *matrixDisplayIRQ = NULL; TaskHandle_t irqHandlerTask = NULL, ClockTask = NULL; SemaphoreHandle_t I2Caccess; @@ -419,14 +416,6 @@ void setup() { button_init(HAS_BUTTON); #endif // HAS_BUTTON - // gps buffer read interrupt -#if (HAS_GPS) - gpsIRQ = timerBegin(2, 80, true); - timerAttachInterrupt(gpsIRQ, &GpsIRQ, true); - timerAlarmWrite(gpsIRQ, 300 * 1000, true); - timerAlarmEnable(gpsIRQ); -#endif - // cyclic function interrupts sendcycler.attach(SENDCYCLE * 2, sendcycle); housekeeper.attach(HOMECYCLE, housekeeping); diff --git a/src/rcommand.cpp b/src/rcommand.cpp index 20f8cc36..e1cb37f4 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -253,6 +253,7 @@ void get_status(uint8_t val[]) { void get_gps(uint8_t val[]) { ESP_LOGI(TAG, "Remote command: get gps status"); #if(HAS_GPS) + gps_storelocation(&gps_status); payload.reset(); payload.addGPS(gps_status); SendPayload(GPSPORT, prio_high); diff --git a/src/senddata.cpp b/src/senddata.cpp index ecbfb0ec..8b95f219 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -87,6 +87,7 @@ void sendCounter() { case GPS_DATA: // send GPS position only if we have a fix if (gps.location.isValid()) { + gps_storelocation(&gps_status); payload.reset(); payload.addGPS(gps_status); SendPayload(GPSPORT, prio_high); diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index 7cd1bbe0..d80d0d3a 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -131,7 +131,7 @@ void IRAM_ATTR CLOCKIRQ(void) { SyncToPPS(); // advance systime, see microTime.h - // store recent gps time, and try to get gps time if time is not synced + // store recent gps time #if (HAS_GPS) gps_storetime(&gps_status); #endif From cc9997c64b6e235711bcb846ea1f105707f0af18 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Mon, 29 Jul 2019 10:29:44 +0200 Subject: [PATCH 03/34] removed unused variable gps_pps_time --- include/globals.h | 1 - src/main.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/include/globals.h b/include/globals.h index 20eb6934..dcfd17a1 100644 --- a/include/globals.h +++ b/include/globals.h @@ -118,7 +118,6 @@ extern TaskHandle_t irqHandlerTask, ClockTask; extern TimerHandle_t WifiChanTimer; extern Timezone myTZ; extern time_t userUTCTime; -extern time_t volatile gps_pps_time; // application includes #include "led.h" diff --git a/src/main.cpp b/src/main.cpp index 34787246..7e1584ab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -85,7 +85,6 @@ hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL, *matrixDisplayIRQ = NULL; TaskHandle_t irqHandlerTask = NULL, ClockTask = NULL; SemaphoreHandle_t I2Caccess; bool volatile TimePulseTick = false; -time_t volatile gps_pps_time = 0; time_t userUTCTime = 0; timesource_t timeSource = _unsynced; From 3f3c58feeb4d3b55a6f9ddbba0fd75f143419c50 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Mon, 29 Jul 2019 11:00:14 +0200 Subject: [PATCH 04/34] gpsread.cpp: init gps_status --- src/gpsread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index b63be1ab..8a8ab504 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -6,7 +6,7 @@ static const char TAG[] = __FILE__; TinyGPSPlus gps; -gpsStatus_t gps_status; +gpsStatus_t gps_status = {0}; TaskHandle_t GpsTask; #ifdef GPS_SERIAL From 11cfa27c7665e7e8f8856cae6767da02a1a89af5 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Mon, 29 Jul 2019 14:43:37 +0200 Subject: [PATCH 05/34] i2c locking for rtc & timesync streamlined --- include/globals.h | 1 - include/rtctime.h | 2 +- src/lorawan.cpp | 12 ++---------- src/rtctime.cpp | 16 +++++++++------- src/timekeeper.cpp | 2 +- src/timesync.cpp | 5 ++--- 6 files changed, 15 insertions(+), 23 deletions(-) diff --git a/include/globals.h b/include/globals.h index dcfd17a1..ea477a95 100644 --- a/include/globals.h +++ b/include/globals.h @@ -99,7 +99,6 @@ typedef struct { enum sendprio_t { prio_low, prio_normal, prio_high }; enum timesource_t { _gps, _rtc, _lora, _unsynced }; -enum mutexselect_t { no_mutex, do_mutex }; extern std::set, Mallocator> macs; extern std::array::iterator it; diff --git a/include/rtctime.h b/include/rtctime.h index 08baa9f6..3429d44e 100644 --- a/include/rtctime.h +++ b/include/rtctime.h @@ -9,7 +9,7 @@ extern RtcDS3231 Rtc; // make RTC instance globally available uint8_t rtc_init(void); -uint8_t set_rtctime(time_t t, mutexselect_t mutex); +uint8_t set_rtctime(time_t t); void sync_rtctime(void); time_t get_rtctime(void); float get_rtctemp(void); diff --git a/src/lorawan.cpp b/src/lorawan.cpp index af8d04bb..228f3a1e 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -507,15 +507,8 @@ void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime, return; } - // begin of time critical section - - // lock I2C bus and application irq to ensure accurate timing + // mask application irq to ensure accurate timing mask_user_IRQ(); - if (!I2C_MUTEX_LOCK()) { - ESP_LOGW(TAG, "[%0.3f] Timesync handshake error: i2c bus locking failed", - millis() / 1000.0); - goto finish; // failure - } // Update userUTCTime, considering the difference between the GPS and UTC // time, and the leap seconds until year 2019 @@ -532,8 +525,7 @@ void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime, setMyTime(*pUserUTCTime + requestDelaySec, 0); finish: - // end of time critical section: release I2C bus and app irq - I2C_MUTEX_UNLOCK(); + // end of time critical section: release app irq lock unmask_user_IRQ(); } // user_request_network_time_callback diff --git a/src/rtctime.cpp b/src/rtctime.cpp index 086beb29..a3fc2a31 100644 --- a/src/rtctime.cpp +++ b/src/rtctime.cpp @@ -46,21 +46,20 @@ uint8_t rtc_init(void) { } // rtc_init() -uint8_t set_rtctime(time_t t, mutexselect_t mutex) { // t is sec epoch time - if (!mutex || I2C_MUTEX_LOCK()) { +uint8_t set_rtctime(time_t t) { // t is sec epoch time + if (I2C_MUTEX_LOCK()) { #ifdef RTC_INT // sync rtc 1Hz pulse on top of second Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone); // off Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeClock); // start #endif Rtc.SetDateTime(RtcDateTime(t - SECS_YR_2000)); // epoch -> sec2000 - if (mutex) - I2C_MUTEX_UNLOCK(); + I2C_MUTEX_UNLOCK(); ESP_LOGI(TAG, "RTC time synced"); return 1; // success } else { ESP_LOGE(TAG, "RTC set time failure"); - return 0; - } // failure + return 0; // failure + } } // set_rtctime() time_t get_rtctime(void) { @@ -71,8 +70,11 @@ time_t get_rtctime(void) { t = tt.Epoch32Time(); // sec2000 -> epoch } I2C_MUTEX_UNLOCK(); + return timeIsValid(t); + } else { + ESP_LOGE(TAG, "RTC get time failure"); + return 0; // failure } - return timeIsValid(t); } // get_rtctime() float get_rtctemp(void) { diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index d80d0d3a..646069c2 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -31,7 +31,7 @@ time_t timeProvider(void) { t = fetch_gpsTime(gps_status); if (t) { #ifdef HAS_RTC - set_rtctime(t, do_mutex); // calibrate RTC + set_rtctime(t); // calibrate RTC #endif timeSource = _gps; timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat diff --git a/src/timesync.cpp b/src/timesync.cpp index cb75b4ce..95515ec9 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -132,9 +132,8 @@ void process_timesync_req(void *taskparameter) { finish: // end of time critical section: release app irq lock - unmask_user_IRQ(); - timeSyncPending = false; + unmask_user_IRQ(); } // infinite while(1) } @@ -223,7 +222,7 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec) { // set RTC time and calibrate RTC_INT pulse on top of second #ifdef HAS_RTC - set_rtctime(time_to_set, no_mutex); + set_rtctime(time_to_set); #endif // sync pps timer to top of second From 85aa9655c6d35f96089ed247829bfbea4e3e3bb4 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Mon, 29 Jul 2019 20:23:27 +0200 Subject: [PATCH 06/34] BME task removed / do i2c masking via interrupt --- include/bmesensor.h | 7 +++-- include/irqhandler.h | 2 ++ src/bmesensor.cpp | 67 ++++++++++++++++++++------------------------ src/cyclic.cpp | 13 +++------ src/irqhandler.cpp | 6 ++++ src/main.cpp | 13 ++------- src/paxcounter.conf | 3 +- src/rcommand.cpp | 12 ++++---- 8 files changed, 58 insertions(+), 65 deletions(-) diff --git a/include/bmesensor.h b/include/bmesensor.h index 059cf332..2d1ec9ce 100644 --- a/include/bmesensor.h +++ b/include/bmesensor.h @@ -11,14 +11,16 @@ #include #endif +extern Ticker bmecycler; + extern bmeStatus_t bme_status; // Make struct for storing gps data globally available -extern TaskHandle_t BmeTask; // --- Bosch BSEC v1.4.7.4 library configuration --- // 3,3V supply voltage; 3s max time between sensor_control calls; 4 days // calibration. Change this const if not applicable for your application (see // BME680 datasheet) +// Note: 3s max time not exceed BMECYCLE frequency set in paxcounter.conf! const uint8_t bsec_config_iaq[454] = { 4, 7, 4, 1, 61, 0, 0, 0, 0, 0, 0, 0, 174, 1, 0, 0, 48, 0, 1, 0, 0, 192, 168, 71, 64, 49, 119, 76, 0, 0, @@ -54,7 +56,8 @@ const uint8_t bsec_config_iaq[454] = { // Helper functions declarations int bme_init(); -void bme_loop(void *pvParameters); +void bmecycle(void); +void bme_storedata(bmeStatus_t *bme_store); int checkIaqSensorStatus(void); void loadState(void); void updateState(void); diff --git a/include/irqhandler.h b/include/irqhandler.h index 54b0e1a4..08d6bd8c 100644 --- a/include/irqhandler.h +++ b/include/irqhandler.h @@ -8,12 +8,14 @@ #define TIMESYNC_IRQ 0x010 #define MASK_IRQ 0x020 #define UNMASK_IRQ 0x040 +#define BME_IRQ 0x080 #define MATRIX_DISPLAY_IRQ 0x100 #include "globals.h" #include "cyclic.h" #include "senddata.h" #include "timekeeper.h" +#include "bmesensor.h" void irqHandler(void *pvParameters); void mask_user_IRQ(); diff --git a/src/bmesensor.cpp b/src/bmesensor.cpp index d9638d7f..deb8e45e 100644 --- a/src/bmesensor.cpp +++ b/src/bmesensor.cpp @@ -5,8 +5,9 @@ // Local logging tag static const char TAG[] = __FILE__; -bmeStatus_t bme_status; -TaskHandle_t BmeTask; +bmeStatus_t bme_status = {0}; + +Ticker bmecycler; #define SEALEVELPRESSURE_HPA (1013.25) @@ -37,6 +38,8 @@ Adafruit_BME280 bme; // I2C #endif +void bmecycle() { xTaskNotify(irqHandlerTask, BME_IRQ, eSetBits); } + // initialize BME680 sensor int bme_init(void) { @@ -136,47 +139,37 @@ int checkIaqSensorStatus(void) { } // checkIaqSensorStatus() #endif -// loop function which reads and processes data based on sensor settings -void bme_loop(void *pvParameters) { - - configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check +// store current BME sensor data in struct +void bme_storedata(bmeStatus_t *bme_store) { + if (I2C_MUTEX_LOCK()) { // block i2c bus access #ifdef HAS_BME680 - while (1) { - // block i2c bus access - if (I2C_MUTEX_LOCK()) { - if (iaqSensor.run()) { // If new data is available - bme_status.raw_temperature = - iaqSensor.rawTemperature; // Temperature in degree celsius - bme_status.raw_humidity = iaqSensor.rawHumidity; - bme_status.temperature = iaqSensor.temperature; - bme_status.humidity = - iaqSensor.humidity; // Humidity in % relative humidity x1000 - bme_status.pressure = // Pressure in Pascal - (iaqSensor.pressure / 100.0); // conversion Pa -> hPa - bme_status.iaq = iaqSensor.iaqEstimate; - bme_status.iaq_accuracy = iaqSensor.iaqAccuracy; - bme_status.gas = iaqSensor.gasResistance; // Gas resistance in Ohms - updateState(); - } - I2C_MUTEX_UNLOCK(); + if (iaqSensor.run()) { // if new data is available + bme_store->raw_temperature = + iaqSensor.rawTemperature; // temperature in degree celsius + bme_store->raw_humidity = iaqSensor.rawHumidity; + bme_store->temperature = iaqSensor.temperature; + bme_store->humidity = + iaqSensor.humidity; // humidity in % relative humidity x1000 + bme_store->pressure = // pressure in Pascal + (iaqSensor.pressure / 100.0); // conversion Pa -> hPa + bme_store->iaq = iaqSensor.iaqEstimate; + bme_store->iaq_accuracy = iaqSensor.iaqAccuracy; + bme_store->gas = iaqSensor.gasResistance; // gas resistance in ohms + updateState(); } - } #elif defined HAS_BME280 - while (1) { - if (I2C_MUTEX_LOCK()) { - bme_status.temperature = bme.readTemperature(); - bme_status.pressure = - (bme.readPressure() / 100.0); // conversion Pa -> hPa - // bme.readAltitude(SEALEVELPRESSURE_HPA); - bme_status.humidity = bme.readHumidity(); - bme_status.iaq = 0; // IAQ feature not present with BME280 - I2C_MUTEX_UNLOCK(); - } - } + bme_store->temperature = bme.readTemperature(); + bme_store->pressure = (bme.readPressure() / 100.0); // conversion Pa -> hPa + // bme.readAltitude(SEALEVELPRESSURE_HPA); + bme_store->humidity = bme.readHumidity(); + bme_store->iaq = 0; // IAQ feature not present with BME280 #endif -} // bme_loop() + I2C_MUTEX_UNLOCK(); // release i2c bus access + } + +} // bme_storedata() #ifdef HAS_BME680 void loadState(void) { diff --git a/src/cyclic.cpp b/src/cyclic.cpp index 53b16956..9658be78 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -38,10 +38,6 @@ void doHousekeeping() { ESP_LOGD(TAG, "Gpsloop %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(GpsTask), eTaskGetState(GpsTask)); #endif -#if (HAS_BME) - ESP_LOGD(TAG, "Bmeloop %d bytes left | Taskstate = %d", - uxTaskGetStackHighWaterMark(BmeTask), eTaskGetState(BmeTask)); -#endif #if (defined HAS_DCF77 || defined HAS_IF482) ESP_LOGD(TAG, "Clockloop %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(ClockTask), eTaskGetState(ClockTask)); @@ -59,16 +55,15 @@ void doHousekeeping() { ESP_LOGI(TAG, "Voltage: %dmV", batt_voltage); #endif -// display BME sensor data +// display BME680/280 sensor data +#if (HAS_BME) #ifdef HAS_BME680 ESP_LOGI(TAG, "BME680 Temp: %.2f°C | IAQ: %.2f | IAQacc: %d", bme_status.temperature, bme_status.iaq, bme_status.iaq_accuracy); -#endif - -// display BME280 sensor data -#ifdef HAS_BME280 +#elif defined HAS_BME280 ESP_LOGI(TAG, "BME280 Temp: %.2f°C | Humidity: %.2f | Pressure: %.0f", bme_status.temperature, bme_status.humidity, bme_status.pressure); +#endif #endif // check free heap memory diff --git a/src/irqhandler.cpp b/src/irqhandler.cpp index 6574bbcc..62cf1007 100644 --- a/src/irqhandler.cpp +++ b/src/irqhandler.cpp @@ -45,6 +45,12 @@ void irqHandler(void *pvParameters) { refreshTheMatrixDisplay(); #endif +// BME sensor data to be read? +#if (HAS_BME) + if (InterruptStatus & BME_IRQ) + bme_storedata(&bme_status); +#endif + // are cyclic tasks due? if (InterruptStatus & CYCLIC_IRQ) doHousekeeping(); diff --git a/src/main.cpp b/src/main.cpp index 7e1584ab..fb09f5b9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,7 +35,6 @@ clockloop 1 4 generates realtime telegrams for external clock timesync_req 1 3 processes realtime time sync requests irqhandler 1 2 display, timesync, gps, etc. triggered by timers gpsloop 1 2 reads data from GPS via serial or i2c -bmeloop 1 2 reads data from BME sensor via i2c looptask 1 1 runs the LMIC LoRa stack (arduino loop) IDLE 1 0 ESP32 arduino scheduler -> runs wifi channel rotator @@ -63,6 +62,7 @@ fired by software (Ticker.h) TIMESYNC_IRQ -> timeSync() -> irqHandlerTask (Core 1) CYLCIC_IRQ -> housekeeping() -> irqHandlerTask (Core 1) SENDCYCLE_IRQ -> sendcycle() -> irqHandlerTask (Core 1) +BME_IRQ -> bmecycle() -> irqHandlerTask (Core 1) // External RTC timer (if present) @@ -368,16 +368,8 @@ void setup() { #elif defined HAS_BME280 strcat_P(features, " BME280"); #endif - if (bme_init()) { + if (bme_init()) ESP_LOGI(TAG, "Starting BME sensor..."); - xTaskCreatePinnedToCore(bme_loop, // task function - "bmeloop", // name of task - 2048, // stack size of task - (void *)1, // parameter of the task - 2, // priority of the task - &BmeTask, // task handle - 1); // CPU core - } #endif // starting timers and interrupts @@ -418,6 +410,7 @@ void setup() { // cyclic function interrupts sendcycler.attach(SENDCYCLE * 2, sendcycle); housekeeper.attach(HOMECYCLE, housekeeping); + bmecycler.attach(BMECYCLE, bmecycle); #if (TIME_SYNC_INTERVAL) diff --git a/src/paxcounter.conf b/src/paxcounter.conf index 13b6c0b7..7382d8d8 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -48,7 +48,7 @@ #define PAYLOAD_BUFFER_SIZE 51 // maximum size of payload block per transmit #define LORASFDEFAULT 9 // 7 ... 12 SF, according to LoRaWAN specs #define MAXLORARETRY 500 // maximum count of TX retries if LoRa busy -#define SEND_QUEUE_SIZE 10 // maximum number of messages in payload send queue [1 = no queue] +#define SEND_QUEUE_SIZE 10 // maximum number of messages in payload send queue [1 = no queue] // Hardware settings #define RGBLUMINOSITY 30 // RGB LED luminosity [default = 30%] @@ -58,6 +58,7 @@ // Settings for BME680 environmental sensor #define BME_TEMP_OFFSET 5.0f // Offset sensor on chip temp <-> ambient temp [default = 5°C] #define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // update every 360 minutes = 4 times a day +#define BMECYCLE 1 // bme sensor read cycle in seconds [default = 1 secs] // OTA settings #define USE_OTA 1 // set to 0 to disable OTA update diff --git a/src/rcommand.cpp b/src/rcommand.cpp index e1cb37f4..c2a1fb37 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -8,7 +8,7 @@ static const char TAG[] = __FILE__; // helper function void do_reset() { ESP_LOGI(TAG, "Remote command: restart device"); -#if(HAS_LORA) +#if (HAS_LORA) LMIC_shutdown(); #endif delay(3000); @@ -132,7 +132,7 @@ void set_gps(uint8_t val[]) { } void set_sensor(uint8_t val[]) { -#if(HAS_SENSORS) +#if (HAS_SENSORS) switch (val[0]) { // check if valid sensor number 1...4 case 1: case 2: @@ -170,7 +170,7 @@ void set_monitor(uint8_t val[]) { } void set_lorasf(uint8_t val[]) { -#if(HAS_LORA) +#if (HAS_LORA) ESP_LOGI(TAG, "Remote command: set LoRa SF to %d", val[0]); switch_lora(val[0], cfg.txpower); #else @@ -179,7 +179,7 @@ void set_lorasf(uint8_t val[]) { } void set_loraadr(uint8_t val[]) { -#if(HAS_LORA) +#if (HAS_LORA) ESP_LOGI(TAG, "Remote command: set LoRa ADR mode to %s", val[0] ? "on" : "off"); cfg.adrmode = val[0] ? 1 : 0; @@ -222,7 +222,7 @@ void set_rgblum(uint8_t val[]) { }; void set_lorapower(uint8_t val[]) { -#if(HAS_LORA) +#if (HAS_LORA) ESP_LOGI(TAG, "Remote command: set LoRa TXPOWER to %d", val[0]); switch_lora(cfg.lorasf, val[0]); #else @@ -252,7 +252,7 @@ void get_status(uint8_t val[]) { void get_gps(uint8_t val[]) { ESP_LOGI(TAG, "Remote command: get gps status"); -#if(HAS_GPS) +#if (HAS_GPS) gps_storelocation(&gps_status); payload.reset(); payload.addGPS(gps_status); From 31cd61355553bda24b703f01875057887e020e44 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Wed, 31 Jul 2019 22:20:18 +0200 Subject: [PATCH 07/34] bugfix bmecycler --- src/bmesensor.cpp | 2 ++ src/main.cpp | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bmesensor.cpp b/src/bmesensor.cpp index deb8e45e..78298798 100644 --- a/src/bmesensor.cpp +++ b/src/bmesensor.cpp @@ -109,6 +109,8 @@ int bme_init(void) { finish: I2C_MUTEX_UNLOCK(); // release i2c bus access + if (rc) + bmecycler.attach(BMECYCLE, bmecycle); return rc; } // bme_init() diff --git a/src/main.cpp b/src/main.cpp index fb09f5b9..3674b6bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -410,7 +410,6 @@ void setup() { // cyclic function interrupts sendcycler.attach(SENDCYCLE * 2, sendcycle); housekeeper.attach(HOMECYCLE, housekeeping); - bmecycler.attach(BMECYCLE, bmecycle); #if (TIME_SYNC_INTERVAL) From 5dcb3b315e94a068758d11062cb7001741a93432 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Fri, 2 Aug 2019 21:53:05 +0200 Subject: [PATCH 08/34] Moved LMiC to dedicated task with raised prio --- include/lorawan.h | 2 ++ src/cyclic.cpp | 4 ++++ src/lorawan.cpp | 61 +++++++++++++++++++++++++++++++---------------- src/main.cpp | 9 +++---- 4 files changed, 51 insertions(+), 25 deletions(-) diff --git a/include/lorawan.h b/include/lorawan.h index 47170b4a..0b6cabad 100644 --- a/include/lorawan.h +++ b/include/lorawan.h @@ -21,8 +21,10 @@ #endif extern QueueHandle_t LoraSendQueue; +extern TaskHandle_t lmicTask; esp_err_t lora_stack_init(); +void lmictask(void *pvParameters); void onEvent(ev_t ev); void gen_lora_deveui(uint8_t *pdeveui); void RevBytes(unsigned char *b, size_t c); diff --git a/src/cyclic.cpp b/src/cyclic.cpp index 9658be78..9e338cef 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -34,6 +34,10 @@ void doHousekeeping() { ESP_LOGD(TAG, "IRQhandler %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(irqHandlerTask), eTaskGetState(irqHandlerTask)); +#if (HAS_LORA) + ESP_LOGD(TAG, "LMiCtask %d bytes left | Taskstate = %d", + uxTaskGetStackHighWaterMark(lmicTask), eTaskGetState(lmicTask)); +#endif #if (HAS_GPS) ESP_LOGD(TAG, "Gpsloop %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(GpsTask), eTaskGetState(GpsTask)); diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 228f3a1e..333218dd 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -20,6 +20,7 @@ static const char TAG[] = "lora"; osjob_t sendjob; QueueHandle_t LoraSendQueue; +TaskHandle_t lmicTask = NULL; class MyHalConfig_t : public Arduino_LMIC::HalConfiguration_t { @@ -423,28 +424,15 @@ esp_err_t lora_stack_init() { ESP_LOGI(TAG, "LORA send queue created, size %d Bytes", SEND_QUEUE_SIZE * sizeof(MessageBuffer_t)); + // starting lorawan stack ESP_LOGI(TAG, "Starting LMIC..."); - - os_init(); // initialize lmic run-time environment on core 1 - LMIC_reset(); // initialize lmic MAC - LMIC_setLinkCheckMode(0); - // This tells LMIC to make the receive windows bigger, in case your clock is - // faster or slower. This causes the transceiver to be earlier switched on, - // so consuming more power. You may sharpen (reduce) CLOCK_ERROR_PERCENTAGE - // in src/lmic_config.h if you are limited on battery. - LMIC_setClockError(MAX_CLOCK_ERROR * CLOCK_ERROR_PROCENTAGE / 100); - // Set the data rate to Spreading Factor 7. This is the fastest supported - // rate for 125 kHz channels, and it minimizes air time and battery power. - // Set the transmission power to 14 dBi (25 mW). - LMIC_setDrTxpow(DR_SF7, 14); - -#if defined(CFG_US915) || defined(CFG_au921) - // in the US, with TTN, it saves join time if we start on subband 1 - // (channels 8-15). This will get overridden after the join by parameters - // from the network. If working with other networks or in other regions, - // this will need to be changed. - LMIC_selectSubBand(1); -#endif + xTaskCreatePinnedToCore(lmictask, // task function + "lmictask", // name of task + 4096, // stack size of task + (void *)1, // parameter of the task + 2, // priority of the task + &lmicTask, // task handle + 1); // CPU core if (!LMIC_startJoining()) { // start joining ESP_LOGI(TAG, "Already joined"); @@ -531,4 +519,35 @@ finish: } // user_request_network_time_callback #endif // TIME_SYNC_LORAWAN +// LMIC lorawan stack task +void lmictask(void *pvParameters) { + configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check + + os_init(); // initialize lmic run-time environment on core 1 + LMIC_reset(); // initialize lmic MAC + LMIC_setLinkCheckMode(0); + // This tells LMIC to make the receive windows bigger, in case your clock is + // faster or slower. This causes the transceiver to be earlier switched on, + // so consuming more power. You may sharpen (reduce) CLOCK_ERROR_PERCENTAGE + // in src/lmic_config.h if you are limited on battery. + LMIC_setClockError(MAX_CLOCK_ERROR * CLOCK_ERROR_PROCENTAGE / 100); + // Set the data rate to Spreading Factor 7. This is the fastest supported + // rate for 125 kHz channels, and it minimizes air time and battery power. + // Set the transmission power to 14 dBi (25 mW). + LMIC_setDrTxpow(DR_SF7, 14); + +#if defined(CFG_US915) || defined(CFG_au921) + // in the US, with TTN, it saves join time if we start on subband 1 + // (channels 8-15). This will get overridden after the join by parameters + // from the network. If working with other networks or in other regions, + // this will need to be changed. + LMIC_selectSubBand(1); +#endif + + while (1) { + os_runloop_once(); // execute lmic scheduled jobs and events + delay(2); // yield to CPU + } +} // lmictask + #endif // HAS_LORA diff --git a/src/main.cpp b/src/main.cpp index 3674b6bb..d88722b5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,9 +33,10 @@ IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer clockloop 1 4 generates realtime telegrams for external clock timesync_req 1 3 processes realtime time sync requests -irqhandler 1 2 display, timesync, gps, etc. triggered by timers -gpsloop 1 2 reads data from GPS via serial or i2c -looptask 1 1 runs the LMIC LoRa stack (arduino loop) +lmictask 1 2 MCCI LMiC LORAWAN stack +irqhandler 1 1 display, timesync, gps, etc. triggered by timers +gpsloop 1 1 reads data from GPS via serial or i2c +looptask 1 1 arduino loop (unused) IDLE 1 0 ESP32 arduino scheduler -> runs wifi channel rotator Low priority numbers denote low priority tasks. @@ -268,7 +269,7 @@ void setup() { "gpsloop", // name of task 2048, // stack size of task (void *)1, // parameter of the task - 2, // priority of the task + 1, // priority of the task &GpsTask, // task handle 1); // CPU core } From bf70f2f9f28c5b99349416219a434adb5b7a3391 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sat, 3 Aug 2019 11:35:16 +0200 Subject: [PATCH 09/34] removed spi & lora houskeeping functions --- include/lorawan.h | 1 - include/spislave.h | 2 -- src/cyclic.cpp | 12 +++++------- src/spislave.cpp | 4 ---- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/include/lorawan.h b/include/lorawan.h index 0b6cabad..b3331751 100644 --- a/include/lorawan.h +++ b/include/lorawan.h @@ -37,7 +37,6 @@ void switch_lora(uint8_t sf, uint8_t tx); void lora_send(osjob_t *job); void lora_enqueuedata(MessageBuffer_t *message, sendprio_t prio); void lora_queuereset(void); -void lora_housekeeping(void); #if (TIME_SYNC_LORAWAN) void user_request_network_time_callback(void *pVoidUserUTCTime, int flagSuccess); diff --git a/include/spislave.h b/include/spislave.h index 74b77db0..44c58455 100644 --- a/include/spislave.h +++ b/include/spislave.h @@ -31,6 +31,4 @@ esp_err_t spi_init(); void spi_enqueuedata(MessageBuffer_t *message, sendprio_t prio); void spi_queuereset(); -void spi_housekeeping(); - #endif // _SPISLAVE_H diff --git a/src/cyclic.cpp b/src/cyclic.cpp index 9e338cef..d78d56c4 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -23,13 +23,6 @@ void doHousekeeping() { if (cfg.runmode == 1) do_reset(); -#ifdef HAS_SPI - spi_housekeeping(); -#endif -#if (HAS_LORA) - lora_housekeeping(); -#endif - // task storage debugging // ESP_LOGD(TAG, "IRQhandler %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(irqHandlerTask), @@ -42,6 +35,11 @@ void doHousekeeping() { 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)); +#endif + #if (defined HAS_DCF77 || defined HAS_IF482) ESP_LOGD(TAG, "Clockloop %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(ClockTask), eTaskGetState(ClockTask)); diff --git a/src/spislave.cpp b/src/spislave.cpp index a288d4b0..9801058b 100644 --- a/src/spislave.cpp +++ b/src/spislave.cpp @@ -170,8 +170,4 @@ void spi_enqueuedata(MessageBuffer_t *message, sendprio_t prio) { void spi_queuereset(void) { xQueueReset(SPISendQueue); } -void spi_housekeeping(void) { - ESP_LOGD(TAG, "spiloop %d bytes left", uxTaskGetStackHighWaterMark(spiTask)); -} - #endif // HAS_SPI \ No newline at end of file From 139738a14dea814bee3e3a9e0df9db2f384c4324 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sat, 3 Aug 2019 12:27:24 +0200 Subject: [PATCH 10/34] timesync code sanitized --- README.md | 4 ++-- include/timekeeper.h | 2 +- include/timesync.h | 2 +- src/irqhandler.cpp | 4 +--- src/lorawan.cpp | 9 ++------- src/timekeeper.cpp | 25 +++++++++++++------------ src/timesync.cpp | 10 ++++++---- 7 files changed, 26 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 997a51d0..a9f2ebed 100644 --- a/README.md +++ b/README.md @@ -405,11 +405,11 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts. bytes 1..4 = time/date in UTC epoch seconds (LSB) byte 5 = time source & status, see below - bits 0..3 time source + bits 0..3 last seen time source 0x00 = GPS 0x01 = RTC 0x02 = LORA - 0x03 = unsynched + 0x03 = unsynched (never synched) bits 4..7 time status 0x00 = timeNotSet (never synched) diff --git a/include/timekeeper.h b/include/timekeeper.h index 87f999c0..6239f082 100644 --- a/include/timekeeper.h +++ b/include/timekeeper.h @@ -26,7 +26,7 @@ void timepulse_start(void); void timeSync(void); uint8_t timepulse_init(void); time_t timeIsValid(time_t const t); -time_t timeProvider(void); +void calibrateTime(void); time_t compiledUTC(void); TickType_t tx_Ticks(uint32_t framesize, unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPins); diff --git a/include/timesync.h b/include/timesync.h index 94ec86bb..498952c1 100644 --- a/include/timesync.h +++ b/include/timesync.h @@ -15,6 +15,6 @@ void send_timesync_req(void); int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len); void process_timesync_req(void *taskparameter); void store_time_sync_req(uint32_t t_millisec); -void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec); +void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, timesource_t timesource); #endif \ No newline at end of file diff --git a/src/irqhandler.cpp b/src/irqhandler.cpp index 62cf1007..cb5de1ec 100644 --- a/src/irqhandler.cpp +++ b/src/irqhandler.cpp @@ -59,9 +59,7 @@ void irqHandler(void *pvParameters) { // is time to be synced? if (InterruptStatus & TIMESYNC_IRQ) { now(); // ensure sysTime is recent - time_t t = timeProvider(); - if (timeIsValid(t)) - setTime(t); + calibrateTime(); } #endif diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 333218dd..e82ac1f5 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -464,11 +464,6 @@ void lora_enqueuedata(MessageBuffer_t *message, sendprio_t prio) { void lora_queuereset(void) { xQueueReset(LoraSendQueue); } -void lora_housekeeping(void) { - // ESP_LOGD(TAG, "loraloop %d bytes left", - // uxTaskGetStackHighWaterMark(LoraTask)); -} - #if (TIME_SYNC_LORAWAN) void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime, int flagSuccess) { @@ -510,7 +505,7 @@ void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime, time_t requestDelaySec = osticks2ms(ticksNow - ticksRequestSent) / 1000; // Update system time with time read from the network - setMyTime(*pUserUTCTime + requestDelaySec, 0); + setMyTime(*pUserUTCTime + requestDelaySec, 0, _lora); finish: // end of time critical section: release app irq lock @@ -523,7 +518,7 @@ finish: void lmictask(void *pvParameters) { configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check - os_init(); // initialize lmic run-time environment on core 1 + os_init(); // initialize lmic run-time environment LMIC_reset(); // initialize lmic MAC LMIC_setLinkCheckMode(0); // This tells LMIC to make the receive windows bigger, in case your clock is diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index 646069c2..a3c14829 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -22,9 +22,10 @@ Ticker timesyncer; void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); } -time_t timeProvider(void) { +void calibrateTime(void) { time_t t = 0; + timesource_t timeSource; #if (HAS_GPS) // fetch recent time from last NMEA record @@ -34,9 +35,7 @@ time_t timeProvider(void) { set_rtctime(t); // calibrate RTC #endif timeSource = _gps; - timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat - ESP_LOGD(TAG, "GPS time = %d", t); - return t; + goto finish; } #endif @@ -45,8 +44,7 @@ time_t timeProvider(void) { t = get_rtctime(); if (t) { timeSource = _rtc; - timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); // short retry - ESP_LOGD(TAG, "RTC time = %d", t); + goto finish } #endif @@ -58,14 +56,17 @@ time_t timeProvider(void) { LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime); #endif - if (!t) { - timeSource = _unsynced; - timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); // short retry +finish: + + if (t) { // sync successful + setMyTime(t, 0, timeSource); // set time + timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); + ESP_LOGD(TAG, "time = %d | source: %c", t, timeSetSymbols[timeSource]); + } else { // sync failed, we want to retry shortly + timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); } - return t; - -} // timeProvider() +} // calibrateTime() // helper function to setup a pulse per second for time synchronisation uint8_t timepulse_init() { diff --git a/src/timesync.cpp b/src/timesync.cpp index 95515ec9..f8ba0157 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -128,7 +128,7 @@ void process_timesync_req(void *taskparameter) { // calculate fraction milliseconds time_to_set_fraction_msec = (uint16_t)(time_offset_ms.count() % 1000); - setMyTime(time_to_set, time_to_set_fraction_msec); + setMyTime(time_to_set, time_to_set_fraction_msec, _lora); finish: // end of time critical section: release app irq lock @@ -208,7 +208,8 @@ int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) { } // adjust system time, calibrate RTC and RTC_INT pps -void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec) { +void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, + timesource_t timesource) { time_t time_to_set = (time_t)(t_sec + 1); @@ -218,7 +219,8 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec) { if (timeIsValid(time_to_set)) { // wait until top of second with millisecond precision - vTaskDelay(pdMS_TO_TICKS(1000 - t_msec)); + if (t_msec) + vTaskDelay(pdMS_TO_TICKS(1000 - t_msec)); // set RTC time and calibrate RTC_INT pulse on top of second #ifdef HAS_RTC @@ -233,7 +235,7 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec) { setTime(time_to_set); // set the time on top of second - timeSource = _lora; + timeSource = timesource; timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was adjusted", millis() / 1000.0); From 7fa9269d0b75ead69d1a4d0f2e5acce19d2fea5d Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sat, 3 Aug 2019 14:01:25 +0200 Subject: [PATCH 11/34] GPS msec handling added (experimental) --- include/gpsread.h | 2 +- src/gpsread.cpp | 12 +++++------- src/paxcounter.conf | 2 +- src/timekeeper.cpp | 34 +++++++++++++--------------------- src/timesync.cpp | 35 ++++++++++++++++++++--------------- 5 files changed, 40 insertions(+), 45 deletions(-) diff --git a/include/gpsread.h b/include/gpsread.h index 17336afd..eca6645c 100644 --- a/include/gpsread.h +++ b/include/gpsread.h @@ -21,7 +21,7 @@ int gps_init(void); void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store); void gps_storelocation(gpsStatus_t *gps_store); void gps_loop(void *pvParameters); -time_t fetch_gpsTime(gpsStatus_t value); +time_t fetch_gpsTime(gpsStatus_t value, uint16_t *msec); int gps_config(); #endif \ No newline at end of file diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 8a8ab504..068127e6 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -12,7 +12,7 @@ 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; + (tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL) / portTICK_PERIOD_MS); #else static uint16_t nmea_txDelay_ms = 0; #endif @@ -82,10 +82,7 @@ void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store) { if (gps.time.isUpdated() && gps.date.isValid() && (gps.time.age() < 1000)) { - // nmea telegram serial delay compensation; not sure if we need this? - // if (gps.time.age() > nmea_txDelay_ms) - // gps_store->timedate.Second = gps.time.second() + 1; - // else + gps_store->time_age = gps.time.age() + nmea_txDelay_ms; gps_store->timedate.Second = gps.time.second(); gps_store->timedate.Minute = gps.time.minute(); gps_store->timedate.Hour = gps.time.hour(); @@ -99,10 +96,11 @@ void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store) { } // function to fetch current time from struct; note: this is costly -time_t fetch_gpsTime(gpsStatus_t value) { +time_t fetch_gpsTime(gpsStatus_t value, uint16_t *msec) { + *msec = 1000 - value.time_age; time_t t = timeIsValid(makeTime(value.timedate)); - ESP_LOGD(TAG, "GPS time: %d", t); + ESP_LOGD(TAG, "GPS time: %d | time age: %d", t, value.time_age); return t; } // fetch_gpsTime() diff --git a/src/paxcounter.conf b/src/paxcounter.conf index 7382d8d8..30dcedc0 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -72,7 +72,7 @@ #define TIME_SYNC_INTERVAL_RETRY 10 // retry time sync after lost sync each .. minutes [default = 10], 0 means off #define TIME_SYNC_COMPILEDATE 0 // set to 1 to use compile date to initialize RTC after power outage [default = 0] #define TIME_SYNC_LORAWAN 0 // set to 1 to use LORA network as time source, 0 means off [default = 0] -#define TIME_SYNC_LORASERVER 0 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0] +#define TIME_SYNC_LORASERVER 1 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0] // settings for syncing time with timeserver applications #define TIME_SYNC_SAMPLES 1 // number of time requests for averaging diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index a3c14829..99f6f002 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -1,4 +1,5 @@ #include "timekeeper.h" +#include "paxcounter.conf" #if !(HAS_LORA) #if (TIME_SYNC_LORASERVER) @@ -25,29 +26,17 @@ void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); } void calibrateTime(void) { time_t t = 0; - timesource_t timeSource; + uint16_t t_msec = 0; #if (HAS_GPS) // fetch recent time from last NMEA record - t = fetch_gpsTime(gps_status); + t = fetch_gpsTime(gps_status, &t_msec); if (t) { -#ifdef HAS_RTC - set_rtctime(t); // calibrate RTC -#endif timeSource = _gps; goto finish; } #endif -// no time from GPS -> fallback to RTC time while trying lora sync -#ifdef HAS_RTC - t = get_rtctime(); - if (t) { - timeSource = _rtc; - goto finish - } -#endif - // kick off asychronous Lora timeserver timesync if we have #if (HAS_LORA) && (TIME_SYNC_LORASERVER) send_timesync_req(); @@ -56,15 +45,18 @@ void calibrateTime(void) { LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime); #endif +// no time from GPS -> fallback to RTC time while trying lora sync +#ifdef HAS_RTC + t = get_rtctime(); + if (t) { + timeSource = _rtc; + goto finish; + } +#endif + finish: - if (t) { // sync successful - setMyTime(t, 0, timeSource); // set time - timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); - ESP_LOGD(TAG, "time = %d | source: %c", t, timeSetSymbols[timeSource]); - } else { // sync failed, we want to retry shortly - timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); - } + setMyTime(t, t_msec, timeSource); // set time } // calibrateTime() diff --git a/src/timesync.cpp b/src/timesync.cpp index f8ba0157..9499502d 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -209,22 +209,25 @@ int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) { // adjust system time, calibrate RTC and RTC_INT pps void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, - timesource_t timesource) { + timesource_t mytimesource) { - time_t time_to_set = (time_t)(t_sec + 1); - - ESP_LOGD(TAG, "[%0.3f] Calculated UTC epoch time: %d.%03d sec", - millis() / 1000.0, time_to_set, t_msec); + time_t time_to_set = (time_t)(t_sec); if (timeIsValid(time_to_set)) { + ESP_LOGD(TAG, "[%0.3f] UTC epoch time: %d.%03d sec", millis() / 1000.0, + time_to_set, t_msec); // wait until top of second with millisecond precision - if (t_msec) + if (t_msec) { vTaskDelay(pdMS_TO_TICKS(1000 - t_msec)); + time_to_set++; + } -// set RTC time and calibrate RTC_INT pulse on top of second +// if we got a timesource, set RTC time and calibrate RTC_INT pulse on top of +// second #ifdef HAS_RTC - set_rtctime(time_to_set); + if (mytimesource != _rtc) + set_rtctime(time_to_set); #endif // sync pps timer to top of second @@ -235,13 +238,15 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, setTime(time_to_set); // set the time on top of second - timeSource = timesource; - timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat - ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was adjusted", - millis() / 1000.0); - } else - ESP_LOGW(TAG, "[%0.3f] Timesync failed, outdated time calculated", - millis() / 1000.0); + timeSource = mytimesource; // set global variable + timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); + ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was set | source: %c", + millis() / 1000.0, timeSetSymbols[timeSource]); + } else { + timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); + ESP_LOGI(TAG, "[%0.3f] Timesync failed, invalid time fetched | source: %c", + millis() / 1000.0, timeSetSymbols[timeSource]); + } } void timesync_init() { From 7284d7ce4df4209c3bbec1322a88bf6fffcbf757 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sat, 3 Aug 2019 18:06:06 +0200 Subject: [PATCH 12/34] timekeeper.cpp: code sanitization --- src/timekeeper.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index 99f6f002..b6a2051b 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -202,11 +202,13 @@ void clock_init(void) { void clock_loop(void *taskparameter) { // ClockTask // caveat: don't use now() in this task, it will cause a race condition - // due to concurrent access to i2c bus for setting rtc! + // due to concurrent access to i2c bus when reading/writing from/to rtc chip! #define nextmin(t) (t + DCF77_FRAME_SIZE + 1) // next minute +#ifdef HAS_TWO_LED static bool led1_state = false; +#endif uint32_t printtime; time_t t = *((time_t *)taskparameter), last_printtime = 0; // UTC time seconds From 1efc9be6c3338b1699df742c5cb4e54f68fe4ba0 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 4 Aug 2019 15:17:50 +0200 Subject: [PATCH 13/34] GPS handling and timesync code refactored --- include/globals.h | 2 -- include/gpsread.h | 9 ++---- src/gpsread.cpp | 76 +++++++++++++++++++++++++++++++--------------- src/main.cpp | 4 +-- src/rcommand.cpp | 1 + src/senddata.cpp | 1 + src/timekeeper.cpp | 7 +---- src/timesync.cpp | 19 ++++++------ 8 files changed, 69 insertions(+), 50 deletions(-) diff --git a/include/globals.h b/include/globals.h index ea477a95..e8e8bb48 100644 --- a/include/globals.h +++ b/include/globals.h @@ -82,8 +82,6 @@ typedef struct { uint8_t satellites; uint16_t hdop; int16_t altitude; - uint32_t time_age; - tmElements_t timedate; } gpsStatus_t; typedef struct { diff --git a/include/gpsread.h b/include/gpsread.h index eca6645c..3a780530 100644 --- a/include/gpsread.h +++ b/include/gpsread.h @@ -10,18 +10,15 @@ #endif #define NMEA_FRAME_SIZE 82 // NEMA has a maxium of 82 bytes per record -#define NMEA_BUFFERTIME 50 // 50ms safety time regardless extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe -extern gpsStatus_t - gps_status; // Make struct for storing gps data globally available extern TaskHandle_t GpsTask; int gps_init(void); -void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store); +int gps_config(); void gps_storelocation(gpsStatus_t *gps_store); void gps_loop(void *pvParameters); -time_t fetch_gpsTime(gpsStatus_t value, uint16_t *msec); -int gps_config(); +time_t fetch_gpsTime(uint16_t *msec); +time_t fetch_gpsTime(void); #endif \ No newline at end of file diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 068127e6..eb97b4a4 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -5,7 +5,12 @@ // Local logging tag static const char TAG[] = __FILE__; +// we use NMEA $GPZDA sentence field 1 for time synchronization +// $GPZDA gives time for preceding pps pulse, but does not has a constant offset TinyGPSPlus gps; +TinyGPSCustom gpstime(gps, "GPZDA", 1); // field 1 = UTC time +static const String ZDA_Request = "$EIGPQ,ZDA*39\r\n"; + gpsStatus_t gps_status = {0}; TaskHandle_t GpsTask; @@ -27,7 +32,7 @@ int gps_init(void) { return 0; } -#if defined GPS_SERIAL +#ifdef GPS_SERIAL GPS_Serial.begin(GPS_SERIAL); ESP_LOGI(TAG, "Using serial GPS"); #elif defined GPS_I2C @@ -55,11 +60,11 @@ int gps_config() { int rslt = 1; // success #if defined GPS_SERIAL - /* to come */ + /* insert user configuration here, if needed */ #elif defined GPS_I2C - /* to come */ + /* insert user configuration here, if needed */ #endif return rslt; @@ -68,7 +73,7 @@ int gps_config() { // store current GPS location data in struct void gps_storelocation(gpsStatus_t *gps_store) { if (gps.location.isUpdated() && gps.location.isValid() && - (gps.time.age() < 1500)) { + (gps.location.age() < 1500)) { gps_store->latitude = (int32_t)(gps.location.lat() * 1e6); gps_store->longitude = (int32_t)(gps.location.lng() * 1e6); gps_store->satellites = (uint8_t)gps.satellites.value(); @@ -77,34 +82,55 @@ void gps_storelocation(gpsStatus_t *gps_store) { } } -// store current GPS timedate in struct -void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store) { +// function to fetch current time from struct; note: this is costly +time_t fetch_gpsTime(uint16_t *msec) { - if (gps.time.isUpdated() && gps.date.isValid() && (gps.time.age() < 1000)) { + time_t time_sec = 0; - gps_store->time_age = gps.time.age() + nmea_txDelay_ms; - gps_store->timedate.Second = gps.time.second(); - gps_store->timedate.Minute = gps.time.minute(); - gps_store->timedate.Hour = gps.time.hour(); - gps_store->timedate.Day = gps.date.day(); - gps_store->timedate.Month = gps.date.month(); - gps_store->timedate.Year = + // poll NMEA $GPZDA sentence +#ifdef GPS_SERIAL + GPS_Serial.print(ZDA_Request); +#elif defined GPS_I2C + Wire.print(ZDA_Request); +#endif + + // wait for gps NMEA answer + vTaskDelay(tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL)); + + // did we get a current time? + if (gpstime.isUpdated() && gpstime.isValid()) { + + tmElements_t tm; + + String rawtime = gpstime.value(); + uint32_t time_bcd = rawtime.toFloat() * 100; + uint32_t delay_ms = gpstime.age() + nmea_txDelay_ms; + uint8_t year = CalendarYrToTm(gps.date.year()); // year offset from 1970 in microTime.h - } else - gps_store->timedate = {0}; -} + ESP_LOGD(TAG, "time [bcd]: %u", time_bcd); -// function to fetch current time from struct; note: this is costly -time_t fetch_gpsTime(gpsStatus_t value, uint16_t *msec) { + tm.Second = (time_bcd / 100) % 100; // second + tm.Minute = (time_bcd / 10000) % 100; // minute + tm.Hour = time_bcd / 1000000; // hour + tm.Day = gps.date.day(); // day + tm.Month = gps.date.month(); // month + tm.Year = year; // year - *msec = 1000 - value.time_age; - time_t t = timeIsValid(makeTime(value.timedate)); - ESP_LOGD(TAG, "GPS time: %d | time age: %d", t, value.time_age); - return t; + // add protocol delay to time with millisecond precision + time_sec = makeTime(tm) + delay_ms / 1000; + *msec = (delay_ms % 1000) ? delay_ms % 1000 : 0; + } + + return timeIsValid(time_sec); } // fetch_gpsTime() +time_t fetch_gpsTime(void) { + uint16_t msec; + return fetch_gpsTime(&msec); +} + // GPS serial feed FreeRTos Task void gps_loop(void *pvParameters) { @@ -113,7 +139,7 @@ void gps_loop(void *pvParameters) { while (1) { if (cfg.payloadmask && GPS_DATA) { -#if defined GPS_SERIAL +#ifdef GPS_SERIAL // feed GPS decoder with serial NMEA data from GPS device while (GPS_Serial.available()) { gps.encode(GPS_Serial.read()); @@ -128,7 +154,7 @@ void gps_loop(void *pvParameters) { } // if // show NMEA data in verbose mode, useful for debugging GPS - ESP_LOGV(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d", + ESP_LOGV(TAG, "GPS NMEA data: passed %u / failed: %u / with fix: %u", gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix()); diff --git a/src/main.cpp b/src/main.cpp index d88722b5..72422bbc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -419,9 +419,9 @@ void setup() { #warning you did not specify a time source, time will not be synched #endif - // initialize gps time +// initialize gps time #if (HAS_GPS) - gps_storetime(&gps_status); + fetch_gpsTime(); #endif #if (defined HAS_IF482 || defined HAS_DCF77) diff --git a/src/rcommand.cpp b/src/rcommand.cpp index c2a1fb37..415283a9 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -253,6 +253,7 @@ void get_status(uint8_t val[]) { void get_gps(uint8_t val[]) { ESP_LOGI(TAG, "Remote command: get gps status"); #if (HAS_GPS) + gpsStatus_t gps_status; gps_storelocation(&gps_status); payload.reset(); payload.addGPS(gps_status); diff --git a/src/senddata.cpp b/src/senddata.cpp index 8b95f219..fd5df963 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -87,6 +87,7 @@ void sendCounter() { case GPS_DATA: // send GPS position only if we have a fix if (gps.location.isValid()) { + gpsStatus_t gps_status; gps_storelocation(&gps_status); payload.reset(); payload.addGPS(gps_status); diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index b6a2051b..4d01f7d9 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -30,7 +30,7 @@ void calibrateTime(void) { #if (HAS_GPS) // fetch recent time from last NMEA record - t = fetch_gpsTime(gps_status, &t_msec); + t = fetch_gpsTime(&t_msec); if (t) { timeSource = _gps; goto finish; @@ -124,11 +124,6 @@ void IRAM_ATTR CLOCKIRQ(void) { SyncToPPS(); // advance systime, see microTime.h - // store recent gps time -#if (HAS_GPS) - gps_storetime(&gps_status); -#endif - // advance wall clock, if we have #if (defined HAS_IF482 || defined HAS_DCF77) xTaskNotifyFromISR(ClockTask, uint32_t(now()), eSetBits, diff --git a/src/timesync.cpp b/src/timesync.cpp index 9499502d..6e168ae3 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -211,22 +211,22 @@ int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) { void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, timesource_t mytimesource) { - time_t time_to_set = (time_t)(t_sec); + time_t time_to_set = (time_t)(t_sec + t_msec / 1000); if (timeIsValid(time_to_set)) { - ESP_LOGD(TAG, "[%0.3f] UTC epoch time: %d.%03d sec", millis() / 1000.0, - time_to_set, t_msec); // wait until top of second with millisecond precision - if (t_msec) { - vTaskDelay(pdMS_TO_TICKS(1000 - t_msec)); + if (t_msec % 1000) { time_to_set++; + vTaskDelay(pdMS_TO_TICKS(1000 - t_msec % 1000)); } -// if we got a timesource, set RTC time and calibrate RTC_INT pulse on top of -// second + ESP_LOGD(TAG, "[%0.3f] UTC epoch time: %d.%03d sec", millis() / 1000.0, + time_to_set, t_msec % 1000); + +// if we got a timesource, set RTC time and RTC_INT pulse on top of second #ifdef HAS_RTC - if (mytimesource != _rtc) + if ((mytimesource == _gps) || (mytimesource == _lora)) set_rtctime(time_to_set); #endif @@ -234,6 +234,7 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, #if (!defined GPS_INT && !defined RTC_INT) timerWrite(ppsIRQ, 0); // reset pps timer CLOCKIRQ(); // fire clock pps, this advances time 1 sec + time_to_set--; #endif setTime(time_to_set); // set the time on top of second @@ -249,8 +250,8 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, } } +// create task for timeserver handshake processing, called from main.cpp void timesync_init() { - // create task for timeserver handshake processing, called from main.cpp xTaskCreatePinnedToCore(process_timesync_req, // task function "timesync_req", // name of task 2048, // stack size of task From c81502ac60a4c50f24774d6b1aee20b962843f99 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 4 Aug 2019 15:39:25 +0200 Subject: [PATCH 14/34] main.cpp: disable gps time init to avoid i2c error --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 72422bbc..c6dae99e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -419,10 +419,12 @@ void setup() { #warning you did not specify a time source, time will not be synched #endif +/* // initialize gps time #if (HAS_GPS) fetch_gpsTime(); #endif +*/ #if (defined HAS_IF482 || defined HAS_DCF77) ESP_LOGI(TAG, "Starting Clock Controller..."); From be208ab539c075160f4885588a97c066e026825f Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 4 Aug 2019 23:18:04 +0200 Subject: [PATCH 15/34] GPS timing fine tuning --- include/gpsread.h | 1 + src/gpsread.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/gpsread.h b/include/gpsread.h index 3a780530..d8728b7d 100644 --- a/include/gpsread.h +++ b/include/gpsread.h @@ -10,6 +10,7 @@ #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/src/gpsread.cpp b/src/gpsread.cpp index eb97b4a4..262daf0a 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -95,7 +95,7 @@ time_t fetch_gpsTime(uint16_t *msec) { #endif // wait for gps NMEA answer - vTaskDelay(tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL)); + //vTaskDelay(tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL)); // did we get a current time? if (gpstime.isUpdated() && gpstime.isValid()) { @@ -104,7 +104,7 @@ time_t fetch_gpsTime(uint16_t *msec) { String rawtime = gpstime.value(); uint32_t time_bcd = rawtime.toFloat() * 100; - uint32_t delay_ms = gpstime.age() + nmea_txDelay_ms; + uint32_t delay_ms = gpstime.age() + nmea_txDelay_ms + NMEA_COMPENSATION_FACTOR; uint8_t year = CalendarYrToTm(gps.date.year()); // year offset from 1970 in microTime.h From 64222bf8b35c30f4d3ed7266d7e8e211724b3bb3 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Mon, 5 Aug 2019 11:20:23 +0200 Subject: [PATCH 16/34] timesync.cpp: fix +1 second bug --- src/timesync.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/timesync.cpp b/src/timesync.cpp index 6e168ae3..1d3034c3 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -234,7 +234,6 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, #if (!defined GPS_INT && !defined RTC_INT) timerWrite(ppsIRQ, 0); // reset pps timer CLOCKIRQ(); // fire clock pps, this advances time 1 sec - time_to_set--; #endif setTime(time_to_set); // set the time on top of second From b2ef9249da3efd08ff2e51e873a32edc7c296f26 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Tue, 6 Aug 2019 11:37:58 +0200 Subject: [PATCH 17/34] timesync.cpp: comments updated --- src/timesync.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/timesync.cpp b/src/timesync.cpp index 1d3034c3..ef50041d 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -211,11 +211,14 @@ int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) { void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, timesource_t mytimesource) { + // increment t_sec only if t_msec > 1000 time_t time_to_set = (time_t)(t_sec + t_msec / 1000); + // do we have a valid time? if (timeIsValid(time_to_set)) { - // wait until top of second with millisecond precision + // if we have msec fraction, then wait until top of second with + // millisecond precision if (t_msec % 1000) { time_to_set++; vTaskDelay(pdMS_TO_TICKS(1000 - t_msec % 1000)); @@ -224,13 +227,14 @@ void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, ESP_LOGD(TAG, "[%0.3f] UTC epoch time: %d.%03d sec", millis() / 1000.0, time_to_set, t_msec % 1000); -// if we got a timesource, set RTC time and RTC_INT pulse on top of second +// if we have got an external 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 -// sync pps timer to top of second +// if we have a software pps timer, shift it to top of second #if (!defined GPS_INT && !defined RTC_INT) timerWrite(ppsIRQ, 0); // reset pps timer CLOCKIRQ(); // fire clock pps, this advances time 1 sec From 3518c2660ff3b22b690378476c71606a9bc8024f Mon Sep 17 00:00:00 2001 From: Oliver Brandmueller Date: Wed, 7 Aug 2019 20:10:37 +0200 Subject: [PATCH 18/34] Update vendor_array.h with new vendor codes --- include/vendor_array.h | 476 +++++++++++++++++++++-------------------- 1 file changed, 243 insertions(+), 233 deletions(-) diff --git a/include/vendor_array.h b/include/vendor_array.h index b1330931..76ee4618 100644 --- a/include/vendor_array.h +++ b/include/vendor_array.h @@ -1,233 +1,243 @@ -std::array vendors = { - 0x38f23e, 0x807abf, 0x90e7c4, 0x7c6193, 0x485073, 0x74e28c, 0x8463d6, - 0xd48f33, 0x2c8a72, 0x980d2e, 0xa826d9, 0xd4206d, 0x00155d, 0x806c1b, - 0xa470d6, 0x985fd3, 0x1c69a5, 0x382de8, 0xd087e2, 0x205531, 0x5440ad, - 0x842e27, 0x50f0d3, 0x84119e, 0x08eca9, 0x10d38a, 0x382dd1, 0xe0cbee, - 0x64b853, 0xf4428f, 0x188331, 0x8455a5, 0xa87c01, 0xc01173, 0xbce63f, - 0xb857d8, 0x94b10a, 0xe458b8, 0x088c2c, 0xb86ce8, 0x9c65b0, 0xc8a823, - 0xc44202, 0xd059e4, 0x64b310, 0x9476b7, 0x8c1abf, 0xb47443, 0x30cbf8, - 0x182195, 0xa88195, 0x88add2, 0xd0fccc, 0x14c913, 0x4c6641, 0x3cbdd8, - 0x38256b, 0x849866, 0xe89309, 0x0016db, 0x5c3c27, 0x10d542, 0xa0821f, - 0xc45006, 0x88329b, 0xbc8ccd, 0x400e85, 0xec9bf3, 0xf8042e, 0x843838, - 0x54880e, 0xbc79ad, 0x30d6c9, 0xb0df3a, 0x805719, 0x78a873, 0x041bba, - 0x08fd0e, 0x08d42b, 0x00e3b2, 0xc81479, 0xf0728c, 0x94350a, 0x001fcd, - 0xd0dfc7, 0x1c62b8, 0x18e2c2, 0x001a8a, 0x002567, 0xa8f274, 0x001599, - 0x0012fb, 0x7cf854, 0x8cc8cd, 0xe81132, 0xa02195, 0x8c71f8, 0x04180f, - 0x9463d1, 0x0cdfa4, 0xcc051b, 0x68ebae, 0x60d0a9, 0x60a10a, 0xa07591, - 0x001fcc, 0xec107b, 0xa01081, 0xf4f524, 0xbc8385, 0x900628, 0xd4ae05, - 0x3c0518, 0xe8bba8, 0xbc3aea, 0x8c0ee3, 0x6c5c14, 0x78abbb, 0x1816c9, - 0xfc8f90, 0x244b03, 0x988389, 0x14bb6e, 0x1c3ade, 0xf83f51, 0xd8e0e1, - 0xecf342, 0x5092b9, 0xb4bff6, 0xc8d7b0, 0x982d68, 0xd80831, 0xdc5583, - 0x2c54cf, 0x001fe3, 0x0026e2, 0x001e75, 0x6cd68a, 0x2021a5, 0x0c4885, - 0xdc0b34, 0xac0d1b, 0x60e3ac, 0xf895c7, 0xc4438f, 0xa816b2, 0xe892a4, - 0x700514, 0x88c9d0, 0x2c598a, 0xec8350, 0x4cdd31, 0x705aac, 0xfc643a, - 0xd4e6b7, 0x2802d8, 0x48605f, 0xf0766f, 0x40cbc0, 0x4098ad, 0x6c4d73, - 0xc48466, 0xb8634d, 0x503237, 0xd4619d, 0xb0481a, 0x989e63, 0xdca904, - 0x48a195, 0x6cab31, 0x7c5049, 0xe42b34, 0x1c36bb, 0x3c2eff, 0x6c96cf, - 0x3035ad, 0xa8be27, 0x70a2b3, 0x4c57ca, 0x68fb7e, 0x90c1c6, 0xa4f1e8, - 0xac61ea, 0x38b54d, 0x00cdfe, 0x18af61, 0xcc4463, 0x34159e, 0x58b035, - 0xf0b479, 0x109add, 0x40a6d9, 0x7cf05f, 0xa4b197, 0x0c74c2, 0x403004, - 0x4860bc, 0xd02b20, 0x9ce33f, 0xf0989d, 0xace4b5, 0x6c72e7, 0x60fec5, - 0x00a040, 0x000d93, 0xacbc32, 0x30d9d9, 0x6030d4, 0x94bf2d, 0xc49880, - 0xe0338e, 0x68fef7, 0xbce143, 0x645aed, 0xc0b658, 0x881908, 0xfc2a9c, - 0x44d884, 0xec852f, 0x286aba, 0x705681, 0x7cd1c3, 0xf0dce2, 0xb065bd, - 0xa82066, 0xbc6778, 0x68967b, 0x848506, 0x54ae27, 0x6476ba, 0x84b153, - 0x783a84, 0x2cbe08, 0x24e314, 0x68d93c, 0x2cf0ee, 0x84788b, 0x6c94f8, - 0x703eac, 0xb4f0ab, 0x10ddb1, 0x04f7e4, 0x34c059, 0xf0d1a9, 0xbc3baf, - 0x786c1c, 0x041552, 0x38484c, 0x701124, 0xc86f1d, 0x685b35, 0x380f4a, - 0x3010e4, 0x04db56, 0x881fa1, 0x04e536, 0xf82793, 0xacfdec, 0xd0e140, - 0x8c7c92, 0x7831c1, 0xf437b7, 0x50ead6, 0x28e02c, 0x60c547, 0x7c11be, - 0x003ee1, 0xc01ada, 0x34363b, 0xc81ee7, 0x9cfc01, 0xccc760, 0x087402, - 0x285aeb, 0x28f076, 0x70700d, 0x9cf48e, 0xfcd848, 0x001cb3, 0x64b9e8, - 0xf8e94e, 0xf40616, 0xbcb863, 0x885a06, 0xc08c71, 0x108ee0, 0x68e7c2, - 0x3c576c, 0x0ce0dc, 0x702ad5, 0x889f6f, 0x1c427d, 0x5029f5, 0x4c569d, - 0x14c213, 0x38539c, 0x58e6ba, 0xb831b5, 0x90633b, 0x782327, 0xf8a45f, - 0x8cbebe, 0x640980, 0x98fae3, 0x185936, 0x9c99a0, 0xc40bcb, 0xecd09f, - 0xf4f5db, 0xe446da, 0x18f0e4, 0x9c2ea1, 0x50a009, 0x20a60c, 0x20326c, - 0xa8346a, 0xb06fe0, 0x98460a, 0xac88fd, 0x149d99, 0x846fce, 0xe0dcff, - 0x60ab67, 0x188796, 0x002376, 0x84100d, 0x04c23e, 0x5c5188, 0xe89120, - 0x9c6c15, 0x4886e8, 0x2c2997, 0x102f6b, 0x00eebd, 0x281878, 0x6045bd, - 0x7ced8d, 0xe85b5b, 0x000d3a, 0xe09861, 0xf4f1e1, 0x60beb5, 0xb4e1c4, - 0x70aab2, 0x0026ff, 0x406f2a, 0x002557, 0xf05a09, 0x503275, 0x28cc01, - 0xb46293, 0x04fe31, 0x845181, 0xd831cf, 0xf8d0bd, 0xfcc734, 0xe4b021, - 0xb0ec71, 0x3cbbfd, 0x2cae2b, 0xc488e5, 0x7c9122, 0xe8b4c8, 0x18895b, - 0xe0db10, 0xe09971, 0x6077e2, 0x680571, 0x6c2f2c, 0x300d43, 0x6c2779, - 0x607edd, 0x9c2a83, 0xe45d75, 0xe4faed, 0xc83f26, 0x54f201, 0xa06090, - 0xac3743, 0x141f78, 0x006f64, 0xdc6672, 0x001e7d, 0x3c6200, 0x0024e9, - 0x002399, 0xe4e0c5, 0xe8039a, 0xc4731e, 0x8c7712, 0x2013e0, 0x0007ab, - 0x0021d2, 0xbc4760, 0xd0176a, 0x2cbaba, 0x24920e, 0x40d3ae, 0xf01dbc, - 0x24dbed, 0xac3613, 0x1449e0, 0xc0bdd1, 0xe8508b, 0xf025b7, 0xc8ba94, - 0xec1f72, 0x9852b1, 0x1489fd, 0xccfe3c, 0x789ed0, 0xe440e2, 0x1caf05, - 0xe492fb, 0x0073e0, 0xbc4486, 0x380b40, 0x002490, 0x0023d7, 0xfca13e, - 0xa00798, 0x945103, 0xc819f7, 0x2c4401, 0xec51bc, 0xf079e8, 0x887598, - 0xd0b128, 0xd00401, 0xf06d78, 0x10683f, 0x74a722, 0x58a2b5, 0x64899a, - 0x88074b, 0x64bc0c, 0xa039f7, 0x041b6d, 0x001f6b, 0x30b4b8, 0x503cea, - 0x54fcf0, 0x08aed6, 0xa816d0, 0x88bd45, 0x641cb0, 0x3cdcbc, 0xf47190, - 0x587a6a, 0xe4c483, 0xfcaab6, 0xc0bdc8, 0xa887b3, 0x742344, 0xd832e3, - 0xe06267, 0x482ca0, 0x1801f1, 0x70bbe9, 0xf0b429, 0x0c9838, 0x0c1daf, - 0x28e31f, 0x14f65a, 0xd4c94b, 0x703a51, 0xdc080f, 0xf82d7c, 0x9c648b, - 0x14d00d, 0xd467d3, 0x58c6f0, 0xc02e25, 0x804a14, 0xb85d0a, 0x941625, - 0x34a8eb, 0x4883b4, 0xa8db03, 0x2479f3, 0x98b8ba, 0xd49dc0, 0x8cf5a3, - 0x14568e, 0x8058f8, 0xf0d7aa, 0xc49ded, 0xb0aa36, 0x2c5bb8, 0x1c48ce, - 0x24f5aa, 0xf877b8, 0x682737, 0x5056bf, 0x9097f3, 0x58c5cb, 0xacafb9, - 0x30074d, 0x5c5181, 0x389af6, 0xe0aa96, 0x507705, 0x2c4053, 0x084acf, - 0x1cddea, 0x08152f, 0xb8c111, 0x3408bc, 0x844167, 0xb4f61c, 0x68ab1e, - 0x2c61f6, 0xe49adc, 0xd0817a, 0xc4618b, 0x3451c9, 0xe0b9ba, 0xd023db, - 0xb88d12, 0xb817c2, 0x68a86d, 0x78a3e4, 0x680927, 0x60facd, 0x1caba7, - 0x784f43, 0x404d7f, 0x7c04d0, 0xbc9fef, 0x8866a5, 0x88e87f, 0xb853ac, - 0x2c3361, 0xa860b6, 0x24f094, 0x90b0ed, 0xc4b301, 0xe05f45, 0x483b38, - 0xe0c767, 0x1c9e46, 0x0cd746, 0x440010, 0xe498d6, 0x606944, 0x0452f3, - 0x241eeb, 0xf431c3, 0x64a5c3, 0xbc926b, 0x0050e4, 0x003065, 0x000a27, - 0x001451, 0x8c7b9d, 0x88c663, 0xc82a14, 0x9803d8, 0x8c5877, 0x0019e3, - 0x002312, 0x002332, 0x002436, 0x00254b, 0x0026bb, 0x70f087, 0x886b6e, - 0x4c74bf, 0xe80688, 0xcc08e0, 0x5855ca, 0x5c0947, 0x38892c, 0x40831d, - 0x50bc96, 0x985aeb, 0x2078f0, 0x78d75f, 0xe0accb, 0x98e0d9, 0xc0cecd, - 0x70e72c, 0xd03311, 0x5cadcf, 0x006d52, 0x48437c, 0x34a395, 0x9cf387, - 0xa85b78, 0x908d6c, 0x0c1539, 0xbc4cc4, 0x0cbc9f, 0xa45e60, 0x544e90, - 0x9ce65e, 0x90dd5d, 0x08f69c, 0xd461da, 0xc8d083, 0x88e9fe, 0x88ae07, - 0x18af8f, 0xc8b5b7, 0xa8bbcf, 0x90b21f, 0xb8e856, 0x1499e2, 0xb418d1, - 0x80006e, 0x60d9c7, 0xc8f650, 0x1c1ac0, 0xe06678, 0x5c8d4e, 0xc0f2fb, - 0x00f76f, 0xac87a3, 0x542696, 0xd8d1cb, 0x64a3cb, 0x44fb42, 0xf41ba1, - 0x3ce072, 0xe88d28, 0xcc785f, 0xac3c0b, 0x88cb87, 0xec3586, 0xf0c1f1, - 0xf4f951, 0x8cfaba, 0x5c95ae, 0xe0c97a, 0xbc52b7, 0x14109f, 0x00c3f4, - 0x74eb80, 0xa82bb9, 0x7c6b9c, 0x1cc3eb, 0xbca58b, 0x70fd46, 0xd07fa0, - 0x9caa1b, 0x18d717, 0xb4cb57, 0x74b587, 0xd81c79, 0x8cfe57, 0xc0a600, - 0xa823fe, 0x00092d, 0xf8db7f, 0xe899c4, 0x24da9b, 0x1c56fe, 0xe4907e, - 0x80c5e6, 0x800184, 0xf8cfc5, 0xc808e9, 0x206274, 0x30d587, 0xc0eefb, - 0x502e5c, 0x847a88, 0x0025ae, 0x002538, 0x0022a1, 0x00125a, 0x9cd917, - 0x9068c3, 0x408805, 0xf8f1b6, 0x001ccc, 0x94ebcd, 0xa4e4b8, 0x389496, - 0x0cb319, 0x08ee8b, 0xa89fba, 0xfc1910, 0x083d88, 0x5c2e59, 0x646cb2, - 0xf884f2, 0x14b484, 0x608f5c, 0x4cbca5, 0x78595e, 0xb0d09c, 0x4ca56d, - 0xa48431, 0xe4f8ef, 0x1432d1, 0xe458e7, 0x8cbfa6, 0x7840e4, 0x9000db, - 0x183a2d, 0x08373d, 0x50f520, 0xa4ebd3, 0x28987b, 0xf40e22, 0x9c3aaf, - 0x0821ef, 0xa0cbfd, 0x34145f, 0x6c8fb5, 0xac5f3e, 0x509ea7, 0xdccf96, - 0x6c2483, 0xc09727, 0xd85b2a, 0xacc33a, 0x88797e, 0x00e091, 0x6cd032, - 0xc041f6, 0x0017d5, 0x001247, 0xe4121d, 0x684898, 0xf409d8, 0xb479a7, - 0x002339, 0xd487d8, 0x184617, 0x5001bb, 0x380a94, 0xd857ef, 0x1c66aa, - 0x58c38b, 0x001ee2, 0x001c43, 0x001d25, 0x3c5a37, 0x549b12, 0x3c8bfe, - 0x00265d, 0xd4e8b2, 0x0808c2, 0xb0c4e7, 0xd890e8, 0x34aa8b, 0x24c696, - 0x181eb0, 0x20d390, 0x343111, 0x34be00, 0x78521a, 0x7825ad, 0xf4d9fb, - 0x0017c9, 0x00166b, 0x00166c, 0xe47cf9, 0x002454, 0x20d5bf, 0x30cda7, - 0xc87e75, 0x00233a, 0x60a4d0, 0x2c0e3d, 0x7c787e, 0xc0d3c0, 0x440444, - 0xc09f05, 0xcc2d83, 0x38295a, 0x4c1a3d, 0xa81b5a, 0xdc6dcd, 0x54fa3e, - 0x0c8910, 0xfcf136, 0x981dfa, 0x84a466, 0x1867b0, 0xccb11a, 0xb8bbaf, - 0x60c5ad, 0x28395e, 0xc4ae12, 0xdc74a8, 0xc087eb, 0x74f61c, 0x986f60, - 0x4c189a, 0x3cf591, 0x602101, 0xa89675, 0x608e08, 0x7c2edd, 0x3cf7a4, - 0x342d0d, 0x94d029, 0x308454, 0x087808, 0xd03169, 0xbc5451, 0x641cae, - 0xa4e975, 0xc0a53e, 0x9800c6, 0x787b8a, 0x3866f0, 0x20ee28, 0x08f4ab, - 0x8c8590, 0x68ef43, 0xcc2db7, 0xd4a33d, 0xe4e0a6, 0x70ef00, 0xb0ca68, - 0x9810e8, 0xb49cdf, 0xdca4ca, 0x8c8fe9, 0x98ca33, 0xfc253f, 0x183451, - 0xc0847a, 0x64200c, 0x74e1b6, 0x0c771a, 0x00f4b9, 0xc8334b, 0xb8f6b1, - 0xc09f42, 0x189efc, 0x6c3e6d, 0x8c2daa, 0xe4e4ab, 0x58404e, 0xdc0c5c, - 0x2c200b, 0x609ac1, 0xf07960, 0x9c8ba0, 0x28a02b, 0xb44bd2, 0x9c4fda, - 0x1c5cf2, 0x3871de, 0xbc5436, 0x5cf938, 0x4c3275, 0x2cf0a2, 0xecadb8, - 0x9801a7, 0xb48b19, 0xe49a79, 0x406c8f, 0x00c610, 0x70dee2, 0x182032, - 0x6cc26b, 0x1040f3, 0x001d4f, 0x001e52, 0x001f5b, 0x001ff3, 0x0021e9, - 0x00236c, 0x002500, 0x60fb42, 0xf81edf, 0x90840d, 0xd8a25e, 0xc8bcc8, - 0x28e7cf, 0xd89e3f, 0x040cce, 0xa4d1d2, 0x7cfadf, 0x101c0c, 0x001124, - 0x6c709f, 0x0c3e9f, 0x34e2fd, 0x609217, 0x8863df, 0x80e650, 0x006171, - 0x90fd61, 0x5c97f3, 0x6c4008, 0x24a074, 0xf02475, 0x20a2e4, 0x5cf5da, - 0x649abe, 0x94e96a, 0xac293a, 0x10417f, 0xb844d9, 0xdc2b2a, 0x14205e, - 0x5c1dd9, 0x18f1d8, 0xf86fc1, 0xf099b6, 0x907240, 0x0c4de9, 0xd89695, - 0x0c3021, 0xf0f61c, 0xb03495, 0x848e0c, 0x949426, 0xe0f5c6, 0x28e14c, - 0x54e43a, 0xc8e0eb, 0xa88808, 0x444c0c, 0x84fcfe, 0xe48b7f, 0x5c969d, - 0xa8fad8, 0x7014a6, 0xa8667f, 0xd02598, 0xcc29f5, 0xdcd3a2, 0x08c5e1, - 0x00bf61, 0xf80cf3, 0x30766f, 0x8c3ae3, 0x78f882, 0xb4f1da, 0x0021fb, - 0xd013fd, 0xa8b86e, 0xdcbfe9, 0x306a85, 0x4466fc, 0xfca621, 0x0ccb85, - 0xa4d990, 0xd003df, 0x24fce5, 0xe4b2fb, 0xf83880, 0x241b7a, 0x402619, - 0xbcfed9, 0x808223, 0x3830f9, 0x6c006b, 0x38a4ed, 0xb0e235, 0x64cc2e, - 0xd86375, 0x80ad16, 0x2047da, 0x8035c1, 0x9487e0, 0x7c03ab, 0xd4970b, - 0xf48b32, 0x4c49e3, 0x04b167, 0xd8ce3a, 0xb8c74a, 0xfc183c, 0xc0e862, - 0xec2ce2, 0x64c753, 0x48fda3, 0x7c035e, 0x70bc10, 0x2c5d34, 0x64c2de, - 0x58d9c3, 0x489dd1, 0xd81edd, 0x2034fb, 0xf4afe7, 0x7c9a1d, 0xa483e7, - 0xc4e39f, 0x7cd661, 0x70dda8, 0xbc98df, 0x38e7d8, 0xd8b377, 0xb4cef6, - 0xd40b1a, 0x5882a8, 0xb4ae2b, 0x0c413e, 0xd0929e, 0x4480eb, 0xb84fd5, - 0xec59e7, 0x3059b7, 0x501ac5, 0x1cb094, 0xa0f450, 0x002248, 0xec8892, - 0xb07994, 0x141aa3, 0xccc3ea, 0x34bb26, 0x40786a, 0xf40b93, 0x68ed43, - 0x34bb1f, 0x489d24, 0x000f86, 0xacee9e, 0xc08997, 0x2827bf, 0xf05b7b, - 0x7cf90e, 0xac5a14, 0xb0c559, 0xbcd11f, 0xa0b4a5, 0x80656d, 0x48137e, - 0xe83a12, 0x9c0298, 0x6c8336, 0xb8c68e, 0x74458a, 0xa49a58, 0xb4ef39, - 0x14a364, 0x3ca10d, 0x206e9c, 0x183f47, 0x0c715d, 0x0c1420, 0xa80600, - 0x6cf373, 0x78c3e9, 0xc83870, 0x288335, 0x44783e, 0x202d07, 0x98398e, - 0x348a7b, 0xbc765e, 0x78009e, 0x68c44d, 0xf8e61a, 0x888322, 0x84b541, - 0x0015b9, 0x001df6, 0xece09b, 0x606bbd, 0x0000f0, 0x4844f7, 0x1c5a3e, - 0xf47b5e, 0x008701, 0xfc4203, 0x1c232c, 0xcc61e5, 0x404e36, 0x9893cc, - 0x3ccd93, 0xf06bca, 0x3423ba, 0xd022be, 0xd02544, 0xbc20a4, 0x14f42a, - 0xbc851f, 0xb85e7b, 0xc462ea, 0x0023d6, 0x002491, 0x001b98, 0x44f459, - 0x34c3ac, 0x94d771, 0x4c3c16, 0x9401c2, 0xb43a28, 0xd0c1b1, 0xf008f1, - 0x78471d, 0x3816d1, 0xd48890, 0x002566, 0x00265f, 0x5cba37, 0x3096fb, - 0xf0ee10, 0xa43d78, 0xec01ee, 0xb83765, 0xc4576e, 0x90f1aa, 0x78bdbc, - 0xd47ae2, 0x84c0ef, 0x7c1c68, 0xd463c6, 0x7c6456, 0x448f17, 0x04d6aa, - 0x9ce063, 0xf06e0b, 0x5c865c, 0x003de8, 0x08e689, 0x7836cc, 0x08d46a, - 0x485929, 0x34fcef, 0x002483, 0x001c62, 0x583f54, 0x40b0fa, 0xa8922c, - 0x98d6f7, 0x505527, 0x0034da, 0xa09169, 0x88365f, 0x9c8c6e, 0xbcffeb, - 0x685acf, 0xb4f7a1, 0x785dc8, 0x48c796, 0x804e70, 0x3880df, 0xdc415f, - 0x30636b, 0xf45c89, 0x68dbca, 0x044bed, 0x6c8dc1, 0x38cada, 0xa4d18c, - 0x186590, 0x64b0a6, 0x84fcac, 0x6c19c0, 0x20ab37, 0x203cae, 0x748d08, - 0xa03be3, 0x7c6d62, 0x40d32d, 0xd83062, 0xc42c03, 0x7cc537, 0x70cd60, - 0xc0d012, 0xd4dccd, 0x484baa, 0xf80377, 0x14bd61, 0xcc25ef, 0xb8782e, - 0x000502, 0x0010fa, 0x000393, 0x0016cb, 0x409c28, 0x78886d, 0xa85c2c, - 0x00db70, 0x0c5101, 0x086d41, 0x04d3cf, 0xbcec5d, 0x80b03d, 0xc83c85, - 0xa04ea7, 0x0017f2, 0x001b63, 0x001ec2, 0x002608, 0xa4c361, 0xac7f3e, - 0x280b5c, 0x90b931, 0x24a2e1, 0x80ea96, 0x600308, 0x04f13e, 0x54724f, - 0x48746e, 0xd4f46f, 0x787e61, 0x60f81d, 0x4c7c5f, 0x48e9f1, 0xfce998, - 0xf099bf, 0x68644b, 0x789f70, 0x24ab81, 0x581faa, 0xa46706, 0x3c0754, - 0xe4ce8f, 0xe8040b, 0xb8c75d, 0x403cfc, 0x98fe94, 0xd8004d, 0x98b8e3, - 0x80929f, 0x885395, 0x9c04eb, 0xa8968a, 0xdc3714, 0x40331a, 0x94f6a3, - 0xd81d72, 0x70ece4, 0x38c986, 0xfcfc48, 0x4c8d79, 0x207d74, 0xf4f15a, - 0x042665, 0x2cb43a, 0x689c70, 0x087045, 0x3cab8e, 0x7c6df8, 0x48d705, - 0x78fd94, 0xc88550, 0x286ab8, 0x7cc3a1, 0x3cd0f8, 0x98d6bb, 0x4cb199, - 0x64e682, 0x804971, 0xcc20e8, 0x209bcd, 0xf0b0e7, 0xa056f3, 0x549963, - 0x28ff3c, 0x1094bb, 0xf01898, 0x48a91c, 0x58b10f, 0x304b07, 0x1496e5, - 0x80ceb9, 0xcc2119, 0x0057c1, 0x14c697, 0xfc039f, 0x9c0cdf, 0x007204, - 0x90e17b, 0x18810e, 0x608c4a, 0xa4d931, 0x6cc7ec, 0x647bce, 0x584498, - 0xacc1ee, 0x7802f8, 0x508f4c, 0x04d13a, 0x0cf346, 0x082525, 0xf460e2, - 0xa45046, 0x009ec8, 0x7c1dd9, 0xa086c6, 0x102ab3, 0xacf7f3, 0x601d91, - 0x38f9d3, 0x44e66e, 0xe83617, 0x344262, 0xc09ad0, 0xa41232, 0xb8bc5b, - 0xacf6f7, 0x7c38ad, 0x3c20f6, 0x703c69, 0xb8b2f8, 0x005b94, 0x88b291, - 0x5462e2, 0x4418fd, 0xccd281, 0xd09c7a, 0x4c6f9c, 0x201742, 0x902155, - 0x64a769, 0xbccfcc, 0xa4516f, 0x3c8375, 0x149a10, 0x0ce725, 0xc0335e, - 0x20a99b, 0x4c0bbe, 0x7c1e52, 0xdcb4c4, 0x7c6f06, 0x001dd8, 0x0017fa, - 0x000a75, 0x0003ff, 0xf8e079, 0x1430c6, 0xe0757d, 0x9cd35b, 0x60af6d, - 0xb85a73, 0x103047, 0x109266, 0xb047bf, 0x7c0bc6, 0x804e81, 0x244b81, - 0x50a4c8, 0x8425db, 0xd8c4e9, 0x50c8e5, 0x446d6c, 0x38d40b, 0x647791, - 0x781fdb, 0x08fc88, 0x30c7ae, 0x18227e, 0x00f46f, 0x9ce6e7, 0xe498d1, - 0x5cca1a, 0x70288b, 0x4849c7, 0x205ef7, 0x182666, 0xc06599, 0xcc07ab, - 0xe84e84, 0x50fc9f, 0xe432cb, 0x889b39, 0xbcb1f3, 0x38ece4, 0xccf9e8, - 0xf0e77e, 0x5ce8eb, 0xb8d9ce, 0x70f927, 0x301966, 0x28bab5, 0x103b59, - 0x6cb7f4, 0x001ee1, 0x0018af, 0xbc72b1, 0x78f7be, 0xf49f54, 0x00214c, - 0x001632, 0xd0667b, 0x001377, 0x50b7c3, 0x8018a7, 0x444e1a, 0xe8e5d6, - 0x5492be, 0x101dc0, 0x0021d1, 0xcc2d8c, 0x949aa9, 0x20dbab, 0x5c9960, - 0x88b4a6, 0x2c5491, 0x5c70a3, 0x10f96f, 0xf01c13, 0x00aa70, 0xbcf5ac, - 0xccfa00, 0xf8a9d0, 0x805a04, 0x5caf06, 0xb81daa, 0x10f1f2, 0x0025e5, - 0x0022a9, 0xc49a02, 0x344df7, 0xd41a3f, 0xcc6ea4, 0xa46cf1, 0x0ca8a7, - 0x54b802, 0x24181d, 0xf4c248, 0xa8515b, 0xc048e6, 0xd07714, 0x2816a8, - 0x84a134, 0x1c9148, 0xc0ccf8, 0x80ed2c, 0xe8b2ac, 0x8489ad, 0x20768f, - 0x28ed6a, 0x34ab37, 0x60a37d, 0x0056cd, 0xbca920, 0x5082d5, 0x9c84bf, - 0x00b362, 0xf86214, 0xb0702d, 0xd0c5f3, 0x0023df, 0x0025bc, 0x00264a, - 0x0026b0, 0x041e64, 0xd49a20, 0x9027e4, 0x60334b, 0x5c5948, 0x60f445, - 0x5cf7e6, 0xa0d795, 0xcc088d, 0x8c8ef2, 0xf40f24, 0x24f677, 0x7867d7, - 0x5433cb, 0xd0d2b0, 0xd88f76, 0x3c2ef9, 0x7081eb, 0x086698, 0x9060f1, - 0x741bb2, 0x28cfe9, 0xe425e7, 0xb019c6, 0x58e28f, 0xac1f74, 0x48bf6b, - 0x245ba7, 0xdc56e7, 0x347c25, 0xd4909c, 0x080007, 0x000a95, 0x002241, - 0x18ee69, 0x748114, 0x18f643, 0xd0a637, 0xa01828, 0xd0034b, 0xa43135, - 0x9c35eb, 0x507a55, 0xa0999b, 0x24240e, 0x903c92, 0xa88e24, 0xe8802e, - 0x68ae20, 0xe0b52d, 0x80be05, 0xd8bb2c, 0xd04f7e, 0x2c1f23, 0x549f13, - 0xb8098a, 0xf0dbe2, 0x8c2937, 0xdc9b9c, 0x98f0ab, 0xf0dbf8, 0xaccf5c, - 0x3c15c2, 0x04489a, 0xd8cf9c, 0xa886dd, 0x54eaa8, 0xe4c63d, 0x843835, - 0xc06394, 0x8c006d, 0xb09fba, 0xdc86d8, 0x78ca39, 0x18e7f4, 0xb8ff61, - 0xdc2b61, 0x1093e9, 0x442a60, 0xe0f847, 0x145a05, 0x28cfda, 0x148fc6, - 0x283737, 0x045453, 0xf0cba1, 0x30f7c5, 0x008865, 0x40b395, 0x3090ab, - 0x1ce62b, 0xa0edcd, 0x842999, 0x74e2f5, 0x20c9d0, 0x7073cb, 0x9c207b, - 0x341298, 0x9c293f, 0x7c0191, 0x70480f, 0xa4b805, 0x587f57, 0x80d605, - 0xc869cd, 0xbc6c21, 0x0469f8, 0x749eaf, 0xb841a4, 0xf895ea, 0x50a67f, - 0x647033, 0x846878, 0x948bc1, 0x4827ea, 0x388c50, 0xa09347, 0xc8f230, - 0x1c77f6, 0xe44790, 0xd4503f, 0x40163b, 0x5c497d, 0xe47dbd, 0x503da1, - 0x508569, 0x1077b1, 0x5cf6dc, 0x380195, 0xbc1485, 0x88d50c, 0x947be7, - 0x54bd79, 0xdc44b6, 0x1007b6, 0xc0174d, 0xa407b6, 0x149f3c, 0xd868c3, - 0xc493d9, 0x00b5d0, 0x8c83e1, 0xfcb6d8, 0x6ce85c, 0x007c2d, 0xf47def, - 0x7c8bb5, 0xdcf756, 0x68dfdd, 0x64b473, 0x7451ba, 0x3480b3, 0x2082c0, - 0xfc64ba, 0xc46ab7, 0x00ec0a, 0x38e60a, 0x04e598, 0x2ca9f0, 0x586b14, - 0x94b01f, 0x94f6d6, 0x40bc60, 0xd85575, 0xd411a3, 0x6489f1, 0x04ba8d, - 0x489507, 0xa89ced, 0xc42ad0, 0xe0897e, 0x103025, 0x8c79f5, 0x90735a, - }; +std::array vendors = { + 0xa44519, 0x2446c8, 0xd0d003, 0x8cb84a, 0x608b0e, 0x88299c, 0x7c8956, + 0x201742, 0xd09c7a, 0xc4e39f, 0x2479f3, 0x8c79f5, 0xccd281, 0x88b291, + 0xc42ad0, 0xd81edd, 0xacf6f7, 0xc02e25, 0x64c2de, 0x58c6f0, 0x70bc10, + 0x2ca9f0, 0x586b14, 0xbcb863, 0x1040f3, 0x44e66e, 0xc0e862, 0xf40616, + 0x601d91, 0xd4c94b, 0x70bbe9, 0xf83880, 0x4c569d, 0x38539c, 0x402619, + 0x6ce85c, 0xe4b2fb, 0xd003df, 0xb4cb57, 0xfc039f, 0x18d717, 0x0057c1, + 0xa4d990, 0x20a60c, 0x08c5e1, 0x3c576c, 0xe4b021, 0x28ff3c, 0xf099b6, + 0x1094bb, 0x88e9fe, 0x94bf2d, 0xf86fc1, 0x38892c, 0x749eaf, 0x8035c1, + 0x2047da, 0xe4c483, 0xc048e6, 0x785dc8, 0x40cbc0, 0xc4618b, 0x08e689, + 0xdc56e7, 0x38e60a, 0xdcbfe9, 0xcc6ea4, 0xa46cf1, 0x08aed6, 0xa816d0, + 0x3408bc, 0x1c36bb, 0x3c2eff, 0xf06e0b, 0x24f677, 0xb0ca68, 0xc83c85, + 0x5433cb, 0x149f3c, 0x9ce063, 0xd03169, 0x7c6456, 0x084acf, 0xb8634d, + 0xa4e975, 0x3035ad, 0x844167, 0x9800c6, 0xac1f74, 0xa85c2c, 0x00db70, + 0x4c49e3, 0x389af6, 0xe0aa96, 0x507705, 0xa89675, 0x00ec0a, 0xc8d7b0, + 0x9097f3, 0x7c1c68, 0xc087eb, 0x388c50, 0xd4503f, 0x245ba7, 0x70f087, + 0xf0d7aa, 0x3096fb, 0x4827ea, 0x7c787e, 0x28395e, 0x38295a, 0x8cf5a3, + 0xd47ae2, 0xd8e0e1, 0xe44790, 0xb0702d, 0x6c19c0, 0xf01dbc, 0xf83f51, + 0x404e36, 0xdc0b34, 0x60a4d0, 0x008701, 0x5c9960, 0x2c3361, 0x101dc0, + 0x78471d, 0xa07591, 0x0cdfa4, 0x68ebae, 0x444e1a, 0x4844f7, 0x001377, + 0x002454, 0xe81132, 0x50b7c3, 0x1c5a3e, 0xa02195, 0xf4d9fb, 0x3c6200, + 0x00e3b2, 0x301966, 0x94350a, 0x0017d5, 0x001e7d, 0x001df6, 0xc06599, + 0xbc79ad, 0xf0e77e, 0xf008f1, 0xe47cf9, 0x58c38b, 0x001d25, 0x08fd0e, + 0x041bba, 0x889b39, 0xe432cb, 0x10d542, 0xa0821f, 0xf06bca, 0xac3613, + 0xbc8ccd, 0xd022be, 0xec9bf3, 0xf409d8, 0x4c3c16, 0x0073e0, 0x343111, + 0x4849c7, 0x849866, 0x9476b7, 0xc4438f, 0xa09169, 0x9893cc, 0x3ccd93, + 0x2021a5, 0x6cd68a, 0x002483, 0x001fe3, 0x2c54cf, 0x485929, 0x58a2b5, + 0x10f96f, 0x4c6641, 0xac3743, 0x28e31f, 0xecadb8, 0x9801a7, 0xb8bbaf, + 0x60c5ad, 0x24f094, 0x086d41, 0xe4faed, 0x288335, 0xdccf96, 0xccb11a, + 0xac61ea, 0x38b54d, 0x1c5cf2, 0xe0c767, 0x80ed2c, 0xa80600, 0xf05a09, + 0x503275, 0x08fc88, 0xf8d0bd, 0x94b10a, 0x3cbbfd, 0xa48431, 0xa0b4a5, + 0xe4f8ef, 0x78595e, 0x0c1420, 0x24f5aa, 0x988389, 0x84a466, 0xc4576e, + 0x508569, 0x489d24, 0xb07994, 0xa470d6, 0xc8f230, 0x8c0ee3, 0x28ed6a, + 0x38f23e, 0x902155, 0xd8b377, 0xa09347, 0xe8bba8, 0xb0aa36, 0xa4d18c, + 0x241eeb, 0xcc25ef, 0x28cfe9, 0x00a040, 0x003065, 0x3cd0f8, 0x680927, + 0x1093e9, 0x442a60, 0xc82a14, 0x3c0754, 0xa4b197, 0xa4d1d2, 0x28cfda, + 0x6cc26b, 0x44d884, 0x64200c, 0x001451, 0x001e52, 0x0021e9, 0x002608, + 0x0026b0, 0x0026bb, 0xd49a20, 0xf81edf, 0xcc08e0, 0xf0b479, 0x045453, + 0xe88d28, 0x949426, 0x207d74, 0xf4f15a, 0xc86f1d, 0x18af8f, 0xc8b5b7, + 0x90b21f, 0xb8e856, 0xd89695, 0x64a3cb, 0x30f7c5, 0x40b395, 0x44fb42, + 0x98fe94, 0xd8004d, 0x542696, 0xc8334b, 0x64e682, 0x9c207b, 0xb065bd, + 0x8c2daa, 0x848506, 0xf4f951, 0xc06394, 0x3090ab, 0x1499e2, 0xfce998, + 0x0cbc9f, 0x34363b, 0xd0a637, 0x789f70, 0xe0accb, 0xa0999b, 0x24240e, + 0x903c92, 0xd81d72, 0xd8bb2c, 0xd04f7e, 0x9cf387, 0xa85b78, 0xb418d1, + 0xf0dbf8, 0x48746e, 0x341298, 0x70e72c, 0x70ece4, 0x54ae27, 0xc8f650, + 0x68ae20, 0xac87a3, 0xa88e24, 0x2078f0, 0x70480f, 0xcc20e8, 0xf0b0e7, + 0x0469f8, 0x205531, 0xe8b4c8, 0xd087e2, 0xf05b7b, 0xb047bf, 0x7c0bc6, + 0x80c5e6, 0x5440ad, 0x804e81, 0xfc8f90, 0xe89120, 0x4480eb, 0x9cd35b, + 0xa89fba, 0x4886e8, 0x30d587, 0xec59e7, 0x2c2997, 0xd059e4, 0x14a364, + 0x7ced8d, 0x002538, 0x0022a1, 0x7cf31b, 0x0c2fb0, 0xf4d620, 0x8cf112, + 0x44aeab, 0xa4f05e, 0x28167f, 0xf887f1, 0x305714, 0xc8b1cd, 0x1460cb, + 0xb8f12a, 0x04c807, 0x20f478, 0x90735a, 0x00fa21, 0x7c2302, 0xd49dc0, + 0xe0dcff, 0x846fce, 0x804a14, 0x703c69, 0x489dd1, 0xb06fe0, 0xc08c71, + 0x60d0a9, 0x48fda3, 0xa45046, 0x007c2d, 0xb831b5, 0x14c213, 0xa4d931, + 0xbcfed9, 0x808223, 0x5029f5, 0x007204, 0xbca58b, 0x80ceb9, 0xe06267, + 0x082525, 0xf460e2, 0x1cc3eb, 0x00c3f4, 0x7836cc, 0x48605f, 0x2816a8, + 0x9c2ea1, 0xbce143, 0x647033, 0x846878, 0xc8d083, 0x6030d4, 0xf895ea, + 0x18f1d8, 0x30d9d9, 0x0cf346, 0x80ad16, 0xfc643a, 0xa8515b, 0xb4f7a1, + 0x88bd45, 0x54fcf0, 0x306a85, 0x4cdd31, 0xd0817a, 0x98ca33, 0x68ab1e, + 0x70ef00, 0xbcffeb, 0x0c1539, 0x88b4a6, 0x2c8a72, 0xd88f76, 0x409c28, + 0xd0b128, 0xbc5451, 0xec51bc, 0xf079e8, 0x58e28f, 0x787b8a, 0x88365f, + 0x2c4053, 0x3cf591, 0x602101, 0xacafb9, 0x041b6d, 0xecf342, 0x503da1, + 0x4c1a3d, 0x503237, 0xb0481a, 0xb49cdf, 0x48bf6b, 0x3c0518, 0x900628, + 0x9c84bf, 0x00b362, 0xe4e4ab, 0x60334b, 0xf4f524, 0xcc2d83, 0xfcd848, + 0xec107b, 0x1c232c, 0x0021d1, 0x001fcc, 0xec8892, 0x60a10a, 0x8c71f8, + 0xcc051b, 0x8c7712, 0x9463d1, 0x0021d2, 0x5c497d, 0x7825ad, 0xece09b, + 0xbc20a4, 0x08d42b, 0x789ed0, 0xb0c4e7, 0xa00798, 0x001fcd, 0x38ece4, + 0x945103, 0x002490, 0x0023d7, 0x549b12, 0xfca13e, 0x24c696, 0x94d771, + 0xe84e84, 0x001632, 0xe4e0c5, 0xc81479, 0x1caf05, 0x0016db, 0x001ee2, + 0x20d5bf, 0x5ce8eb, 0xc0bdd1, 0xb479a7, 0xb0df3a, 0x805719, 0x34be00, + 0x78521a, 0x38256b, 0x205ef7, 0x141f78, 0xb47443, 0x30766f, 0xa8922c, + 0xf80cf3, 0xc49a02, 0x001f6b, 0x0026e2, 0xa860b6, 0xc4b301, 0xe05f45, + 0x483b38, 0x1c9148, 0x5c70a3, 0x64cc2e, 0xf877b8, 0x182195, 0x44783e, + 0x30636b, 0xa4f1e8, 0x14bb6e, 0xe498d1, 0x6c2779, 0x28cc01, 0x6cf373, + 0x9c3aaf, 0x781fdb, 0x4ca56d, 0xb86ce8, 0x0cb319, 0x183f47, 0xb46293, + 0x50a4c8, 0x1867b0, 0x6c8336, 0x002557, 0x001ccc, 0xb4e1c4, 0xe0757d, + 0x34bb26, 0x806c1b, 0x2082c0, 0xdc6dcd, 0x440010, 0x0056cd, 0x00cdfe, + 0xe498d6, 0xf8db7f, 0x64a769, 0xe899c4, 0xbccfcc, 0xf431c3, 0x64a5c3, + 0xbc3aea, 0x7c1dd9, 0xa086c6, 0x9c99a0, 0x584498, 0x002332, 0x00236c, + 0x0023df, 0x002500, 0x0025bc, 0x0019e3, 0x001b63, 0x001ec2, 0x001ff3, + 0x0010fa, 0x0050e4, 0x000d93, 0x7cfadf, 0x78a3e4, 0x148fc6, 0x286ab8, + 0x28e02c, 0xe0b9ba, 0x00c610, 0xb8f6b1, 0x8cfaba, 0x7cd1c3, 0xf0dce2, + 0x24ab81, 0xe0f847, 0x28e7cf, 0xe4ce8f, 0xa82066, 0xbc52b7, 0x5c5948, + 0xc8bcc8, 0xe8040b, 0x145a05, 0x1caba7, 0xc0847a, 0x34159e, 0x58b035, + 0xdc86d8, 0x90b931, 0xd0e140, 0x24a2e1, 0x80ea96, 0x600308, 0x04f13e, + 0x98f0ab, 0x7831c1, 0x783a84, 0x5c8d4e, 0x8863df, 0x881fa1, 0xc8e0eb, + 0x98b8e3, 0x885395, 0x786c1c, 0x4c8d79, 0x1ce62b, 0x0c3021, 0x0c3e9f, + 0xfcfc48, 0x9c293f, 0x087402, 0x94f6a3, 0x98e0d9, 0xcc29f5, 0x285aeb, + 0xf02475, 0x2c1f23, 0x549f13, 0xf0dbe2, 0x748114, 0x18f643, 0xa45e60, + 0xa01828, 0xd0034b, 0x10417f, 0xa8667f, 0xd02598, 0x80be05, 0x24a074, + 0x84788b, 0x587f57, 0x006d52, 0xacee9e, 0xb857d8, 0xb844d9, 0x1c56fe, + 0xac5a14, 0x08eca9, 0xf8cfc5, 0x7840e4, 0xe09971, 0x10d38a, 0x206274, + 0xd48f33, 0x20a99b, 0x6077e2, 0xfc1910, 0x3ca10d, 0x646cb2, 0x680571, + 0x14b484, 0x3059b7, 0xa43d78, 0x00eebd, 0x502e5c, 0x980d2e, 0xd4206d, + 0x7c1e52, 0xdcb4c4, 0x7c6f06, 0x749ef5, 0x68bfc4, 0x04b1a1, 0xcc464e, + 0x507ac5, 0x6cd71f, 0x4c6be8, 0x8c861e, 0x542b8d, 0x8ce5c0, 0xf08a76, + 0xecaa25, 0x9078b2, 0xbc7fa4, 0x687d6b, 0x485169, 0xa8db03, 0x60ab67, + 0x4418fd, 0x005b94, 0xe0897e, 0xa8346a, 0x3c20f6, 0x7c38ad, 0x885a06, + 0x2c5d34, 0x7c035e, 0xd467d3, 0xa41232, 0x64c753, 0x38f9d3, 0xfc183c, + 0xf47def, 0x7c8bb5, 0x3830f9, 0x90e17b, 0xd81c79, 0x58e6ba, 0x1801f1, + 0x9c0cdf, 0x14c697, 0x7c03ab, 0x00b5d0, 0x1496e5, 0xd07fa0, 0x7c6b9c, + 0x108ee0, 0xfca621, 0xd832e3, 0x9487e0, 0x4466fc, 0x50a009, 0x50a67f, + 0xd461da, 0xb841a4, 0x9ce65e, 0xc49880, 0xe0338e, 0xf01898, 0x881908, + 0x5c0947, 0x14205e, 0x08f69c, 0x641cae, 0x003de8, 0x48c796, 0xf4c248, + 0xf47190, 0x2802d8, 0x24181d, 0x641cb0, 0x54b802, 0xd4909c, 0xe4e0a6, + 0x00e091, 0x503cea, 0xb4f1da, 0x80b03d, 0xe49adc, 0xace4b5, 0xf06d78, + 0xd0d2b0, 0x448f17, 0x1cddea, 0x78886d, 0x20ee28, 0xb4f61c, 0x08f4ab, + 0x8c8590, 0x6c96cf, 0x508f4c, 0xd463c6, 0xdc44b6, 0x1007b6, 0x342d0d, + 0x54bd79, 0x30074d, 0x947be7, 0x5092b9, 0xdc74a8, 0x88d50c, 0xc4ae12, + 0x989e63, 0x886b6e, 0xd4dccd, 0x484baa, 0xd4ae05, 0xdca904, 0x6cab31, + 0x4c74bf, 0x5082d5, 0xf0ee10, 0xb81daa, 0x5caf06, 0x64b0a6, 0x7c04d0, + 0x84fcac, 0xdc0c5c, 0x70700d, 0x186590, 0xf86214, 0x784f43, 0x404d7f, + 0x1c48ce, 0x6c5c14, 0xcc61e5, 0x609ac1, 0x20dbab, 0x748d08, 0x9c8ba0, + 0xcc088d, 0x38a4ed, 0x0007ab, 0xe8e5d6, 0xc87e75, 0x00265f, 0x00233a, + 0x382dd1, 0x10ddb1, 0x00166c, 0x001599, 0x0012fb, 0xd0667b, 0x1c66aa, + 0x1489fd, 0xbc851f, 0x002491, 0x3c8bfe, 0xd4e8b2, 0xe8039a, 0x30cda7, + 0x2c4401, 0xb8d9ce, 0x002339, 0x5001bb, 0x001247, 0x0015b9, 0xb85e7b, + 0x1c77f6, 0x742344, 0xc8ba94, 0x843838, 0x54880e, 0xf025b7, 0xe492fb, + 0x6cb7f4, 0x181eb0, 0x5c3c27, 0xbc72b1, 0x78f7be, 0x684898, 0x3423ba, + 0x400e85, 0x88797e, 0xd013fd, 0x888322, 0xe89309, 0x6cd032, 0x3cbdd8, + 0x78c3e9, 0x64899a, 0xf8a9d0, 0xccfa00, 0xa816b2, 0x64bc0c, 0x74a722, + 0xf01c13, 0x344df7, 0x583f54, 0xc01ada, 0x8c1abf, 0x30cbf8, 0xa0cbfd, + 0xe45d75, 0x408805, 0x98398e, 0xd0fccc, 0xc09727, 0x84a134, 0x0c5101, + 0x2cf0a2, 0x68fb7e, 0x6c2483, 0x5cca1a, 0xac0d1b, 0x0034da, 0x202d07, + 0xb44bd2, 0xdc415f, 0x102ab3, 0xe8b2ac, 0xe49a79, 0xf45c89, 0x20768f, + 0x300d43, 0x607edd, 0x08373d, 0xc488e5, 0x1077b1, 0x64b853, 0x389496, + 0x5056bf, 0x90f1aa, 0x74458a, 0xfcc734, 0x8425db, 0xb0ec71, 0xe458b8, + 0x088c2c, 0xa49a58, 0x08ee8b, 0x68ed43, 0x70aab2, 0x000f86, 0xf8e079, + 0xccc3ea, 0x40786a, 0x38cada, 0x34ab37, 0x18af61, 0x5cf938, 0x002376, + 0x38e7d8, 0x188796, 0xb4cef6, 0xcc4463, 0x6c72e7, 0x741bb2, 0xf8a45f, + 0x640980, 0x185936, 0x60fec5, 0xe425e7, 0x7c6d62, 0x40d32d, 0xc42c03, + 0x9027e4, 0xbc926b, 0x101c0c, 0x080007, 0x0016cb, 0x0017f2, 0x001f5b, + 0x002436, 0x00254b, 0x6c3e6d, 0xbc6778, 0x20c9d0, 0x68967b, 0x581faa, + 0x88c663, 0xa46706, 0x8c5877, 0xa8fad8, 0x008865, 0xbc3baf, 0x3ce072, + 0x84fcfe, 0xe48b7f, 0xd8d1cb, 0xb817c2, 0x7c11be, 0x98d6bb, 0x283737, + 0x50ead6, 0x189efc, 0x804971, 0x7cf05f, 0x109add, 0x848e0c, 0x3c15c2, + 0x6c709f, 0x6476ba, 0x34e2fd, 0x04489a, 0x80e650, 0x90fd61, 0x2cf0ee, + 0x5c97f3, 0x8c2937, 0xaccf5c, 0x80006e, 0xa4c361, 0xb09fba, 0x0c4de9, + 0xe0f5c6, 0xa0edcd, 0x087045, 0xa88808, 0xc0f2fb, 0x24e314, 0xf0f61c, + 0x38484c, 0x38c986, 0xd03311, 0xd4f46f, 0x48437c, 0x34a395, 0x787e61, + 0x60f81d, 0x5cf5da, 0x18ee69, 0x649abe, 0xac293a, 0x9cfc01, 0x9c35eb, + 0xf099bf, 0x94e96a, 0x507a55, 0x5882a8, 0x24da9b, 0xe83a12, 0x80656d, + 0x38d40b, 0x209bcd, 0xfcf136, 0x18895b, 0x7cf90e, 0x50f0d3, 0x78bdbc, + 0x84119e, 0xe4907e, 0x149a10, 0x485073, 0x244b03, 0x74e28c, 0x244b81, + 0x60af6d, 0xb85a73, 0x981dfa, 0x102f6b, 0xc44202, 0x103047, 0xf884f2, + 0x5c2e59, 0xe0cbee, 0x002248, 0x8031f0, 0xe0d083, 0xd80b9a, 0x5c666c, + 0xc4e1a1, 0x1855e3, 0xe450eb, 0x886440, 0x6070c0, 0xf0c371, 0x987a14, + 0xc83ddc, 0x845733, 0x1819d6, 0xbc98df, 0x70dda8, 0x4c6f9c, 0x4883b4, + 0x0017fa, 0x941625, 0x34a8eb, 0xa483e7, 0xf4afe7, 0xac88fd, 0x20326c, + 0x6489f1, 0x2034fb, 0xa89ced, 0xe458e7, 0xdc080f, 0xf8e94e, 0xec2ce2, + 0x40bc60, 0xe83617, 0x9c648b, 0x344262, 0x14d00d, 0x703a51, 0x04e598, + 0x6cc7ec, 0xc0bdc8, 0x647bce, 0xa887b3, 0x6c006b, 0x24fce5, 0x9caa1b, + 0x70fd46, 0x8c83e1, 0x889f6f, 0x482ca0, 0x0ccb85, 0x08d46a, 0x68e7c2, + 0x58b10f, 0x645aed, 0xc0b658, 0x48a91c, 0x50bc96, 0xfc2a9c, 0xa056f3, + 0x549963, 0x90dd5d, 0xc819f7, 0x3880df, 0x3cdcbc, 0x804e70, 0xd4e6b7, + 0x04d13a, 0xc48466, 0x347c25, 0xcc2db7, 0x0c9838, 0xd41a3f, 0x5c865c, + 0x04b167, 0xec8350, 0x2c5491, 0xe42b34, 0x3c2ef9, 0xa04ea7, 0xf0989d, + 0xd80831, 0x10f1f2, 0x982d68, 0xb019c6, 0x3866f0, 0x703eac, 0x7c2edd, + 0x3cf7a4, 0x986f60, 0xc49ded, 0x9810e8, 0xc0d012, 0xbca920, 0x48a195, + 0xf80377, 0x8058f8, 0xdca4ca, 0x8c8fe9, 0x5cba37, 0x2c200b, 0x8866a5, + 0xacc1ee, 0x805a04, 0xbc8385, 0x2c598a, 0xe47dbd, 0x001cb3, 0x24920e, + 0xfc4203, 0xa01081, 0xf07960, 0xa0d795, 0xbc4760, 0x04180f, 0x2013e0, + 0x002566, 0xc09f05, 0x606bbd, 0x00214c, 0x0018af, 0x001ee1, 0x00166b, + 0x0000f0, 0x8cc8cd, 0xa8f274, 0xd487d8, 0x184617, 0x380a94, 0xd0dfc7, + 0xd0c1b1, 0x8018a7, 0xf47b5e, 0x70f927, 0xc45006, 0x88329b, 0x1449e0, + 0xd02544, 0xbc4486, 0x20d390, 0x9401c2, 0x50fc9f, 0x380b40, 0xb8ff61, + 0xf0728c, 0x34aa8b, 0x24dbed, 0x68c44d, 0x440444, 0x84b541, 0x006f64, + 0xdc6672, 0xf8e61a, 0xcc2d8c, 0x98d6f7, 0x700514, 0xe892a4, 0x10683f, + 0x40b0fa, 0x0025e5, 0x0021fb, 0x34fcef, 0xbcf5ac, 0x0c4885, 0x0022a9, + 0x9c2a83, 0xa039f7, 0xb0e235, 0x14c913, 0xe09861, 0xa06090, 0xbc765e, + 0xd85b2a, 0x90c1c6, 0x70a2b3, 0xf40f24, 0x4c57ca, 0xc46ab7, 0x48e9f1, + 0xc83f26, 0x40163b, 0xc83870, 0x6c8fb5, 0x1c9e46, 0xc0ccf8, 0x9c4fda, + 0x8489ad, 0x647791, 0x9ce6e7, 0x9c0298, 0x28987b, 0x54fa3e, 0x0c8910, + 0x78abbb, 0xd8c4e9, 0xbcd11f, 0xf4428f, 0x446d6c, 0x00f46f, 0x0c715d, + 0x34bb1f, 0x406f2a, 0x985fd3, 0x60beb5, 0xf8f1b6, 0xf4f1e1, 0x9cd917, + 0x9068c3, 0x68dbca, 0x086698, 0xbc5436, 0x044bed, 0x6c8dc1, 0x0cd746, + 0x60a37d, 0xd40b1a, 0xfc64ba, 0x9060f1, 0xa4516f, 0x68dfdd, 0x98fae3, + 0xf0b429, 0xb8782e, 0x000502, 0x000a95, 0x00264a, 0x041e64, 0x001124, + 0x002241, 0x7cc537, 0x78ca39, 0x18e7f4, 0x70cd60, 0x8c7b9d, 0xd89e3f, + 0xb8c75d, 0x0c74c2, 0x403004, 0x842999, 0x74e2f5, 0xe0c97a, 0x68a86d, + 0x7cc3a1, 0x7073cb, 0x90840d, 0xe80688, 0xec852f, 0x00f4b9, 0x5c95ae, + 0x9803d8, 0x60c547, 0x685b35, 0x2cb43a, 0x689c70, 0x380f4a, 0x3010e4, + 0xa886dd, 0x444c0c, 0xb4f0ab, 0x80929f, 0x9c04eb, 0x5c969d, 0x609217, + 0x84b153, 0xe06678, 0x48d705, 0x041552, 0xcc785f, 0x88cb87, 0xf0c1f1, + 0x843835, 0x8c006d, 0xa8968a, 0xf41ba1, 0x60d9c7, 0x3cab8e, 0xf82793, + 0x907240, 0x908d6c, 0xb8098a, 0x4c7c5f, 0x68644b, 0xc81ee7, 0xa43135, + 0x68d93c, 0x00f76f, 0xc88550, 0x7014a6, 0x985aeb, 0x78d75f, 0xe0b52d, + 0x6c94f8, 0xc0cecd, 0x2cae2b, 0xc869cd, 0xa4b805, 0x5cadcf, 0xbc6c21, + 0xf40e22, 0x544e90, 0xc01173, 0xbce63f, 0x7c9122, 0xacbc32, 0x2827bf, + 0x800184, 0x8cbfa6, 0xc8a823, 0xb0c559, 0xbc1485, 0x9c6c15, 0xc0335e, + 0xd0929e, 0x083d88, 0x608f5c, 0x109266, 0x281878, 0x847a88, 0xa0f450, + 0xa826d9, 0x00155d, 0x00125a, 0x000d3a, 0x0003ff, 0x18d0c5, 0x1cccd6, + 0x582059, 0x74e1b6, 0xf40e01, 0x1495ce, 0x50de06, 0xcc660a, 0xfc1d43, + 0x0024e9, 0xb4c4fc, 0x7cd661, 0x98b8ba, 0x103025, 0xb8b2f8, 0x98460a, + 0xb85d0a, 0x7c9a1d, 0x5462e2, 0x149d99, 0x489507, 0xd85575, 0xd411a3, + 0x04ba8d, 0xe446da, 0x58d9c3, 0x3c8375, 0xb8bc5b, 0xd8ce3a, 0xb8c74a, + 0x94f6d6, 0xf82d7c, 0xc09ad0, 0x94b01f, 0x90633b, 0xfcaab6, 0x782327, + 0xdcf756, 0x74b587, 0xfcb6d8, 0x18810e, 0x608c4a, 0x241b7a, 0x8cfe57, + 0xc0a600, 0xa823fe, 0x1c427d, 0xcc2119, 0x304b07, 0x000393, 0x702ad5, + 0x74eb80, 0x0ce0dc, 0xd868c3, 0xc493d9, 0xa82bb9, 0x1c1ac0, 0x88ae07, + 0x40831d, 0xdcd3a2, 0x5c1dd9, 0x68fef7, 0xd07714, 0x587a6a, 0x705aac, + 0x685acf, 0x0ca8a7, 0x2c61f6, 0xd4a33d, 0xf0766f, 0x4098ad, 0x6c4d73, + 0x68ef43, 0xd02b20, 0xd86375, 0x30b4b8, 0x9c8c6e, 0x18f0e4, 0x00bf61, + 0xd00401, 0xdc5583, 0xb8c111, 0x9ce33f, 0x7867d7, 0x087808, 0x887598, + 0xc0174d, 0xa407b6, 0x04d6aa, 0x08152f, 0xf4f5db, 0xc0a53e, 0xecd09f, + 0xa8be27, 0x94d029, 0x308454, 0x5c5181, 0x608e08, 0x4c189a, 0x58c5cb, + 0xb4bff6, 0x74f61c, 0x84c0ef, 0xa8b86e, 0xc40bcb, 0xb83765, 0x14bd61, + 0xc0d3c0, 0x948bc1, 0x14568e, 0xd4619d, 0x7c5049, 0x64b473, 0x7451ba, + 0x7802f8, 0xec01ee, 0x682737, 0x58404e, 0xd0c5f3, 0xbc9fef, 0x20ab37, + 0x60f445, 0x2c0e3d, 0x88e87f, 0x9cf48e, 0x5cf7e6, 0xb853ac, 0x203cae, + 0x2cbaba, 0x40d3ae, 0xa03be3, 0x4c3275, 0x3816d1, 0xd0176a, 0xd48890, + 0x5492be, 0x949aa9, 0x001c43, 0x002399, 0x0017c9, 0x7cf854, 0xc4731e, + 0xec1f72, 0xe4121d, 0xe8508b, 0xf8042e, 0x0023d6, 0x001b98, 0x001a8a, + 0x3c5a37, 0xf49f54, 0x34c3ac, 0x44f459, 0x00265d, 0x002567, 0xbcb1f3, + 0xc462ea, 0x182666, 0x30d6c9, 0xcc07ab, 0x1c62b8, 0xccf9e8, 0xd857ef, + 0x18e2c2, 0x28bab5, 0xe440e2, 0x103b59, 0xd890e8, 0x9852b1, 0x14f42a, + 0x0808c2, 0xccfe3c, 0xb43a28, 0x78a873, 0xd83062, 0xc041f6, 0x001e75, + 0x001c62, 0xf895c7, 0x34145f, 0x0821ef, 0x505527, 0x88c9d0, 0x8c3ae3, + 0x00aa70, 0x60e3ac, 0x4c0bbe, 0xb88d12, 0x845181, 0x348a7b, 0x78009e, + 0xacc33a, 0x54f201, 0x70288b, 0x8c8ef2, 0x90b0ed, 0x04d3cf, 0x1c3ade, + 0x509ea7, 0xa88195, 0x88add2, 0xac5f3e, 0xb48b19, 0xbcec5d, 0x28a02b, + 0xb8c68e, 0x04fe31, 0x4cbca5, 0xd831cf, 0x188331, 0x9c65b0, 0x8455a5, + 0xa87c01, 0x50f520, 0x64b310, 0xa4ebd3, 0xb0d09c, 0x50c8e5, 0x5cf6dc, + 0x0026ff, 0xa4e4b8, 0xf40b93, 0x1c69a5, 0x94ebcd, 0x141aa3, 0x1430c6, + 0x88074b, 0x3871de, 0x7081eb, 0x78f882, 0x606944, 0x807abf, 0x00092d, + 0x7c6193, 0x0452f3, 0x90e7c4, 0xa81b5a, 0x2c5bb8, 0xacf7f3, 0xd4970b, + 0x8cbebe, 0x14f65a, 0x009ec8, 0x0c1daf, 0x3480b3, 0xf48b32, 0x60fb42, + 0x64b9e8, 0xd8a25e, 0x000a27, 0x001d4f, 0x002312, 0x60facd, 0x003ee1, + 0xfc253f, 0x183451, 0x0c771a, 0x286aba, 0x3451c9, 0x406c8f, 0xd023db, + 0x70dee2, 0x5855ca, 0xdc2b61, 0x40a6d9, 0x4cb199, 0xc09f42, 0x705681, + 0x040cce, 0x403cfc, 0x4860bc, 0xf0cba1, 0x182032, 0x34c059, 0xf0d1a9, + 0x14109f, 0x04f7e4, 0xdc9b9c, 0x54724f, 0x8c7c92, 0xb03495, 0x042665, + 0xec3586, 0x54eaa8, 0x28e14c, 0xe4c63d, 0x54e43a, 0x04db56, 0x04e536, + 0xe8802e, 0x006171, 0x6c4008, 0x7c6df8, 0x78fd94, 0x2cbe08, 0xac3c0b, + 0x701124, 0xf437b7, 0xd8cf9c, 0xa8bbcf, 0xac7f3e, 0x280b5c, 0xacfdec, + 0x28f076, 0x20a2e4, 0xbc4cc4, 0xdc3714, 0x40331a, 0xccc760, 0x7c0191, + 0x84100d, 0x80d605, 0xdc2b2a, 0x48137e, 0x382de8, 0xc08997, 0x04c23e, + 0x380195, 0xb4ae2b, 0x5c5188, 0x0ce725, 0xe0db10, 0x1432d1, 0x1816c9, + 0x842e27, 0x0c413e, 0x9000db, 0xb4ef39, 0xc808e9, 0x183a2d, 0x8463d6, + 0xb84fd5, 0xc0eefb, 0x206e9c, 0x6c2f2c, 0x18227e, 0x30c7ae, 0x501ac5, + 0x6045bd, 0x1cb094, 0xe85b5b, 0x0025ae, 0x001dd8, 0x000a75, 0xa4c939, + 0xc0dcda, 0x04b429, 0x48794d, +}; From 5b8cef880c40e31d97fb36e2f5039ec7d837334e Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 11 Aug 2019 21:12:27 +0200 Subject: [PATCH 19/34] v1.7.91 --- platformio.ini | 2 +- src/timekeeper.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index a4499620..4df4cb24 100644 --- a/platformio.ini +++ b/platformio.ini @@ -40,7 +40,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 = 1.7.841 +release_version = 1.7.91 ; 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 diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index 4d01f7d9..4afe5641 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -54,6 +54,8 @@ void calibrateTime(void) { } #endif +goto finish; + finish: setMyTime(t, t_msec, timeSource); // set time From b926d908b22da2380c8d6aaca34766b5dc7b2ea7 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Tue, 13 Aug 2019 22:40:33 +0200 Subject: [PATCH 20/34] timekeeper/timesync: fixed dependencies --- include/timekeeper.h | 1 + include/timesync.h | 1 - src/timekeeper.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++- src/timesync.cpp | 46 ------------------------------------------ 4 files changed, 48 insertions(+), 48 deletions(-) diff --git a/include/timekeeper.h b/include/timekeeper.h index 6239f082..20199ac1 100644 --- a/include/timekeeper.h +++ b/include/timekeeper.h @@ -27,6 +27,7 @@ void timeSync(void); uint8_t timepulse_init(void); time_t 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 compiledUTC(void); TickType_t tx_Ticks(uint32_t framesize, unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPins); diff --git a/include/timesync.h b/include/timesync.h index 498952c1..7a0013ec 100644 --- a/include/timesync.h +++ b/include/timesync.h @@ -15,6 +15,5 @@ void send_timesync_req(void); int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len); void process_timesync_req(void *taskparameter); void store_time_sync_req(uint32_t t_millisec); -void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, timesource_t timesource); #endif \ No newline at end of file diff --git a/src/timekeeper.cpp b/src/timekeeper.cpp index 4afe5641..16236de0 100644 --- a/src/timekeeper.cpp +++ b/src/timekeeper.cpp @@ -58,10 +58,56 @@ goto finish; finish: - setMyTime(t, t_msec, timeSource); // set time + setMyTime((uint32_t)t, t_msec, timeSource); // set time } // calibrateTime() +// adjust system time, calibrate RTC and RTC_INT pps +void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, + timesource_t mytimesource) { + + // increment t_sec only if t_msec > 1000 + time_t time_to_set = (time_t)(t_sec + t_msec / 1000); + + // do we have a valid time? + if (timeIsValid(time_to_set)) { + + // if we have msec fraction, then wait until top of second with + // millisecond precision + if (t_msec % 1000) { + time_to_set++; + vTaskDelay(pdMS_TO_TICKS(1000 - t_msec % 1000)); + } + + ESP_LOGD(TAG, "[%0.3f] UTC epoch time: %d.%03d sec", millis() / 1000.0, + time_to_set, t_msec % 1000); + +// if we have got an external 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 (!defined GPS_INT && !defined RTC_INT) + timerWrite(ppsIRQ, 0); // reset pps timer + CLOCKIRQ(); // fire clock pps, this advances time 1 sec +#endif + + setTime(time_to_set); // set the time on top of second + + timeSource = mytimesource; // set global variable + timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); + ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was set | source: %c", + millis() / 1000.0, timeSetSymbols[timeSource]); + } else { + timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); + ESP_LOGI(TAG, "[%0.3f] Timesync failed, invalid time fetched | source: %c", + millis() / 1000.0, timeSetSymbols[timeSource]); + } +} + // helper function to setup a pulse per second for time synchronisation uint8_t timepulse_init() { diff --git a/src/timesync.cpp b/src/timesync.cpp index ef50041d..b1814538 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -207,52 +207,6 @@ int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) { } } -// adjust system time, calibrate RTC and RTC_INT pps -void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, - timesource_t mytimesource) { - - // increment t_sec only if t_msec > 1000 - time_t time_to_set = (time_t)(t_sec + t_msec / 1000); - - // do we have a valid time? - if (timeIsValid(time_to_set)) { - - // if we have msec fraction, then wait until top of second with - // millisecond precision - if (t_msec % 1000) { - time_to_set++; - vTaskDelay(pdMS_TO_TICKS(1000 - t_msec % 1000)); - } - - ESP_LOGD(TAG, "[%0.3f] UTC epoch time: %d.%03d sec", millis() / 1000.0, - time_to_set, t_msec % 1000); - -// if we have got an external 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 (!defined GPS_INT && !defined RTC_INT) - timerWrite(ppsIRQ, 0); // reset pps timer - CLOCKIRQ(); // fire clock pps, this advances time 1 sec -#endif - - setTime(time_to_set); // set the time on top of second - - timeSource = mytimesource; // set global variable - timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); - ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was set | source: %c", - millis() / 1000.0, timeSetSymbols[timeSource]); - } else { - timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); - ESP_LOGI(TAG, "[%0.3f] Timesync failed, invalid time fetched | source: %c", - millis() / 1000.0, timeSetSymbols[timeSource]); - } -} - // create task for timeserver handshake processing, called from main.cpp void timesync_init() { xTaskCreatePinnedToCore(process_timesync_req, // task function From 8717d5e3a738798714345d5aa6166eba06406cb0 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Tue, 13 Aug 2019 22:47:19 +0200 Subject: [PATCH 21/34] changed lmic clock error procentage --- src/lmic_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lmic_config.h b/src/lmic_config.h index 9e90a439..f4ddf4ab 100644 --- a/src/lmic_config.h +++ b/src/lmic_config.h @@ -35,7 +35,7 @@ // so consuming more power. You may sharpen (reduce) this value if you are // limited on battery. // ATTN: VALUES > 7 WILL CAUSE RECEPTION AND JOIN PROBLEMS WITH HIGH SF RATES -#define CLOCK_ERROR_PROCENTAGE 5 +#define CLOCK_ERROR_PROCENTAGE 7 // Set this to 1 to enable some basic debug output (using printf) about // RF settings used during transmission and reception. Set to 2 to From c566b302d576828978521aa3090a0d43067ab92a Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Wed, 14 Aug 2019 21:52:12 +0200 Subject: [PATCH 22/34] add tinyPICO board --- platformio.ini | 3 ++- src/hal/eboxtube.h | 2 +- src/hal/fipy.h | 2 +- src/hal/generic.h | 2 +- src/hal/lolin32litelora.h | 2 +- src/hal/lolin32lora.h | 2 +- src/hal/lopy.h | 2 +- src/hal/lopy4.h | 4 ++-- src/hal/octopus32.h | 2 +- src/hal/tinypico.h | 24 ++++++++++++++++++++++++ src/led.cpp | 2 +- src/main.cpp | 10 +++++++++- src/paxcounter.conf | 2 +- 13 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 src/hal/tinypico.h diff --git a/platformio.ini b/platformio.ini index 4df4cb24..b35fa91e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -28,6 +28,7 @@ halfile = generic.h ;halfile = wemos32oled.h ;halfile = wemos32matrix.h ;halfile = octopus32.h +;halfile = tinypico.h [platformio] ; upload firmware to board with usb cable @@ -40,7 +41,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 = 1.7.91 +release_version = 1.7.92 ; 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 diff --git a/src/hal/eboxtube.h b/src/hal/eboxtube.h index 9278f0a6..34abe865 100644 --- a/src/hal/eboxtube.h +++ b/src/hal/eboxtube.h @@ -14,7 +14,7 @@ #define CFG_sx1276_radio 1 #define HAS_LED (22) // Green LED on board -#define HAS_RGB_LED (2) // WS2812B RGB LED on board +#define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_2) // WS2812B RGB LED on board #define HAS_BUTTON (0) // button "FLASH" on board #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature diff --git a/src/hal/fipy.h b/src/hal/fipy.h index c59dff59..f904d716 100644 --- a/src/hal/fipy.h +++ b/src/hal/fipy.h @@ -13,7 +13,7 @@ #define CFG_sx1272_radio 1 #define HAS_LED NOT_A_PIN // FiPy has no on board LED, so we use RGB LED -#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0 +#define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_0) // WS2812B RGB LED on GPIO0 #define BOARD_HAS_PSRAM // use extra 4MB extern RAM // Pins for LORA chip SPI interface, reset line and interrupt lines diff --git a/src/hal/generic.h b/src/hal/generic.h index 1579221f..c606e5ba 100644 --- a/src/hal/generic.h +++ b/src/hal/generic.h @@ -51,7 +51,7 @@ #define HAS_LED (21) // on board LED #define HAS_BUTTON (39) // on board button -#define HAS_RGB_LED (0) // WS2812B RGB LED on GPIO0 +#define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_0) // WS2812B RGB LED on GPIO0 // GPS settings #define HAS_GPS 1 // use on board GPS diff --git a/src/hal/lolin32litelora.h b/src/hal/lolin32litelora.h index 79f9bb6b..11f3f156 100644 --- a/src/hal/lolin32litelora.h +++ b/src/hal/lolin32litelora.h @@ -17,7 +17,7 @@ //#define DISPLAY_FLIP 1 // uncomment this for rotated display #define HAS_LED 22 // ESP32 GPIO12 (pin22) On Board LED #define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW -#define HAS_RGB_LED 13 // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED +#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 #define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown diff --git a/src/hal/lolin32lora.h b/src/hal/lolin32lora.h index a6fa2f37..a79b0d84 100644 --- a/src/hal/lolin32lora.h +++ b/src/hal/lolin32lora.h @@ -18,7 +18,7 @@ #define HAS_LED NOT_A_PIN // Led os on same pin as Lora SS pin, to avoid problems, we don't use it #define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW // Anyway shield is on over the LoLin32 board, so we won't be able to see this LED -#define HAS_RGB_LED 13 // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED +#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 #define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown diff --git a/src/hal/lopy.h b/src/hal/lopy.h index 4bf50781..733eb603 100644 --- a/src/hal/lopy.h +++ b/src/hal/lopy.h @@ -12,7 +12,7 @@ #define HAS_LORA 1 // comment out if device shall not send data via LoRa #define CFG_sx1272_radio 1 #define HAS_LED NOT_A_PIN // LoPy4 has no on board mono LED, we use on board RGB LED -#define HAS_RGB_LED (0) // WS2812B RGB LED on GPIO0 +#define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_0) // WS2812B RGB LED on GPIO0 (P2) // Note: Pins for LORA chip SPI interface come from board file pins_arduino.h diff --git a/src/hal/lopy4.h b/src/hal/lopy4.h index 321244e4..e0736229 100644 --- a/src/hal/lopy4.h +++ b/src/hal/lopy4.h @@ -20,8 +20,8 @@ //#define SPI_CS GPIO_NUM_36 #define CFG_sx1276_radio 1 -//#define HAS_LED NOT_A_PIN // LoPy4 has no on board mono LED, we use on board RGB LED -#define HAS_RGB_LED (0) // WS2812B RGB LED on GPIO0 (P2) +#define HAS_LED NOT_A_PIN // LoPy4 has no on board mono LED, we use on board RGB LED +#define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_0) // WS2812B RGB LED on GPIO0 (P2) #define BOARD_HAS_PSRAM // use extra 4MB extern RAM // Note: Pins for LORA chip SPI interface come from board file pins_arduino.h diff --git a/src/hal/octopus32.h b/src/hal/octopus32.h index c2bf3735..d245a8c2 100644 --- a/src/hal/octopus32.h +++ b/src/hal/octopus32.h @@ -23,7 +23,7 @@ #define HAS_LED 13 // ESP32 GPIO12 (pin22) On Board LED //#define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW -//#define HAS_RGB_LED 13 // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED +//#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 //#define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown diff --git a/src/hal/tinypico.h b/src/hal/tinypico.h new file mode 100644 index 00000000..415f793d --- /dev/null +++ b/src/hal/tinypico.h @@ -0,0 +1,24 @@ +// clang-format off +// upload_speed 921600 +// board esp32dev + + +#ifndef _TINYPICO_H +#define _TINYPICO_H + +#include + +// Hardware related definitions for crowdsupply tinypico board + +#define HAS_LED NOT_A_PIN // Green LED on board +#define HAS_RGB_LED Apa102 rgb_led(1, GPIO_NUM_12, GPIO_NUM_2) // APA102 RGB LED on board + +//#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature +#define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 +#define BAT_VOLTAGE_DIVIDER 2.7625f // voltage divider 160k/442k on board +#define BOARD_HAS_PSRAM // use extra 4MB external RAM +#define LED_POWER_SW (13) // switches LED power +#define LED_POWER_ON 0 // switch on transistor for LED power +#define LED_POWER_OFF 1 + +#endif \ No newline at end of file diff --git a/src/led.cpp b/src/led.cpp index 624fb7d9..d7925b4e 100644 --- a/src/led.cpp +++ b/src/led.cpp @@ -14,7 +14,7 @@ unsigned long LEDBlinkStarted = 0; // When (in millis() led blink started) #ifdef HAS_RGB_LED // RGB Led instance -SmartLed rgb_led(LED_WS2812, 1, HAS_RGB_LED); +HAS_RGB_LED; float rgb_CalcColor(float p, float q, float t) { if (t < 0.0f) diff --git a/src/main.cpp b/src/main.cpp index c6dae99e..976ad625 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -195,17 +195,25 @@ void setup() { #if (HAS_LED != NOT_A_PIN) pinMode(HAS_LED, OUTPUT); strcat_P(features, " LED"); + +#ifdef LED_POWER_SW + pinMode(LED_POWER_SW, OUTPUT); + digitalWrite(LED_POWER_SW, LED_POWER_ON); +#endif + #ifdef HAS_TWO_LED pinMode(HAS_TWO_LED, OUTPUT); strcat_P(features, " LED1"); #endif + // use LED for power display if we have additional RGB LED, else for status #ifdef HAS_RGB_LED switch_LED(LED_ON); strcat_P(features, " RGB"); rgb_set_color(COLOR_PINK); #endif -#endif + +#endif // HAS_LED #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) // start led loop diff --git a/src/paxcounter.conf b/src/paxcounter.conf index 30dcedc0..7382d8d8 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -72,7 +72,7 @@ #define TIME_SYNC_INTERVAL_RETRY 10 // retry time sync after lost sync each .. minutes [default = 10], 0 means off #define TIME_SYNC_COMPILEDATE 0 // set to 1 to use compile date to initialize RTC after power outage [default = 0] #define TIME_SYNC_LORAWAN 0 // set to 1 to use LORA network as time source, 0 means off [default = 0] -#define TIME_SYNC_LORASERVER 1 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0] +#define TIME_SYNC_LORASERVER 0 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0] // settings for syncing time with timeserver applications #define TIME_SYNC_SAMPLES 1 // number of time requests for averaging From 49a6714dbc90df29c39bab6513214d62b9dd45ae Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Wed, 14 Aug 2019 21:54:12 +0200 Subject: [PATCH 23/34] readme.md updated --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a9f2ebed..d8956b0a 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ LoLin32lite + [LoraNode32-Lite shield](https://github.com/hallard/LoLin32-Lite-L - Pyom: WiPy - WeMos: LoLin32, LoLin32 Lite, WeMos D32, [Wemos32 Oled](https://www.instructables.com/id/ESP32-With-Integrated-OLED-WEMOSLolin-Getting-Star/) +- Crowdsupply: [TinyPICO](https://www.crowdsupply.com/unexpected-maker/tinypico) - Generic ESP32 Depending on board hardware following features are supported: From 267d04488b1f2209a4129ff9550f683850444033 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Thu, 15 Aug 2019 12:02:03 +0200 Subject: [PATCH 24/34] added tinypicomatrix.h --- src/hal/tinypicomatrix.h | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/hal/tinypicomatrix.h diff --git a/src/hal/tinypicomatrix.h b/src/hal/tinypicomatrix.h new file mode 100644 index 00000000..c24c8059 --- /dev/null +++ b/src/hal/tinypicomatrix.h @@ -0,0 +1,46 @@ +// clang-format off +// upload_speed 921600 +// board esp32dev + + +#ifndef _TINYPICO_H +#define _TINYPICO_H + +#include + +// Hardware related definitions for crowdsupply tinypico board +// for operating a 96x16 shift register LED matrix display + +#define HAS_LED NOT_A_PIN // Green LED on board +#define HAS_RGB_LED Apa102 rgb_led(1, GPIO_NUM_12, GPIO_NUM_2) // APA102 RGB LED on board + +//#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature +#define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 +#define BAT_VOLTAGE_DIVIDER 2.7625f // voltage divider 160k/442k on board +#define BOARD_HAS_PSRAM // use extra 4MB external RAM +#define LED_POWER_SW (13) // switches LED power +#define LED_POWER_ON 0 // switch on transistor for LED power +#define LED_POWER_OFF 1 + +// LED Matrix display settings +#define HAS_MATRIX_DISPLAY 1 // Uncomment to enable LED matrix display output +#define LED_MATRIX_WIDTH 64 // Width in pixels (LEDs) of your display +#define LED_MATRIX_HEIGHT 16 // Height in pixels (LEDs ) of your display + +// Explanation of pin signals see https://learn.adafruit.com/32x16-32x32-rgb-led-matrix/new-wiring +#define MATRIX_DISPLAY_SCAN_US 500 // Matrix display scan rate in microseconds (1ms is about 'acceptable') +#define LED_MATRIX_LATCHPIN 32 // LAT (or STB = Strobe) +#define LED_MATRIX_CLOCKPIN 33 // CLK +#define LED_MATRIX_EN_74138 21 // EN (or OE) +#define LED_MATRIX_LA_74138 23 // LA (or A) +#define LED_MATRIX_LB_74138 19 // LB (or B) +#define LED_MATRIX_LC_74138 18 // LC (or C) +#define LED_MATRIX_LD_74138 5 // LD (or D) +#define LED_MATRIX_DATA_R1 22 // R1 (or R0) + +// CLK: The clock signal moves the data bits from pin R1 ("red") in the shift registers +// LAT: The latch signal enables LEDs according to the shift register's contents +// Line Selects: LA, LB, LC, LD select which rows of the display are currently lit (0 .. 15) +// OE: Output enable switches the LEDs on/off while transitioning from one row to the next + +#endif \ No newline at end of file From d332a17b2872a771479f3d2b7d8ebd5c909206a7 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sat, 17 Aug 2019 18:30:45 +0200 Subject: [PATCH 25/34] added ledmatrix footfall line diagram --- src/ledmatrixdisplay.cpp | 50 ++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/src/ledmatrixdisplay.cpp b/src/ledmatrixdisplay.cpp index 3cfe31f2..14e0008c 100644 --- a/src/ledmatrixdisplay.cpp +++ b/src/ledmatrixdisplay.cpp @@ -2,7 +2,8 @@ #include "globals.h" -#define NUMCHARS 5 +#define NUMROWS 16 +#define NUMCOLS 96 #define MATRIX_DISPLAY_PAGES (2) // number of display pages // local Tag for logging @@ -17,7 +18,7 @@ LEDMatrix matrix(LED_MATRIX_LA_74138, LED_MATRIX_LB_74138, LED_MATRIX_LC_74138, LED_MATRIX_LATCHPIN, LED_MATRIX_CLOCKPIN); // Display Buffer 128 = 64 * 16 / 8 -uint8_t displaybuf[LED_MATRIX_WIDTH * LED_MATRIX_HEIGHT / NUMCHARS]; +uint8_t displaybuf[LED_MATRIX_WIDTH * LED_MATRIX_HEIGHT / 8]; // --- SELECT YOUR FONT HERE --- const FONT_INFO *ActiveFontInfo = &digital7_18ptFontInfo; @@ -34,11 +35,11 @@ void init_matrix_display(bool reverse) { if (reverse) matrix.reverse(); matrix.clear(); - DrawNumber(String("0")); + matrix.drawPoint(0, NUMROWS - 1, 1); } // init_display void refreshTheMatrixDisplay(bool nextPage) { - static uint8_t DisplayPage = 0; + static uint8_t DisplayPage = 0, col = 0, row = 0; char buff[16]; // if Matrixdisplay is switched off we don't refresh it to relax cpu @@ -54,19 +55,48 @@ void refreshTheMatrixDisplay(bool nextPage) { DisplayPage = (DisplayPage >= MATRIX_DISPLAY_PAGES - 1) ? 0 : (DisplayPage + 1); matrix.clear(); + col = 0; } switch (DisplayPage % MATRIX_DISPLAY_PAGES) { - // page 0: pax - // page 1: time + // page 0: number of current pax OR footfall line diagram + // page 1: time of day case 0: - if (ulLastNumMacs != macs.size()) { - ulLastNumMacs = macs.size(); - matrix.clear(); - DrawNumber(String(ulLastNumMacs)); + if (cfg.countermode == 1) + + { // cumulative counter mode -> display total number of pax + if (ulLastNumMacs != macs.size()) { + ulLastNumMacs = macs.size(); + matrix.clear(); + DrawNumber(String(ulLastNumMacs)); + } + } + + else { // cyclic counter mode -> plot a line diagram + + if (ulLastNumMacs != macs.size()) { + + // next count cycle? + if (macs.size() == 0) { + col++; + // display full? + if (col >= NUMCOLS) { + col = 0; + matrix.clear(); + } + } else { + // clear previous dot + matrix.drawPoint(col, row, 0); + } + + // set current dot + ulLastNumMacs = macs.size(); + row = NUMROWS - 1 - (ulLastNumMacs / 2) % NUMROWS; + matrix.drawPoint(col, row, 1); + } } break; From 15b53596509e06a97e4d0c4f6af814aff920dd6e Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sat, 17 Aug 2019 18:31:45 +0200 Subject: [PATCH 26/34] platformio.ini: added tinypicomatrix --- platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio.ini b/platformio.ini index b35fa91e..2afbf626 100644 --- a/platformio.ini +++ b/platformio.ini @@ -29,6 +29,7 @@ halfile = generic.h ;halfile = wemos32matrix.h ;halfile = octopus32.h ;halfile = tinypico.h +;halfile = tinypicomatrix.h [platformio] ; upload firmware to board with usb cable From 77352b832e0fd8cfa4254d045e04baf3dd60ba1b Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sat, 17 Aug 2019 18:45:00 +0200 Subject: [PATCH 27/34] ledmatrix scale factor --- src/ledmatrixdisplay.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ledmatrixdisplay.cpp b/src/ledmatrixdisplay.cpp index 14e0008c..5c8fef39 100644 --- a/src/ledmatrixdisplay.cpp +++ b/src/ledmatrixdisplay.cpp @@ -5,6 +5,7 @@ #define NUMROWS 16 #define NUMCOLS 96 #define MATRIX_DISPLAY_PAGES (2) // number of display pages +#define LINE_DIAGRAM_DIVIDER (2) // scales pax numbers to led rows // local Tag for logging static const char TAG[] = __FILE__; @@ -94,7 +95,7 @@ void refreshTheMatrixDisplay(bool nextPage) { // set current dot ulLastNumMacs = macs.size(); - row = NUMROWS - 1 - (ulLastNumMacs / 2) % NUMROWS; + row = NUMROWS - 1 - ((ulLastNumMacs / LINE_DIAGRAM_DIVIDER) % NUMROWS); matrix.drawPoint(col, row, 1); } } From a4419ab6f08e830492eca28d2efdab9e0e4d49ed Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 18 Aug 2019 16:47:28 +0200 Subject: [PATCH 28/34] LED matrix scroll function added --- include/ledmatrixdisplay.h | 1 + src/ledmatrixdisplay.cpp | 39 +++++++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/include/ledmatrixdisplay.h b/include/ledmatrixdisplay.h index 9adfcd11..5c3dca0d 100644 --- a/include/ledmatrixdisplay.h +++ b/include/ledmatrixdisplay.h @@ -13,5 +13,6 @@ void refreshTheMatrixDisplay(bool nextPage = false); void DrawNumber(String strNum, uint8_t iDotPos = 0); uint8_t GetCharFromFont(char cChar); uint8_t GetCharWidth(char cChar); +void ShiftLeft(uint8_t *arr, uint32_t len); #endif \ No newline at end of file diff --git a/src/ledmatrixdisplay.cpp b/src/ledmatrixdisplay.cpp index 5c8fef39..b9af6ec5 100644 --- a/src/ledmatrixdisplay.cpp +++ b/src/ledmatrixdisplay.cpp @@ -14,13 +14,14 @@ uint8_t MatrixDisplayIsOn = 0; static unsigned long ulLastNumMacs = 0; static time_t ulLastTime = myTZ.toLocal(now()); +// Display Buffer 128 = 64 * 16 / 8 +static const uint32_t DisplaySize = LED_MATRIX_WIDTH * LED_MATRIX_HEIGHT / 8; +uint8_t displaybuf[DisplaySize] = {0}; + LEDMatrix matrix(LED_MATRIX_LA_74138, LED_MATRIX_LB_74138, LED_MATRIX_LC_74138, LED_MATRIX_LD_74138, LED_MATRIX_EN_74138, LED_MATRIX_DATA_R1, LED_MATRIX_LATCHPIN, LED_MATRIX_CLOCKPIN); -// Display Buffer 128 = 64 * 16 / 8 -uint8_t displaybuf[LED_MATRIX_WIDTH * LED_MATRIX_HEIGHT / 8]; - // --- SELECT YOUR FONT HERE --- const FONT_INFO *ActiveFontInfo = &digital7_18ptFontInfo; // const FONT_INFO *ActiveFontInfo = &arialNarrow_17ptFontInfo; @@ -41,6 +42,7 @@ void init_matrix_display(bool reverse) { void refreshTheMatrixDisplay(bool nextPage) { static uint8_t DisplayPage = 0, col = 0, row = 0; + uint8_t level; char buff[16]; // if Matrixdisplay is switched off we don't refresh it to relax cpu @@ -82,20 +84,20 @@ void refreshTheMatrixDisplay(bool nextPage) { // next count cycle? if (macs.size() == 0) { - col++; - // display full? - if (col >= NUMCOLS) { - col = 0; - matrix.clear(); - } - } else { - // clear previous dot - matrix.drawPoint(col, row, 0); - } - // set current dot + // matrix full? then scroll left 1 dot, else increment column + if (col < NUMCOLS - 1) + col++; + else + ShiftLeft(displaybuf, DisplaySize); + + } else + matrix.drawPoint(col, row, 0); // clear current dot + + // scale and set new dot ulLastNumMacs = macs.size(); - row = NUMROWS - 1 - ((ulLastNumMacs / LINE_DIAGRAM_DIVIDER) % NUMROWS); + level = ulLastNumMacs / LINE_DIAGRAM_DIVIDER; + row = level <= NUMROWS ? NUMROWS - 1 - level % NUMROWS : 0; matrix.drawPoint(col, row, 1); } } @@ -195,4 +197,11 @@ uint8_t GetCharWidth(char cChar) { return CharDescriptor.width; } +void ShiftLeft(uint8_t *arr, uint32_t len) { + uint32_t i; + for (i = 0; i < len - 1; ++i) { + arr[i] = (arr[i] << 1) | ((arr[i + 1] >> 31) & 1); + } + arr[len - 1] = arr[len - 1] << 1; +} #endif // HAS_MATRIX_DISPLAY \ No newline at end of file From 381286331f628621f60a41f0dfe6860922f18c2e Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 18 Aug 2019 16:55:43 +0200 Subject: [PATCH 29/34] LED matrix on/off added --- src/ledmatrixdisplay.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/ledmatrixdisplay.cpp b/src/ledmatrixdisplay.cpp index b9af6ec5..6c22fd23 100644 --- a/src/ledmatrixdisplay.cpp +++ b/src/ledmatrixdisplay.cpp @@ -34,6 +34,12 @@ const FONT_CHAR_INFO *ActiveFontCharInfo = ActiveFontInfo->Descriptors; void init_matrix_display(bool reverse) { ESP_LOGI(TAG, "Initializing LED Matrix display"); matrix.begin(displaybuf, LED_MATRIX_WIDTH, LED_MATRIX_HEIGHT); + + if (MatrixDisplayIsOn) + matrix.on(); + else + matrix.off(); + if (reverse) matrix.reverse(); matrix.clear(); @@ -52,6 +58,10 @@ void refreshTheMatrixDisplay(bool nextPage) { // set display on/off according to current device configuration if (MatrixDisplayIsOn != cfg.screenon) { MatrixDisplayIsOn = cfg.screenon; + if (MatrixDisplayIsOn) + matrix.on(); + else + matrix.off(); } if (nextPage) { From 1d8969f645361e60c5ef250358be6ee7b1edadb3 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 18 Aug 2019 16:58:29 +0200 Subject: [PATCH 30/34] ledmatrixdisplay.cpp code sanitizations --- src/ledmatrixdisplay.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/ledmatrixdisplay.cpp b/src/ledmatrixdisplay.cpp index 6c22fd23..a92f4cf9 100644 --- a/src/ledmatrixdisplay.cpp +++ b/src/ledmatrixdisplay.cpp @@ -10,14 +10,11 @@ // local Tag for logging static const char TAG[] = __FILE__; -uint8_t MatrixDisplayIsOn = 0; +static const uint32_t DisplaySize = LED_MATRIX_WIDTH * LED_MATRIX_HEIGHT / 8; +uint8_t MatrixDisplayIsOn = 0, displaybuf[DisplaySize] = {0}; static unsigned long ulLastNumMacs = 0; static time_t ulLastTime = myTZ.toLocal(now()); -// Display Buffer 128 = 64 * 16 / 8 -static const uint32_t DisplaySize = LED_MATRIX_WIDTH * LED_MATRIX_HEIGHT / 8; -uint8_t displaybuf[DisplaySize] = {0}; - LEDMatrix matrix(LED_MATRIX_LA_74138, LED_MATRIX_LB_74138, LED_MATRIX_LC_74138, LED_MATRIX_LD_74138, LED_MATRIX_EN_74138, LED_MATRIX_DATA_R1, LED_MATRIX_LATCHPIN, LED_MATRIX_CLOCKPIN); @@ -214,4 +211,5 @@ void ShiftLeft(uint8_t *arr, uint32_t len) { } arr[len - 1] = arr[len - 1] << 1; } + #endif // HAS_MATRIX_DISPLAY \ No newline at end of file From ba08662323e8615f573b3dadfbdae5e888b3a98b Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 18 Aug 2019 17:04:02 +0200 Subject: [PATCH 31/34] update LED matrix size --- README.md | 2 +- src/ledmatrixdisplay.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d8956b0a..c4993e5b 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Depending on board hardware following features are supported: - Real Time Clock (Maxim DS3231 I2C) - IF482 (serial) and DCF77 (gpio) time telegram generator - Switch external power / battery -- 64x16 pixel LED Matrix display (similar to [this model](https://www.instructables.com/id/64x16-RED-LED-Marquee/), can be ordered on [Aliexpress](https://www.aliexpress.com/item/P3-75-dot-matrix-led-module-3-75mm-high-clear-top1-for-text-display-304-60mm/32616683948.html)) +- LED Matrix display (similar to [this 64x16 model](https://www.instructables.com/id/64x16-RED-LED-Marquee/), can be ordered on [Aliexpress](https://www.aliexpress.com/item/P3-75-dot-matrix-led-module-3-75mm-high-clear-top1-for-text-display-304-60mm/32616683948.html)) Target platform must be selected in [platformio.ini](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/platformio.ini).
Hardware dependent settings (pinout etc.) are stored in board files in /hal directory. If you want to use a ESP32 board which is not yet supported, use hal file generic.h and tailor pin mappings to your needs. Pull requests for new boards welcome.
diff --git a/src/ledmatrixdisplay.cpp b/src/ledmatrixdisplay.cpp index a92f4cf9..c517fdf7 100644 --- a/src/ledmatrixdisplay.cpp +++ b/src/ledmatrixdisplay.cpp @@ -3,7 +3,7 @@ #include "globals.h" #define NUMROWS 16 -#define NUMCOLS 96 +#define NUMCOLS 64 #define MATRIX_DISPLAY_PAGES (2) // number of display pages #define LINE_DIAGRAM_DIVIDER (2) // scales pax numbers to led rows From c0692c38798ccaf72177ed3292b713def075147b Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 18 Aug 2019 17:44:42 +0200 Subject: [PATCH 32/34] gps initial time sync added --- src/gpsread.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 262daf0a..bcefd2a2 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -90,13 +90,12 @@ time_t fetch_gpsTime(uint16_t *msec) { // poll NMEA $GPZDA 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 - // wait for gps NMEA answer - //vTaskDelay(tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL)); - // did we get a current time? if (gpstime.isUpdated() && gpstime.isValid()) { @@ -104,7 +103,8 @@ time_t fetch_gpsTime(uint16_t *msec) { String rawtime = gpstime.value(); uint32_t time_bcd = rawtime.toFloat() * 100; - uint32_t delay_ms = gpstime.age() + nmea_txDelay_ms + NMEA_COMPENSATION_FACTOR; + uint32_t delay_ms = + gpstime.age() + nmea_txDelay_ms + NMEA_COMPENSATION_FACTOR; uint8_t year = CalendarYrToTm(gps.date.year()); // year offset from 1970 in microTime.h From 1de9a0bcd2b4e127a8ea15508b6c25277cd545d8 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 18 Aug 2019 17:45:16 +0200 Subject: [PATCH 33/34] remove arduino loop task --- src/main.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 976ad625..087bf867 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -427,12 +427,10 @@ void setup() { #warning you did not specify a time source, time will not be synched #endif -/* // initialize gps time #if (HAS_GPS) fetch_gpsTime(); #endif -*/ #if (defined HAS_IF482 || defined HAS_DCF77) ESP_LOGI(TAG, "Starting Clock Controller..."); @@ -452,15 +450,8 @@ void setup() { // show compiled features ESP_LOGI(TAG, "Features:%s", features); + vTaskDelete(NULL); + } // setup() -void loop() { - - while (1) { -#if (HAS_LORA) - os_runloop_once(); // execute lmic scheduled jobs and events -#else - delay(2); // yield to CPU -#endif - } -} +void loop() { vTaskDelete(NULL); } From 0a970f3dcf095061e160ca9086efc85f29bbb6e1 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Sun, 18 Aug 2019 17:46:10 +0200 Subject: [PATCH 34/34] v1.7.93 --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 2afbf626..33c863ce 100644 --- a/platformio.ini +++ b/platformio.ini @@ -42,7 +42,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 = 1.7.92 +release_version = 1.7.93 ; 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