Computing stuff tied to the physical world

Maximum speed wireless transfers

In Software on Nov 26, 2011 at 00:01

Prompted by a question of the forum, I wanted to go bit into the way you can collect data from multiple JeeNodes as quickly as possible.

Warning: I’m completely disregarding the “1% rule” on 868 MHz, which says that a device should not be sending more than 1% of the time, so that other devices have a good chance of getting through as well (even if they are used for completely unrelated tasks). This rule is what keeps the 868 MHz band relatively clean – no one is allowed to “flood”. Which is exactly what I’m going to do in this test…

Ok, first of all note that all devices on the 868 MHz wireless ISM band have to share that frequency. It only works if at most one device is transmitting at a time. Many simple OOK transmitters, such as weather sensor nodes, don’t do that: they just send out their packet when they feel like it. Fortunately, most of them do so relatively infrequently, once every few minutes or so. And due to the 1% rule, most transmissions will be ok – since the 868 MHz band is available most of the time.

This changes when you start to try and push as much information across as you can. With one sender, it’s easy: just ignore the rule and send as much as you can. With the default RF12 settings, you should be able to get a few hundred small packets per second across. With occasional loss due to a collision with another sender.

But how do you get the maximum amount of data across from say three different nodes?

It won’t work to let them all send at will. It’s also a bit complicated to make them work in perfect sync, with each of them keeping accurate track of time and taking turns in the right order.

Here’s a simpler idea to “arbitrate media access”, as this is called: let the central node poll each of the remote nodes, and let each remote node then send out an ACK with the “requested” data only when asked.

I decided to give it a go with two simple sketches. One is the poller, which sits at the center and tries to obtain as many packets as it can:

Screen Shot 2011 11 24 at 12 47 39

It cycles over each of the remote node ID’s, sends them a packet, and waits briefly for a reply to come in. Note that the packet sent out is empty – it just needs to trigger the remote node to send an ACK with the actual payload.

The remote nodes each run a copy of the pollee sketch, which is even simpler:

Screen Shot 2011 11 24 at 12 37 07

They just wait for an empty incoming packet addressed to them, and reply with the data they want to get across. I just send the node ID and the current time in milliseconds.

Here is the result, with one poller and three pollee’s:

    1: 36974
    2: 269401
    3: 10128
    1: 36992
    2: 269417
    3: 10145
    1: 37009
    2: 269434
    3: 10163

As you can see, each node gets one packet across about once every 17 ms (this will slow down if more data needs to be sent). So that’s 6 short packets flying through the air every 17 ms, i.e. ≈ 350 packets per second.

There are ways to take this further, at the cost of extra complexity. One idea (called TDMA), is to send out one poll packet to line up the remote’s clocks, and then have them send their payload a specific amount of time later. IOW, each node gets its own “time slot”. This reduces the 6 packets to 4, in the case of 3 remote nodes.

No more collisions, but again: this will block every other transmission attempted on the 868 MHz band!

  1. Very nice! does this mean that if you adjust the time delay of the poller to 1700ms you are then in compliance with the 1% rule?

    • Yes, but you can do better. Each node has the 1% limit. In this case, the central node is sending 3x as often as the rest. Since each packet send takes about 3 ms, It could send a poll packet once every 300 ms and still be in compliance with the 1% rule.

  2. Hmmm, “Prompted by a question of the forum, I wanted to go bit into the way you can collect data from multiple JeeNodes as quickly as possible.”…

    The link to the forum links to this weblog post ;-)

    Considering this way of communication: will JeeMon/JeeRev support this type in the future so I can configure either poll-mode or unsolicited mode for each JeeNode??

    • Thx – link fixed. The (somewhat lame) general answer to “can JeeMon do …?” is that it can, if you, me, or someone else adds the code to do so.

      One of my goals with JeeMon is to let more people participate in the programming process. Small features should be small tasks, and easy to add/tweak. I don’t want to see myself as the producer of a finished solution, which others install and configure, but as someone who started the design of a tool / framework which is powerful, flexible, and convenient enough to embrace contributions from anyone who wants to take it further (me included, absolutely!). The challenge is to create a system which is extra-ordinarily modular, so that it doesn’t constantly fall over like a house of cards if you mess with it and try things out.

      A bit like chips which don’t immediately get damaged if you hook ’em up the wrong way :)

    • Keep in mind that poll mode needs remote receivers which are constantly in receive mode (or clever timer logic to make them wake up at just the right time – which is hard). So this mode is less suited for battery-powered remote nodes.

    • The (somewhat lame) general answer to “can JeeMon do …?” is that > it can, if you, me, or someone else adds the code to do so.

      Adding code won’t be the problem…as you have everything in Github!

      The challenge is to create a system which is extra-ordinarily modular, so that it doesn’t constantly fall over like a house of > cards if you mess with it and try things out.

      That’s the exact problem I wanted to point out. If things can be added easily you’ll find more and more ppl that conribute, but if you have to make large modifications, that can’t be merged anymore with the main trunk, everybody will have a lot of work for his/her own fork, instead of reusing everybodies work!

    • Maybe there is no need to be in constant receive mode. All a pollee needs to do is wake up when it’s time to send and stay awake for just one poll period, until it hears its name. As soon as if finishes sending it goes back to sleep and wakes up when it’s again time to send.

  3. if the pollees need to be in receive mode you can also consider the following scheme : poller asks node 1; node1 replies; node 2 and 3 hear that node1 answers; node 2 decides it is his turn and sends package; then node 3 get the turn then 1 again. if poller does not get a packet in time X, then it sends a request again (either to the next in line after last successful packet received or randomly to some node)

    • Nice! That’d half the number of packets. Only small detail is that node 1 will need to know the number of the last node (or perhaps the central node could always step in to reset the circle).

      What I really like about all this, is that it takes very little code to try out such behaviors.

  4. I do not invent it : it is just the token ring idea ;-). You could put the “next in line” number in the answer you send out as a pollee. That way, only the last node needs to know it is the last node (so it fills in a 1 when answering). That is local knowledge, not global knowledge. slight improvement..

  5. Does anyone know the exact definition of the ‘1% rule’ or is this just a rule of thumb? It makes a big difference if this is defined per year, per minute or per second. It could for example be ok to send a 10 second ‘bursts’ of packets by one node, if the same node than stays quiet for the next (100-1)*10s.

    And if I have 100 nodes in my house? Am I than allowed to have each node send 1% of the time, effectively completely blocking the band in the nearer surrounding?

Comments are closed.