Protocol how-to

I'm trying to write code for some sensor nodes that use nrf24l01+ to transmit values to a gateway, but I'm having some issues getting the code the way I want it.

I can easily use a struct to define a hardcoded set of data that I send to the gateway, but that requires that the gw also uses the exact same struct, which makes it a bit harder as I expand the sensor network.

I want to define what is sent dynamically (ie, the node self-discovers available sensors and sends only those values, or the node ignores faulty sensor values and do not send them). I also want to be able to add a new node with a new type of sensor (ie, add a new data type) without upgrading all the other nodes.

I've tried googling to find a suitable protocol and/or example code I could use, but I have so far not been able to find anything usable. But sensor nodes aren't exactly breaking new ground, so there's gotta be someone who has written something like this before, right?

Is the protocol/code I'm looking for out there?

Is the goal to minimize the number of characters sent over the air? If not, use a verbose protocol. Send every possible value but if that particular sensor is not installed on that node, send X in place of the value.

Have a field to identify what kind of sensor it is, and some data fields or block of data as a byte array. The meaning of each number in the data would be dependent on the type of sensor. Then the receiver would look at the sensor type and look up what kind of sensor it is and thus what the fields mean. Thus only the receiver would need to be updated (and that's a reasonable thing to update, right?)

Almost all the capabilities you mention could be contained in structs. In fact, they would be very useful to you for defining your data fields. Your problem is just that you have multiple data structures and they may have different lengths. That can be achieved by mapping byte vectors to different structs. You could easily begin each payload with a type identifier that tells the receiver which data format to apply. I'm basically repeating reply #2, but emphasizing that you can and probably should still use structs. You can accomplish that with unions or pointers.

MorganS:
Is the goal to minimize the number of characters sent over the air? If not, use a verbose protocol. Send every possible value but if that particular sensor is not installed on that node, send X in place of the value.

I’m not trying to reduce the number of characters purely out of optimization madness, but trying to stay within the boundaries of one packet (32 bytes) even with a wide array of sensors. The power usage is more important, since some of the sensors will be running on batteries.

aarg:
… That can be achieved by mapping byte vectors to different structs. You could easily begin each payload with a type identifier that tells the receiver which data format to apply. I’m basically repeating reply #2, but emphasizing that you can and probably should still use structs. You can accomplish that with unions or pointers.

Ok, I get it. Struct is still the way to go. But you lost me at “byte vector”. That’s not a concept I’m familiar with.

But {identifier byte}{struct}{identifier byte}{struct}…etc looks like what I’m after.

Thanks a lot :slight_smile:

ximinez:
I get it. Struct is still the way to go. But you lost me at "byte vector". That's not a concept I'm familiar with.

Byte array.

I use a common header with a type field that defines the layout of the payload.

So for new types (layouts) I have to change the gateway/concentrator/master only.

If size of payload isn't a real concern, you might consider a human readable ASCII protocol, that allows you to easily 'see' messages, and manually type new commands into the stream during development...