I am working on developing a synchronized mesh network of low power sensors. I am trying to maintain an average power consumption of 100's of µW while still broadcasting data about once every 5 minutes and going to sleep. To be able to realize this I need some high-resolution (<10µs) time synchronization which will be updated frequently. For now I am starting with a single-hop time-sync protocol which I will later expand, but I need a foundation. I'm using an nrf52840 with the S140 soft device.SDK v16.0.0MESH v3.2.0
What I want to do:
I am attempting to write a piece of firmware such that I can:
What I think I should do:
From my investigation into the problem I have been convinced that I need to use the timeslot api to be able to send a ble packet with reliable time-delay. In order to minimize the time delay and also in interest of consistency, I wish to use the Radio HAL api to be able to trigger a tx task on an event. Before I can send this message as a mesh message I need to construct my message with the relevant metadata (destination address, source address, TTL, keys, etc.) Then I should encrypt the message (assuming no segmentation is needed) and then use this encrypted payload as my tx-data for my manual radio transmission.
HELP!I found this blog post, which has greatly helped me understand what must go into a good time-sync protocol in the case of BLE, but I am having great difficulty figuring out how to translate it usefully to Mesh. I'm not sure how my choice of bearer (ADV) affects the formatting of the message, or how I should go about encrypting my payload. I am not an experienced developer, and have even less experience in BT/Mesh but I am determined to finding a solution. I would also like advise on improving my approach to solving this problem.
Your requirements: Mesh + 100's of µW + 5 minutes sleep + <10µs time synchronization isn't viable.
Have you considered using low power nodes in a mesh network? You still need mesh nodes that use more power, but you can have low power nodes that connect to some of these normal mesh nodes.
The blog post you refer to is intended for "normal" BLE. It is no walk in the park, but it is possible to synchronize the clocks. However, remember that in a normal BLE connection, the devices sync their timing every connection interval. The clocks will probably drift more than 10µs in 5 minutes. And if a node runs out of battery, and is turned back on, how will it sync with the rest of the network?
I think you should concider using LPN (low power nodes) in a regular mesh network.
Thank you for your input Edvin. I recognize that this is not the typical intended application of BT Mesh. However, we have run the analysis and done the math and it is certainly possible to make this work.
I am aware of the clock drift over time. Timing windows can be expanded to compensate, and the clocks will be resynced with each interaction. The BLE post got a minimum agreement of 1 hfclk cycle (10s of ns) so our desire for <10µs is not only viable, but conservative. Obviously we have considered using LPN nodes. The core Mesh specification does not meet our needs but provides a robust message-passing framework. Many synchronized mesh protocols exist which accomplish exactly what we are attempting, however nordic chips do not support these networks. At this time we will not be reconsidering our product or our approach. If you have advice on how I should go about achieving my goals in the "What I Want to Do" section I would be very grateful.
Send this message only as single-hop (TTL = 1)
Not a problem. This can be configured in the project, inside the mesh model that you are using. You can look at e.g. the access_default_ttl_set() function.
Take advantage of mesh features like encryption, opcodes, and addressing (virtual, group, etc..)
Be able to capture the hf-clock value at this message's time of arrival on receiving end
You can, but you must experiment with the time it takes from the packet is sent until you get the event in the application.
Send hf-clock value right when I capture it (or with reliable delay)
You must look at the proprietary method described in the blog post that you link to.
Again, this is not straight forward. I wouldn't say it is impossible, but there is probably some work to be done, in order to sync the clocks with the accuracy that you need. BLE itself is not ideal for time synchronization, because you can't know from the application whether the message was relayed or not. It probably isn't any easier in Mesh, which is why you need to use the proprietary timeslot_api described in the guide to send the timestamps.
I understand all of this. My issue is with implementation. For example, how can I send a mesh message reliably using time slots? Either
The reason why the mesh stack makes this a bit tricky is because once you do this, it is no longer a valid mesh stack, meaning you will not get it certified. You can try to use the API in the mesh SDK to create the messages and send them, but as I have said, it isn't straight forward to do what you are describing.
It may be easier to use the radio without the softdevice, but then you will have to read up on how the provisioning is done, and how the messages are encrypted using the keys.
Question: Are your devices going to be communicating with other mesh certified devices? Or are there only your own devices? Because if it is only your devices, perhaps the Mesh stack isn't the correct approach at all. Maybe something completely proprietary is the easiest solution.
Marciano-PL said:For example, how can I send a mesh message reliably using time slots?
If you are going to have reliable messages, you need some form of ACK. That will require you to use the radio for longer intervals. The key behind mesh is that all the messages are flooding the network. This takes time, but it is also the mechanism ensuring that the loss of a packet is extremely unlikely. If one of the messages are lost, then the chance of the rest of the relayed messages being lost is very small.
So if you want to have reliable messages, I would suggest that you try to disable the stack, and go to sleep with the radio off. Then when your time has passed (5 minutes), turn all of the nodes back on. If they are provisioned then they should start up quite quickly. Send whatever messages you need to send. Remember that you don't have a lot of payload throughput. Wait for the messages to propagate the network, and turn them back off.
What sort of data are you going to send by the way? You probably need to send one empty packet (or a short packet) to sync up the clocks, even if the other devices doesn't have any payload data to send. Unless the clocks of the devices will drift over time.
I have made progress towards reaching my goal. So far, I am only sending the LFCLK value + number of overflows in an unsegmented message. I have created some infrastructure to do all of the encrypting, and loading with metadata. The devices will be resyncing once every 5 minutes or so. My current issue is that the mesh stack takes possession of the softdevices timeslot api so I cannot give it my own handler without disabling the mesh. Unfortunately none of the functions for disabling the mesh seem to actually do what they are meant to. I have another support case open on those issues. https://devzone.nordicsemi.com/f/nordic-q-a/57450/reliably-disabling-mesh-stack-quickly-for-low-power
Did you get the answers to your questions in the other ticket?
Hello Edvin,Thanks for checking in! Yes, I discovered what the actual issue was and got some helpful advice along the way.Best,Marciano
I've opened a new ticket for the specific issue I'm running into now.I have written the code to capture a time and package it up like a mesh message but for the timing to be reliable I need this to happen once the timeslot is open. This is an issue because the Softdevice prevents usage of the ECB during operation. How else might I send my message in a deterministic time profile?devzone.nordicsemi.com/.../sd_ecb_block_encrypt-results-in-hardfault