I am excited to see a library for the RFM69 for CircuitPython from Adafruit.  While I want to use LoRa, this library is a good start to a RadioHead port. 

The Goal

The goal of this post is to document the steps that got to a conversation between two Feather M0 RFM69’s using the new adafruit_RFM69.py library developed by Tony DiCola.  A “successful” conclusion has one RFM69 Feather sending packets while the other receives them.

Thanks to Those That Went Before

  • Tony Dicola for many things related to the projects I work on.  In particular for this post, Tony wrote the RFM69 for CircuitPython library.  I also enjoy his videos, like this one:  – MicroPython mpy-utils: Mount MicroPython board as filesystem and more with Tony D!  Clearly useful in understanding and using these tools within the CircuitPython workflow.  When I think of Tony, I think of an exceptionally gifted programmer who has the rare skills of being able to kindly teach and communicate.   
  • Adafruit – thank you for treating me – us – your customers – as people you care about.  The would would be AH-MAZ- ZING …if companies – especially the largest one – saw their shareholders as not only EVERYONE that works for them but also the customers.  Thank you for the great products.  Thank you for sharing your passion and knowledge.
  • @kattni @jerryn @cater @þeshipu @tonydi on Adafruit’s circuitpython discord channel.  I would not have been able to get this working without their help.  @cater pointed me to the location where there were mpy-cross utilities for the different platforms.  @kattni built me a version of mpy-cross that works on Mac Sierra since the version on the site.  @jerryn provided me with a build of CircuitPython that accepted pin settings for CS and RST.

Open Source

The Adafruit team is constantly evolving Circuit Python.  There seems to be new goodies at about once a month.  The latest release as I write this post is CircuitPython 2.2.1.  What is a YIPPEE! moment regarding this release is the inclusion of CircuitPython build for the RFM69 Feather and RFM8Z Feather.  I’m using the RFM69 Feather for now because it appears to be the one Tony works and tests on first.  Besides, the GitHub readme notes: 


The files I used for this post are located in my CircuitPythonRadio GitHub repository.

  • lib contains the .mpy library files that need to be copied to the /lib folder on the Feather.
  • lib_extra contains the mpy-cross utility @kattni built for me that runs on Mac Sierra.  Also, adafruit_rfm69.py is in this folder since I created a .mpy from this file.  Adafruit had the adafruit_rfm69.py library posted at this GitHub location.
  • Python contains:
    • The simpltest.py Tony wrote to test the adafruit_rfm69.py library 
    • send.py and receive.py – a riff on Tony’s example to keep sending packets.  I found it simpler to have one script whose job was solely to send packets and another whose job was to receive packets.  I copied send.py to one of the Feathers and renamed it main.py .  Similarly, I copied receive.py to the other Feather and renamed it main.py. 
    • Remove_comments_adafruit_rfm69.py I wrote to practice regular expressions.  I thought I might be able to remove all comments and then get to a file size that was equivalent to a .mpy.  Alas, I got to 15KB.  The .mpy is 10KB.  However, the more practice I can get with regular expressions is a “good thing” for me because they certainly come in handy…I just know, know, know in the future I will want to whip out my bag-oh-regular expression tricks…but for now…my knowledge will stay minimal and my use at this moment will remain dormant.

CircuitPython + Atom

It is best to use a code editor when working with Circuit Python.  On the mac, the Finder and text editors will bloat away any space on the Feather with backup, indexing files, etc….stuff that isn’t needed for Circuit Python.  The other reason is it can simplify running and debugging code.  My code editor of choice is Atom.

Tony talks about this in his video: CircuitPython & macOS: Getting Started and Editing Files with Tony D!  It’s worth a watch if you are not familiar with CircuitPython + Atom workflow.

Install the software

I use a Mac.  The steps I used include:

  • Install the RFM69 Feather version of circuit python.  At the time I was trying out the library, there was no RFM Feather CircuitPython bin.  Lucky for me, the most kind @jerryn sent me feather_m0_rfm69_firmware.bin.  I used BOSSA to install onto the Feather, erasing all files.  Don’t forget to click the reset button twice to get into boot loader mode. 
  • After installation, restart the Feather by clicking the reset button once.
  • (Maybe in the future a lack space will be less of an issue…for now…)  Maximize the amount of space for code on the Feather M0 by following the instructions given in  “welcome-to-circuitpython.pdf.” From the doc:

