Receive data from BLE advertising devices and publish them

Hello guys,

Let me try to describe my system before I ask you for your opinion…
I am using Particle Boron 2G/3G as a gateway device. The Boron should collect data from BLE-based (nRF52832) sensor nodes around and publish them to the cloud. Every sensor node is most of the time in deep-sleep mode, without any activity. Few times par day, on the pressure of a button, sensor node should wake up, and send a few bytes of data to the gateway in BLE advertisement mode. As I already explained, Particle boron should publish the data from the sensor node as soon as they are received. There will be a few (5-10) sensor nodes around one single Particle Boron gateway.

The system seems to be simple but I see a few challenges here.

  1. How to be 100% sure that Boron gateway will properly receive BLE advertising messages from all sensor nodes no matter the moment in time they wake up and advertise. Consequently, Boron board should be continuously scanning (being in BLE observer mode).

  2. Being in BLE advertisement mode, sensor node periodically sends advertisement messages (BLE advertising interval can be from 20ms to 10.24s) for some time defined by BLE advertisement duration parameter.

NOTE: My sensor nodes are powered with the coin-cell batteries so I am interested to advertise as short as possible!

I want to be able to publish sensor data only ONCE per BLE advertising from the sensor node, even though my Boron gateway receives a few consecutive (and same) BLE advertising messages from the same sensor node.

I was able to analyze code examples concerning BLE scanning that I found on this forum (e.g. here). The code comprises the following steps:

a) define scan Timeout interval (with BLE.scanTimeout(X) function).

b) start scan process with BLE.scan() function. scanResults array will be populated with the elements of BleScanResult type. Each element in scanResults array is actually one BLE device found during the scan time. We can go through the scanResults array and do whatever we want (e.g. extract MANUFACTURER_SPECIFIC_DATA only from specific BLE devices). Once we extract desired data, we can publish them with Particle.publish() method.

c) wait for some time

d) go to step a)

The above BLE scan approach seems to be reasonable. I was able to implement it and publish some data. However, I see two challenges here:

  1. How can I make sure I don’t miss BLE advertisement messages from the sensor nodes that will advertise while I am in the process of publishing data from other sensor nodes (in a for loop after BLE.scan)? In that sense, I should not have any delay between two BLE.scan executions (no step c).
  2. However, when I remove delay between two BLE.scan executions, I receive multiple advertisement messages from the same sensor node and, consequently, publish multiple data to the cloud instead of only one. The solution would be that I block publishing data from the single node for some time after I publish first BLE advertisement packet received but I am not sure how to implement it given the fact that I can have a few different nodes.

Do you have any suggestion for me how to avoid missing the data from the sensor node as well as how to avoid publishing too much?

I thought one solution could be to implement a kind of handshaking communication protocol here:

  1. Sensor node broadcasts BLE advertisement packages
  2. Boron observer receives BLE advertisement data and sends scan request message to the node
  3. Once the node receives scan request message, it replies with scan response message and goes to the sleep (stops advertising)
  4. Once Boron receives scan response message, it publish the data to the cloud.

What do you think about it? How can I send scan request message form the Particle Boron?

Thank you very much, guys, for your time and effort! It is really appreciated.

Sincerely,
Bojan.

Welcome to the community. Since this post appears to be a BLE related issue could you please categorise under BLE? Also, the challenges referred to at the end aren’t there!

Hi @armor, thanks for your warm welcoming. :upside_down_face:

I moved the question under BLE category and added the challenges I am facing with given the fact that the question was uploaded earlier than I wanted (after unintentionally pressing ctrl + enter keys).
Any suggestion/advice is welcome!

Cheers,
Bojan.

How „smart“ are those sensor-nodes and do you have control over what they advertise?
Maybe these nodes can generate some kind of ID of their advertisement so the gateway knows that the message has already been processed. You could also use that ID to publish a message from the gateway to let your sensors know it got the message and they can sleep knowing their message has been processed (adds some time awake but I guess that’s the only way making sure the gateway got the message), otherwise they could publish it again within some time. Can’t the nodes just connect normally and the gateway publishes the values on disconnect of the node’s connection? :thinking:

1 Like

Hey, @glx!

I am designing those sensors so they can be as smart as I am able to implement! :slight_smile:

Yes, I have control over what the sensor nodes are advertising. It is the ID of the node (4 Bytes) + 2 protection Bytes + 3 Bytes of useful data (1 status Byte + 2 Bytes for battery voltage). So 4 + 2 + 3 = 9 Bytes of data are advertised. Here is how the Particle cloud looks like after I published a few consecutive BLE advertising messages from my sensor node. Sensor ID is embedded into the name of publishing variable whereas 3 Bytes of data (1 status Byte + 2 Bytes of battery voltage) are merged and published withing the DATA field of the variable.

For ID of the node I am reading DEVICEID[0] register of nRF52832 SoC. It is not 100% unique but there are 1/(2^32) chances that I will have two sensor nodes with the same ID in my network (more details here)!

There is one possibility, as you suggest, that I establish BLE connection, disconnect and publish data. On the sensor node side, I would go to sleep mode after disconnection knowing that the advertising message is properly received and published. This is for sure one of the possibility but I thought to save some more power and just exchange scan request/scan response messages without establishing BLE connection because, to the best of my understanding, this will take some more of the so precious battery juice! :tropical_drink:

Is it possible to send BLE scan request message form the Particle Boron side? If negative, I would need to connect/disconnect as you suggested!

Sincerely,
Bojan.

I honestly don’t have deeper knowledge of BLE but in general there’s not really a way to make an unidirectional broadcasted message-protocol reliable. To make sure the broadcasted BLE-message was received, you would have to put the node in listening mode to receive a message back from the gateway, I think that’s not worth the effort (also I don’t see a time-saving compared to just establish a connection, I didn’t measure it but thinking of transmitting two broadcast-messages “doesn’t sound” any faster).
Also I personally don’t like the idea that in theory everyone could also listen to your unencrypted data and even manipulate it. But that depends on the environment.
If you want to do it that way anyway I’d do something like a checksum at the end of each message and broadcast it twice in a short amount of time, so the gateway can be quite sure this is the message he already got if he receives both, after some time the checksum could be deleted (if you maybe just wanna use two bytes or so) :thinking:

Bojan - suggest you remove the device ID and serial number from the image you posted and in future - it is not good for the security of your devices!

2 Likes

Thanks for the suggestion, @armor!