My aquarium’s data radioed through the shelf

Started 23Dec2017. 21Jan2018, in work

This page is in group Technology and is a blog note where I will show the route ahead. The My WiFi101 library port or an Ethernet based web server will be implemented following this work. But to connect the two boxes I have dropped the Bluetooth Low Energy (BLE) suggestion as discussed in Me relying on relaying BLE? I went for the simpler(?) radio solution discussed here. The boards have been ordered. There is an overview of related notes at “My XMOS notes”, chapter MY OTHER NOTES WHERE XMOS MATTERS.


Standard disclaimer, this is just for fun. No money, gifts, ads etc. Also, my non-association with any of the companies mentioned here. Other than some times exchanging technical matters, mostly in open forums. I am basically positive until I may have experienced the opposite; this is reflected in all my blog notes.

My aquarium’s data radioed through the shelf

Fig.1 Sum of suggestions II (Press for PDF)

Many of the components and the rationale for the architecture have been discussed in the already mentioned Me relying on relaying BLE? note. I’ll call it the “BLE note” below.

Why packet radio instead of BLE?

BLE seems to be more complex. But my disclaimer is that I will not have acquired hands-on with BLE and radio, so this is based on the research in the BLE note. And that research is based on reading what other people write. I must admit that I lean a lot on the Adafruit’s considerations since they have both BLE and radio boards with full documentation, also with how to get them on-air.

I want everything just connected from power-up. Adafruit has caught my mood (or admittedly even formed my mood) with this statement from [1]:

Also, these packet radios are simpler than WiFi or BLE, you dont have to associate, pair, scan, or worry about connections. All you do is send data whenever you like, and any other modules tuned to that same frequency (and, with the same encryption key) will receive. The receiver can then send a reply back. The modules do packetization, error correction and can also auto-retransmit so its not like you have worry about everything but less power is wasted on maintaining a link or pairing.

And I am almost certain that I will get the needed code into the rather packed Aquarium Controller Box ACBox, to export all the data so that the larger Relay Box RBox can build HTML with dynamic data, and also do logging. In other words, a web server there.

Radio alternatives are many

There would be breakout boards and chips.

Breakout boards

Adafruit has at least the below. I am including what I found interesting

  • Boards based on RFM69HCW in either 433 MHz or 868/915MHz using the Semtech SX1231 packet radio
    • I went for a 433 MHz SPI version of this, the Adafruit 3071, see [3]
    • The smaller board that’s on it is called RFM69HCW. This Programmable 315-915Mhz RF Transceiver Module is made by Hoperf Electronics [11] (called “Hope” in the RadioHead texts) However, the Hoperf board uses this Semtech chip:
    • The RFM69HCW contains a Semtech SX1231 Integrated RF tranceiver, see [4]. as told by Adafruit (but I haven’t seen it explained). Reading Hoperf’s [11] there’s not a word there about “1231” or “Semtech”, but chapter “1.1. Simplified Block Diagram” shows in a rather crude bitmap Semtech’s SX1231 high resolution block diagram from [4]. But observe:
    • Studying more I see that Hoperf’s [11] and Semtech’s [4] are almost equal. Searching another round I find a proof that it is Hoperf who uses the Semtech chips [12] (long discussion thread at LowPowerLab Forum). There I also found this: Semtech (in the USA) informs that Hoperf is one of their partners [13]
    • On all five of the Adafruit 3071 breakout boards I received the Semtech chip on RFM69HCW is printed with “H RF69 1714 W4C405”. This is different from on the pictures on the Adafruit page. Hoperf have printed their own label on the Semtech chip [12].
  • Boards based on RFM9x (like RFM96) LoRa in either 433 MHz or 868/915MHz using the Semtech SX1276
    • The Semtech page for the SX1231, see [5]
  • Also boards with processor (ARM ATSAMD21G18) in the Feather format

Sparkfun also works in this area. Here is their version of the Adafruit 3071 (more or less): The RFM69HCW is seen at [9], and their breakout board at [10].

