The Forth driver for the RFM69 on the JeeNode Zero is in
flib/spi/rf69.fs.
It is normally included in core.fs
and therefore always available from flash
memory. It’s very simple to use: call rf69-init
to intitialise the RFM69
module, and then call either rf69-recv
to poll for new incoming packets or
rf69-send
to send out a single packet. The current driver does not use any
interrupt pins, so only the RFM69’s 4 SPI pins plus power need to be hooked up.
Here’s an example of how to receive one packet, followed by a dump to show the payload data:
rf69-init ok.
rf69-recv . 9 ok.
rf.buf hex. 20001E94 ok.
rf.buf 9 dump
20001E90 01 00 00 00 C0 01 81 80 06 8F 7A F1 80 7A 7A 7A ........ ..z..zzz
20001EA0 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A 7A zzzzzzzz zzzzzzzz
ok.
This is not very useful, other than to illustrate that the driver works. Here
is a better example based on rf69-listen
- it configures a different frequency
(868.600 MHz) and net group to listen to, and then dumps each incoming packet in hex format,
including reception details:
8686 rf69.freq ! ok.
6 rf69.group ! ok.
rf69-listen
RF69 21EE06C00102BEC0010A 8101D119CC029A7AE980
RF69 21EE06A202006EC00107 818002A07AEA80
RF69 21EE06C3010108C00107 8101CF19CE8080
The format of these reported packets is as follows:
This is the public API of the RF69 driver:
0 variable rf.rssi
0 variable rf.lna
0 variable rf.afc
66 buffer: rf.buf
8683 variable rf69.freq
42 variable rf69.group
61 variable rf69.nodeid
: rf69-init ( -- ) \ init RFM69 with current rf69.group and rf69.freq values
: rf69-recv ( -- b ) \ check whether a packet has been received, return #bytes
: rf69-send ( addr count hdr -- ) \ send out one packet
: rf69-power ( n -- ) \ change TX power level (0..31)
: rf69-sleep ( -- ) \ put radio module to sleep
: rf69-listen ( -- ) \ init RFM69 and report incoming packets until key press
: rf69-txtest ( n -- ) \ send out a test packet with the number as ASCII chars
: rf69. ( -- ) \ print out all the RF69 registers
The rf69-listen
word is a wrapper around rf69-recv
to format the above
packet messages:
: rf69-listen ( -- )
rf69-init cr
begin
rf69-recv ?dup if
." RF69 " rf69-info
dup 0 do
rf.buf i + c@ h.2
i 1 = if 2- h.2 space then
loop cr
then
key? until ;
Likewise, the rf69-txtest
is a small wrapper to generated a test message, the
payload is an integer, converted to ASCII text:
: rf69-txtest ( n -- ) rf69-init 16 rf-power 0 <# #s #> 0 rf69-send ;
We can enter this on a second node to send out one test packet:
12345 rf69-txtest
The result will then be reported as follows by that first listening node:
RF69 21EE0650060016C03D05 3132333435
For debugging, there’s rf69.
(note the trailing dot), which
dumps all RFM69 register settings:
rf69.
0 1 2 3 4 5 6 7 8 9 A B C D E F
00: -- 10 00 02 8A 05 C3 D9 26 40 41 60 02 92 F5 20
10: 24 9F 09 1A 40 B0 7B 9B 08 42 42 40 80 06 5C 00
20: 00 FC 8D 00 A2 00 07 D9 46 C4 00 00 00 05 88 2D
30: 06 00 00 00 00 00 00 D0 42 00 00 00 8F 12 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00
50: 14 05 88 08 00 00 01 00 1B 09 55 80 70 33 CA 08 ok.
And if you want to experiment with different register settings, there’s nothing simpler than entering some interactive commands to change or read out the RFM69 on the fly:
%1000 $4E rf! ok.
$4F rf@ . 142 ok.
This starts a temperature measurement by setting bit 3 of register $4E, and then reads out the result from register $4F. This has to be calibrated before it can be turned into a temperature value, but at least it shows how you can dynamically set a register and read out another one.