Remote node discovery

The current use of the wireless RF12 driver is very basic. That’s by design: simple works.

All you get is the ability to send out 0..66 bytes of data, either as broadcast or directed to a specific node. The latter is just a little trick, since the nature of wireless communication is such that everything goes everywhere anyway – so point to point is simply a matter of receivers filtering out and ignoring packets not intended for them.

The other thing you get with the RF12 driver, is the ability to request an acknowledgement of good reception, which the receiver deals with by sending an “ACK” packet back. Note that ACKs can contain data – so this same mechanism can also be used to request data from another node, if they both agree to use the protocol in this way, that is.

So there are three types of packets: data sent out as is, data sent out with the request to send an ACK back, and packets with this ACK. Each of them with a 0..66 byte payload.

But even though it all works well, there’s an important aspect of wireless sensor networks which has never been addressed: the ability for nodes to tell other nodes what/who they are. As a consequence, I always have to manually update a little table on my receiving server with a mapping from node ID to what sketch that node is currently running.

Trivial stuff, but still a bit inconvenient in the longer run. Why can’t each node let me know what it is and then I don’t have to worry about mixing things up, or keeping that table in sync with reality every time something changes?

Well… there’s more to it than a mapping of node ID’s – I also want to track the location of each node, and assign it a meaningful name such as “room node in the living room”. This is not something each node can know, so the need to maintain a table on the server is not going to disappear just by having nodes send out their sketch + version info.

Another important piece of information is the packet format. Each sketch uses its own format, and some of them can be non-trivial, for example with the OOK relay sending out all sorts of packets, received from a range of different brands of OOK sensors.

It would be sheer madness to define an XML DTD or schema and send validated XML with namespace info and the whole shebang in each packet, even though that is more or less the level of detail we’re after.

When power is so scarce that microcoulombs matter, you want to keep packet sizes as absolutely minimal as possible. A switch from a 1-bye to a 2-byte payload increases the average transmit power consumption of the node by about 10%. That’s because each packet has a fixed header + trailer byte overhead, and because the energy consumption of the transmitter is proportional to the time it is kept on.

The best way to keep packet sizes minimal, is to let each node pick what works best!

That’s why I play lots and lots of tricks each time when coming up with a remote sketch. The room node gets all its info across in just 4 bytes of data. Short packets keep power consumption low and also reduce the chance of collisions. Short is good.

I had been wondering about this for some time and even commented a few days ago in a prev post. In the end I went for a power-up->schema broadcast until ack (every 10secs) or timeout after 2 mins->ack with echo of schema crc. It uses a larger payload for that initial cycle but it allows the node to provide full capability to central. I’m sure you have a much more elegant solution, so am really interested. nb: I used a simple bencode for the initial schema payload. The flaw I will have is that I will have to ‘time-out’ my schema data if I repurpose a node or re-power it, not a problem as it does not happen often. (not implemented that bit yet). Perhaps I will use that ‘spare’ sequence bit to flip formats. Anyhow – await with much anticipation.

I’d use a “schema on request”: when a receiver sees a packet addressed to it and it doesn’t know the schema (or the data doesn’t make sense in that schema), it asks the sender to broadcast its schema. For broadcast packets, just add a random wait before asking for the schema: if someone else asks it first, just store.

My assumption is that my base station / server is always on A/C power, so it can listen non-stop. At least some of my sensor nodes are battery powered and so cannot listen non-stop. Here, we are talking about nodes informing the server of their existence when they come online. I want to allow for the possibility of my server coming and going. The server might not be able to remember what it was told before a power cycle (especially if the power cycle happens at just the wrong time).

Another thing I would like the sensor nodes to be able to report is what kind of sensors they have. This could either be during their power-up self-reporting or some kind of self-describing data format when they report readings. Although there are a lot of sensors available, there aren’t really that many distinct types. A single byte for reporting the sensor type is probably sufficient. I’d want the sensor node to report something like:

local sensor id so I can tell which temp sensor is which when they are separated by several meters of wire;

what kind of sensor (temp, humidity, astrological sign, …) [[I guess I would use distinct sensor ids for combo sensors]];

what kind of data/units/format are being reported.

I’m not as frugal as you were planning to be, so I was going to allocate 1 byte for each of those. You would then also have whatever bytes were needed for the actual data. The data part is not yet thought out, but I was thinking you could easily fit half a dozen sensor reports into a single 66-byte packet.

As you said, the server still has to know the physical location of the sensors. In my case, I want to be more specific than just the location of the multi-sensor Jeenode.

Yep – that pretty much sums up a bunch of scenarios. With 1-wire sensors, their 64-bit ID’s are a bit on the large side to send out as is. Then again, if the node registers them in its EEPROM, it can probably just report a couple of 1-byte ID’s.

Note that with an online registry (not necessarily public), you’d have another way to get at each node’s config.