MikroElectronika [6] has a lot of sub 1 GHz breakout boards. As of Dec2017 I find all the below. It’s OK to see these listed like this, even if it comes close to name-dropping since I haven’t studied any of them. But this list tells me that there certainly are competitors:

  • IQRF click with DCTR-72DAT by IQRF
  • ccRF 3 click with CC1120 by Texas Instruments,
  • SPIRIT click carries the SP1ML 8 by ST
  • EnOcean click carries a TCM 310 by enocean
  • LoRa click carries Microchip’s RN2483 by Microchip
  • ccRF2 click carries CC1120 by Texas Instruments
  • tRF click with Telit LE70-868 by Telit
  • M-BUS RF click is a mikroBUS™ add-on board with a Telit ME70-169 RF wireless module by Telit


Nordic has chips, nRF905 [7] and nRF9E5, [8] much harder for me to use since I don’t want to build and solder boards.

Fig.1 board 69. SX1231.a Transceiver Radio Breakout

This chapter also covers 69. SX1231.b and 69. SX1231.x in the figure. This is the Adafruit RFM69HCW (with Semtech SX1231) Transceiver Radio Breakout – 433 MHz – RadioFruit (3071). The description and just about everything about it is covered in [3]. Plus [1] and [2].

The 88 pages long datasheet of the Semtech RFM69 (like RFM69HCW) (packet radio) chip SX1231 datasheet [4] was last updated in June 2013. This could either mean that it’s been slowly outpaced or that it’s become stable.

By comparison the 132 pages long datasheet of the Semtech RFM9x (like RFM96) (LoRa) chip SX1276 [5] was last updated in August 2016. I am writing this in Dec. 2017.

But Adafruit writes that:

These radio modules come in four variants (two modulation types and two frequencies). The RFM69’s are easiest to work with, and are well known and understood. The LoRa radios are exciting and more powerful but also more expensive [1]

To me that looked rather reassuring, so I decided to go for the RFM69. But I needed to know this when I ordered (from two Adafruit pages):

All radios are sold individually and can only talk to radios of the same part number. E.g. RFM69 900 MHz can only talk to RFM69 900 MHz, LoRa 433 MHz can only talk to LoRa 433, etc. [1]

You will, of course, need at least two paired radios to do any testing! The radios must be matched in frequency (e.g. 900 MHz & 900 MHz are ok, 900 MHz & 433 MHz are not). They also must use the same encoding schemes, you cannot have a 900 MHz RFM69 packet radio talk to a 900 MHz RFM9x LoRa radio [2]

My setup

Fig.2 Overview of Adafruit RFM69HCW Transceiver Radio Breakout RadioFruit connected to Feather M0 basic proto (press for more pixels)

I use the same Adafruit Feather board “box” as shown for the first time in Fig.2 of My Piggyback WiFi1500 sliceCARD. But this time I need two to tango. However, I decided to reuse the 1-13 connection to the right on the box and therefore had to add a cross coupling board. The RFM69HCW has only nine pins, but Adafruit had either been lucky or probably smart so that I could happily plug it into pins 1-9 of the 1-13 pins row. For the SPI pins SCK, MOSI and MISO that’s so much easier, since all example code for ARDUINO_SAMD_FEATHER_M0 (define in Adafruit code) use it rather hard coded. Also, redefining the other pins (see next chapter: RFM69_CS, RFM69_INT and RFM69_RST) has been made easy to do in the example code.

Frequencies allowed in Norway

In Norwegian:

Lovlige frekvenser i Norge (FOR-2012-01-19-77)

I henhold til Forskrift om generelle tillatelser til bruk av frekvenser (fribruksforskriften) [17] ser jeg dette:

  • FOR-2012-01-19-77
    • Kap. III. Utstyr for kortdistansekommunikasjon
      • § 8.Diverse utstyr for kortdistansekommunikasjon
        • (11) Frekvensbåndet 433,050–434,790 MHz tillates brukt med en maksimal tillatt utstrålt effekt på 10 mW e.r.p. Maksimal sendetid er mindre enn 10 prosent.

