Computing stuff tied to the physical world

Time-controlled transmissions

In Hardware, Software on Jun 27, 2011 at 00:01

Receiving data on remote battery-powered JeeNodes is a bit of a dilemma: you can’t just leave the receiver on, because it’ll quickly drain the battery. Compare this to sending, where nodes can easily run for months on end.

The difference is that with a remote node initiating all transmissions, it really only has to enable the RFM12B wireless module very briefly. With a 12..23 mA current drain, brevity matters!

So how do you get data from a central node, to remote and power-starved nodes?

One way is to poll: let the remote node ask for data, and return that data in an ACK packet as soon as asked. This will indeed work, and is probably the easiest way to implement that return data path towards remote nodes. One drawback is that if all nodes start polling a lot, the band may become overloaded and there will be more collisions.

Another approach is to agree on when to communicate. So now, the receiver again “polls” the airwaves, but now it tracks real time and knows when transmissions for it might occur. This is more complex, because it requires the transmitter(s) and receiver(s) to be in sync, and to stay in sync over time.

Note that both approaches imply a difficult trade-off between power consumption and responsiveness. Maximum responsiveness requires leaving the receiver on at all times – which just isn’t an option. But suppose we were able to stay in sync within 1 ms on both sides. The receiver would then only have to start 1 ms early, and wait up to 2 ms for a packet to come in. If it does this once a second, then it would still be on just 0.2% of the time, i.e. a 500-fold power saving.

Let’s try this out. Here’s the timedRecv.pde sketch (now in the RF12 library):

Screen Shot 2011 06 24 at 20.54.37

It listens for incoming packets, then goes into low-power mode for 2 seconds, then it starts listening again. The essential trick is to report two values as ACK to the sender: the time the receiver started listening (relative to that receiver’s notion of time), and the number of milliseconds it had to wait for the packet to arrive.

There’s no actual data processing – I’m just interested in the syncing bit here.

The sender side is in the timedSend.pde sketch:

Screen Shot 2011 06 24 at 20.58.17

This one tries to send a new packet each time the receiver is listening. If done right, the receiver will wake up at just the right time, and then go to sleep again. The ACK we get back in the sender contains valuable information, because it lets us see how accurate our timing was.

Here’s what I get when sending a new packet exactly 2,096 milliseconds after an ACK comes in:

Screen Shot 2011 06 24 at 20.39.33

Not bad, one ack for each packet sent out, and the receiver only has to wait about 6 milliseconds with its wireless receiver powered up. I’ve let it run for 15 minutes, and it didn’t miss a beat.

For some reason, send times need to be ≈ 2.1 s instead of the expected 2.0 s.

Now let’s try with 2,095 milliseconds:

Screen Shot 2011 06 24 at 20.37.17

Something strange is happening: there’s consistently 1 missed packet for each 5 successful ones!

My hunch is that there’s an interaction with the watchdog timer on the receiver end, which is used to power down for 2000 milliseconds. I suspect that when you ask it to run for 16 ms (the miminum), then it won’t actually synchronize its timer, but will fit the request into what is essentially a free-running counter.

There may also be some unforeseen interaction due to the ACKs which get sent back, i.e. there’s a complete round-trip involved in the above mechanism

Hmm… this will need further analysis.

I’m using a standard JeeNode on the receiving end, i.e. running at 16 MHz with a ceramic resonator (specs say it’s 0.5% accurate). On the sender side, where timing is much more important, I’m using a JeeLink which conveniently has an accurate 16 MHz crystal (specs say it’s 10 ppm, i.e. 0.001% accurate).

But still – even this simple example illustrates how a remote can receive data while keeping its wireless module off more than 99% of the time.

  1. Another interesting approach might be z-wave’s approach. Nodes wake up and a timed interval let’s say every 2 minutes. Then the node sends a “hey I am awake packet”. If the master/main node has no data in queue for this node, it sends the node back to sleep using a “hey, go back to sleep” packet. There is a fail-safe mechanism (i.e. maximum number of milliseconds to keep the receiver on) for when the main node is not available. If there is data available for the node, the data will be send to the node and the node goes in sleep mode after the “go back to sleep” packet is received.

    • Yep – this is more or less the polling approach I mentioned as first option. The remote node initiates, and the central node is always listening.

  2. How about auto-tuning the value for Sleepy::looseSomeTime() to further minimize the listen times of the receiver to, say 1..2ms? That way it’d synchronize itself to the sender’s timing without having to send the timing values across the link.

    An algorithm like this should do the trick: Start with a value of 1995. If the wait time was >2ms, add one If the wait time was <2ms, substract one

    • That’s a good idea in principle, but there’s a small drawback. There is no way to wait less than 16 ms in the lowest power mode (i.e. powered down with just the watchdog running). Best we could do is run in idle mode with the clock pre-scaler set high, but that still draws a fair amount of current if the 16 MHz resonator or crystal is active.

  3. nice solution for a problem which is for most JeeNode-People very interessting. Also a demo for transmitting and receiving data. Thanks JCW

  4. I like it, exposes some very interesting aspects.

    Thanks jcw!

  5. Could the low-power duty cycle feature of the RFM12B be of any use for low-power listening ? The crystal of the RF12BM is accurate and the controller would be woken only when there’s a valid transmission going on.

    I suspect that this ‘valid transmission’ could be problematic though, as probably the DQD would generate false positives.

    • I’ve had some trouble with reliably using the RFM12B’s watchdog in the past (the slightest failure causes the node to never wake up again) – although that might not be an issue with something which is going to fire repeatedly. But more importantly perhaps, is that this low-power duty cycle can’t keep the crystal oscillator running. If it did, power consumption would be fairly high. I suspect that this doesn’t give us any really new options – but then again, I haven’t tried or measured it…

  6. I took a peek inside the Silabs spec. The wake-up timer which is used for the lower-power duty-cycle runs without the crystal oscillator (as you suspected), so the accuracy is not as good, only 10% in fact. Power consumption of the wakeup timer is low though, only 1,5uA.

    I guess the idea is not to be in exact sync, but only the poll the airwaves every once in a while. The transmitter would have to send repeatedly until the receiver wakes up.

    Adam Dunkels (author of uIP) compared exactly synced WSN systems with systems that use this low-power listening technique. He found that, although not as optimal as synced systems, low-power listening systems can actually come quite close with respect to power consumption to these synced systems. Getting an good exact sync is not easy. According to him. the advantage of a reduced complexity might outweigh the (relatively small) extra power consumption saving.

    I can lookup the exact numbers if you like.

    • It would be interesting to compare that approach to the one I described in the weblog post. One drawback I see of periodic preamble checking using the RFM12B, is that you’re still faced with that 10% variation, which for periodic use of say once a minute would be quite a bit. By having a central accurate setup know how each remote’s clock is running, I would hope that it can “get it right” a bit better. If there is always a packet + ack, then the central node can track gradual changes due to temperature etc.

      But I agree – exact sync is no doubt very hard. With a 32 KHz crystal (as in my next weblog post, or using an RTC chip/plug) it’s probably easier.

      All in all, I think the remote-initiating-all-wireless-comms approach is probably the easiest way to keep power use really low. With as optional refinement: a bit of centrally-controlled coordination to reduce collisions between the different remote nodes.

Comments are closed.