Computing stuff tied to the physical world

Sending data TO remote nodes

In Software on Oct 31, 2010 at 00:01

Yesterday’s post described an easy way to get some data from remote battery-powered nodes to a central node. This is the most common scenario for a WSN, i.e. when reading sensors scattered around the house, for example.

Sometimes, you need more reliability, in which case the remote node can request an “ACK” and wait (briefly) until that is received. If something went wrong, the remote node can then retry a little later. The key of ACKs is that you know for sure that your data packet has been picked up.

But what if you want to send data from the central node TO a remote node?

There are a couple of hurdles to take. First of all, remote nodes running on batteries cannot continuously listen for incoming requests – the RFM12B receiver draws more than the ATmega at full power, it would drain the battery within a few days. There is simply no way a remote node can be responsive 100% of the time.

One solution is to agree on specific times, so that both sides know when communication is possible. Even just listening 5 ms every 500 ms would create a fairly responsive setup, and still take only 1% of the battery as compared to the always-on approach.

But this TDMA-like approach requires all parties to be (and remain!) in sync, i.e. they all need to have pretty accurate clocks. And you have to solve the initial sync when powered up as well as when reception fails for a prolonged period of time.

A much simpler mechanism is to let the remote take the initiative at all times: let it send out a “poll” packet every so often, so we can send an ACK packet with some payload data if the remote node needs to be signaled. There is a price: sending a packet takes even more power than listening for a packet, so battery consumption will be higher than with the previous option.

The next issue is how to generate those acks-with-payload. Until now, most uses of the RF12 driver required only packet reception or simple no-payload acks. This is built into RF12demo and works as follows:

Screen Shot 2010 10 30 at 20.17.37

That’s not quite good enough for sending out data to remote nodes, because the central JeeLink wouldn’t know what payload to include in the ACK.

The solution is the RF12demo’s “collect mode”, which is enabled by sending the “1c” command to RF12demo (you can disable it again with “0c”). What collect mode does, is to prevent automatic ACKs from being sent out to remote nodes requesting it. Instead, the task is delegated to the attached computer:

Screen Shot 2010 10 30 at 20.17.48

IOW, in collect mode, it becomes the PC/Mac’s task to send out an ACK (using the “s” command). This gives you complete control to send out whatever you want in the ACK. So with this setup, remote nodes can simply broadcast an empty “poll” packet using:

    rf12_sendStart(0, 0, 0);

… and then process the incoming ACK payload as input.

It’s a good first step, since it solves the problem of how to get data from a central node to a remote node. But it too has a price: the way ACKs are generated, you need to take the round-trip time from JeeLink to PC/Mac and back into account. At 57600 baud, that takes at least a few milliseconds. This means the remote node will have to wait longer for the reply ACK – with the RFM12B still in receive mode, i.e. drawing quite a bit of current!

You can’t win ’em all. This simple setup will probably work fine with remotes set to wait for the ACK using Sleepy::loseSometime(16). A more advanced setup will need more smarts in the JeeLink, so that it can send out the ACK right away – without the extra PC round-trip delay.

I’ll explore this approach further when I get to controlling remote nodes. But that will need more work – such as secure transmissions: once we start controlling stuff by wireless, we’ll need to look into authorization (who may control this node?), authentication (is this packet really from who it says it is?), and being replay-proof (can’t snoop the packet and re-send it later). These are all big topics!

More on this some other time…

  1. In May 2010 (after you posted the February blog note), there was a crypto result against XXTEA at the Wikipedia link you cite. I don’t really understand the attack, but I assume a requirement of 2^59 queries means you’re pretty safe if you’re at the far end of a radio link!

  2. how do you manage if two (or more) nodes send message in the same time (this kind of architecture is asynchronous)? do the driver looks if a communication is in progress before emitting?

    TDMA doesn’t meed necessarily high precision timer. If the cycle is about 1 minute (or one hour), and slots enough large, clock deviation will not be problem ;-)

    At each cycle starts, the master send a message that can be a time reference.

    The main problem of TDMA, is that slot length are limited, so it’s means that long buffer might be split, or the slot length must be equal to the longer message emitted by a node (that is difficult to know in an open source project where everyone can decide to send anything by radio ;-) )

    • The rf12_canSend() code checks that no carrier is currently being received. That greatly reduces the chance of collisions.

      In general, I don’t think collisions are very common – even if some of the weather data don’t do this check. All 868 transmissions take less than 1 % of the bandwidth, and in the case of JeeNodes with room boards, far far less than that (a few msec every few minutes).

  3. Idea: keep a one-packet buffer on the PC-connected node. PC sends data (and destination ID) to node, packet is received, ACK-with-data is transmitted. If the PC has data for more than one node, presumably it knows which node is most likely to send next.

    If the return data depends on the input (e.g. “room temperature is X °C” => “OK, set valve to Y %”), send a special “check again in 2sec” ACK packet.

    As to crypto: Something like XXTEA with per-device key and sequence number. Not at all difficult, I’d say.

    • Thanks for the tips. Something like this may indeed provide a simple-yet-effective solution.

      As someone also pointed out in email: in many cases where the remote node controls something, it also needs power for whatever it’s controlling, so chances are that it can be continuously powered anyway. In that case, permanent listening is feasible again.

      As for XXTEA – see the “secure transmissions” link in the post – it’s already included in the RF12 driver (and @Jbeale: yes, I’m perfectly happy with XXTEA for home automation purposes).

Comments are closed.