ESP-Now BATMAN time sync

One of the things I really liked about PainlessMesh was it had a built in time protocol that synced across all the nodes. If you're building a mesh of interacting things then having them share a common clock is useful.

The PainlessMesh developers have gone the whole hog and implemented an NTP inspired protocol taking into account latency and jitter of communication between nodes. While I don't have the enthusiasm to do this, I have come up with a simple clock syncing option that seems to work fine at low mesh sizes.

I was already sharing uptime information across the mesh so my very simple scheme is as follows...

  • The node with the highest uptime is considered the time server.
  • All other nodes work out their offset from this figure as NHS packets come in.
  • There's then a function that returns this calculated 'mesh time'.
  • If the clocks drift then every NHS packet from the time server tweaks it back into line.
  • If the time server goes away, the node with the next highest uptime takes over, faking its own uptime to be what it understands 'mesh time' to be.
  • If the previous time server comes back the current time server stops.
This simplistic approach seems to be working just fine so far and the sum of all clock drift corrections over several hours is in the tens of milliseconds. Which means it really doesn't need to sync very often.

The nodes aren't perfectly in sync down to the millisecond (mostly because ESP-Now iterates through sending packets to its peers) but nobody is going to notice in real use. This is entirely about making events happen in sequence on human timeframes. It doesn't need to be more accurate to achieve this.

I've done a little video demo of it syncing up.


No comments: