Accurate UDP sync for NTP enabled instances
This commit is contained in:
parent
7cbc9d21b5
commit
bfc7f56c4d
@ -1,6 +1,7 @@
|
||||
#ifndef TFTS_H
|
||||
#define TFTS_H
|
||||
|
||||
#include "wled.h"
|
||||
#include <FS.h>
|
||||
|
||||
#include <TFT_eSPI.h>
|
||||
@ -92,9 +93,10 @@ private:
|
||||
uint16_t padding = (4 - ((w * 3) & 3)) & 3;
|
||||
uint8_t lineBuffer[w * 3 + padding];
|
||||
|
||||
uint8_t serviceStrip = (!realtimeMode || realtimeOverride) ? 7 : 0;
|
||||
// row is decremented as the BMP image is drawn bottom up
|
||||
for (row = h-1; row >= 0; row--) {
|
||||
if (row & 0b00000111 == 7) strip.service(); //still refresh backlight to mitigate stutter every few rows
|
||||
if ((row & 0b00000111) == serviceStrip) strip.service(); //still refresh backlight to mitigate stutter every few rows
|
||||
bmpFS.read(lineBuffer, sizeof(lineBuffer));
|
||||
uint8_t* bptr = lineBuffer;
|
||||
|
||||
|
@ -42,30 +42,24 @@ uint16_t WS2812FX::mode_static(void) {
|
||||
* Blink/strobe function
|
||||
* Alternate between color1 and color2
|
||||
* if(strobe == true) then create a strobe effect
|
||||
* NOTE: Maybe re-rework without timer
|
||||
*/
|
||||
uint16_t WS2812FX::blink(uint32_t color1, uint32_t color2, bool strobe, bool do_palette) {
|
||||
uint16_t stateTime = SEGENV.aux1;
|
||||
uint32_t cycleTime = (255 - SEGMENT.speed)*20;
|
||||
uint32_t onTime = 0;
|
||||
uint32_t offTime = cycleTime;
|
||||
uint32_t onTime = FRAMETIME;
|
||||
if (!strobe) onTime += ((cycleTime * SEGMENT.intensity) >> 8);
|
||||
cycleTime += FRAMETIME*2;
|
||||
uint32_t it = now / cycleTime;
|
||||
uint32_t rem = now % cycleTime;
|
||||
|
||||
if (!strobe) {
|
||||
onTime = (cycleTime * SEGMENT.intensity) >> 8;
|
||||
offTime = cycleTime - onTime;
|
||||
bool on = false;
|
||||
if (it != SEGENV.step //new iteration, force on state for one frame, even if set time is too brief
|
||||
|| rem <= onTime) {
|
||||
on = true;
|
||||
}
|
||||
|
||||
stateTime = ((SEGENV.aux0 & 1) == 0) ? onTime : offTime;
|
||||
stateTime += 20;
|
||||
SEGENV.step = it; //save previous iteration
|
||||
|
||||
if (now - SEGENV.step > stateTime)
|
||||
{
|
||||
SEGENV.aux0++;
|
||||
SEGENV.aux1 = stateTime;
|
||||
SEGENV.step = now;
|
||||
}
|
||||
|
||||
uint32_t color = ((SEGENV.aux0 & 1) == 0) ? color1 : color2;
|
||||
uint32_t color = on ? color1 : color2;
|
||||
if (color == color1 && do_palette)
|
||||
{
|
||||
for(uint16_t i = 0; i < SEGLEN; i++) {
|
||||
|
@ -75,7 +75,7 @@
|
||||
#define SEGENV _segment_runtimes[_segment_index]
|
||||
#define SEGLEN _virtualSegmentLength
|
||||
#define SEGACT SEGMENT.stop
|
||||
#define SPEED_FORMULA_L 5 + (50*(255 - SEGMENT.speed))/SEGLEN
|
||||
#define SPEED_FORMULA_L 5U + (50U*(255U - SEGMENT.speed))/SEGLEN
|
||||
#define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes))
|
||||
|
||||
// some common colors
|
||||
|
@ -6,6 +6,7 @@
|
||||
* Acquires time from NTP server
|
||||
*/
|
||||
//#define WLED_DEBUG_NTP
|
||||
#define NTP_SYNC_INTERVAL 42000UL //Get fresh NTP time about twice per day
|
||||
|
||||
Timezone* tz;
|
||||
|
||||
@ -143,6 +144,10 @@ void handleTime() {
|
||||
|
||||
if (toki.isTick()) //true only in the first loop after a new second started
|
||||
{
|
||||
#ifdef WLED_DEBUG_NTP
|
||||
Serial.print(F("TICK! "));
|
||||
toki.printTime(toki.getTime());
|
||||
#endif
|
||||
updateLocalTime();
|
||||
checkTimers();
|
||||
checkCountdown();
|
||||
@ -152,7 +157,7 @@ void handleTime() {
|
||||
|
||||
void handleNetworkTime()
|
||||
{
|
||||
if (ntpEnabled && ntpConnected && millis() - ntpLastSyncTime > 50000000L && WLED_CONNECTED)
|
||||
if (ntpEnabled && ntpConnected && millis() - ntpLastSyncTime > (1000*NTP_SYNC_INTERVAL) && WLED_CONNECTED)
|
||||
{
|
||||
if (millis() - ntpPacketSentTime > 10000)
|
||||
{
|
||||
|
@ -103,16 +103,25 @@ class Toki {
|
||||
return unix;
|
||||
}
|
||||
|
||||
uint32_t msDifference(Time &t0, Time &t1) {
|
||||
//gets the absolute difference between two timestamps in milliseconds
|
||||
uint32_t msDifference(const Time &t0, const Time &t1) {
|
||||
bool t1BiggerSec = (t1.sec > t0.sec);
|
||||
uint32_t secDiff = (t1BiggerSec) ? t1.sec - t0.sec : t0.sec - t1.sec;
|
||||
uint32_t t0ms = t0.ms, t1ms = t1.ms;
|
||||
if (t1BiggerSec) t1ms += secDiff;
|
||||
else t0ms += secDiff;
|
||||
if (t1BiggerSec) t1ms += secDiff*1000;
|
||||
else t0ms += secDiff*1000;
|
||||
uint32_t msDiff = (t1ms > t0ms) ? t1ms - t0ms : t0ms - t1ms;
|
||||
return msDiff;
|
||||
}
|
||||
|
||||
//return true if t1 is later than t0
|
||||
bool isLater(const Time &t0, const Time &t1) {
|
||||
if (t1.sec > t0.sec) return true;
|
||||
if (t1.sec < t0.sec) return false;
|
||||
if (t1.ms > t0.ms) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void adjust(Time&t, int32_t offset) {
|
||||
int32_t secs = offset /1000;
|
||||
int32_t ms = offset - secs*1000;
|
||||
@ -139,7 +148,7 @@ class Toki {
|
||||
}
|
||||
|
||||
void resetTick() {
|
||||
tick = TickT::inactive;
|
||||
if (tick == TickT::active) tick = TickT::inactive;
|
||||
}
|
||||
|
||||
bool isTick() {
|
||||
|
@ -245,6 +245,7 @@ void handleNotifications()
|
||||
}
|
||||
}
|
||||
|
||||
bool timebaseUpdated = false;
|
||||
//apply effects from notification
|
||||
if (version < 200 && (receiveNotificationEffects || !someSel))
|
||||
{
|
||||
@ -258,21 +259,32 @@ void handleNotifications()
|
||||
t += PRESUMED_NETWORK_DELAY; //adjust trivially for network delay
|
||||
t -= millis();
|
||||
strip.timebase = t;
|
||||
timebaseUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
//adjust system time, but only if sender is more accurate than self
|
||||
if (version > 7 && udpIn[29] > toki.getTimeSource())
|
||||
if (version > 7)
|
||||
{
|
||||
Toki::Time tm;
|
||||
tm.sec = (udpIn[30] << 24) | (udpIn[31] << 16) | (udpIn[32] << 8) | (udpIn[33]);
|
||||
tm.ms = (udpIn[34] << 8) | (udpIn[35]);
|
||||
if (udpIn[29] > toki.getTimeSource()) { //if sender's time source is more accurate
|
||||
toki.adjust(tm, PRESUMED_NETWORK_DELAY); //adjust trivially for network delay
|
||||
uint8_t ts = TOKI_TS_UDP;
|
||||
if (udpIn[29] > 99) ts = TOKI_TS_UDP_NTP;
|
||||
else if (udpIn[29] >= TOKI_TS_SEC) ts = TOKI_TS_UDP_SEC;
|
||||
toki.setTime(tm, ts);
|
||||
//TODO: even receive this if own time source is better, to offset network delay from timebase
|
||||
} else if (timebaseUpdated && toki.getTimeSource() > 99) { //if we both have good times, get a more accurate timebase
|
||||
Toki::Time myTime = toki.getTime();
|
||||
uint32_t diff = toki.msDifference(tm, myTime);
|
||||
strip.timebase -= PRESUMED_NETWORK_DELAY; //no need to presume, use difference between NTP times at send and receive points
|
||||
if (toki.isLater(tm, myTime)) {
|
||||
strip.timebase += diff;
|
||||
} else {
|
||||
strip.timebase -= diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (version > 3)
|
||||
|
Loading…
Reference in New Issue
Block a user