Alstå er 434 MHz (i båndet 433,050 – 434,790 MHz) lovlig, under de betingelsene som er gitt ovenfor.

Using the RFM69 Radio

Basic RX & TX example

Top level fies:

  • RadioHead69_RawDemo_RX.ino and _TX
  • RadioHead69_AddrDemo_RX.ino and _TX
Doing it

After having done all the soldering (see top right of Fig. 2, press for more pixels) I must get the code and start doing something even more fun than soldering:

  1. Downloading from Adafruit GitHub gives examples ok, but outdated ReadHead. The above points is from going through Adafruit’s teaching pages starting at [2]. I downloaded the RadioHead library via it (Adafruit has a GitHub repo that’s pointed to). I got the Adafruit [examples] ok. But I got an outdated version of RadioHeadObserve that any git-repository with RadioHead out there probably will not have the latest version, according to its author Mike McCauley [20]. On 16Jan2018 the RadioHead version I got via Adafruit was 1.74 from 8Mar2017. So, when you have got the examples to work with the Adafruit examples, download the latest and greatest from [14]. It’s 1.82 7Jan2018, just about a week old. When I diffed the directories and looked at RH_RF69.cpp in particular I saw that they have added using the INT interrupt from the RF69 board, first diff with spiUsingInterrupt(interruptNumber); I moved the old directory away from the Arduino [libaries] directory and moved the new in. I then copied the [exampes/feather/] back again and recompiled. It worked. So I believe Adafruit has a job to do to get this right, not to leave us with old RadioHead libraries. I have given them feedback by pressing on “Feedback? Corrections?” about this
  2. The text in [2] says that ..”and check that the RadioHead folder contains files like RH_RFM69.cpp and RH_RFM69.h”.
    • It doesn’t. The closest is “RH_RF69.cpp” and “RH_RF69.h”. This is so for the GitHub site and the direct download link. I’ll proceed anyhow.
    • However, I can find one mention of RH_RFM69 in [14] from 2014: (sic) “Fixed problem with ambigiguous print call in RH_RFM69 when compiling for Codec2.”
    • However, [14] also explains that  “The following Drivers are provided:” and in the list: “RH_RF69 Works with Hope-RF RF69B based radio modules, such as the RFM69 module, (…) and compatible chips and modules such as RFM69W, RFM69HW, RFM69CW, RFM69HCW (Semtech SX1231, SX1231H). … Supports GFSK, FSK.”
      I added the RH_RF69 class reference document as ref [15] here
  3. In the RadioHead69_RawDemo_TX.ino and RadioHead69_RawDemo_RX.ino examples I changed to RF69_FREQ 434.0. Then I changed in the defined ARDUINO_SAMD_FEATHER_M0 region RFM69_CS 10, RFM69_INT 6 and RFM69_RST 5, as shown in Fig.2.
  4. On the Mac I was not able to start another instance of the Arduino IDE, so I duplicated the Arduino IDE app and called it Arduino2. It works didn’t have to. There are lots of discussion threads on how to do this this out there, and here is one that works by starting a macOS Terminal window that starts another instance of the same Arduino executable [16]. I was able to start the Arduino2 (and also [16]) and compile and download on a other USB port. The Arduino2 way has two equal Arduino icons when they run, the via-Terminal has one Arduino and one Terminal icon, rather confusing. So I guess I’ll stick to Arduino2. The individual Serial Monitor’s logs look like this when the RX board is being connected. Colour by me:
    Sending Hello World #414
    No reply, is another RFM69 listening?
    Sending Hello World #415
    Got a reply: And hello back to you
  5. Received [17]: Hello World #415
    RSSI: -29
    Sent a reply
  6. But I coud hear the RF radio tick on my speakers when they are silent! The one without the amplifier ticks like a clock, the other like a clock inside a pillow. The connection is not shielded or twisted. It doesn’t help with a 1 nF capacitor on the noisiest, and shortening the terminals doesn’t mute it 100%. Disconnecting it and shortening the terminal removed the noise, so it’s not picked up by the coil. Also, removing the power cable to the amplifier speaker unit removes the noise. Unplugging the 3.5 mm jack for the sound cable from the Mac did not help. (I don’t use Bluetooth there either..) I’ll look into turning down the power of the senders or using shielded cable:
    • I looked at the code, and I could actually set the power! Here’s the code (layout shorter lines here).
      // If you are using a high power RF69 eg RFM69HW, you *must*
      // set a Tx power with the ishighpowermodule flag set like this:
      //              20 original value that ticked my speakers!
      rf69.setTxPower(14, true); // range from 14-20 for power, (no: -2 to 20)
                                 // 2nd arg must be true for 69HCW

      Going all the way to 14 dB helped, but my speaker seems to be rather sensitive, so I can still hear a faint tick. So I need to try shielding

    • Shielded cable also helped a little. The shield goes to the black terminal, the wire to the red terminal. Now the ticking of a silent speaker is at almost not irritable level 🙁
    • However I see in the setTxPower document that “For RF69HW (ishighpowermodule = true), valid values are from -2 to +20“. At 6 dB I can still almost hear the ticking, at -2 dB it’s gone to my ears! Great! Now I have more to tune with! Received levels at -2 dB sent is about -30 dB when they sit beside each other on my desk (from the rf69.lastRssi(); call)
  7. Since the Arduino IDE burns the code into FLASH I can move the units and run them from a 5V power alone and it will start with the proper code. It certainly works all over the house (with 14-20 dB sent)