Mac OSX loves to add extra files.  Luckily you can disable some of the extra hidden files that Mac OSX adds by running a few commands to disable search indexing and create zero byte placeholders.

ls -l /Volumes 

Look for a volume with a name like CIRCUITPY (the default for CircuitPython). The full path to the volume is the /Volumes/CIRCUITPY path.  Now follow these handy-dandy-not-easy-to-remember steps:

mdutil -i off /Volumes/CIRCUITPY

cd /Volumes/CIRCUITPY

rm -rf .{,_.}{fseventsd,Spotlight-V*,Trashes}

mkdir .fseventsd

touch .fseventsd/no_log .metadata_never_index .Trashes

Now let’s never use the finder….and not forget to use the easy-to-forget command.  The doc goes on to caution: …you need to be careful to copy files to the board with a special command that prevents future hidden files from being created…

cp -X foo.mpy /Volumes/CIRCUITPY

cp -rX folder_to_copy /Volumes/CIRCUITPY

we’ll also want to check out how much space there is on the CIRCUITPYTHON volume with the df command.


  • Compress adafruit_rfm69.py from 33KB to adafruit_rfm69.mpy which will end up being 10KB.  If I didn’t do this, I ran out of memory.
    • GOTCHA: I had a vague idea what a mpy file was all about.  But…bummer…in Tony’s post he notes that mpy-cross runs on Vagrant.  Sadly, I installed/uninstalled Vagrant…great stuff…but a level of complexity I wanted to avoid.
      • @cater sent me a message on Adafruit/discord/circuitpython that the circuitpython builds included mpy-cross builds.  OOH!! Excitedly download mpy-cross-2.2.0-macos-high-sierra.  I am running Sierra on my Mac.  Unfortunately, despite help I gratefully received from the discord channel, I could not get mpy-cross to run on my Mac. @kattni jumped in and very kindly built me a version of mpy-cross that runs on Sierra.
      • go to a terminal window, get the file paths right (as needed):
        • $ ./mpy-cross adafruit_rfm69.py
  • Make a /lib folder on the Feather:  CIRCUITPY margaret$ mkdir lib
  • Copy adafruit_rfm69.mpy and BusDevice folder into the /lib folder.  This way we can use one copy command to copy the libraries into the Feather’s /lib folder.  Use -X and -r as noted above. 

Run Code

After copying the python libraries (adafruit_rfm69.mpy and the adafruit_bus_device folder) to the CIRCUITPY volume’s lib folder, i.e.: /Volumes/CIRCUITPY/lib, I used the Atom editor to copy send.py on one of the Feathers and receive.py on the other.  Both were then renamed main.py.

Note the pin settings:

CS = digitalio.DigitalInOut(board.RFM69_CS)

RESET = digitalio.DigitalInOut(board.RFM69_RST)

I then opened two screens, one for each of the Feathers:


and YIPPEE!!! RFM69 packets whizzed between the sending Feather and the receiving Feather….

Notes from Along the Way

I put stuff here that I thought was worth sharing and remembering…at least documenting somewhere in the somewhat doubtful attempt I’ll be able to find in the future.

Kill Process

Sometimes the serial port continues to run even after I closed down the window.  When that happens, I close the process by doing the following in a terminal window:

$ lsof | grep /dev/tty.usbmodem1421

This gives me the process number:


screen    2451 margaret    5u      CHR              20,10    0t2103     1457 /dev/tty.usbmodem1421

I can then kill it:


$ kill 2451

Tried -> Not Useful

I originally tried to simplify the file copy workflow by using mpy-fuse to mount the Feather’s storage as a drive on Finder.  This generates errors most likely because I turn off indexing (and other?) goo that Finder wants to put on a storage device.  I’m sticking to ampy for file operations.  

Steps I took setting up mpy-fuse:

  • Install  Fuse.  I had done this when I was starting out programming on a Raspberry Pi.  Fuse extends the MacOS file system to devices like the Feather and Raspberry Pi that have a different file system than what is native on the Mac OS.
  • Install the mpy-utils, The utilities includes may-fuse.  I used pip within Terminal:

pip install mpy-utils Tony talks about needing sudo. However, just pip worked for me. This is most likely because I am not using the default Python that comes on a Mac. The version of Python I am using is Python 3.6.1 |Anaconda custom (x86_64)| (default, May 11 2017, 13:04:09) check the install:

mpy-fuse — help



mpy-fuse –port /dev/tty.usbmodem1421 –baud 115200 /Users/margaret/feather_board

Now I can see the Feather as a drive: