• Hello,
    I'm trying to get Espruino to store a timestamp in Storage, and the read from it on boot and set the current time accordingly. This is the salient code:

    var TimeController = {
      currentTimeFilename: "currentTime",
      writeCurrentTime: function() {
        var currentTime = Number(new Date(Date.now()).getTime() / 1000);
        Storage.writeJSON(this.currentTimeFilena­me, {
          "timestamp": currentTime,
        });
      },
      readCurrentTime: function() {
        var currentTime = Storage.readJSON(this.currentTimeFilenam­e, true);
         if (currentTime) {
           setTime(currentTime.timestamp);
        }
      },
    };
    
    E.on('init', function() {
      clearInterval();
      clearTimeout();
      clearWatch();
      TimeController.readCurrentTime();
      setInterval(() => {
        TimeController.writeCurrentTime();
      }, 30000);
    });
    
    save();
    

    However, when the code executes the first time after Espruino is plugged into power (not PC), all of the intervals fire incredibly rapidly (similarly to issue described here). Removing all instances of setTime remedies this. Not sure what kind of conflict is occurring there, any help would be appreciated!

  • Hi - which board are you running the code on?

    The STM32-based boards run a high res timer which they adjust to match the RTC, to allow for high resolution timing. I guess it's possible that if you adjust time time during the initial calibration phase, it's possible it might confuse it.

    When the timers fire rapidly, does it go back to normal after some time? And what about if you call TimeController.readCurrentTime maybe 10 seconds after boot? Does it work then?

  • Hello,

    I'm running the original Espruino board, latest revision.
    As far as I could tell, rapid firing would continue indefinitely, though I usually wouldn't wait that long.
    Didn't know about the calibration phase, anywhere I could read up on that? Delaying the code execution by 10 seconds did indeed solve the issue, thank you.

  • Ok, great - I just filed an issue at https://github.com/espruino/Espruino/iss­ues/2005 so hopefully we can get that fixed at some point.

    There's no specific documentation on the calibration phase as far as I remember, but basically:

    The real time clock only runs at 32kHz, which means if you're trying to measure pulse widths, you'll bump into problems with accuracy pretty quickly... So we use the 'System Tick' timer which runs at the same speed as the processor - but we want the two to keep in sync (neither is 100% accurate).

    There's some code which keeps track of how many System Ticks there are for each tick of the RTC, so that when you ask for the time it can look at the system time and work back to a high res value, but in RTC time. It just takes a few seconds to figure out exactly what that should be...

  • @Levon, I suggest the following:

    1) Remove the clearXyz(...) in E.onInit().
    2) Remove the save() from your code you upload.

    Optional (in addition to above):
    a) make a named function out of the anonymous function in E.on(...), for exaple: function initTimeControl() { ... }
    b) drop the E.on("init",...); alltogether
    c) add a simple onInit(){ ... } function, in which you call as 'first order of business' initTimeControl();.

    TL;DR:

    Assuming you use the upload function in the the IDE to get (all) the code (in post #1) onto the board, this happens:

    You are connected and upload the the code (into the RAM). Because you have save() as last statement, the code is saved (into FLASH). Because save() includes as last item to run the saved code, the code is (reloaded into RAM and) executed all to the end, including the save()... you get the point.

    I assume further, that you tried to fix this issue by adding all these clearXyz(...)... to no avail, because that messes even more with things, last but not leas because you added in an E.on("init",...). At first this looks like a good idea, butE.on(...)is position dependent: the sequence of encounter ofE.on(...)on upload will also be the sequence of execution at runtime. By pulling in modules that may also have "E.on(...)", you have no real control over the execution sequence and theseclearXYZ(...)``` may destroy things you just established or even Espruino in its firmware has established before even your code runs.

    You may read this post and then the whole conversation further this TL;DR: simple explanation how to save code that Espruino run on start? Even though some aspects have changed since this conversation took place, it points out the major difference between Espruino IoT platform and others, such as Arduino,...

  • Thanks you @Gordon, @allObjects

  • @Gordon

    After some additional testing, it seems that making any setInterval() calls within that calibration period will throw it off. I have some fairly innocuous code firing within 50ms intervals, and before removing it, I noticed a significant time drift (about 1 minute per hour).

  • @Gordon, that has obviously nothing to do with save or not top save. Also others have in the past complained about time inaccuracy. Many timers are usually started soon after power on. Since any interval / timeout messes with the calibration phase, it would be interesting to know how long that calibration phase lasts. For practically all applications it is good enough to start the related timers (time marks) after that calibration phase.

    A change in the firmware is required, because any other software controlled delay messes with that calibration.

    Sacrificing a pin, adding an RC and not repeatedly watching that pin could be used to created such a delay with current firmware. The raising could though be so slow that the time until the watch fires has great variance, and a short brown out has also an impact.

  • @Levon please could you post up a complete example that shows the problem of setInterval messing with the clocks?

    The calibration should take around 2 seconds I believe. Originally we used to delay execution of JS until everything had settled down but there were complaints about that, so now we just get started immediately.

    I'm pretty sure that actually setting a timeout/interval during the calibration phase won't mess everything up, as those never touch the system time (just read it). However during those initial few seconds, they may fire faster/slower than usual.

    Clock drift is tricky - @Levon which version of Original board do you have? I think the original boards didn't have a low speed oscillator crystal (part X3). Also if you're using pin C15 I believe that can stop the external oscillator from working.

    Because Espruino tries to use the RTC as a base, if there is no external oscillator installed/working then it'll use the internal RC oscillator, which really isn't that accurate and would cause the time drift

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Combination of setInterval and setTime rapid fires all intervals

Posted by Avatar for Levon @Levon

Actions