Feedback for Adafruit 2Jan2018

Summary, already discussed above:

  1. [2] says that “and check that the RadioHead folder contains files
  2. In the RadioHead69_RawDemo_TX.ino and RadioHead69_RawDemo_RX.ino it should be noted that the dB range is -2 to 20 as the first param of rf69.setTxPower. If Adafruit has some reason to stop at 14 dB then it should be noted that -2 is the lowest, and it works!
  3. I cannot see that the documentation treats the fact that Hoperf Electronics (“Hope”) has relabeled the Semtech SX1231 to something “H RF69 1714 W4C405” (but of Adafruit and other pictures, that would have different labels, plus documentation I haven’t been able to figure out the nomenclature)
  4. Starting another instance of the Arduino IDE and then of the Serial Monitor needs an explanation that on Macs it’s done differently from Windows. See [16] and the comments above

Psst. Reach me here

Addressed RX and TX Demo

Top level files: RadioHead69_AddrDemo_RX.ino and _TX

This worked out of the box, once I had changed the parameters above. The only things I thought could be different are the file names and address defines. They confused me. Everything is nicely commented in the code, but naming doesn’t follow in my opinion:

In RadioHead69_AddrDemo_RX.ino // RadioHead69_AddrDemo_RX_Server.ino instead?

// who am i? (server address)

In RadioHead69_AddrDemo_TX.ino // RadioHead69_AddrDemo_TX_This_Client.ino instead?

// Where to send packets to!
// change addresses for each client board, any number :)

I also added RADIO_ since there are so many “server” and “client” and “address” in a large code base (especially XC), and a global search should preferably yield unique results.

Observation of the RF69 original code

To no surprise this code is built like much of the rest of the Arduino examples (or real code?) I guess. I have covered my points pretty much at My WiFi101 library port (chapters about concurrency in particular).

But I’m stunned by how easy it is to download and get the examples to run. It even takes care of the changes I need to do, and has me move those files into separate directories. This is the first IDE I have seen this on.

Porting to XMOS / XC

  • I have queried about this at the radiohead-arduino discussion group [20]. It includes a response from RadioHead’s author Mike McCauley. The list below has been updated after the response I got there
  • Also queried at XCore Exchange [21]

