2

I want to make two devices synchronize metronome over bluetooth/wifi. However I've got no idea how to make it perfectly synchronized. There are two possible solutions that I've found out:

  • Naive -> Send start command to other device then start metronome after fixed time (30ms or so)
  • Measure mean delay between devices and start master device after timeout

I also thought about Atomic Clock API but I find it to be an overkill.

Any ideas?

2

Perfection isn't possible. But you can probably get pretty close basing your synchronization on ntp's time synchronization strategy.

Basically, you can designate a master, have the client send a packet, including send time, have the server copy that to a response packet, also recording it's receive time, and time of response. The client issues sync requests until it's satisfied that it's seeing reasonably consistent latency measures, and then adjusts its clock.

More or less.

And then it's just a matter of having one or the other take responsibility for setting start and stop times. And deciding how critical it is that the other app not miss the first beat. (Versus delaying start time to account for network congestion.) E.g., start 70bpm, effective at time. If time is in the past when the slave receives the message, just compute the rate and when the next beat must occur.

1

There will definitely have to be some sort of mutual delay measurement going on as part of any robust solution. You can also never get perfect synchronization, since clocks can drift apart in addition to starting off slow or fast, and the network performance may be schizophrenic enough to defeat any precise measurement, so aim for a margin of error like 100ms or 50ms.

Some things I can think of which might help:

  • Send timestamps with each packet. The devices' clocks won't be in perfect sync, but knowing when the other device thinks everything happened can make it easier to work out the mean delay.

  • Designate one device to be the "authoritative server" with regards to metronome status, and have the two devices continue pinging each other after initial sync so the "client" device can correct itself if it drifts away over time.

  • Have both devices measure the mean delay, then check if they agree with each other, then have them "test" that value by sending a start signal and checking if they receive pings from each other at the times and with the timestamps they were expecting.

  • Try asking an external source for the time, hoping the delay from it to both devices will be similar. This StackOverflow thread suggests GPS and NIST.

The "correct" answer will have to be determined through experimentation. Depending on the nature of your app, you may even want some "manual sync" options for when the network just isn't cooperating.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.