I’ve extended the RF12 driver with three “rf12_easy…()” functions, which should make it easier to implement nodes which need to periodically report some data to a central JeeNode or JeeLink.
Here’s a complete sketch which sends the current value of the millisecond counter over wireless:
The above sketch compiles to roughly 3 Kb of code. Some extra notes:
- The “rf12_initialize(…)” call sets this node up as node “W” (23), using 868 MHz, and using group 5.
- The “rf12_easyInit(5)” call sets up the easy transmission system, with data to be sent every 5 seconds.
- The “rf12_easyPoll()” call needs to be called often – at least once per millisecond or so would be best.
- The “rf12_easySend(…)” call passes the data to be sent, i.e. pointer to that data and the number of bytes.
There’s quite a bit of additional logic hidden behind these three calls:
- Even if called often, new data will only be sent at most every 5 seconds, as requested.
- Lost and damaged packets will automatically be resent, with up to 8 retries.
- Packets are only sent if the data has changed.
- To force data to be re-sent even if unchanged, call “rf12_easySend(0,0)”.
Here is some output from a capture utility I use:
As you can see, the 4-byte millisecond value is only sent once, every 5 seconds.
The argument to rf12_easyInit() is in seconds, and can be anything from 1 to 255 seconds. In addition, using zero as argument means: send as often as possible. For the 815 MHz band this depends on the number of data bytes, to enforce the “1% max bandwidth rule”. The actual rate will range from about 7 packets per second for 1 byte of data, to about 1 packet per second for 66 bytes of data. For the 433 and 915 MHz frequency bands, the maximum rate is fixed at 10 packets per second, regardless of the data size.
I’m currently using a simple algorithm which tries to resend at 1-second interfals when packets are lost or damaged. This can be extended to “exponential back-off with randomization” later on. My first concern is a simple-but-robust first implementation.
There is still an issue with the current RF12 driver, which can cause duplicate packets to arrive at the destination (an extra sequence bit needs to be added to each packet to detect loss of acknowledgement packets – this change affects the protocol and requires re-flashing all the current nodes, which I don’t want to do just yet). Such duplicate packets can easily be filtered out at the destination. There is also an issue with picking up the wrong ack, this probably only affects nodes at the limit of their range (i.e. when not all the nodes receive the same things).
No changes were made to the RF12 driver core, these calls are purely a layer on top. They use broadcasting to get data from different nodes to a single central node, and currently there is no way to combine this with reception of data coming towards a node. But as the above example shows, for the specific scenario of sending out data these calls should simplify the development of remote nodes a fair bit.
The new code is now in the subversion repository, as well as in the RF12.zip archive.
Update – documentation for these new calls has been added to the Café docs.