Here is how I would attack this. (I already ported some Adafruit code into XC for the aquarium controller (like the SSD1306 display driver and graphics) by rewriting some C++ code to XC and connect it to an XMOS I2C library [lib_i2c] / [module_i2c_master]). In this case I’d probably want to keep the Cpp files. xTIMEcomposer compiles and builds XC, C and Cpp. However, I would need to address at least these points:

  1. Mike McCauley wrote that “If you can send your compatible changes in the form of a patch set, including documentation, we will consider rolling your changes in to the baseline code rather than you maintaining your own git repository. IMHO multiple git repositories makes for much confusion for end-users”. So..
    • ..I will need to modify RadioHead.h, and add code that accurately detects my
      compilation environment with something like:

      #define RH_PLATFORM_XMOS 16
  2. The top level would be some XC task that’s started in a par statement in main.xc. It needs chan or interface communication with the other concurrent tasks, like the aquarium controller’s tasks. XC has this in the language. Then I will need to define the services I need in the chan or interface declarations
  3. Functionality that in XC most probably will be done as a parameter to a select. I guess that wrapping up the standard interrupt function in the Arduino code into proper select may be a challenge. Both of these are standard functionality for XC, but ending up with a shared library may be difficult
    • I need to port the Arduino attachInterrupt() function to set interrupts that are triggered when digital inputs change state. This is an essential behaviour in many RH drivers
    • RH_ASK.cpp requires a timer that will trigger an interrupt at tightly controlled intervals. I will need to find a way to do that too
  4. The arduino millis() will need to be ported. The easiest port ever!
  5. All the RadioHead SPI bus calls will have to be done with the XMOS SPI library [lib_spi] (search for [lib_spi] here). The calls will use the interface needed by spi_master, carried down from main. The parameter to the SPI lib is an array of interface so I could have more than one client in the future. Like adding a WiFi web server. These code changes need to be done in RHHardwareSPI.cpp
  6. The other digital IOs would be just mapped to XC pins and wrapped up. The Arduino digital I/O library only consist of DigitalWrite, DigitalRead and PinMode. See [18]
  7. XC data types are limited. All the cores are 32 bit. However, the C types long long int, float and double are unsupported. See XC is C plus X [2]. One example, I guess that the params for setFrequency would have to become signed binary fraction built with signed int (32 bit). There is a library called [sc_lib_fixed_point] with a mathf8_24.h file that probably is a good start. But that’s 8.24 fixed point numbers, and 433.0 MHz isn’t in the range.. [19]. I would like 16.16 I guess. I’ll have to look into this closer
  8. I will have a challenge with file names. The RadioHead library has standard C and Cpp files, in addition to the top level .ino file. It also has individual .pde files (old convention for the newer .ino according to Mike McCauley). I don’t think that the xTIMEcomposer wants to compile .ino and .pde files. I have queried at this at [21]. Both must contain setup() and loop() methods which are called by a higher level like this:
        while (1)

    I cant’ wait to try to port it to XC!

  9. Starting research on this, here is a query on XCore Exchange that I posted: Preprocessor not resolving parameter at usage of a port macro
  10. Another one, about how to get the XC part of the compiler to pick up Cpp, see combining XC and C++ (search for “Sat Jan 20, 2018”)
  11. There is a rather frightening post by finiksa in 2014 about porting Arduino libraries, see C++ and XMOS. I don’t know about when to proceed and when to give up..
  12. Perhaps How to call C++ functions from XC? might help?

Adafruit SSD1306 on XMOS board

I have been asked about the code that makes it possible to use the SSD1306 on XMOS boards.

The Adafruit monochrome 128×32 I2C OLED graphic display is their product id 931 (here), containing module UG-2832HSWEG02 with chip SSD1306 from Univision Technology Inc. You will find Univision’s data sheets in the said url as well.

