Is it possible to sync Bangle.js 2 time to smartphone time?

Posted on
of 5
  • Every time you connect to the watch time is set by that website.

    ... as long as "Always update time when we connect" is not switched off, like on my PC (I did not do this).

    I reset my GPS chip to factory settings with


    and still got a time within a second.
    I think as long as there is a satelite in view, it will also find the time.

    ... or the AT6558R has a RTC inside that's not affected by a reset to factory settings and only loses time with a flat battery.

  • I may be misunderstanding, but does the time it takes to get a connection really matter? Surely you connect first, then check and send the accurate time. The time to check and send is the only bit that matters, isn't it?

  • I don't think it matters (except for maybe power usage). But the problem was that the "check and send the accurate time" takes 90-100 ms usually and occasionally up to 300 ms, i.e. it's not accurate at all.

  • it may be related to negotiated connection interval, also in BLE this can be done via subscribing to notification, not reading. when you subscribe the other end sends data when it makes sense (temperature changes, in this case seconds value changes) and you just receive it without request

  • If anyone else is using Raspberry Pi as time source, note that by default new Debian 11 -based image uses awful systemd-timesyncd which can make Raspberry Pi have 10x worse clock drift than Bangle.js 2.

    You can install chrony for far better time syncing.

  • Now that that is fixed I'm finally starting to get stable clock drift measurements. Current code can measure Bangle.js 2 clock drift in just 5 minutes somewhat accurately, usually giving 61-69 ppm for me, with occasional worse values.

    Basic idea:

    • Raspberry Pi broadcasts time once per second with microsecond resolution.
    • Bangle.js 2 scans for time broadcasts in bursts, getting 4-5 time-deltas in one burst.
      • Largest time-delta is discarded and average of the rest is taken.
    • Clock drift is calculated from two time-delta-averages separated by 5 minutes.
  • [from another thread]
    The question is now how to get the watch to use Apple's Time Service to adopt the iOS time at specified intervals. The information I see is some years old or requires a developer's knowledge.

    Needs a UUID? NRF input? A little more code?

    Can someone here help?

  • It may be possible to use the JS ANCS code from @jeffmer as a base.­lob/3e0d263ceaa7f3dd3bdec29fd95822e52f91­3aba/apps/widancs/ancs.js#L106

    Now ANCS is implemented in Espruino, most of the work is done internally and it's just the bit I highlighed you need. It'll need modifying to use Apple's time service UUID, as well as a few other changes.

    It's going to be a decent size job though.

  • Actually, I have a bit of code that sets the Bangle time using the iPhone Time service. However, I did it as a quick hack from the original ANCS app and it is a bit clumsy as you must first be paired with the iPhone and the routine then disconnects and reconnects so that it can create the needed GATT service. The code is here if you would like to try it.
    @Gordon - There must be an easier way of creating the GATT service since all the information must already be held internally? I am sure I am missing something obvious!

  • @jeffmer I notice you've got a getGattforCentralServer in there. Did you ever implement that in your own server?

    Right now as I know the JS implementation of Bluetooth Central can only deal with one connection, which is handled with a global m_central_connection variable. As a quick hack I guess we could set that to the same as m_peripheral_connection with a function, but the best solution would be to store the handle in the BluetoothGattServer structure and then we could interface with >1 central device at the same time

  • @Gordon Yes, I have the function implemented in my Bangle firmware, however, getting time does work if it is not defined. It is a bit frustrating as actually its not dealing with >1 central device, as you are connecting back to to the iPhone you are already connected to for ANCS. If you could get the address of the iPhone you are connected to then something like getGattforCentralServer would let you get the time without disconnecting and reconnecting.

  • I can only confirm that the Android/Gadgetbridge TimeSync after connect works like a charm.
    Personally, for me, it doesn't matter if the time difference is e.g. 5s per day.

    1. I don't use a clock with seconds active
    2. The clock reconnects 10 times during day and resync time (because the mobile lays somewhere on desk and i leave the BT radius -> resynced time after within raduis again)
    3. If I would need to know the exact time I took a look at the mobile or some other ntp time-synced device
  • @jeffmer
    Thanks for that help. I'm not a programmer, so don't understand much of your discussion with Gordon. I've placed your code before the code for my watchface, loaded the lot onto my watch, then cut that connection and paired with my iPhone. If something different or more needs to be done, just let me know.

    The left side of the IDE delivers these apparently non-fatal messages on loading your code with mine:
    WARNING: SD ERR 0x11 (BUSY) (:1803)
    WARNING: SD ERR 0x11 (BUSY) (:650)

    Anyhow, how often (at what interval) does your code make the watch's time the same as the iPhone's time?

    (I'll see how the experiment's gone in 12 hours.)

  • The code synchronises time once when you invoke
    setTimefromPhone. I have not seen those errors before but they look like they are coming from the Soft Device which is the Nordic Bluetooth code.

  • Just a note that on the cutting edge firmwares I added a field to NRF.getSecurityStatus which tells you the currently connected device's address, which should make things easier @jeffmer :)

  • @jeffmer
    As expected, what I did makes no difference. I assume that I have to call setTimefromPhone in my code and make sure nothing interferes with that. I have my own font size, colour, etc., and I'll have to see whether my determination of the time interferes or may preferably be overridden by yours. (Someone else wrote my code but has left the project.)

    If your code synchronizes only once, is there an easy way to get it to do that 4 or 24 times a day, for example? Just call the function at the desired times?

    I'd be grateful for any further advice, including whether Gordon's update changes what I may or need to do.

  • An easy and universal way to make regular updates is to create a widget that will sort of a backgroung job. It will get data from a time server and set the watch RTC. Then any watchface will get the correct time.
    Probably you do not have to even to create it. As DDDanny wrote
    that the Android/Gadgetbridge TimeSync after connect works like a charm.
    Some people here is working on a connectionless (ads based) way of time synchronizing with jitter < 10ms. Is it what you need?

  • ... the Android/Gadgetbridge TimeSync after connect works like a charm.

    no, that is awful: clock error can be over 3 seconds after Gadgetbridge sync

  • @Mark_M
    Like some other people here, I'm interested in whatever will work with an iPhone. (Android and Gadgetbridge are not possibilities.)

    Some people here is working on a connectionless (ads based) way of time synchronizing with jitter < 10ms.

    Which devices will provide the synchronization?

  • Which devices will provide the synchronization?

    Using Bluetooth LE ads should in theory work on any device which can send those ads. However I only have example code for Linux (tested in Debian 11 and Raspberry Pi OS) as I don't know how to use Bluetooth LE on other devices.

  • Thanks Gordon, I will see what happens if I use that instead of disconnecting and reconnecting.

    @Numerist Better to wait to see how this works out as it would make the operation much more lightweight.

  • This is a fun project, now I'm trying to implement temperature-corrected clock drift. :)

    This graph shows clock drift on my Bangle.js 2 in PPM in different temperatures (Celcius).

    1 Attachment

    • clock-drift-in-ppm-by-temperature.png
  • Cool!
    This function can be applied if there is no time service available, no GPS, no BT, no GadgetBridge.

    Also does it show the watch RTC oscillator is not T compensated (not TCXO)?

  • This is really interesting! Guess it will vary somewhat from watch to watch?

    On a tangentially related note, I was looking at the two temperature sensors earlier (barometer and internal temperature sensor), and I was surprised that they read pretty much the same. I don't know why I have in my head that another component might have a temperature sensor built in but not exposed... I might be misremembering something though.

  • @Mark_M

    Also does it show the watch RTC oscillator is not T compensated (not TCXO)?

    yep, TCXO would be much more stable over temperature range.


    This is really interesting! Guess it will vary somewhat from watch to watch?

    Most likely, and this article says that crystals have aging effect so it also depends on watch age.

    ... two temperature sensors earlier (barometer and internal temperature sensor) ...

    What internal temperature sensor ?

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

Is it possible to sync Bangle.js 2 time to smartphone time?

Posted by Avatar for malaire @malaire