Merge pull request #259 from cyberman54/development

v1.7.41
This commit is contained in:
Verkehrsrot 2019-01-29 00:08:58 +01:00 committed by GitHub
commit a3286ada2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 90 additions and 82 deletions

View File

@ -17,7 +17,6 @@
#endif
void doHousekeeping(void);
void do_timesync(void);
uint64_t uptime(void);
void reset_counters(void);
int redirect_log(const char *fmt, va_list args);

View File

@ -15,5 +15,6 @@ extern TaskHandle_t GpsTask;
int gps_init(void);
void gps_read(void);
void gps_loop(void *pvParameters);
time_t get_gpstime(void);
#endif

View File

@ -30,7 +30,7 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng
[common]
; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
release_version = 1.7.14
release_version = 1.7.141
; 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

View File

@ -7,8 +7,8 @@
// Local logging tag
static const char TAG[] = "main";
uint32_t userUTCTime; // Seconds since the UTC epoch
unsigned long nextTimeSync = millis();
time_t userUTCTime; // Seconds since the UTC epoch
unsigned long nextLoraTimeSync = millis();
// do all housekeeping
void doHousekeeping() {
@ -23,12 +23,14 @@ void doHousekeeping() {
spi_housekeeping();
lora_housekeeping();
// time sync once per TIME_SYNC_INTERVAL
#ifdef TIME_SYNC_INTERVAL
if (millis() >= nextTimeSync) {
nextTimeSync =
millis() + TIME_SYNC_INTERVAL * 60000; // set up next time sync period
do_timesync();
// do cyclic time sync with LORA network
#ifdef TIME_SYNC_INTERVAL_LORA
if (millis() >= nextLoraTimeSync) {
nextLoraTimeSync = millis() + TIME_SYNC_INTERVAL_LORA *
60000; // set up next time sync period
// Schedule a network time sync request at the next possible time
LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime);
ESP_LOGI(TAG, "LORAWAN time request scheduled");
}
#endif
@ -120,37 +122,6 @@ void reset_counters() {
macs_ble = 0;
}
void do_timesync() {
#ifdef TIME_SYNC_INTERVAL
// set system time to time source GPS, if we have valid gps time
#ifdef HAS_GPS
if (gps.time.isValid()) {
setTime(gps.time.hour(), gps.time.minute(), gps.time.second(),
gps.date.day(), gps.date.month(), gps.date.year());
// set RTC time to time source GPS, if RTC is present
#ifdef HAS_RTC
if (!set_rtctime(RtcDateTime(now())))
ESP_LOGE(TAG, "RTC set time failure");
#endif
time_t tt = myTZ.toLocal(now());
ESP_LOGI(TAG, "GPS has set system time to %02d/%02d/%d %02d:%02d:%02d",
month(tt), day(tt), year(tt), hour(tt), minute(tt), second(tt));
return;
} else {
ESP_LOGI(TAG, "No valid GPS time");
}
// set system time to time source LoRa Network, if network supports DevTimeReq
#elif defined LMIC_ENABLE_DeviceTimeReq
// Schedule a network time sync request at the next possible time
LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime);
ESP_LOGI(TAG, "Network time request scheduled");
#endif // HAS_GPS
#endif // TIME_SYNC_INTERVAL
} // do_timesync()
#ifndef VERBOSE
int redirect_log(const char *fmt, va_list args) {
// do nothing

View File

@ -53,6 +53,32 @@ void gps_read() {
gps.passedChecksum(), gps.failedChecksum(), gps.sentencesWithFix());
}
// helper function to convert gps date/time into time_t
time_t tmConvert_t(uint16_t YYYY, uint8_t MM, uint8_t DD, uint8_t hh,
uint8_t mm, uint8_t ss) {
tmElements_t tm;
tm.Year = YYYY - 1970; // note year argument is offset from 1970 in time.h
tm.Month = MM;
tm.Day = DD;
tm.Hour = hh;
tm.Minute = mm;
tm.Second = ss;
return makeTime(tm);
}
// function to fetch current time from gps
time_t get_gpstime(void) {
// never call now() in this function, this would cause a recursion!
time_t t = 0;
if (gps.time.age() < 1500) {
t = tmConvert_t(gps.date.year(), gps.date.month(), gps.date.day(),
gps.time.hour(), gps.time.minute(), gps.time.second());
} else {
ESP_LOGW(TAG, "GPS has no confident time");
}
return t;
} // get_gpstime()
// GPS serial feed FreeRTos Task
void gps_loop(void *pvParameters) {

View File

@ -41,7 +41,7 @@
#define BOARD_HAS_PSRAM // use extra 4MB extern RAM
#define HAS_GPS 1 // use if board has GPS
#define GPS_SERIAL 9600, SERIAL_8N1, GPIO_NUM_12, GPIO_NUM_15 // UBlox NEO 6M or 7M with default configuration
#define GPS_SERIAL 9600, SERIAL_8N1, GPIO_NUM_17, GPIO_NUM_16 // UBlox NEO 6M or 7M with default configuration
// Pins for I2C interface of OLED Display
#define MY_OLED_SDA (4)
@ -50,6 +50,10 @@
// Pins for on board DS3231 RTC chip
#define HAS_RTC MY_OLED_SDA, MY_OLED_SCL // SDA, SCL
#define RTC_INT GPIO_NUM_34 // interrupt input from rtc
// Settings for IF482 interface
#define HAS_IF482 9600, SERIAL_7E1, GPIO_NUM_12, GPIO_NUM_14 // IF482 serial port parameters
// Pins for LORA chip SPI interface, reset line and interrupt lines
#define LORA_SCK (5)

View File

@ -1,7 +1,19 @@
#if defined HAS_IF482 && defined HAS_RTC
/*
/* NOTE:
The IF482 Generator needs an high precise 1 Hz clock signal which cannot be
acquired in suitable precision on the ESP32 SoC itself. Additional clocking
hardware is required, ususally the clock signal is generated by external RTC or
GPS chip or a GPS chip which can generate a precise clock signal (+/- 2ppm). In
this example code we use a Maxim DS3231 RTC chip, and configure it's interrupt
output as clock output. The clock signal triggers an interrupt on the ESP32,
which controls the realtime output of IF482 telegram. This is why code in
IF482.cpp depends on code in RTCTIME.cpp.
*/
///////////////////////////////////////////////////////////////////////////////
/*
IF482 Generator to control clocks with IF482 telegram input (e.g. BÜRK BU190)
Example IF482 telegram: "OAL160806F170400"
@ -63,6 +75,7 @@ L: Local Time
not evaluated by model BU-190
*/
///////////////////////////////////////////////////////////////////////////////
#include "if482.h"
@ -79,7 +92,7 @@ int if482_init(void) {
// open serial interface
IF482.begin(HAS_IF482);
// use rtc 1Hz clock for triggering IF482 telegram send
// use external rtc 1Hz clock for triggering IF482 telegram
Rtc.SetSquareWavePinClockFrequency(DS3231SquareWaveClock_1Hz);
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeClock);
pinMode(RTC_INT, INPUT_PULLUP);
@ -124,7 +137,7 @@ void if482_loop(void *pvParameters) {
time_t t, tt;
const TickType_t shotTime = pdMS_TO_TICKS(IF482_OFFSET);
// wait until begin of a new second
// wait until begin of a new second to sync clock signal and absolute time
t = tt = now();
do {
tt = now();
@ -146,7 +159,7 @@ void if482_loop(void *pvParameters) {
// now we're synced to start of second t and wait
// until it's time to start transmit telegram for t+1
vTaskDelayUntil(&wakeTime, shotTime);
IF482.print(if482Telegram(t+1));
IF482.print(if482Telegram(t + 1));
}
vTaskDelete(IF482Task); // shoud never be reached
} // if482_loop()

View File

@ -192,7 +192,13 @@ void setup() {
#ifdef HAS_RTC
strcat_P(features, " RTC");
assert(rtc_init());
sync_rtctime();
setSyncProvider(&get_rtctime);
if (timeStatus() != timeSet)
ESP_LOGI(TAG, "Unable to sync system time with RTC");
else
ESP_LOGI(TAG, "RTC has set the system time");
setSyncInterval(TIME_SYNC_INTERVAL_RTC);
#ifdef HAS_IF482
strcat_P(features, " IF482");
assert(if482_init());
@ -205,6 +211,7 @@ void setup() {
&IF482Task, // task handle
0); // CPU core
#endif // HAS_IF482
#endif // HAS_RTC
// initialize wifi antenna
@ -416,6 +423,15 @@ void setup() {
#endif
#endif // HAS_BUTTON
#ifdef HAS_GPS
setSyncProvider(&get_gpstime);
if (timeStatus() != timeSet)
ESP_LOGI(TAG, "Unable to sync system time with GPS");
else
ESP_LOGI(TAG, "GPS has set the system time");
setSyncInterval(TIME_SYNC_INTERVAL_GPS);
#endif
// start RTC interrupt
#if defined HAS_IF482 && defined HAS_RTC
// setup external interupt for active low RTC INT pin

View File

@ -82,9 +82,11 @@
#define RESPONSE_TIMEOUT_MS 60000 // firmware binary server connection timeout [milliseconds]
// settings for syncing time of node and external time sources
#define TIME_SYNC_INTERVAL 60 // sync time each ... minutes with external source [default = 60], comment out means off
#define TIME_SYNC_INTERVAL_GPS 5 // sync time each ... minutes with GPS [default = 5], comment out means off
#define TIME_SYNC_INTERVAL_RTC 5 // sync time each ... minutes with RTC [default = 5], comment out means off
//#define TIME_SYNC_INTERVAL_LORA 60 // sync time each ... minutes with LORA network [default = 60], comment out means off
#define IF482_OFFSET 984 // 1sec minus IF482 serial transmit time [ms]: e.g. 9 bits * 17 bytes * 1/9600 bps = 16ms
// time zone, see https://github.com/JChristensen/Timezone/blob/master/examples/WorldClock/WorldClock.ino
#define DAYLIGHT_TIME {"CEST", Last, Sun, Mar, 2, 120} // Central European Summer Time
#define STANDARD_TIME {"CET ", Last, Sun, Oct, 3, 60} // Central European Standard Time

View File

@ -57,11 +57,11 @@ error:
} // rtc_init()
int set_rtctime(uint32_t UTCTime) {
int set_rtctime(uint32_t t) {
// return = 0 -> error / return = 1 -> success
// block i2c bus access
if (I2C_MUTEX_LOCK()) {
Rtc.SetDateTime(RtcDateTime(UTCTime));
Rtc.SetDateTime(RtcDateTime(t));
I2C_MUTEX_UNLOCK(); // release i2c bus access
return 1;
}
@ -81,44 +81,20 @@ int set_rtctime(RtcDateTime t) {
time_t get_rtctime(void) {
// never call now() in this function, this would cause a recursion!
time_t tt = 0;
time_t t = 0;
// block i2c bus access
if (I2C_MUTEX_LOCK()) {
if (!Rtc.IsDateTimeValid()) {
ESP_LOGW(TAG, "RTC has no confident time");
if (Rtc.IsDateTimeValid()) {
RtcDateTime tt = Rtc.GetDateTime();
t = tt.Epoch32Time();
} else {
RtcDateTime t = Rtc.GetDateTime();
tt = t.Epoch32Time();
ESP_LOGW(TAG, "RTC has no confident time");
}
I2C_MUTEX_UNLOCK(); // release i2c bus access
return tt;
}
return tt;
return t;
} // get_rtctime()
void sync_rtctime(void) {
if (timeStatus() != timeSet) { // do we need time sync?
time_t t = get_rtctime();
if (t) { // have we got a valid time from RTC?
setTime(t);
time_t tt = myTZ.toLocal(t);
ESP_LOGI(TAG, "RTC has set system time to %02d/%02d/%d %02d:%02d:%02d",
month(tt), day(tt), year(tt), hour(tt), minute(tt), second(tt));
} else
ESP_LOGW(TAG, "System time was not synced");
}
#ifdef TIME_SYNC_INTERVAL_RTC
setSyncProvider(&get_rtctime); // does not sync if callback function returns 0
if (timeStatus() != timeSet)
ESP_LOGI("Unable to sync with the RTC");
else
ESP_LOGI("RTC has set the system time");
setSyncInterval(TIME_SYNC_INTERVAL_RTC);
#endif
} // sync_rtctime;
float get_rtctemp(void) {
// block i2c bus access
if (I2C_MUTEX_LOCK()) {
@ -127,6 +103,6 @@ float get_rtctemp(void) {
return temp.AsFloatDegC();
} // while
return 0;
} // get_rtc()
} // get_rtctemp()
#endif // HAS_RTC