espruino / EspruinoAppLoaderCore

Core code used for Bangle.js and Espruino app loaders
MIT License
9 stars 18 forks source link

setTime() on BangleJs 2 accuracy #46

Closed nxdefiant closed 1 year ago

nxdefiant commented 1 year ago

When using Comms.setTime() for my Bangle.Js 2 e.g. from the app loader "Set Bangle.js Time" button under Utilities the time set lags behind nearly a second. I believe accounting for the round trip time would increase the accuracy, this could be done with e.g.

--- a/js/comms.js
+++ b/js/comms.js
@@ -356,9 +356,13 @@ const Comms = {
     we end up with a delay dependent on how long it took
     to open the device chooser. */
     return Comms.write("\x03").then(() => {
+      var t1 = performance.now();
+      Promise.resolve(Comms.write("\nsetTime((new Date()).getTime()/1000)\n")); // noop that includes the execution time of setTime()
+      var t2 = performance.now();
+      const delta = (t2-t1)/2.0;
       let d = new Date();
       let tz = d.getTimezoneOffset()/-60
-      let cmd = '\x10setTime('+(d.getTime()/1000)+');';
+      let cmd = '\x10setTime('+(d.getTime()/1000 + delta)+');';
       // in 1v93 we have timezones too
       cmd += 'E.setTimeZone('+tz+');';
       cmd += "(s=>{s&&(s.timezone="+tz+")&&require('Storage').write('setting.json',s);})(require('Storage').readJSON('setting.json',1))\n";

On my setup the delta is about 0.6 seconds. What do you think?

gfwilliams commented 1 year ago

I'm afraid this doesn't work for several reasons...

This should provide a slightly more accurate estimate:

var t=performance.now();Puck.write("print('hello')\n", function() { console.log("delay", performance.now()-t,"ms"); }, true)

And if you run it when the Bangle connected, you'll see there's usually about a 20ms delay, which is about what you'd expect (7.5ms connection interval, plus a bit of overhead).

So basically it would seem to be setting the time just fine.

How were you measuring the difference in time that was set?

This code will measure the difference (ignoring the connection interval):

var t = Date.now();console.log("PC", t);Puck.eval("Date.now()", function(e) {console.log("Bangle", e); console.log("Diff", e-t);})
PC 1674204044674
undefined
Bangle 1674204044658.5474
Diff -15.45263671875

Initially I saw a difference of ~170ms which was due to the connection interval being low to save power, but after doing it a few times it sped up and I saw the above - so 15ms difference - but much of that could be from the connection delay, so the actual difference is probably under 10ms.

So I think this is a non-issue. If the clocks are showing the time a little out then that's probably because they use setInterval(1000) which isn't guaranteed to update on the second exactly