NordicPlayground / nRF51-ble-bcast-mesh

Other
323 stars 121 forks source link

Time Synchronization Advice Needed #92

Open glenne opened 8 years ago

glenne commented 8 years ago

I have an application where I need nodes in a mesh to activate a gpio simultaneously at a designated future time. I'm hoping for a skew less than 1ms.

The technique used with IEEE1588 Precision Time Protocol is to have a 'master' node send out periodic sync messages with the current time which are then used by the slaves to calibrate their internal clocks. A PI loop is used to average out errors due to tx and rx jitter. The better the tx transmit time and rx time is known, the better the ultimate synchronization. In practice, the master sends two messages, one is an initial sync message and the 2nd is a followup message that has the exact time the prior message was timestamped by the hardware. The followup message is used because most implementations cannot send a precise transmit time in the same message that is being timestamped without dedicated mac hardware support.

In the mesh I'm hoping to do the following:

This leads to two questions:

  1. What is the best way to timestamp the actual transmit time of a master sync slot update?
  2. What is the best way to timestamp the arrival time of a master sync slot update?
trond-snekvik commented 8 years ago

Hey, that's a pretty cool application!

All transmits in the OpenMesh appear at random time intervals. This puts it in the category of implementations that need a follow up message. The timestamps can be implemented in a lot of ways, depending on the required accuracy. A target of 10ms accuracy gives the devices plenty of time to process messages, and propagate them through the stack. The delay from radio RX-time to application-event is 0.5-5.5ms. The jitter from radio TX to application-event is similar. If you want better accuracy, I'm afraid you have to dive into the framework code. Adding this functionality to get microsecond precision isn't very difficult, but it requires some alterations to the radio code.

To timestamp the events, I suggest using the RTC1-clock, which has 30us accuracy. Its counter is only 24 bits, so you will have to handle frequent rollovers. RTC1 is not used by the Mesh or Softdevice, so you should have it all to yourself. The current value of the RTC1-clock can be read from NRF_RTC1->COUNTER at any time. You of course need to clear and start the RTC when you start your application. NRF_TIMER1 has even better granularity (1/16th of a microsecond!), but its interface is a bit harder to use.

If you want to get the microsecond accuracy, I suggest you set up a PPI channel from the NRF_RADIO->EVENTS_ADDRESS, which occurs when the radio detects the RX/TX of the access address at the beginning of every packet. Connect the other end of this PPI channel to one of the NRF_RTC1->TASK_CAPTURE[..] tasks, enable the channel, and you'll be able to read out the RTC-timestamp in the radio-interrupt handler, then propagate it however you want. I think the rest is straight forward (except perhaps the PI, but that's separate from the mesh :)).

Both the RTC1, TIMER1 and PPI modules have example projects in the nRF SDK which should help you get started, but feel free to ask Mesh specific questions here, and hardware-specific questions on the DevZone, and me or someone from the Nordic support team will help you out :)

glenne commented 8 years ago

Thanks for the detailed response and pointer on how to get good resolution on the timestamps. I've also updated my question to change from 10ms to 1ms (a typo) but it sounds like that is still very doable with the PPI channel approach. Being able to capture the radio tx/rx so well is a plus I wasn't expecting.

daviddedwin commented 8 years ago

Update: To assist the Time Sync all the received packets will be timestamped. The transmited packets will get the timestamp in the RBC_MESH_EVENT_TYPE_TX event. The accuracy of the timestamp will be the accuracy of the LF(32KHz) clock source. We will roll this out in the next iterative release.

oldrich-s commented 8 years ago

Wow great! I "hacked" my own timestamp but looking forward to the official one ;) . BTW: How will the timestamps influence the amount of data that can be transmitted by a single packet? Now it is 23 bytes if I remember correctly. My timestamps take 2 bytes but I can imagine that a general timestamp can take 4 bytes, right?

And the most important question, when will the next release be available? :)

EDIT: BTW Where do you get the time for timespamp from? I have a common point in time in the mesh (where all sensor measurements occur) and then I measure ticks from that event but would be interesting to know how you solve that ;)

olsky commented 8 years ago

@daviddedwin much appreciated!

as far as I understand your update, the struct rbc_mesh_event_t will get a timestamp field, and will be set by the framework on RX/TX events. Right?

trond-snekvik commented 8 years ago

@olsky got it right. We don't intend to enforce a timestamp field in every packet, as it won't add value to most use cases. The timestamp will be present in the rbc_mesh_event_t, both in RX and TX events. This should make the protocol @glenne talks about much easier to implement, as all the data you need will be propagated by the stack.

We hope to add native global time in a later release, as a service similar to the DFU.

olsky commented 8 years ago

@trond-snekvik global time... coooool! :)

bootchk commented 7 years ago

In IEEE 1588 a 'master' clock server is 'elected' using a ' Best Master Clock' algorithm. But I think it assumes the network is alway on, i.e. that all nodes receive all transmissions (at least in a wire segment). In an RF mesh where nodes are sleeping often (not listening, to save power) and wake up at the same time according to a global clock, how do you initially establish the global clock e.g. elect the master? I suppose instead you could statically define the ID of the master clock server, or assume enough power to listen for a long time on startup?

I just began reading this repository and papers about clock synch algorithms; maybe this question does not apply. Maybe the trickle algorithm helps the problem of electing the master clock server even tolerating network faults?

peterson79 commented 6 years ago

@daviddedwin Did the packet timestamps get implemented into the current release? Just read the post again, @trond-snekvik did "global time" get implemented into the current release? Any info appreciated! Thanks!