I have wrapped my code into a zip, but it is not at all a “runnable” test program. I had that in my early xTIMEcomposer version control (Git) system, but I didn’t want to publish it here because my latest code is the greatest. Instead I have just pulled some files out of my aquarium project “as is”. Observe that the broader part of the SSD1306 code have been written by Adafruit (some based on Univision’s pseudo code), and then modified by me. I probably should have made a branch on their GitHub node (here). The reason I haven’t done it is because I think it too much different. Maybe this is a recipe of how not to do things, but I’ll give it a try and publish it here. The code works and has been taking care of my fishes for some time now. Disclaimer: It may be easier to port the Cpp and C files more directly (as I explained in the chapter above) but I didn’t do that. So here are .xc files for .cpp etc.

Observe that I have used the older XMOS code [module_i2c_master] and not the newer [lib_i2c], which is more advanced.

Here’s the code, which I guarantee nothing about and have no responsibility for: here (rev2). It’s rev2 since I for some hours overlooked that the display is connected to my internal I2C, not the external hw-protected I2C bus that reads temperatures. A failure of the latter (even short) will be shown in the display. Should you find out that I have not included something very important then please mail me. Also, should you end up with a runnable test system for f.ex. the startKIT, maybe we should join forces and do something on GitHub?


I think I will continue to keep all my conclusions to the same chapter, in a previous blog note. See My single-board boards and why note, chapter Conclusion, bullet 4 there.

Radio on three boards

See picture below. This is how it goes when I don’t plan as much as I should. The longer cross coupling field caused the board to become too long for the PCIe piggy-back board (shown here). So the white board below the radio board is shorter and nicer on the rightmost unit in the picture. I could have done it like that from the start.

Fig.3 My Adafruit RFM69HCW radio board plugged onto an XMOS eXplorerKIT, Adafruit Feather ARM M0 (Arduino Zero like) and Xmos startKIT (press for more pixels)


  1. Adafruit RFM69HCW and RFM9X LoRa Packet Radio Breakouts, see
  2. Adafruit: Using the RFM69 Radio, see
  3. Adafruit RFM69HCW Transceiver Radio Breakout – 433 MHz – RadioFruit, see
  4. Semtech SX1231 Integrated RF Transceiver with on +17dBm 290-1000MHz, see
  5. Semtech SX1276 137 MHz to 1020 MHz Low Power Long Range Transceiver, see
  6. MikroElektronika, WIRELESS CONNECTIVITY. RF Sub 1GHz, see*=rf-sub-1ghz
  7. Nordic nRF905 Low power Multiband Sub 1-GHz RF Transceiver IC, see
  8. Nordic nRF9E5 Multiband Sub 1-GHz RF System-on-Chip (SoC), see
  9. SparkfunRFM69HCW Wireless Transceiver – 434MHz, see
  10. Sparkfun: SparkFun RFM69 Breakout (434MHz), see
  11. Hoperf Electronics, RFM69HCW Programmable 315-915Mhz RF Transceiver Module, see
  12. Re: RFM69 & HopeRF: clones or not?,see
  13. Semtech: Wireless RF Design Providers, see – including Hoperf Electronics
  14. RadioHead Packet Radio library for embedded microprocessors, see
  15. RadioHead RH_RF69 Class Reference, see
  16. Re: how to use many arduinos (at the same time) with just a single computer?, see Observe that the last action should be -Double-click ‘Arduino’ to run it.
  17. Forskrift om generelle tillatelser til bruk av frekvenser (fribruksforskriften), se
  18. Arduino Language Reference, Functions, see
  19. XMOS Fixed point library, see
  20. Getting the RF69 to run on XMOS processor, at the radiohead-arduino discussion group, see!topic/radiohead-arduino/P8SrTO9kGEY. Started by me
  21. Porting the Arduino RadioHead library to XMOS at the XCore Exchange, discussion group, see Started by me
Email this to someoneShare on Facebook

Leave a Reply

Your email address will not be published. Required fields are marked *


* Copy This Password *

* Type Or Paste Password Here *

14,551 Spam Comments Blocked so far by Spam Free Wordpress

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>