Czy wolisz polską wersję strony elektroda?
Nie, dziękuję Przekieruj mnie tamp.kaczmarek2 wrote:Probably store deltas and collect them in quick tick...
max4elektroda wrote:Using this for now - working on W800, will test with others soon ...
Code: text Expand Select all Copy to clipboarddiff --git a/src/user_main.c b/src/user_main.c
index a0ea6322..dbee5483 100644
--- a/src/user_main.c
+++ b/src/user_main.c
@@ -583,6 +583,11 @@ float g_wifi_temperature = 0;
static byte g_secondsSpentInLowMemoryWarning = 0;
void Main_OnEverySecond()
{
+#if PLATFORM_W600 || PLATFORM_W800
+#define TimeOut_t xTimeOutType
+#endif
+ TimeOut_t myTimeout; // to get uptime from xTicks
+
int newMQTTState;
const char* safe;
int i;
@@ -754,8 +759,9 @@ void Main_OnEverySecond()
}
}
}
-
- g_secondsElapsed++;
+// g_secondsElapsed++;
+ vTaskSetTimeOutState( &myTimeout );
+ g_secondsElapsed = (int)((((uint64_t) myTimeout.xOverflowCount << (sizeof(portTickType)*8) | myTimeout.xTimeOnEntering)*portTICK_RATE_MS ) / 1000 );
if (bSafeMode) {
safe = "[SAFE] ";
}
p.kaczmarek2 wrote:- be called twice with the same g_secondsElapsed value
- skip g_secondsElapsed values
.../OpenBeken/main/OpenBK7231T_App$ find src/ -name "*.[ch]" | xargs grep g_secondsElapsed
src/httpserver/new_http.c: hprintf255(request, "<br>Online for <span id=\"onlineFor\" data-initial=\"%i\">-</span>", g_secondsElapsed);
src/httpserver/json_interface.c: format_time(g_secondsElapsed, buff, sizeof(buff));
src/httpserver/json_interface.c: JSON_PrintKeyValue_Int(request, printer, "UptimeSec", g_secondsElapsed, true);
src/httpserver/json_interface.c: JSON_PrintKeyValue_Int(request, printer, "Uptime", g_secondsElapsed, true);
src/httpserver/json_interface.c: if (NTP_GetCurrentTimeWithoutOffset() > g_secondsElapsed) { // would be negative else, leading to unwanted results when converted to (unsigned) time_t
src/httpserver/json_interface.c: ntpTime = (time_t)NTP_GetCurrentTimeWithoutOffset() - (time_t)g_secondsElapsed;
src/httpserver/rest_interface.c: hprintf255(request, "{\"uptime_s\":%d,", g_secondsElapsed);
src/driver/drv_ds1820_full.c: // if (dsread == 1 && g_secondsElapsed % 5 == 2) {
src/driver/drv_ds1820_full.c: float t_float = 20.0 + i/10.0 + (float)(g_secondsElapsed%100)/100.0;
src/driver/drv_ds1820_full.c: lastconv = g_secondsElapsed;
src/driver/drv_ds1820_full.c: lastconv = g_secondsElapsed;
src/driver/drv_ds1820_full.c: if(dsread == 0 && (g_secondsElapsed % ds18_conversionPeriod == 0 || lastconv == 0))
src/driver/drv_dht_internal.c: uint32_t currenttime = g_secondsElapsed;
src/driver/drv_tm_gn_display_shared.c: segments[i] = g_digits[(g_secondsElapsed + i) % 10];
src/driver/drv_tm_gn_display_shared.c: segments[i] = g_digits[(g_secondsElapsed + i) % 10];
src/driver/drv_bl_shared.c: cJSON_AddNumberToObject(root, "uptime", g_secondsElapsed);
src/driver/drv_ntp.c: if (g_secondsElapsed < 60) {
src/driver/drv_ds1820_simple.c: hprintf255(request, "<h5>DS1820 Temperature: %.2f C (read %i secs ago)</h5>", (float)t / 100, g_secondsElapsed - lastconv);
src/driver/drv_ds1820_simple.c: // if (dsread == 1 && g_secondsElapsed % 5 == 2) {
src/driver/drv_ds1820_simple.c: lastconv = g_secondsElapsed;
src/driver/drv_ds1820_simple.c: if(g_secondsElapsed % ds18_conversionPeriod == 0 || lastconv == 0) //dsread == 0
src/mqtt/new_mqtt.c: sprintf(dataStr, "%d", g_secondsElapsed);
src/new_common.h:extern int g_secondsElapsed;
src/cmnds/cmd_if.c: return g_secondsElapsed;
src/cmnds/cmd_test.c: cJSON_AddNumberToObject(root, "uptime", g_secondsElapsed);
src/user_main.c:int g_secondsElapsed = 0;
src/user_main.c: if(g_secondsElapsed < 30)
src/user_main.c: if (g_secondsElapsed < 30) {
src/user_main.c: if (g_timeSinceLastPingReply != -1 && g_secondsElapsed > 60)
src/user_main.c: g_secondsElapsed++;
src/user_main.c: safe, g_secondsElapsed, idleCount, xPortGetFreeHeapSize(), bMQTTconnected,
src/user_main.c: safe, g_secondsElapsed, idleCount, xPortGetFreeHeapSize(),g_bHasWiFiConnected, g_timeSinceLastPingReply, LWIP_GetActiveSockets(), LWIP_GetMaxSockets(),
src/user_main.c: if (!(g_secondsElapsed % 10))
src/user_main.c: if (g_secondsElapsed > bootCompleteSeconds)
src/user_main.c: if (g_secondsElapsed < 5)
src/hal/w800/hal_main_w800.c: //actually starts shifting g_secondsElapsed. To compensate, we are checking how much
p.kaczmarek2 wrote:Seems to crash on ESP32 for me?
TL;DR: With 1–2 seconds/day drift after switching to RTOS-tick-based uptime, the thread’s core advice is: "split clock from NTP" and keep a local OpenBeken clock from startup time plus corrected elapsed seconds. This helps OpenBeken users who need offline energy stats, local scheduling, or RTC integration without internet or NTP. [#21031093]
Why it matters: A separable device clock lets OpenBeken keep usable time in AP mode, offline LANs, and future RTC-based builds, while reducing dependence on always-on internet time.
| Approach | Internet required | Reported accuracy in thread | Best fit | Main limitation |
|---|---|---|---|---|
| Local clock from startup + corrected uptime | No | about 1–2 s/day | daily energy totals, basic schedules | loses time after power loss |
| NTP-based clock | Yes, at least for sync | network-synced | precise schedules, sunrise/sunset | needs reachable time source |
| DS3231 RTC | No | about 1 minute/year | remote installs, outages, offline switching | needs extra hardware and space |
Key insight: The breakthrough was not “manual time entry” alone. It was replacing naive
g_secondsElapsed++timing with RTOS-tick-derived uptime, then separating generic clock functions from the NTP protocol layer. [#21031093]
#define ENABLE_DRIVER_DS3231 1. [#21865147]g_secondsElapsed; the improved version recalculated elapsed time from RTOS ticks every 10 seconds. That lets the clock run in AP mode and without any network. It is accurate enough for daily energy totals, even when exact wall-clock precision is unnecessary. [#21031093]g_secondsElapsed drifts because a simple one-second increment is not equally accurate on all SDKs and platforms. The fix is to derive uptime from RTOS ticks, including platform-specific tick-to-millisecond factors such as portTICK_RATE_MS or a ratio of 2 on some Beken and WinnerMicro targets. That change fixed slow clocks on BK7231N, BK7231T, W600, and W800, and brought reported drift down to about 1–2 seconds per day. [#21046836]g_secondsElapsed is OpenBeken’s uptime counter, used for status displays, JSON output, driver timing, and offline clock math. "g_secondsElapsed is an uptime counter that tracks seconds since boot, a core timing value reused for status pages, sensor intervals, and local timekeeping when combined with a saved start time." The local-clock approach turns uptime into wall time by adding a stored startup epoch. [#21036229]drv_ntp.c into a separate clock layer, then leave only protocol-specific sync logic in NTP. In the thread, this meant adding files such as drv_deviceclock.c and renaming event logic toward drv_clock_events.c, while keeping feature flags optional in obk_config.h. That design also makes sunrise, DST, manual clock setting, and future RTC sources usable without forcing the NTP driver to own all time functions. [#21031093]ENABLE_LOCAL_CLOCK 1; optionally set ENABLE_LOCAL_CLOCK_ADVANCED 1 for DST support. 2. Rebuild and flash, because the feature was submitted disabled by default. 3. Confirm that the config page shows a browser-time clock option and that status output reports time. The thread used ENABLE_LOCAL_CLOCK for basic clocking and ENABLE_LOCAL_CLOCK_ADVANCED for DST, with the advanced flag requiring the basic one. [#21032907]2; on W600 and W800, portTICK_RATE_MS also equaled 2. After changing the uptime calculation to multiply xTaskGetTickCount() by the correct tick period, the slow-clock behavior was reported fixed across those platforms. [#21039505]STATUS 8, or send HTTP requests to read or set time remotely. The thread showed a shell example using wget against /cm?cmnd=STATUS%208, returning JSON with "StatusSNS":{"Time":"2024-04-07T15:05:09"}. That makes drift testing easy: poll the device at intervals and compare its reported time with a known-good router or Linux host clock. [#21036320]DST.bin was also proposed as a scalable middle ground for per-zone data without hardcoding every rule into firmware. [#21036097]DST.bin and read it as a float array or fetch values as needed. That would let users upload zone-specific DST data separately, instead of recompiling for each timezone. [#21036097]startdriver DS3231 <CLK-Pin> <DATA-Pin> <optional sync>. 2. Use sync 1 to set device time from RTC at startup or 2 to refresh device time regularly. 3. Set RTC time with DS3231_SetEpoch <epoch> or a Linux request such as wget "http://<ip>/cmd_tool?cmd=DS3231_SetEpoch $(date +%s)". The thread also listed DS3231_GetTime and DS3231_GetEpoch. [#21633562]