# Radio FeatherWing

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/035/122/medium800/feather_3229_iso_demo_ORIG.jpg?1472069597)

Add short-hop wireless to your Feather with these Radio Featherwings. These add-ons for any Feather board will let you integrate packetized radio (with the RFM69 radio) or LoRa radio (with the RFM9x's). These radios are good options for kilometer-range radio, and paired with one of our WiFi, cellular or Bluetooth Feathers, will let you bridge from 433/900 MHz to the Internet or your mobile device.

![](https://cdn-learn.adafruit.com/assets/assets/000/035/123/medium800/feather_3229_iso_ORIG.jpg?1472069611)

These radio modules come in&nbsp;four variants&nbsp;(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, longer-range and more powerful but also more expensive.

- **RFM69 @ 433 MHz** - basic packetized FSK/GFSK/MSK/GMSK/OOK radio at 433 MHz for use in Europe ITU 1 license-free ISM, or for amateur use with restrictions (check your local&nbsp; amateur regulations!)
- **RFM69 @ 900 MHz** - basic packetized FSK/GFSK/MSK/GMSK/OOK radio at 868 or 915 MHz for use in Americas ITU 2 license-free ISM, or for amateur use with restrictions (check your amateur regulations!)
- **RFM98 @ 433 MHz** - LoRa capable radio at 433 MHz for use in Europe ITU 1 license-free ISM, or for amateur use with restrictions (check your local amateur regulations!)
- **RFM95 @ 900 MHz** - LoRa capable radio at 868 or 915 MHz for use in Americas ITU 2 license-free ISM, or for amateur use with restrictions (check your local amateur regulations!)

The radio modules themselves have the same pinout so the PCB is the same, but the library usage and wiring may vary. All use SPI for interfacing, and there are great Arduino libraries available for both.

![](https://cdn-learn.adafruit.com/assets/assets/000/035/124/medium800/feather_3229_quarter_ORIG.jpg?1472069638)

## RFM69 Specs

- SX1231 based module with SPI interface
- Packet radio with ready-to-go Arduino libraries
- Uses the license-free ISM bands
- +13 to +20 dBm up to 100 mW Power Output Capability (power output selectable in software)
- 50mA (+13 dBm) to 150mA (+20dBm) current draw for transmissions
- Range of approx. 350 meters, depending on obstructions, frequency, antenna and power output
- Create multipoint networks with individual node addresses
- Encrypted packet engine with AES-128

## RFM9x Specs

- SX127x LoRa®&nbsp;based module with SPI interface
- Packet radio with ready-to-go Arduino libraries
- Uses the license-free ISM bands
- +5 to +20 dBm up to 100 mW Power Output Capability (power output selectable in software)
- ~300uA during full sleep, ~120mA peak during +20dBm transmit, ~40mA during active radio listening.
- Our initial tests with default library settings: over 1.2mi/2Km line-of-sight with wire quarter-wave antennas. ([With setting tweaking and directional antennas, 20Km is possible](http://forum.anarduino.com/posts/list/46.page#2854)).

![](https://cdn-learn.adafruit.com/assets/assets/000/035/127/medium800/feather_3229_kit_ORIG.jpg?1472071965)

Currently tested to work with the **Feather ESP8266** , **Feather 32u4** , **Feather M0, WICED Feather** (RFM69 library only) and **Teensy 3 Feather** series, some wiring is required to configure the FeatherWing for the chipset you plan to use.

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.

Each radio 'Wing comes with some header. Some soldering is required to attach the header. You will need to cut and solder on a small piece of wire (any solid or stranded core is fine) in order to create your antenna. Optionally you can pick up a uFL or SMA edge-mount connector and attach an external duck.

# Radio FeatherWing

## Pinouts

![](https://cdn-learn.adafruit.com/assets/assets/000/035/100/medium800/feather_pinouts.jpg?1472066203)

# SPI Data Pins (Fixed)

The three SPI data pins (MOSI/MISO/SCK) are hardwired to these three pads, which are use for the default SPI interface on all Feathers:

![](https://cdn-learn.adafruit.com/assets/assets/000/035/101/medium800/feather_spipins.jpg?1472066242)

# SPI Control Pins (Flexible)

You also need three more pins to control the radio: **IRQ** ,&nbsp; **CS** and **RST**.

Since there is no guaranteed pin that is consistently interrupt-capable across all Feather boards, we set it up so you can wire these three to any three pins available. For the non-Serial/IC pins on the right, we name them **A** thru **F**. We also indicate the **RX/TX/SDA/SCL** pins if you need to use those:

![](https://cdn-learn.adafruit.com/assets/assets/000/035/102/medium800/feather_extrapins.jpg?1472066413)

 **Three wires** from **IRQ** , **CS** and **RST** will be **soldered** to three of these other points. **Exactly _which_ pins to connect are shown on the next page (it varies among Feather boards)**, this is merely to illustrate how the short soldered wires might look when installed:

![](https://cdn-learn.adafruit.com/assets/assets/000/035/103/medium800/feather_wiring.jpg?1472066452)

Again: **follow the directions on the next page** ; the jumpers shown above are not suitable for every Feather board.

# RFM GPIO

There's some other GPIO pins that you may want to use - they can be configured to give you notice of things like packet completion or incoming data. They're all on the left. **DIO0** is also known as **IRQ** so we don't have that duplicated on the left breakouts

![](https://cdn-learn.adafruit.com/assets/assets/000/035/104/medium800/feather_gpio.jpg?1472066511)

# Antenna

For an antenna, you have **three** options:

- Plain wire antenna (cut a quarter-wavelength piece and solder it into the pad/hole
- [uFL connector (not included)](https://www.adafruit.com/products/1661), which can be soldered and then used to attach a uFL antenna or adapter
- [SMA edge-launch (not included)](https://www.adafruit.com/products/1865), for use with any SMA connector

![](https://cdn-learn.adafruit.com/assets/assets/000/035/105/medium800/feather_antenna.jpg?1472066718)

# Radio FeatherWing

## Wiring

![](https://cdn-learn.adafruit.com/assets/assets/000/035/099/medium800/feather_wiring.jpg?1472065983)

Because each Feather uses a different processor, there is some light wiring that needs to be done to configure the radio pins. In particular, an interrupt-capable pin is required for **IRQ** but there is no one interrupt pin that is consistent across all Feather boards!

So, while MOSI/MISO/SCK are fixed, you will want to solder three short wires for **CS, RST** and **IRQ**

Here is our tested/suggested wiring configurations and code snippets for defining the pins…

# ESP8266 Wiring

The ESP does not have a lot of spare pins, and the SPI pins are taken, so here's what we've tested that works. For LoRa radio projects:

```auto
#define RFM95_CS  2    // "E"
#define RFM95_RST 16   // "D"
#define RFM95_INT 15   // "B"
```

And for RFM69 projects:

```auto
#define RFM69_CS      2
#define RFM69_RST     16
#define RFM69_IRQ     15
#define RFM69_IRQN    digitalPinToInterrupt(RFM69_IRQ )
```

This leaves the I2C default pins (4 and 5) available

# Feather 32u4

The 32u4 doesn't have a lot of IRQs and the only ones available are on pins 0, 1, 2, 3 which are also the Serial RX/TX and I2C pins. So it's not great because you have to give up one of those pins. Here’s a pinout that works for LoRa radio projects:

```auto
#define RFM95_CS  10   // "B"
#define RFM95_RST 11   // "A"
#define RFM95_INT 2    // "SDA" (only SDA/SCL/RX/TX have IRQ!)
```

And for RFM69 radio projects:

```auto
#define RFM69_CS      10   // "B"
#define RFM69_RST     11   // "A"
#define RFM69_IRQ     2    // "SDA" (only SDA/SCL/RX/TX have IRQ!)
#define RFM69_IRQN    digitalPinToInterrupt(RFM69_IRQ )
```

# Feather M0

The Feather M0 is really easy to use, a ton of interrupts so wiring is easy. This works for LoRa radio projects:

```auto
#define RFM95_CS  10   // "B"
#define RFM95_RST 11   // "A"
#define RFM95_INT  6   // "D"
```

And for RFM69:

```auto
#define RFM69_CS      10   // "B"
#define RFM69_RST     11   // "A"
#define RFM69_IRQ     6    // "D"
#define RFM69_IRQN    digitalPinToInterrupt(RFM69_IRQ )
```

# Other Boards

For other boards like the ESP32 or nRF52, any pin can be an interrupt, so feel free to use any wiring setup you like! Some example projects (as in the RadioHead Arduino library) may already have some pins defined for various boards, so you might want to follow those.

# Radio FeatherWing

## Assembly

# Antenna Options

These radio Wings do not have a built-in antenna. Instead, you have three options for attaching an antenna. For most low cost radio nodes, a wire works great. If you need to put the radio into an enclosure, soldering in uFL and using a uFL to SMA adapter will let you attach an external antenna. You can also solder an SMA edge-mount connector directly

## Wire Antenna

A wire antenna, aka "quarter wave whip antenna" is low cost and works very well! You just have to cut the wire down to the right length.

Cut a stranded or solid core wire the the proper length for the module/frequency

- **433 MHz** - 6.5 inches, or 16.5 cm
- **868 MHz** - 3.25 inches or 8.2 cm
- **915 MHz** - 3 inches or 7.8 cm

Strip a mm or two off the end of the wire, tin and solder into the **ANT** pad.

![feather_3229_iso_demo_ORIG.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/107/medium640/feather_3229_iso_demo_ORIG.jpg?1472068951)

# uFL Connector

If you want an external antenna that is a few inches away from the radio, you need to do a tiny bit more work but its not too difficult.

[You'll need to get an SMT uFL connector, these are fairly standard](https://www.adafruit.com/products/1661)

[You'll also need a uFL to SMA adapter](https://www.adafruit.com/products/851)&nbsp;(or whatever adapter you need for the antenna you'll be using, SMA is the most common

Of course, you will also need an antenna of some sort, that matches your radio frequency

Warning: 

Start by melting solder onto the center signal pad

![feather_UFL-1_solder.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/108/medium640/feather_UFL-1_solder.jpg?1472069029)

![feather_UFL-2_board.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/109/medium640/feather_UFL-2_board.jpg?1472069041)

Check the bottom of the uFL connector, note that there's two large side pads (ground) and a little inlet pad. The other small pad is not used!

![feather_UFL-3_orientation.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/110/medium640/feather_UFL-3_orientation.jpg?1472069064)

Solder in the first pad while holding the uFL steady

![feather_UFL-4_solder1.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/111/medium640/feather_UFL-4_solder1.jpg?1472069082)

![feather_UFL-4_solder2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/112/medium640/feather_UFL-4_solder2.jpg?1472069102)

Solder in the two side pads, they are used for signal and mechanical connectivity so make sure there's plenty of solder

![feather_UFL-4_solder3.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/113/medium640/feather_UFL-4_solder3.jpg?1472069120)

![feather_UFL-4_solder4.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/114/medium640/feather_UFL-4_solder4.jpg?1472069128)

Once done, check your work visually

![feather_UFL-5_finished.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/115/medium640/feather_UFL-5_finished.jpg?1472069145)

# SMA Edge-Mount Connector

These strong edge connectors are used for many 'duck' antennas, and can also be panel mounted

You'll need an SMA (or, if you need RP-SMA for some reason) Edge-Mount connector with 1.6mm spacing

The SMA connector 'slides on' the top of the PCB

![feather_2-SMA_onPCB.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/117/medium640/feather_2-SMA_onPCB.jpg?1472069212)

Solder all 5 connections (4 ground/mechanical and 1 signal)

![feather_3-SMA_solder1.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/118/medium640/feather_3-SMA_solder1.jpg?1472069234)

![feather_3-SMA_solder2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/119/medium640/feather_3-SMA_solder2.jpg?1472069239)

![feather_4-SMA_solder1.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/120/medium640/feather_4-SMA_solder1.jpg?1472069264)

Use plenty of solder to make sure you have a good strong mechanical connection. The duck antennas are long and make great levers, so they could pry apart the solder joints if not soldered well

![feather_5-SMA_finished.jpg](https://cdn-learn.adafruit.com/assets/assets/000/035/121/medium640/feather_5-SMA_finished.jpg?1472069283)

# Radio FeatherWing

## Using the RFM69 Radio

This page is shared between the RFM69 breakout and the all-in-one Feather RFM69's. The example code and overall functionality is the same, only the pinouts used may differ! Just make sure the example code is using the pins you have wired up.

![feather_adafruit_products_3070_iso_ORIG.jpg](https://cdn-learn.adafruit.com/assets/assets/000/040/611/medium640/feather_adafruit_products_3070_iso_ORIG.jpg?1491191673)

![feather_3076_iso_demo_ORIG.jpg](https://cdn-learn.adafruit.com/assets/assets/000/040/612/medium640/feather_3076_iso_demo_ORIG.jpg?1491191702)

Before beginning make sure you have your Arduino or Feather working smoothly, it will make this part a lot easier. Once you have the basic functionality going - you can upload code, blink an LED, use the serial output, etc. you can then upgrade to using the radio itself.

Note that the sub-GHz radio is not designed for streaming audio or video! It's best used for small packets of data. The data rate is adjustable but its common to stick to around 19.2 Kbps (thats bits per second). Lower data rates will be more successful in their transmissions

**You will, of course, need at least two paired radios** to do any testing! The radios must be matched in frequency (e.g. two 900 MHz&nbsp; radios are ok, but mixing 900 MHz and 433 MHz is _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.

# "Raw" vs Packetized

The SX1231 can be used in a 'raw rx/tx' mode where it just modulates incoming bits from pin #2 and sends them on the radio, however there's no error correction or addressing so we wont be covering that technique.

Instead, 99% of cases are best off using _packetized_ mode. This means you can set up a recipient for your data, error correction so you can be sure the whole data set was transmitted correctly, automatic re-transmit retries and return-receipt when the packet was delivered. Basically, you get the transparency of a data pipe without the annoyances of radio transmission unreliability

# Arduino Libraries

These radios have really great libraries already written, so rather than coming up with a new standard we suggest using existing libraries such as&nbsp;[LowPowerLab's RFM69 Library](https://github.com/LowPowerLab/RFM69) and&nbsp;[AirSpayce's Radiohead library](http://www.airspayce.com/mikem/arduino/RadioHead/) which also suppors a vast number of other radios

These are really great Arduino Libraries, so please support both companies in thanks for their efforts!

We recommend using the **Radiohead**  **library** - it is very cross-platform friendly and used a lot in the community!

## RadioHead Library example

To begin talking to the radio, you will need to [download our fork of the Radiohead library from our github repository](https://github.com/adafruit/RadioHead "Link: https://github.com/adafruit/RadioHead"). You can do that by visiting the github repo and manually downloading or, easier, just click this button to download the zip:

[Download RadioHead Library](https://github.com/adafruit/RadioHead/archive/master.zip)
Rename the uncompressed folder **RadioHead** and check that the **RadioHead** folder contains files like **RH\_RF69.**** cpp **and** RH\_RF69 ****.h** (and many others!)  
  
Place the **RadioHead** &nbsp;library folder in your **_arduinosketchfolder_/libraries/** folder.   
You may need to create the **libraries** subfolder if it's your first library. Restart the IDE.  
  
We also have a great tutorial on Arduino library installation at:  
[http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use](http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use "Link: http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use")

# Basic RX & TX example

Lets get a basic demo going, where one radio transmits and the other receives. We'll start by setting up the transmitter

## Basic Transmitter example code

This code will send a small packet of data once a second to another RFM69 radio, without any addressing.

Open up the example **RadioHead→feather→RadioHead69\_RawDemo\_TX**

Load this code into your Transmitter Arduino or Feather!

![](https://cdn-learn.adafruit.com/assets/assets/000/040/603/medium800/feather_basictx.png?1491189415)

Danger: 

Info: 

Once uploaded you should see the following on the serial console

![](https://cdn-learn.adafruit.com/assets/assets/000/040/599/medium800/feather_txdemo.png?1491188161)

Now open up another instance of the Arduino IDE - this is so you can see the serial console output from the TX device while you set up the RX device.

## Basic receiver example code

This code will receive and reply with a small packet of data.

Open up the example **RadioHead→feather→RadioHead69\_RawDemo\_RX**

Load this code into your **Receiver** Arduino/Feather!

![](https://cdn-learn.adafruit.com/assets/assets/000/040/604/medium800/feather_basicrc.png?1491189503)

Danger: 

Info: 

Now open up the Serial console on the receiver, while also checking in on the transmitter's serial console. You should see the receiver is...well, receiving packets

![](https://cdn-learn.adafruit.com/assets/assets/000/040/600/medium800/feather_rxdemo.png?1491188270)

And, on the transmitter side, it is now printing **Got Reply** after each transmisssion because it got a reply from the receiver

![](https://cdn-learn.adafruit.com/assets/assets/000/040/601/medium800/feather_repl.png?1491188298)

That's pretty much the basics of it! Lets take a look at the examples so you know how to adapt to your own radio network

## Radio Freq. Config

Each radio has a frequency that is configurable in software. You can actually tune outside the recommended frequency, but the range won't be good. 900 MHz can be tuned from about 850-950MHz with good performance. 433 MHz radios can be tuned from 400-460 MHz or so.

```auto
// Change to 434.0 or other frequency, must match RX's freq!
#define RF69_FREQ 915.0
```

For all radios they will need to be on the same frequency. If you have a 433MHz radio you will want to stick to 433. If you have a 900 Mhz radio, go with 868 or 915MHz, just make sure all radios are on the same frequency.

## Configuring Radio Pinout

At the top of the sketch you can also set the pinout. The radios will use hardware SPI, but you can select any pins for **RFM69\_CS** (an output), **RFM\_IRQ** (an input) and **RFM\_RST** (an output). RFM\_RST is manually used to reset the radio at the beginning of the sketch. **RFM\_IRQ** must be an interrupt-capable pin. Check your board to determine which pins you can use!

Also, an LED is defined.

For example, here is the Feather 32u4 pinout:

```cpp
#if defined (__AVR_ATmega32U4__)  // Feather 32u4 w/Radio
  #define RFM69_CS    8
  #define RFM69_INT   7
  #define RFM69_RST   4
  #define LED        13
```

If you're using a Feather M0, the pinout is slightly different:

```cpp
#elif defined(ADAFRUIT_FEATHER_M0) || defined(ADAFRUIT_FEATHER_M0_EXPRESS) || defined(ARDUINO_SAMD_FEATHER_M0)  // Feather M0 w/Radio
  #define RFM69_CS    8
  #define RFM69_INT   3
  #define RFM69_RST   4
  #define LED        13
```

And for Feather RP2040:

```cpp
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_RFM)  // Feather RP2040 w/Radio
  #define RFM69_CS   16
  #define RFM69_INT  21
  #define RFM69_RST  17
  #define LED        LED_BUILTIN
```

If you're using an Arduino UNO or compatible, we recommend:

```cpp
#elif defined (__AVR_ATmega328P__)  // Feather 328P w/wing
  #define RFM69_CS    4  //
  #define RFM69_INT   3  //
  #define RFM69_RST   2  // "A"
  #define LED        13
```

If you're using a FeatherWing or different setup, you'll have to set up the `#define` statements to match your wiring

You can then instantiate the radio object with our custom pin numbers. Note that the IRQ is defined by the IRQ pin not number (sometimes they differ).

```auto
// Singleton instance of the radio driver
RH_RF69 rf69(RFM69_CS, RFM69_INT);
```

## Setup

We begin by setting up the serial console and hard-resetting the RFM69

```auto
void setup() 
{
  Serial.begin(115200);
  //while (!Serial) { delay(1); } // wait until serial console is open, remove if not tethered to computer

  pinMode(LED, OUTPUT);     
  pinMode(RFM69_RST, OUTPUT);
  digitalWrite(RFM69_RST, LOW);

  Serial.println("Feather RFM69 RX Test!");
  Serial.println();

  // manual reset
  digitalWrite(RFM69_RST, HIGH);
  delay(10);
  digitalWrite(RFM69_RST, LOW);
  delay(10);
```

If you are using a board with 'native USB' make sure the **while (!Serial)** line is commented out if you are not tethering to a computer, as it will cause the microcontroller to halt until a USB connection is made!

## Initializing Radio

Once initialized, you can set up the frequency, transmission power, radio type and encryption key.

For the **frequency** , we set it already at the top of the sketch

For **transmission power** you can select from 14 to 20 dBi. Lower numbers use less power, but have less range. The second argument to the function is whether it is an HCW type radio, with extra amplifier. This should _always_ be set to **true**!

Finally, if you are **encrypting** data transmission, set up the encryption key

```auto
  if (!rf69.init()) {
    Serial.println("RFM69 radio init failed");
    while (1);
  }
  Serial.println("RFM69 radio init OK!");
  
  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM (for low power module)
  // No encryption
  if (!rf69.setFrequency(RF69_FREQ)) {
    Serial.println("setFrequency failed");
  }

  // If you are using a high power RF69 eg RFM69HW, you *must* set a Tx power with the
  // ishighpowermodule flag set like this:
  rf69.setTxPower(20, true);  // range from 14-20 for power, 2nd arg must be true for 69HCW

  // The encryption key has to be the same as the one in the server
  uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
  rf69.setEncryptionKey(key);
```

## Basic Transmission Code

If you are using the transmitter, this code will wait 1 second, then transmit a packet with "Hello World #" and an incrementing packet number, then check for a reply

```auto
void loop() {
  delay(1000);  // Wait 1 second between transmits, could also 'sleep' here!

  char radiopacket[20] = "Hello World #";
  itoa(packetnum++, radiopacket+13, 10);
  Serial.print("Sending "); Serial.println(radiopacket);
  
  // Send a message!
  rf69.send((uint8_t *)radiopacket, strlen(radiopacket));
  rf69.waitPacketSent();

  // Now wait for a reply
  uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);

  if (rf69.waitAvailableTimeout(500))  { 
    // Should be a reply message for us now   
    if (rf69.recv(buf, &amp;len)) {
      Serial.print("Got a reply: ");
      Serial.println((char*)buf);
      Blink(LED, 50, 3); //blink LED 3 times, 50ms between blinks
    } else {
      Serial.println("Receive failed");
    }
  } else {
    Serial.println("No reply, is another RFM69 listening?");
  }
}
```

Its pretty simple, the delay does the waiting, you can replace that with low power sleep code. Then it generates the packet and appends a number that increases every tx. Then it simply calls `send()` `waitPacketSent() `to wait until is is done transmitting.

It will then wait up to 500 milliseconds for a reply from the receiver with `waitAvailableTimeout(500)`. If there is a reply, it will print it out. If not, it will complain nothing was received. Either way the transmitter will continue the loop and sleep for a second until the next TX.

## Basic Receiver Code

The Receiver has the same exact setup code, but the loop is different

```auto
void loop() {
 if (rf69.available()) {
    // Should be a message for us now   
    uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
    uint8_t len = sizeof(buf);
    if (rf69.recv(buf, &amp;len)) {
      if (!len) return;
      buf[len] = 0;
      Serial.print("Received [");
      Serial.print(len);
      Serial.print("]: ");
      Serial.println((char*)buf);
      Serial.print("RSSI: ");
      Serial.println(rf69.lastRssi(), DEC);

      if (strstr((char *)buf, "Hello World")) {
        // Send a reply!
        uint8_t data[] = "And hello back to you";
        rf69.send(data, sizeof(data));
        rf69.waitPacketSent();
        Serial.println("Sent a reply");
        Blink(LED, 40, 3); //blink LED 3 times, 40ms between blinks
      }
    } else {
      Serial.println("Receive failed");
    }
  }
}
```

Instead of transmitting, it is constantly checking if there's any data packets that have been received. `available()` will return true if a packet with the proper encryption has been received. If so, the receiver prints it out.

It also prints out the RSSI which is the receiver signal strength indicator. This number will range from about -15 to -80. The larger the number (-15 being the highest you'll likely see) the stronger the signal.

If the data contains the text "Hello World" it will also reply to the packet.

Once done it will continue waiting for a new packet

# Basic Receiver/Transmitter Demo w/OLED

OK once you have that going you can try this example, **RadioHead69\_RawDemoTXRX\_OLED**. We're using the Feather with an OLED wing but in theory you can run the code without the OLED and connect three buttons to GPIO #9, 6, and 5 on the Feathers. Upload the same code to each Feather. When you press buttons on one Feather they will be printed out on the other one, and vice versa. Very handy for testing bi-directional communication!

![](https://cdn-learn.adafruit.com/assets/assets/000/040/605/medium800/feather_oledbasic.png?1491189570)

This demo code shows how you can listen for packets and also check for button presses (or sensor data or whatever you like) and send them back and forth between the two radios!

# Addressed RX and TX Demo

OK so the basic demo is well and good but you have to do a lot of _management_ of the connection to make sure packets were received. Instead of manually sending acknowledgements, you can have the RFM69 and library do it for you! Thus the **Reliable Datagram** part of the **RadioHead** library.

Load up the **RadioHead69\_AddrDemo\_RX** and **RadioHead69\_AddrDemo\_TX** sketches to each of your boards

Warning: 

This example lets you have many 'client' RFM69's all sending data to one 'server'

Each client can have its own address set, as well as the server address. See this code at the beginning:

```auto
// Who am i? (server address)
#define MY_ADDRESS   1

// Where to send packets to! MY_ADDRESS in client (RX) should match this.
#define DEST_ADDRESS 2
```

For each client, have a unique **MY\_ADDRESS**. Then pick one server that will be address #1

Once you upload the code to a client, you'll see the following in the serial console:

![](https://cdn-learn.adafruit.com/assets/assets/000/040/606/medium800/feather_noack.png?1491190936)

Because the data is being sent to address #1, but #1 is not acknowledging that data.

If you have the server running, with no clients, it will sit quietly:

![](https://cdn-learn.adafruit.com/assets/assets/000/040/607/medium800/feather_server.png?1491191058)

Turn on the client and you'll see acknowledged packets!

![](https://cdn-learn.adafruit.com/assets/assets/000/040/608/medium800/feather_acked.png?1491191100)

And the server is also pretty happy

![](https://cdn-learn.adafruit.com/assets/assets/000/040/609/medium800/feather_server2.png?1491191127)

The secret sauce is the addition of this new object:

```auto
// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram rf69_manager(rf69, MY_ADDRESS);
```

Which as you can see, is the manager for the RFM69. In **setup()** you'll need to init it, although you still configure the underlying rfm69 like before:

```auto
  if (!rf69_manager.init()) {
    Serial.println("RFM69 radio init failed");
    while (1);
  }
```

And when transmitting, use **sendToWait** which will wait for an ack from the recepient (at DEST\_ADDRESS)

```auto
  if (rf69_manager.sendtoWait((uint8_t *)radiopacket, strlen(radiopacket), DEST_ADDRESS)) {
```

on the 'other side' use the **recvFromAck** which will receive and acknowledge a packet

```auto
    // Wait for a message addressed to us from the client
    uint8_t len = sizeof(buf);
    uint8_t from;
    if (rf69_manager.recvfromAck(buf, &amp;len, &amp;from)) {
```

That function will wait forever. If you'd like to timeout while waiting for a packet, use **recvfromAckTimeout** which will wait an indicated # of milliseconds

```auto
if (rf69_manager.recvfromAckTimeout(buf, &amp;len, 2000, &amp;from)) 
```

# Radio FeatherWing

## CircuitPython for RFM69

It's easy to use the RFM69HCW radio with CircuitPython and the&nbsp;[Adafruit CircuitPython RFM69](https://github.com/adafruit/Adafruit_CircuitPython_RFM69)&nbsp;module.&nbsp; This module allows you to easily write Python code that sends and receives packets of data with the radio. &nbsp;Be careful to note this library is for the RFM69 radio only and **will not** work with the RFM9X LoRa radios!

## Design Considerations

One thing to be aware of before you use the RFM69 series of radios with CircuitPython are some of the limitations and design considerations for its module. &nbsp;Keep these in mind as you think about projects using the RFM69 and CircuitPython:

- You can only send and receive packets up to 60 bytes in length at a time. &nbsp;The size of the radio's internal buffer dictates this limit so if you want to send longer messages you'll need to break them into a series of smaller send calls in your application code.
- Receiving packets is a 'best effort' in pure Python code. &nbsp;Unlike the Arduino versions of the RFM69 library there is no interrupt support which means when a packet is received it must be immediately processed by the Python code or it could be lost. &nbsp;For your application it will work best to only receive small, single packet messages at a time. &nbsp;Don't try to receive kilobytes of data or else you'll lose packets. &nbsp;This module is really intended for simple single packet messages like 'ON', 'OFF', etc.
- Sending and receiving packets will 'block' your Python code until the packet is fully processed. &nbsp;This means you can't do a lot of other things while sending and waiting for packets to be received. &nbsp;Design your application so the radio usage is the primary scenario and very little other tasks need to happen in the background.
- The module is written to be compatible with the RadioHead RFM69 Arduino library. &nbsp;This means by default the module will setup the radio with the same GFSK, 250kbit/s, 250khz deviation, and bit whitening radio configuration so it can send and receive data with itself and other RadioHead-driven modules. &nbsp;In addition the CircuitPython module uses the same sync word and packet preamble (4 bytes) as RadioHead. &nbsp;If you want to use different modulations or settings you'll need to configure the radio yourself (see [the initialization code](https://github.com/adafruit/Adafruit_CircuitPython_RFM69/blob/master/adafruit_rfm69.py#L299-L318) for the registers and bits to access, however you will need to consult the datasheet for the necessary values).
- You can enable encryption and set an AES encryption key. &nbsp;
- The CircuitPython module supports advanced RadioHead features like node addressing and "reliable DataGram".&nbsp; "Reliable DataGram" mode in CircuitPython has some additional parameters to control timing that are not available with the RadioHead library. It may be difficult to get reliable transmission to work between the RadioHead library and CircuitPython.

## Wiring With Breakout

First wire up a RFM69 breakout to your board as shown on the previous pages for Arduino. &nbsp;Note that the G0/interrupt line is not used by the CircuitPython module and can remain unconnected. &nbsp; Here's an example of wiring a Feather M0 to the radio with a SPI connection:

![](https://cdn-learn.adafruit.com/assets/assets/000/050/193/medium800/adafruit_products_m0_rfm69_bb.png?1516149383)

- **Board 3V** &nbsp;to&nbsp; **radio VIN**
- **Board GND** &nbsp;to&nbsp; **radio GND**
- **Board SCK** &nbsp;to&nbsp; **radio SCK**
- **Board MOSI** &nbsp;to&nbsp; **radio MOSI**
- **Board MISO&nbsp;** to&nbsp; **radio MISO**
- **Board D5&nbsp;** to&nbsp; **radio CS&nbsp;** (or any other digital I/O pin)
- **Board D6&nbsp;** to **radio RST&nbsp;** (or any other digital I/O pin)

## Usage with All-In-One Feather M0

Alternatively you can use the Feather M0 RFM69 board but be sure you've loaded the [adafruit-circuitpython-feather\_m0\_rfm69-\*.bin](https://github.com/adafruit/circuitpython/releases) version of CircuitPython on your board!&nbsp; **This is very important as the RFM69 build has special pins added to the board module which are used to access the radio's control lines!**

[For details on how to load a binary circuitpython build, check out our Non-UF2-Install guide](../../../../welcome-to-circuitpython/non-uf2-installation)

### Adafruit Feather M0 RFM69HCW Packet Radio - 868 or 915 MHz

[Adafruit Feather M0 RFM69HCW Packet Radio - 868 or 915 MHz](https://www.adafruit.com/product/3176)
This is the**&nbsp;Adafruit Feather M0 RFM69 Packet Radio&nbsp;(868 or 915 MHz)****. **We call these _RadioFruits** ,**_ our take on an microcontroller with a RFM69HCW packet radio transceiver plus built in USB and battery charging. Its an Adafruit...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3176)
[Related Guides to the Product](https://learn.adafruit.com/products/3176/guides)
![Angled shot of rectangular microcontroller.](https://cdn-shop.adafruit.com/640x480/3176-05.jpg)

### Adafruit Feather M0 RFM69HCW Packet Radio - 433MHz

[Adafruit Feather M0 RFM69HCW Packet Radio - 433MHz](https://www.adafruit.com/product/3177)
This is the**&nbsp;Adafruit Feather M0 RFM69 Packet Radio&nbsp;(433 MHz)****. **We call these _RadioFruits** ,**_ our take on an microcontroller with a RFM69 HCW packet radio transceiver plus built in USB and battery charging. It's an Adafruit...

In Stock
[Buy Now](https://www.adafruit.com/product/3177)
[Related Guides to the Product](https://learn.adafruit.com/products/3177/guides)
![Angled shot of rectangular microcontroller.](https://cdn-shop.adafruit.com/640x480/3177-05.jpg)

## Module Install

If you have the Feather M0 RFM69 and have installed CircuitPython 6.0 or later, it is not necessary to install the library modules. They are "frozen into" the Circuitpython build. Skip to the "Usage" section below.

If you are using an older version of CircuitPython you will need to install the modules as described.

Next you'll need to install the&nbsp;[Adafruit CircuitPython RFM69](https://github.com/adafruit/Adafruit_CircuitPython_RFM69)&nbsp;module on your CircuitPython board. &nbsp;Before you do that make&nbsp;sure you are running the&nbsp;[latest version of Adafruit CircuitPython](../../../../welcome-to-circuitpython/installing-circuitpython)&nbsp;for your board too (again be sure to the load the Feather M0 RFM69 version if you're using that board and want to use its built-in radio module).

Next you'll need to install the necessary libraries&nbsp;to use the hardware--carefully follow the steps to find and install these libraries from&nbsp;[Adafruit's CircuitPython library bundle](https://github.com/adafruit/Adafruit_CircuitPython_Bundle).&nbsp; Our introduction guide has&nbsp;[a great page on how to install the library bundle](../../../../welcome-to-circuitpython/circuitpython-libraries)&nbsp;for both express and non-express boards.

Remember for non-express boards like the Adafruit Feather M0, you'll need to manually install the necessary libraries from the bundle:

- **adafruit\_rfm69.mpy**
- **adafruit\_bus\_device**

You can also download the&nbsp; **adafruit\_rfm69.mpy** &nbsp;from&nbsp;[its releases page on Github](https://github.com/adafruit/Adafruit_CircuitPython_RFM69/releases).

Before continuing make sure your board's lib folder or root filesystem has the&nbsp; **adafruit\_rfm69.mpy,&nbsp;** and **&nbsp;adafruit\_bus\_device**** &nbsp; **files and folders** &nbsp;**copied over.

&nbsp;

# Usage

To demonstrate the usage of the radio we'll initialize it and send and receive data from the board's Python REPL.

[Connect to the board's serial REPL&nbsp;](../../../../welcome-to-circuitpython/the-repl)so you are at the CircuitPython&nbsp; **\>\>\>** &nbsp;prompt.

Run the following code to import the necessary modules and initialize the SPI&nbsp;connection with the sensor:

```auto
import board
import busio
import digitalio
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
```

Now define a few of the pins connected to the RFM69, specifically the CS and RST pins:

```auto
cs = digitalio.DigitalInOut(board.D5)
reset = digitalio.DigitalInOut(board.D6)
```

However if you're using the Feather M0 RFM69 board with a built-in RFM69 radio (and you've loaded the special version of CircuitPython just for this board as mentioned above), you instead want to use these pins for the CS and RST lines:

```auto
cs = digitalio.DigitalInOut(board.RFM69_CS)
reset = digitalio.DigitalInOut(board.RFM69_RST)
```

You're ready to import the RFM69 module and create an instance of the RFM69 class inside it. &nbsp;Before you create the radio module instance you'll need to check if you're using a 433mhz or 915mhz radio module as the initializer requires the frequency to be specified--confirm which frequency your module uses and run **one** of the following lines. &nbsp;

For a 915mhz radio use:

```auto
import adafruit_rfm69
rfm69 = adafruit_rfm69.RFM69(spi, cs, reset, 915.0)
```

Or for a 433mhz radio use:

```auto
import adafruit_rfm69
rfm69 = adafruit_rfm69.RFM69(spi, cs, reset, 433.0)
```

Notice the initializer takes the following required parameters:

- **spi** - The SPI bus connected to the board.
- **cs** - The DigitalInOut instance connected to the CS line of the radio.
- **reset** - The DigitalInOut instance connected to the RST or reset line of the radio.
- **frequency** - The frequency in megahertz of the radio module. &nbsp;Remember this frequency depends on which type of radio you're using and the frequency you desire to use!

In addition there are some optional parameters you might specify:

- **baudrate** - The baud rate to use for the SPI connection to the radio.&nbsp; By default this is 10mhz which is as fast as the radio can handle, but in some cases it might be too fast if you're wiring up a breakout to a breadboard (breadboards can be notorious for not working well with high speed signals).&nbsp; If you run into odd errors like being unable to find the RFM69 radio try lowering the baudrate by specifying a **baudrate=1000000** keyword (which sets the speed to a lower 1mhz value).

Once the RFM69 class is created and initialized you're ready to start sending and receiving data.

Remember by default the module will be configured to interface with the "RadioHead" RFM69 setup so you can also send and receive packets with an Arduino running the 'raw' TX/RX examples!

To send a message simply call the **send** function and provide a string or byte string of data:

```auto
rfm69.send('Hello world!')
```

 **Remember you can only send a message up to 60 bytes in length at a time!** &nbsp; Attempting to send a message longer than 60 bytes will fail with an exception error. &nbsp;If you need to send a longer message it will have to be broken up into multiple send calls and reconstructed on the receiving side.

If you have another RFM69 on the same frequency and modulation waiting to receive messages (like another CircuitPython module running receive code below) you should see it receive the message.

![](https://cdn-learn.adafruit.com/assets/assets/000/050/233/medium800/adafruit_products_Screen_Shot_2018-01-17_at_11.50.01_AM.png?1516218974)

You can even have an Arduino running the RadioHead library's raw RX example see the message that was sent (be sure this receiving side has an encryption key setup exactly the same way as the sending side, see the `encryption_key` property discussion further below):

![](https://cdn-learn.adafruit.com/assets/assets/000/050/234/medium800/adafruit_products_Screen_Shot_2018-01-17_at_11.52.42_AM.png?1516219046)

To receive a message simply call the `receive` function. &nbsp;This function will wait for half a second for any packet to be received. &nbsp;If a packet is found it will be returned as a byte string (remember packets are at most 60 bytes long), or if no packet was found a result of `None` is returned.

```auto
rfm69.receive()
```

You can increase the amount of time the module waits for a packet to be received by specifying the time in seconds as a parameter to the receive call:

```python
rfm69.receive(timeout=5.0)  # Wait 5 seconds instead of 0.5 seconds.
```

Notice this waits longer at the REPL for a packet to be received before returning. &nbsp;If you have another RFM69 setup try having it send a message while the other is waiting to receive it. &nbsp;You should see a byte string returned.&nbsp; You can also have an Arduino running the RadioHead library's raw TX example send messages that are received by your code (again it must be setup with the same encryption key):

![](https://cdn-learn.adafruit.com/assets/assets/000/050/235/medium800/adafruit_products_Screen_Shot_2018-01-17_at_11.53.54_AM.png?1516219172)

One thing to note in Python byte strings aren't exactly like text strings and you might not be able to do all the text processing (like find, replace, etc.) as you expect. &nbsp;However you can convert a byte string into text by assuming a specific text encoding like ASCII. &nbsp;For example to receive a packet and convert the contents to an ASCII text string you can run code like:

```auto
packet = rfm69.receive()  # Wait for a packet to be received (up to 0.5 seconds)
if packet is not None:
    packet_text = str(packet, 'ascii')
    print('Received: {0}'.format(packet_text))
```

Notice this code first receives a packet, then checks if one was actually found (the packet is `not None` check--if no packet is received a value of `None` is returned), and then converts the packet data to a string assuming an ASCII text encoding.

# Beyond RX & TX

Beyond basic sending and receiving there are a few properties of the RFM69 class you might want to interact with:

- **encryption\_key** - This is an optional 16 byte string that defines the AES encryption key used by the radio for sending and receiving packets.&nbsp; Both the sending and receiving code must have the exact same encryption key set or they'll be unable to see each other's packets!&nbsp; See the [simpletest.py example](https://github.com/adafruit/Adafruit_CircuitPython_RFM69/blob/master/examples/rfm69_simpletest.py) below for an example of setting the `encryption_key` to match the default key from RadioHead library raw examples.&nbsp; By default the RFM69 class assumes no encryption key is set, and you can set this property to the value `None` to disable encryption.
- **rssi** - The received signal strength indicator is a property you can read to see the strength of the radio signal being received.&nbsp; This is updated when packets are received and returns a value in decibels (typically negative, so the _smaller_ the number and closer to 0, the higher the strength / better the signal).

![](https://cdn-learn.adafruit.com/assets/assets/000/050/237/medium800/adafruit_products_Screen_Shot_2018-01-17_at_12.02.16_PM.png?1516219542)

![](https://cdn-learn.adafruit.com/assets/assets/000/050/236/medium800/adafruit_products_Screen_Shot_2018-01-17_at_12.02.02_PM.png?1516219532)

That's all there is to the basic RFM69 radio usage! &nbsp;_Remember the CircuitPython module is designed for sending and receiving small up to 60 byte control messages and not large or high bandwidth amounts of data._

Here's a complete example of sending a message and waiting to receive and print any received messages. &nbsp;Save this as **main.py** on your board and open the serial REPL to see it print data and any received messages. &nbsp;If you have two boards and radios setup to run this code at the same time they'll send each other a message on start up!

https://github.com/adafruit/Adafruit_CircuitPython_RFM69/blob/main/examples/rfm69_simpletest.py

# Radio FeatherWing

## Using the RFM9X Radio

![](https://cdn-learn.adafruit.com/assets/assets/000/031/669/medium800/feather_3076_iso_demo_ORIG.jpg?1460574636)

Before beginning make sure you have your Arduino or Feather working smoothly, it will make this part a lot easier. Once you have the basic functionality going - you can upload code, blink an LED, use the serial output, etc. you can then upgrade to using the radio itself.

Note that the sub-GHz radio is not designed for streaming audio or video! It's best used for small packets of data. The data rate is adjustable but its common to stick to around 19.2 Kbps (thats bits per second). Lower data rates will be more successful in their transmissions

**You will, of course, need at least two paired radios** to do any testing! The radios must be matched in frequency (e.g. two 900 MHz&nbsp; radios are ok, but mixing 900 MHz and 433 MHz is _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.

# Arduino Library

These radios have really excellent code already written, so rather than coming up with a new standard we suggest using existing libraries such as [AirSpayce's Radiohead library](http://www.airspayce.com/mikem/arduino/RadioHead/) which also supports a vast number of other radios.

This is a really great Arduino Library, so please support them in saying thanks for their efforts!

## RadioHead RFM9x Library example

To begin talking to the radio, you will need to download the [RadioHead library](http://www.airspayce.com/mikem/arduino/RadioHead/). You can do that by visiting the GitHub repo and manually downloading or, easier, just click the button below to download as a zip file:

[Download RadioHead Library](https://github.com/adafruit/RadioHead/archive/master.zip)
_Note that while all the code in the examples below are based on this version, you can [visit the RadioHead documentation page to get the most recent version which may have bug-fixes or more functionality](http://www.airspayce.com/mikem/arduino/RadioHead/)_

Uncompress the zip and find the folder named **RadioHead** and check that the **RadioHead** folder contains **RH\_RF95.**** cpp **and** RH\_RF95 ****.h** (as well as a few dozen other files for radios that are supported)  
&nbsp;  
Place the **RadioHead** library folder your **arduinosketchfolder/libraries/** folder.   
You may need to create the **libraries** subfolder if its your first library. Restart the IDE.  
  
We also have a great tutorial on Arduino library installation at:  
[http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use](http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use "Link: http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use")

# Basic RX & TX example

Now to get a basic demo going, where one Feather transmits and the other receives. Start by setting up the transmitter.

## Transmitter example code

This code will send a small packet of data once a second to node address #1.

Open up the example **RadioHead→feather→Feather9x\_TX**

Load this code into your Transmitter Arduino/Feather!

Danger: 

Info: 

https://github.com/adafruit/RadioHead/blob/master/examples/feather/Feather9x_TX/Feather9x_TX.ino

Once the code is uploaded, you should see the following on the serial console:

![](https://cdn-learn.adafruit.com/assets/assets/000/031/671/medium800/feather_loratx.png?1460575392)

Now open up another instance of the Arduino IDE - this is so you can see the serial console output from the TX Feather while you set up the RX Feather.

## Receiver example code

This code will receive and acknowledge a small packet of data.

Open up the example **RadioHead→feather→Feather9x\_RX**

Load this code into your **Receiver** Arduino/Feather!

Danger: 

Info: 

https://github.com/adafruit/RadioHead/blob/master/examples/feather/Feather9x_RX/Feather9x_RX.ino

Now open up the Serial console on the receiver, while also checking in on the transmitter's serial console. You should see the receiver is...well, receiving packets:

![](https://cdn-learn.adafruit.com/assets/assets/000/031/672/medium800/feather_rx.png?1460577454)

You can see that the library example prints out the hex-bytes received `48 65 6C 6C 6F 20 57 6F 72 6C 64 20 23 30 0 20 20 20 20 0`, as well as the ASCII 'string' `Hello World`. Then it will send a reply.

And, on the transmitter side, it is now printing that it got a reply after each transmission `And hello back to you` because it got a reply from the receiver.

![](https://cdn-learn.adafruit.com/assets/assets/000/031/673/medium800/feather_rxed.png?1460577540)

That's pretty much the basics of it! Take a look at the examples so you know how to adapt to your own radio setup.

# Feather Radio Pinout

&nbsp;This is the pinout setup for all **Feather 32u4** RFM9X's:

```auto
/* for feather32u4 */
#define RFM95_CS 8
#define RFM95_RST 4
#define RFM95_INT 7
```

This is the pinout for all **Feather M0** RFM9X's:

```auto
/* for feather m0 */
#define RFM95_CS 8
#define RFM95_RST 4
#define RFM95_INT 3
```

And for **RP2040** Feathers:

```cpp
#define RFM95_CS   16
#define RFM95_INT  21
#define RFM95_RST  17
```

# Frequency

You can dial in the frequency you want the radio to communicate on, such as 915.0, 434.0 or 868.0 or any number really. Different countries/ITU Zones have different ISM bands so make sure you're using those or if you are licensed, the frequencies you may use.

```auto
// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 915.0
```

You can then instantiate the radio object with our custom pin numbers.

```auto
// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);
```

# Setup

We begin by setting up the serial console and hard-resetting the radio:

```auto
void setup() 
{
  pinMode(LED, OUTPUT);     
  pinMode(RFM95_RST, OUTPUT);
  digitalWrite(RFM95_RST, HIGH);

  while (!Serial); // wait until serial console is open, remove if not tethered to computer
  Serial.begin(9600);
  delay(100);
  Serial.println("Feather LoRa RX Test!");
  
  // manual reset
  digitalWrite(RFM95_RST, LOW);
  delay(10);
  digitalWrite(RFM95_RST, HIGH);
  delay(10);
```

Remove the `while (!Serial);` line if you are not tethering to a computer, as it will cause the Feather to halt until a USB connection is made!

## Initializing Radio

The library gets initialized with a call to `init()`. Once initialized, you can set the frequency. You can also configure the output power level, the number ranges from 5 to 23. Start with the highest power level (23) and then scale down as necessary.

```auto
  while (!rf95.init()) {
    Serial.println("LoRa radio init failed");
    while (1);
  }
  Serial.println("LoRa radio init OK!");

  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
  if (!rf95.setFrequency(RF95_FREQ)) {
    Serial.println("setFrequency failed");
    while (1);
  }
  Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);

  // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on

  // The default transmitter power is 13dBm, using PA_BOOST.
  // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then 
  // you can set transmitter powers from 5 to 23 dBm:
  rf95.setTxPower(23, false);
```

## Transmission Code

If you are using the transmitter, this code will wait 1 second, then transmit a packet with `Hello World #` and an incrementing packet number.

```auto
void loop()
{
  delay(1000); // Wait 1 second between transmits, could also 'sleep' here!
  Serial.println("Transmitting..."); // Send a message to rf95_server
  
  char radiopacket[20] = "Hello World #      ";
  itoa(packetnum++, radiopacket+13, 10);
  Serial.print("Sending "); Serial.println(radiopacket);
  radiopacket[19] = 0;
  
  Serial.println("Sending..."); delay(10);
  rf95.send((uint8_t *)radiopacket, 20);

  Serial.println("Waiting for packet to complete..."); delay(10);
  rf95.waitPacketSent();
```

Its pretty simple, the delay does the waiting, you can replace that with low power sleep code. Then it generates the packet and appends a number that increases every transmission. Then it simply calls **send** to transmit the data, and passes in the array of data and the length of the data.

**Note that this does not any addressing or subnetworking** - if you want to make sure the packet goes to a particular radio, you may have to add an identifier/address byte on your own!

Then you call `waitPacketSent()` to wait until the radio is done transmitting. You will not get an automatic acknowledgement from the other radio unless it knows to send back a packet. Think of it like the 'UDP' of radio - the data is sent, but it's not certain it was received! Also, there will not be any automatic retries.

## Receiver Code

The Receiver has the same exact setup code, but the loop is different:

```auto
void loop()
{
  if (rf95.available())
  {
    // Should be a message for us now   
    uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
    uint8_t len = sizeof(buf);
    
    if (rf95.recv(buf, &amp;len))
    {
      digitalWrite(LED, HIGH);
      RH_RF95::printBuffer("Received: ", buf, len);
      Serial.print("Got: ");
      Serial.println((char*)buf);
       Serial.print("RSSI: ");
      Serial.println(rf95.lastRssi(), DEC);
```

Instead of transmitting, it is constantly checking if there's any data packets that have been received. `available()` will return true if a packet with proper error-correction was received. If so, the receiver prints it out in hex and also as a 'character string'.

It also prints out the RSSI which is the receiver signal strength indicator. This number will range from about -15 to about -100. The larger the number (-15 being the highest you'll likely see) the stronger the signal.

Once done it will automatically reply, which is a way for the radios to know that there was an acknowledgement:

```auto
// Send a reply
      uint8_t data[] = "And hello back to you";
      delay(200);
      rf95.send(data, sizeof(data));
      rf95.waitPacketSent();
      Serial.println("Sent a reply");
```

It simply sends back a string and waits till the reply is completely sent.

# Radio FeatherWing

## CircuitPython for RFM9x LoRa

It's easy to use the RFM9x LoRa radio with CircuitPython and the&nbsp;[Adafruit CircuitPython RFM9x](https://github.com/adafruit/Adafruit_CircuitPython_RFM9x)&nbsp;module.&nbsp; This module allows you to easily write Python code that sends and receives packets of data with the radio. &nbsp;Be careful to note this library is for the RFM95/96/97/98 LoRa radio only and&nbsp; **will not** work with the simpler RFM69 packet radio.

## Design Considerations

One thing to be aware of before you use the RFM9x series of radios with CircuitPython are some of the limitations and design considerations for its module. &nbsp;Keep these in mind as you think about projects using the RFM9x and CircuitPython:

- You can only send and receive packets up to 252 bytes in length at a time. &nbsp;The size of the radio's internal buffer dictates this limit so if you want to send longer messages you'll need to break them into a series of smaller send calls in your application code.
- Receiving packets is a 'best effort' in pure Python code. &nbsp;Unlike the Arduino versions of the RFM9x library there is no interrupt support which means when a packet is received it must be immediately processed by the Python code or it could be lost. &nbsp;For your application it will work best to only receive small, single packet messages at a time. &nbsp;Don't try to receive kilobytes of data or else you'll lose packets. &nbsp;This module is really intended for simple single packet messages like 'ON', 'OFF', etc.
- Sending and receiving packets will 'block' your Python code until the packet is fully processed. &nbsp;This means you can't do a lot of other things while sending and waiting for packets to be received. &nbsp;Design your application so the radio usage is the primary scenario and very little other tasks need to happen in the background.
- The module is written to be compatible with the RadioHead RFM95 Arduino library. &nbsp;This means by default the module will setup the radio with the same modulation and configuration for transmitting and receiving at the maximum distance with LoRa support. &nbsp;In addition the CircuitPython module uses the same packet preamble (8 bytes) and header (4 bytes) as RadioHead. &nbsp;If you want to use different modulations or settings you'll need to configure the radio yourself after carefully consulting the datasheet.
- The CircuitPython module supports advanced RadioHead features like the node addressing and "Reliable Datagram". "Reliable DataGram" mode in CircuitPython has some additional parameters to control timing that are not available with the RadioHead library. It may be difficult to get reliable transmission to work between the RadioHead library and CircuitPython.
- Encryption and sync words are also not supported by the LoRa radio module.&nbsp; You must perform these operations yourself in your application code if they're desired.

## Wiring With Breakout

First wire up a RFM9x breakout to your board as shown on the previous pages for Arduino. &nbsp;Note that the G0/interrupt line is not used by the CircuitPython module and can remain unconnected. &nbsp; Here's an example of wiring a Feather M0 to the radio with a SPI connection:

![](https://cdn-learn.adafruit.com/assets/assets/000/051/466/medium800/adafruit_products_m0_lora_bb.png?1520033289)

- **Board 3V** &nbsp;to&nbsp; **radio VIN**
- **Board GND** &nbsp;to&nbsp; **radio GND**
- **Board SCK** &nbsp;to&nbsp; **radio SCK**
- **Board MOSI** &nbsp;to&nbsp; **radio MOSI**
- **Board MISO&nbsp;** to&nbsp; **radio MISO**
- **Board D5&nbsp;** to&nbsp; **radio CS&nbsp;** (or any other digital I/O pin)
- **Board D6&nbsp;** to&nbsp; **radio RST&nbsp;** (or any other digital I/O pin)

Warning: 

[Upgrading to the UF2 Bootlader](https://learn.adafruit.com/installing-circuitpython-on-samd21-boards)

## Usage with All-In-One Feather M0

Alternatively you can use the default bootloader on the Feather M0 RFM9x board but be sure you load the&nbsp;[adafruit-circuitpython-feather\_m0\_rfm9x-\*.bin](https://github.com/adafruit/circuitpython/releases)&nbsp;version of CircuitPython on your board!&nbsp;&nbsp; **This is very important as the RFM9x build has special pins added to the board module which are used to access the radio's control lines!**

**[For details on how to load a binary circuitpython build, check out our Non-UF2-Install guide](../../../../welcome-to-circuitpython/non-uf2-installation)**

### Adafruit Feather M0 with RFM95 LoRa Radio - 900MHz

[Adafruit Feather M0 with RFM95 LoRa Radio - 900MHz](https://www.adafruit.com/product/3178)
This is the **Adafruit Feather M0 RFM95 LoRa Radio (900MHz)****. **We call these _RadioFruits** ,**_ our take on an microcontroller with a "[Long Range (LoRa)](https://www.lora-alliance.org/)" packet radio transceiver with built...

In Stock
[Buy Now](https://www.adafruit.com/product/3178)
[Related Guides to the Product](https://learn.adafruit.com/products/3178/guides)
![Angel shot Adafruit Feather M0 with RFM95 LoRa Radio - 900MHz](https://cdn-shop.adafruit.com/640x480/3178-07.jpg)

### Adafruit Feather M0 RFM96 LoRa Radio - 433MHz

[Adafruit Feather M0 RFM96 LoRa Radio - 433MHz](https://www.adafruit.com/product/3179)
This is the **Adafruit Feather M0 RFM96 LoRa Radio (433 MHz).** We call these _RadioFruits **,** _ our take on an microcontroller with a "[Long Range (LoRa)](https://www.lora-alliance.org/)" packet radio transceiver with built in USB and...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3179)
[Related Guides to the Product](https://learn.adafruit.com/products/3179/guides)
![Angled shot of rectangular microcontroller.](https://cdn-shop.adafruit.com/640x480/3179-11.jpg)

## Module Install

If you have the Feather M0 RFM9x and have installed CircuitPython 6.0 or later, &nbsp;it is not necessary to install the library modules. They are "frozen into" the Circuitpython build. Skip to the "Usage" section below.

If you are using an older version of CircuitPython you will need to install the modules as described.

Next you'll need to install the&nbsp;[Adafruit CircuitPython RFM9x](https://github.com/adafruit/Adafruit_CircuitPython_RFM9x)&nbsp;module on your CircuitPython board. &nbsp;Before you do that make&nbsp;sure you are running the&nbsp;[latest version of Adafruit CircuitPython](../../../../welcome-to-circuitpython/installing-circuitpython)&nbsp;for your board too (again be sure to the load the Feather M0 RFM9x version if you're using that board and want to use its built-in radio module).

Next you'll need to install the necessary libraries&nbsp;to use the hardware--carefully follow the steps to find and install these libraries from&nbsp;[Adafruit's CircuitPython library bundle](https://github.com/adafruit/Adafruit_CircuitPython_Bundle).&nbsp; Our introduction guide has&nbsp;[a great page on how to install the library bundle](../../../../welcome-to-circuitpython/circuitpython-libraries)&nbsp;for both express and non-express boards.

Remember for non-express boards like the Feather M0 RFM96 and RFM95, you'll need to manually install the necessary libraries from the bundle:

- **adafruit\_rfm9x.mpy**
- **adafruit\_bus\_device**

You can also download the&nbsp; **adafruit\_rfm9x.mpy** &nbsp;from&nbsp;[its releases page on Github](https://github.com/adafruit/Adafruit_CircuitPython_RFM9x/releases).

Before continuing make sure your board's lib folder or root filesystem has the&nbsp; **adafruit\_rfm9x.mpy,&nbsp;** and **&nbsp;adafruit\_bus\_device**** &nbsp; **files and folders** &nbsp;**copied over.

# Usage

To demonstrate the usage of the radio we'll initialize it and send and receive data from the board's Python REPL.

[Connect to the board's serial REPL&nbsp;](../../../../welcome-to-circuitpython/the-repl)so you are at the CircuitPython&nbsp; **\>\>\>** &nbsp;prompt.

Run the following code to import the necessary modules and initialize the SPI&nbsp;connection with the radio:

```auto
import board
import busio
import digitalio
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
```

Now define a few of the pins connected to the RFM9x, specifically the CS and RST pins:

```auto
cs = digitalio.DigitalInOut(board.D5)
reset = digitalio.DigitalInOut(board.D6)
```

However if you're using the Feather M0 RFM95 board with a built-in RFM9x radio (and you've loaded the special version of CircuitPython just for this board as mentioned above), you instead want to use these pins for the CS and RST lines:

```auto
cs = digitalio.DigitalInOut(board.RFM9X_CS)
reset = digitalio.DigitalInOut(board.RFM9X_RST)
```

You're ready to import the RFM9x module and create an instance of the RFM9x class inside it. &nbsp;Before you create the radio module instance you'll need to check if you're using a 433mhz or 915mhz radio module as the initializer requires the frequency to be specified--confirm which frequency your module uses and run&nbsp; **one** &nbsp;of the following lines. &nbsp;

For a 915mhz radio use:

```auto
import adafruit_rfm9x
rfm9x = adafruit_rfm9x.RFM9x(spi, cs, reset, 915.0)
```

Or for a 433mhz radio use:

```auto
import adafruit_rfm9x
rfm9x = adafruit_rfm9x.RFM9x(spi, cs, reset, 433.0)
```

Notice the initializer takes the following required parameters:

- **spi** &nbsp;- The SPI bus connected to the board.
- **cs** &nbsp;- The DigitalInOut instance connected to the CS line of the radio.
- **reset** &nbsp;- The DigitalInOut instance connected to the RST or reset line of the radio.
- **frequency** &nbsp;- The frequency in megahertz of the radio module. &nbsp;Remember this frequency depends on which type of radio you're using and the frequency you desire to use!

In addition there are some optional parameters you might specify:

- **baudrate** &nbsp;- The baud rate to use for the SPI connection to the radio.&nbsp; By default this is 10mhz which is as fast as the radio can handle, but in some cases it might be too fast if you're wiring up a breakout to a breadboard (breadboards can be notorious for not working well with high speed signals).&nbsp; If you run into odd errors like being unable to find the RFM9x radio try lowering the baudrate by specifying a&nbsp; **baudrate=1000000** &nbsp;keyword (which sets the speed to a lower 1mhz value).

Once the RFM9x class is created and initialized you're ready to start sending and receiving data.

Remember by default the module will be configured to interface with the "RadioHead" RFM9x setup so you can also send and receive packets with an Arduino running the RFM95 TX/RX examples!

To send a message simply call the&nbsp; **send** &nbsp;function and provide a string or byte string of data:

```auto
rfm9x.send('Hello world!')
```

![](https://cdn-learn.adafruit.com/assets/assets/000/051/470/medium800/adafruit_products_Screen_Shot_2018-03-02_at_3.45.41_PM.png?1520034364)

 **Remember you can only send a message up to 252 bytes in length at a time!** &nbsp; Attempting to send a message longer than 252 bytes will fail with an exception error. &nbsp;If you need to send a longer message it will have to be broken up into multiple send calls and reconstructed on the receiving side.

If you have another RFM9x on the same frequency waiting to receive messages (like another CircuitPython module running receive code below) you should see it receive the message.

You can even have an Arduino running the RadioHead library's RFM95 client example see the message that was sent:

![](https://cdn-learn.adafruit.com/assets/assets/000/051/468/medium800/adafruit_products_Screen_Shot_2018-03-02_at_3.13.17_PM.png?1520033871)

To receive a message simply call the&nbsp;`receive`&nbsp;function. &nbsp;This function will wait for half a second for any packet to be received. &nbsp;If a packet is found it will be returned as a byte string (remember packets are at most 252 bytes long), or if no packet was found a result of&nbsp;`None`&nbsp;is returned.

```auto
rfm9x.receive()
```

You can increase the amount of time the module waits for a packet to be received by specifying the time in seconds as a parameter to the receive call:

```python
rfm9x.receive(timeout=5.0)  # Wait 5 seconds instead of 0.5 seconds.
```

Notice this waits longer at the REPL for a packet to be received before returning. &nbsp;If you have another RFM9x setup try having it send a message while the other is waiting to receive it. &nbsp;You should see a byte string returned.&nbsp; You can also have an Arduino running the RadioHead library's RFM95 client example send messages that are received by your code:

![](https://cdn-learn.adafruit.com/assets/assets/000/051/471/medium800/adafruit_products_Screen_Shot_2018-03-02_at_3.46.33_PM.png?1520034421)

One thing to note in Python byte strings aren't exactly like text strings and you might not be able to do all the text processing (like find, replace, etc.) as you expect. &nbsp;However you can convert a byte string into text by assuming a specific text encoding like ASCII. &nbsp;For example to receive a packet and convert the contents to an ASCII text string you can run code like:

```auto
packet = rfm9x.receive()  # Wait for a packet to be received (up to 0.5 seconds)
if packet is not None:
    packet_text = str(packet, 'ascii')
    print('Received: {0}'.format(packet_text))
```

Notice this code first receives a packet, then checks if one was actually found (the packet is&nbsp;`not None`&nbsp;check--if no packet is received a value of&nbsp;`None`&nbsp;is returned), and then converts the packet data to a string assuming an ASCII text encoding.

# Beyond RX & TX

Beyond basic sending and receiving there are a few properties of the RFM69 class you might want to interact with:

- **tx\_power** &nbsp;- This is a power level (in dB) to use when transmitting with the radio.&nbsp; By default this is set to a moderate 13 dB value, however you can increase this depending on the type of radio you're using.&nbsp; For high power radios (the modules sold by Adafruit) they support a range of TX power from 5 to 23 dB.&nbsp; Try increasing this to the maximum 23 dB level (however check your local laws for permission to transmit with such power!) to get the most distance and range.
- **rssi** &nbsp;- The received signal strength indicator is a property you can read to see the strength of the radio signal being received.&nbsp; This is updated when packets are received and returns a value in decibels (typically negative, so the&nbsp;_smaller_&nbsp;the number and closer to 0, the higher the strength / better the signal).

![](https://cdn-learn.adafruit.com/assets/assets/000/051/472/medium800/adafruit_products_Screen_Shot_2018-03-02_at_3.48.45_PM.png?1520034629)

![](https://cdn-learn.adafruit.com/assets/assets/000/051/473/medium800/adafruit_products_Screen_Shot_2018-03-02_at_3.48.22_PM.png?1520034638)

![](https://cdn-learn.adafruit.com/assets/assets/000/051/474/medium800/adafruit_products_Screen_Shot_2018-03-02_at_3.52.38_PM.png?1520034780)

That's all there is to the basic RFM9x radio usage! &nbsp;_Remember the CircuitPython module is designed for sending and receiving small up to 252 byte control messages and not large or high bandwidth amounts of data._

Here's a complete example of sending a message and waiting to receive and print any received messages. &nbsp;Save this as&nbsp; **main.py** &nbsp;on your board and open the serial REPL to see it print data and any received messages. &nbsp;If you have two boards and radios setup to run this code at the same time they'll send each other a message on start up!

https://github.com/adafruit/Adafruit_CircuitPython_RFM9x/blob/main/examples/rfm9x_simpletest.py

# Radio FeatherWing

## Radio Module F.A.Q.

### 

All other things being equal (antenna, power output, location) you will get better range with LoRa than with RFM69 modules. We've found 50% to 100% range improvement is common.

### 

The RFM69 radios have a range of approx. 500 meters **line of sight** with tuned uni-directional antennas. Depending on obstructions, frequency, antenna and power output, you will get lower ranges - _especially_ if you are not line of sight.

### 

The RFM9x radios have a range of up to 2 km **line of sight** with tuned uni-directional antennas. Depending on obstructions, frequency, antenna and power output, you will get lower ranges - _especially_ if you are not line of sight.

### 

Your module is probably _not_ broken. Radio range is dependant on _a lot of things_ and all must be attended to make sure you get the best performance!

1. Tuned antenna for your frequency - getting a well-tuned antenna is incredibly important. Your antenna must be tuned for the exact frequency you are using
2. Matching frequency - make sure all modules are on the same exact frequency
3. Matching settings - all radios must have the same settings so they can communicate
4. Directional vs non-directional antennas - for the best range, _directional_ antennas like Yagi will direct your energy in one path instead of all around
5. Good power supply - a nice steady power supply will keep your transmissions clean and strong
6. Max power settings on the radios - they can be set for higher/lower power! Don't forget to set them to max.
7. Line of sight - No obstructions, walls, trees, towers, buildings, mountains, etc can be in the way of your radio path. Likewise, outdoors is way better than indoors because its very hard to bounce radio paths around a building
8. Radio transmission speed - trying to transmit more data faster will be hard. Go for small packets, with lots of retransmissions. Lowering the baud rate on the radio (see the libraries for how to do this) will give you better reliability

### 

Various antennas will cost diferent amounts and give you different directional gain. In general, spending a lot on a large fixed antenna can give you better power transfer if the antenna is well tuned. For most simple uses, a wire works pretty well  
  
[The ARRL antena book is recommended if you want to learn how to do the modeling and analysis](https://www.arrl.org/shop/Antennas/)  
  
But nothing beats actual tests in your environment!

### 

Look for a little colored paint dot on top of the module.

- **GREEN** , **BLUE** or **NO DOT** = **900 MHz**
- **RED** = **433 MHz**

Every now and then the paint dot shows up without a color or with the ink dot burnt. This is just a manufacturing variance and there is nothing wrong with the board. You should get the frequency you ordered though. So if you plan on mixing these up, you may want to add a new mark of your own.

### 

Nope! The radios have an ink dot on them, which sometimes gets toasty when we put the board through the oven, or rework it, so it may have a burnt appearance. The chip is fine!

### 

Each LoRa device from Adafruit should come with a small label that contains a MAC address in the form **98:76:B6:xx:yy:zz**. This might be a sticker attached to the device itself or included separately. This MAC address is needed if using the LoRa device with [LoRaWAN](https://lora-alliance.org/about-lorawan/). For example, [The Things Network](https://www.thethingsnetwork.org/) uses LoRaWAN. For non-LoRaWAN usage, the MAC address is not needed.

# Radio FeatherWing

## Downloads

# Datasheets & Files

**RFM9x**

- [SX127x Datasheet](https://cdn-shop.adafruit.com/product-files/3179/sx1276_77_78_79.pdf)- The RFM9X LoRa radio chip itself
- [RFM9X](https://cdn-learn.adafruit.com/assets/assets/000/031/659/original/RFM95_96_97_98W.pdf?1460518717) - The radio module, which contains the SX1272 chipset
- [FCC Test Report](https://cdn-shop.adafruit.com/product-files/3078/LoRa_RFM95-915S2%2813dBm%29_FCC.pdf)
- [ETSI Test Report](https://cdn-shop.adafruit.com/product-files/3078/etsireport_RFM95-868S2%2811dBm%29.pdf)
- [RoHS Report](https://cdn-shop.adafruit.com/product-files/3078/rohs_CAN14-015141-02_EC_15137200_F.PDF)

**RFM69**

- [SX1231 Datasheet](https://cdn-shop.adafruit.com/product-files/3076/sx1231.pdf) - The RFM69 radio chip itself
- [RFM69HCW datasheet](https://cdn-shop.adafruit.com/product-files/3076/RFM69HCW-V1.1.pdf)[- contains the SX1231 datasheet plus details about the module](https://cdn-learn.adafruit.com/assets/assets/000/031/659/original/RFM95_96_97_98W.pdf?1460518717)
- [RoHS Test Report](https://cdn-shop.adafruit.com/product-files/3076/CAN14-015141-02_EC_15137200_F.PDF)
- [RoHS Test Report](https://cdn-shop.adafruit.com/product-files/3076/CAN15-031854-04_EC_15983075_F.PDF)
- [REACH Test Report](https://cdn-shop.adafruit.com/product-files/3076/CAN15-031854-07_EC_15983075_F.PDF)
- [ETSI Test Report](https://cdn-shop.adafruit.com/product-files/3076/RFM69HCW-868S2-ETSI.pdf)
- [FCC Test Report](https://cdn-shop.adafruit.com/product-files/3070/p3070p3076_RFM69HCW-915S2-FCC.pdf)

[EagleCAD PCB files on GitHub](https://github.com/adafruit/Adafruit-Radio-FeatherWing-PCB)

[3D models on GitHub](https://github.com/adafruit/Adafruit_CAD_Parts/tree/main/3229%20Radio%20FeatherWing)

[Fritzing object in Adafruit Fritzing library](https://github.com/adafruit/Fritzing-Library)

# Schematic

(Pinouts are the same for all four radio versions)

![](https://cdn-learn.adafruit.com/assets/assets/000/035/125/medium800/feather_schem.png?1472070266)

# Fabrication Print

Dimensions in inches

![](https://cdn-learn.adafruit.com/assets/assets/000/035/126/medium800/feather_fabprint.png?1472070303)

![](https://cdn-learn.adafruit.com/assets/assets/000/116/004/medium800/wireless_3229_Radio_FeatherWing.jpg?1666203132)


## Featured Products

### Adafruit Radio FeatherWing - RFM69HCW 900MHz

[Adafruit Radio FeatherWing - RFM69HCW 900MHz](https://www.adafruit.com/product/3229)
Add short-hop wireless to your Feather with these RadioFruit Featherwings. These add-ons for any Feather board will let you integrate packetized radio (with the RFM69 radio) or LoRa radio (with the RFM9x's). These radios are good options for kilometer-range radio, and paired with one of...

In Stock
[Buy Now](https://www.adafruit.com/product/3229)
[Related Guides to the Product](https://learn.adafruit.com/products/3229/guides)
### Adafruit Radio FeatherWing - RFM69HCW 433MHz

[Adafruit Radio FeatherWing - RFM69HCW 433MHz](https://www.adafruit.com/product/3230)
Add short-hop wireless to your Feather with these RadioFruit Featherwings. These add-ons for any Feather board will let you integrate packetized radio (with the RFM69 radio) or LoRa radio (with the RFM9x's). These radios are good options for kilometer-range radio, and paired with one of...

In Stock
[Buy Now](https://www.adafruit.com/product/3230)
[Related Guides to the Product](https://learn.adafruit.com/products/3230/guides)
### Adafruit LoRa Radio FeatherWing - RFM95W 900 MHz

[Adafruit LoRa Radio FeatherWing - RFM95W 900 MHz](https://www.adafruit.com/product/3231)
Add short-hop wireless to your Feather with these RadioFruit Featherwings. These add-ons for any Feather board will let you integrate packetized radio (with the RFM69 radio) or LoRa radio (with the RFM9x's). These radios are good options for kilometer-range radio, and paired with one of...

In Stock
[Buy Now](https://www.adafruit.com/product/3231)
[Related Guides to the Product](https://learn.adafruit.com/products/3231/guides)
### Adafruit LoRa Radio FeatherWing - RFM95W 433 MHz

[Adafruit LoRa Radio FeatherWing - RFM95W 433 MHz](https://www.adafruit.com/product/3232)
Add short-hop wireless to your Feather with these RadioFruit Featherwings. These add-ons for any Feather board will let you integrate packetized radio (with the RFM69 radio) or LoRa radio (with the RFM9x's). These radios are good options for kilometer-range radio, and paired with one of...

In Stock
[Buy Now](https://www.adafruit.com/product/3232)
[Related Guides to the Product](https://learn.adafruit.com/products/3232/guides)
### Stacking Headers for Feather - 12-pin and 16-pin female headers

[Stacking Headers for Feather - 12-pin and 16-pin female headers](https://www.adafruit.com/product/2830)
These two **Female Stacking Headers** alone are, well, lonely. But pair them with any of our [Feather](https://www.adafruit.com/categories/777) boards and you're in business!

What do they do? They stack. Put the headers through your Feather and then you can...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2830)
[Related Guides to the Product](https://learn.adafruit.com/products/2830/guides)
### SMA to uFL/u.FL/IPX/IPEX RF Adapter Cable

[SMA to uFL/u.FL/IPX/IPEX RF Adapter Cable](https://www.adafruit.com/product/851)
This RF adapter cable is super handy for anyone doing RF work. Often times, small electronics save space by having a pick-and-placeable u.FL connector (also called uFL, IPEX, IPAX, IPX, MHF, and AM). But most antennas have SMA or RP-SMA connectors on them. This little cable will bridge the...

In Stock
[Buy Now](https://www.adafruit.com/product/851)
[Related Guides to the Product](https://learn.adafruit.com/products/851/guides)
### uFL SMT Antenna Connector

[uFL SMT Antenna Connector](https://www.adafruit.com/product/1661)
uFL connectors are very small surface-mount parts used when an external RF antena is desired but a big bulky SMA connector takes up too much space. We use this part on our GPS and WiFi boards, they're great! Chances are your antenna doesn't use uFL as the main connector, in which case...

In Stock
[Buy Now](https://www.adafruit.com/product/1661)
[Related Guides to the Product](https://learn.adafruit.com/products/1661/guides)
### Edge-Launch SMA Connector for 1.6mm / 0.062" Thick PCBs

[Edge-Launch SMA Connector for 1.6mm / 0.062" Thick PCBs](https://www.adafruit.com/product/1865)
This is a great connector for anyone doing RF work, when an SMA connector is required. It hugs the edge of a standard 0.063" thick PCB and 'launches' off of the edge. We like these for their ease of soldering and low profile. Mates with any SMA plug, we also have an SMA to RP-SMA...

In Stock
[Buy Now](https://www.adafruit.com/product/1865)
[Related Guides to the Product](https://learn.adafruit.com/products/1865/guides)

## Related Guides

- [Two Player Game System for PyGamer and RFM69HCW Radio Wing](https://learn.adafruit.com/two-player-game-system-for-pygamer-and-rfm69hcw-radio-wing.md)
- [Glitter Positioning System](https://learn.adafruit.com/glitter-positioning-system.md)
- [Using LoraWAN and The Things Network with CircuitPython](https://learn.adafruit.com/using-lorawan-and-the-things-network-with-circuitpython.md)
- [MagTag Tides Viewer](https://learn.adafruit.com/magtag-tides-viewer.md)
- [SpaceX Next Launch Display with Adafruit MagTag](https://learn.adafruit.com/spacex-next-launch-display-with-adafruit-magtag.md)
- [Introducing the Adafruit WICED Feather WiFi](https://learn.adafruit.com/introducing-the-adafruit-wiced-feather-wifi.md)
- [How To Solder Headers](https://learn.adafruit.com/how-to-solder-headers.md)
- [ESPectre Human Detector for Feather](https://learn.adafruit.com/espectre-human-detector-for-feather.md)
- [Adafruit 8x16 LED Matrix FeatherWing](https://learn.adafruit.com/adafruit-8x16-led-matrix-featherwing.md)
- [Adafruit QT Py ESP32 Pico](https://learn.adafruit.com/adafruit-qt-py-esp32-pico.md)
- [Using Adafruit IO Actions to Make an IoT Door Detector](https://learn.adafruit.com/using-adafruit-io-actions-to-make-an-iot-door-detector.md)
- [Adafruit CAN Bus FeatherWing](https://learn.adafruit.com/adafruit-can-bus-featherwing.md)
- [Adafruit Terminal Block Breakout FeatherWing](https://learn.adafruit.com/adafruit-terminal-block-prototyping-breakout-featherwing.md)
- [Adafruit Prop-Maker FeatherWing](https://learn.adafruit.com/adafruit-prop-maker-featherwing.md)
- [Star Illusion: Laser Cut Audio-Reactive Light with WLED](https://learn.adafruit.com/star-illusion-laser-cut-audio-reactive-light-with-wled.md)
