Analog over wireless Feb 2017
Let’s put the JeeNode Zero to work a bit, i.e. let’s repeatedly measure an analog voltage through its ADC, send the results over to another node via the radio, and display the received readings.
We’re going to need a test setup with two wireless nodes. Something like this, for example:
The top unit is an F103-based Blue Pill with an RFM69 on top, and a SerPlus on the left for programming (it can also be used directly over USB when a USB-enabled Mecrisp is installed). The bottom unit is an L052-based JeeNode Zero, with a SerPlus on the left as USB interface.
We’ll use the JNZ as sensor/transmitter and the F103 as receiver.
This example assumes that everything is properly connected, and that
core.fs sources have been installed on
both nodes, including the
The first step is to try out the ADC, by reading the voltage level on PA0 a few times:
$ folie Folie v2.10 Select the serial port: 1: /dev/cu.Bluetooth-Incoming-Port 2: /dev/cu.usbmodem3430DC31 3: /dev/cu.usbmodemC92AED31 ? 2 Enter '!help' for additional help, or ctrl-d to quit. [connected to /dev/cu.usbmodem3430DC31] Mecrisp-Stellaris RA 2.3.3 with M0 core for STM32L053C8 by Matthias Koch 64 KB <jz3> 3238022C ram/flash: 4920 19200 free ok. adc-init ok. pa0 adc . 0 ok. pa0 adc . 15 ok. pa0 adc . 744 ok.
Ok, that seems to work (touching the PA0 pin helps produce a varying signal).
Next step is to do this repeatedly in a loop:
: forever begin cr pa0 adc . 1000 ms again ; forever 274 10 13 !reset Mecrisp-Stellaris RA 2.3.3 with M0 core for STM32L053C8 by Matthias Koch 64 KB <jz3> 3238022C ram/flash: 4920 19200 free ok. ok.
Ok, that works. Note that we had to force a hardware reset to get the prompt back, since the JNZ was placed in an infinite loop. This is the easiest approach and good enough for now.
Now we’ll send it via the RF69 driver, using its default 868.3 MHz and net group 42 settings:
adc-init rf-init ok. : forever begin pa0 adc rf-txtest 1000 ms again ; forever
rf-txtest, which takes one value off the stack, converts it to a
text string, and sends that as message in an RF packet.
Note that we have to re-initialise the ADC, since we’ve reset the µC and therefore also its ADC.
Hmm - maybe it’s working, but how can we tell? Well, by keeping this running
and connecting a second terminal to the F103. The
rf-listen command is a quick
way to see incoming data:
$ folie Folie v2.10 ? Select the serial port: 1: /dev/cu.Bluetooth-Incoming-Port 2: /dev/cu.usbmodem3430DC31 3: /dev/cu.usbmodemC92AED31 ? 3 Enter '!help' for additional help, or ctrl-d to quit. [connected to /dev/cu.usbmodemC92AED31] Mecrisp-Stellaris RA 2.3.3 for STM32F103 by Matthias Koch 64 KB <g6s> 32212433 ram/flash: 17688 20480 free ok. ok. rf-listen RF69 21EB2AB601FE1E803D02 3139 RF69 21EB2AB401FD0E803D01 30 RF69 21EB2AB701FD56803D03 313137 RF69 21EB2AB701FDA4803D03 313733 ok. ok.
As you can see, there are many $30..$39 hex bytes in the received data payload (the first block of hex info is metadata, as described in this article). These are the “0”..“9” ASCII digits, in hex.
To turn this information into more meaningful values, we need to decode this data, i.e. make assumptions about the packet format and interpret it as ASCII-encoded digits in this case.
We can’t use the
rf-listen code for this, so we’ll need to implement something
similar instead. This is fairly easy to do, starting from this original
: rf-listen ( -- ) \ init RFM69 and report incoming packets until key press rf-init cr 0 rf.last ! begin rf-recv ?dup if ." RF69 " rf-info dup 0 do rf.buf i + c@ h.2 i 1 = if 2- h.2 space then loop cr then key? until ;
Here is a modified version which will print the packet as string:
: rxtest ( -- ) rf-init begin rf-recv ?dup if cr rf.buf 2+ swap 2- type then again ;
rf-recv in an infinite loop. Whenever the result (the number of
bytes received) is not zero, we set up a call to
type with two arguments: the
address to start printing as string and its length. But because the first two
bytes of the received data contain a header we don’t care about, we need
to skip them by adding 2 to the address and subtracting 2 from the length.
If we save this definition to a file called
rxtest.fs, we can then load and
use it as follows:
!s rxtest.fs rxtest 0 30 116 85 12
That’s it for an example of remote sensing - the JeeNode Zero is taking ADC measurements once a second and sending this data wirelessly to another F103-based node, which then prints out all received results. There’s a lot which could be improved upon, but hey - it’s a start!