RFM95W LoRa
An 868/915 MHz LoRa packet radio on Adafruit's breakout, with a 3.3 V regulator and level shifting so it wires to 3.3 V and 5 V boards alike.
- Radio chipSemtech SX1276 LoRa transceiver
- Frequency868 MHz or 915 MHz (RFM95W variants)
- SensitivityDown to -148 dBm (-111 dBm to -148 dBm with spreading factor and bandwidth)
- Transmit power and current+5 to +20 dBm; 120 mA at +20 dBm, 87 mA at +17 dBm

The RFM95W is HopeRF's SX1276-based LoRa module for 868 MHz and 915 MHz, with sensitivity down to -148 dBm and up to +20 dBm out at about 120 mA (HopeRF RFM95/96/97/98(W) datasheet V1.0, pp. 1, 13). Adafruit's breakout adds a 3.3 V regulator for 3.3 V to 6 V on VIN and level shifting on its inputs (Adafruit RFM9x guide, Pinouts), so it connects straight to an Uno, an ESP32 or a Pico over SPI with CS, RST and G0. The LoRa library drives it.
The RFM95W is the LoRa module that most 868 MHz (Europe) and 915 MHz (Americas) maker projects use, from point-to-point links to LoRaWAN nodes on The Things Network. HopeRF builds it around Semtech's SX1276 and specifies spreading factors 6 to 12, bandwidths of 7.8 kHz to 500 kHz and an estimated sensitivity of -111 dBm to -148 dBm (HopeRF datasheet V1.0, p. 10).
The bare module is a 16 mm square with 2 mm pitch castellations and a strict 1.8 V to 3.7 V supply (p. 12). Adafruit's breakout puts it on a 0.1-inch header with a 3.3 V regulator, input level shifters and pads for a wire antenna, a uFL or an SMA connector. VIN accepts 3.3 V to 6 V and must supply about 150 mA, because the radio draws around 120 mA at +20 dBm (Adafruit RFM9x guide, Pinouts; HopeRF datasheet V1.0, p. 13).
Adafruit quotes about 2 km of range with simple antennas (Adafruit product 3072). Range depends far more on antenna height and line of sight than on transmit power, and higher spreading factors buy sensitivity at the cost of time on air. Both ends must use the same frequency, spreading factor, bandwidth and sync word.
RFM95W LoRa pinout
| Pin | Function | Type |
|---|---|---|
| VIN | Supply3.3 V to 6 V, 150 mA | power in |
| GND | Ground | power in |
| EN | Regulator enable | input |
| G0 | Interrupt (DIO0): TX done / RX done3.3 V | output |
| SCK | SPI SCK3 V to 5 V | input |
| MISO | SPI MISO3.3 V | output |
| MOSI | SPI MOSI3 V to 5 V | input |
| CS | SPI CS (active low)3 V to 5 V | input |
| RST | Radio reset (active low)3 V to 5 V | input |
| G1 | DIO13.3 V, not level shifted | output |
| G2 | DIO23.3 V | output |
| G3 | DIO33.3 V | output |
| G4 | DIO43.3 V | output |
| G5 | DIO53.3 V | output |
How to wire the RFM95W LoRa
Pin by pin, for the board you have.
| RFM95W LoRa | Arduino Uno | Note |
|---|---|---|
| VIN | 5V | |
| GND | GND | |
| SCK | D13 | |
| MISO | D12 | |
| MOSI | D11 | |
| CS | D10 | |
| RST | D9 | |
| G0 | D2 |
| RFM95W LoRa | ESP32 DevKit V1 | Note |
|---|---|---|
| VIN | 3V3 | |
| GND | GND | |
| SCK | GPIO18 (D18) | |
| MISO | GPIO19 (D19) | |
| MOSI | GPIO23 (D23) | |
| CS | GPIO5 (D5) | |
| RST | GPIO27 (D27) | |
| G0 | GPIO26 (D26) |
| RFM95W LoRa | Raspberry Pi Pico | Note |
|---|---|---|
| VIN | 3V3(OUT) | |
| GND | GND | |
| SCK | GP18 | |
| MISO | GP16 | |
| MOSI | GP19 | |
| CS | GP17 | |
| RST | GP20 | |
| G0 | GP21 |
RFM95W LoRa code
Every example here compiles for its board.
// RFM95W LoRa on Arduino Uno: wiring and a free simulation at https://www.tinkered.ai/components/rfm95w-lora
// Adafruit RFM95W breakout on an Arduino Uno: CS D10, RST D9, G0 D2, SPI D11/D12/D13
// Flash one board with isSender = true and another with isSender = false.
#include <SPI.h>
#include <LoRa.h>
const long FREQUENCY = 915E6; // 868E6 in Europe, 915E6 in the Americas
const bool isSender = true;
unsigned long counter = 0;
void setup() {
Serial.begin(115200);
LoRa.setPins(10, 9, 2); // CS, RST, G0
if (!LoRa.begin(FREQUENCY)) {
Serial.println(F("RFM95W not found: check wiring and power"));
while (true) {}
}
LoRa.setTxPower(17); // dBm, on the PA_BOOST output the RFM95W uses
LoRa.setSpreadingFactor(9);
LoRa.setSyncWord(0x34);
Serial.println(isSender ? F("RFM95W sender ready") : F("RFM95W receiver ready"));
}
void loop() {
if (isSender) {
LoRa.beginPacket();
LoRa.print("ping ");
LoRa.print(counter);
LoRa.endPacket();
Serial.print(F("Sent ping "));
Serial.println(counter++);
delay(5000);
} else {
if (LoRa.parsePacket() > 0) {
Serial.print(F("Received '"));
while (LoRa.available()) Serial.print((char)LoRa.read());
Serial.print(F("' RSSI "));
Serial.print(LoRa.packetRssi());
Serial.print(F(" dBm, SNR "));
Serial.println(LoRa.packetSnr());
}
}
}
Compiled for arduino:avr:uno on 2026-10-30// RFM95W LoRa on ESP32 DevKit V1: wiring and a free simulation at https://www.tinkered.ai/components/rfm95w-lora
// Adafruit RFM95W breakout on an ESP32 DevKit V1: CS GPIO5, RST GPIO27, G0 GPIO26, VSPI 18/19/23
// Flash one board with isSender = true and another with isSender = false.
#include <SPI.h>
#include <LoRa.h>
const long FREQUENCY = 915E6; // 868E6 in Europe, 915E6 in the Americas
const bool isSender = true;
unsigned long counter = 0;
void setup() {
Serial.begin(115200);
LoRa.setPins(5, 27, 26); // CS, RST, G0
if (!LoRa.begin(FREQUENCY)) {
Serial.println("RFM95W not found: check wiring and power");
while (true) { delay(100); }
}
LoRa.setTxPower(17);
LoRa.setSpreadingFactor(9);
LoRa.setSyncWord(0x34);
Serial.println(isSender ? "RFM95W sender ready" : "RFM95W receiver ready");
}
void loop() {
if (isSender) {
LoRa.beginPacket();
LoRa.print("ping ");
LoRa.print(counter);
LoRa.endPacket();
Serial.printf("Sent ping %lu\n", counter++);
delay(5000);
} else if (LoRa.parsePacket() > 0) {
String text;
while (LoRa.available()) text += (char)LoRa.read();
Serial.printf("Received '%s' RSSI %d dBm, SNR %.1f dB\n", text.c_str(), LoRa.packetRssi(), LoRa.packetSnr());
}
}
Compiled for esp32:esp32:esp32 on 2026-10-30// RFM95W LoRa on Raspberry Pi Pico: wiring and a free simulation at https://www.tinkered.ai/components/rfm95w-lora
// Adafruit RFM95W breakout on a Raspberry Pi Pico (arduino-pico): CS GP17, RST GP20, G0 GP21, SPI0 GP16/18/19
// Flash one board with isSender = true and another with isSender = false.
#include <SPI.h>
#include <LoRa.h>
const long FREQUENCY = 915E6; // 868E6 in Europe, 915E6 in the Americas
const bool isSender = true;
unsigned long counter = 0;
void setup() {
Serial.begin(115200);
SPI.setRX(16);
SPI.setSCK(18);
SPI.setTX(19);
LoRa.setPins(17, 20, 21); // CS, RST, G0
if (!LoRa.begin(FREQUENCY)) {
Serial.println("RFM95W not found: check wiring and power");
while (true) { delay(100); }
}
LoRa.setTxPower(17);
LoRa.setSpreadingFactor(9);
LoRa.setSyncWord(0x34);
Serial.println(isSender ? "RFM95W sender ready" : "RFM95W receiver ready");
}
void loop() {
if (isSender) {
LoRa.beginPacket();
LoRa.print("ping ");
LoRa.print(counter);
LoRa.endPacket();
Serial.print("Sent ping ");
Serial.println(counter++);
delay(5000);
} else if (LoRa.parsePacket() > 0) {
Serial.print("Received '");
while (LoRa.available()) Serial.print((char)LoRa.read());
Serial.print("' RSSI ");
Serial.print(LoRa.packetRssi());
Serial.print(" dBm, SNR ");
Serial.println(LoRa.packetSnr());
}
}
Compiled for rp2040:rp2040:rpipico on 2026-10-30Before you wire it
- Buy the frequency your region allows and set the same value in begin(): 868 MHz in Europe, 915 MHz in the Americas.
- Solder an antenna before transmitting: a straight wire of 7.8 cm for 915 MHz or 8.2 cm for 868 MHz, as Adafruit specifies, or a uFL or SMA antenna.
- Feed VIN from a source that supplies about 150 mA (Adafruit RFM9x guide, Pinouts).
- Use the same spreading factor, bandwidth and sync word on both radios.
- Never power the bare RFM95W module (without a breakout) from 5 V: its absolute maximum is 3.9 V (HopeRF datasheet V1.0, p. 12).
- Never expect G1 to G5 to accept 5 V: unlike SCK, MOSI, CS and RST they are not level shifted (Adafruit RFM9x guide, Pinouts).
- Never transmit continuously on 868 MHz in Europe: the band's duty cycle rules limit time on air.
- The breakout's regulator takes VIN from 3.3 V to 6 V (Adafruit RFM9x guide), so on an Uno, VIN goes to 5V and the SPI pins connect directly.
- MISO and G0 come out at 3.3 V, which ESP32 and Pico read directly and an Uno accepts as a HIGH.
- EN is pulled high; pulling it low switches off the regulator and the radio for the lowest sleep current.
- LoRa.setTxPower() accepts up to 20 dBm on PA_BOOST; 17 dBm draws 87 mA against 120 mA at 20 dBm (HopeRF datasheet V1.0, p. 13), a good default for battery nodes.
- For LoRaWAN (The Things Network), use an LMIC or RadioLib LoRaWAN stack and also wire G1 (DIO1), which those stacks need for receive windows.
Specifications
- Radio chip
- Semtech SX1276 LoRa transceiverAdafruit product 3072 page
- Frequency
- 868 MHz or 915 MHz (RFM95W variants)HopeRF RFM95/96/97/98(W) datasheet V1.0, Table 48, p. 10
- Sensitivity
- Down to -148 dBm (-111 dBm to -148 dBm with spreading factor and bandwidth)HopeRF RFM95/96/97/98(W) datasheet V1.0, pp. 1, 10
- Transmit power and current
- +5 to +20 dBm; 120 mA at +20 dBm, 87 mA at +17 dBmAdafruit product 3072 page; HopeRF datasheet V1.0, Table 51, p. 13
- Receive and sleep current
- 10.8 mA to 11.5 mA receiving, 0.2 µA asleepHopeRF RFM95/96/97/98(W) datasheet V1.0, Table 51, p. 13
- Module supply
- 1.8 V to 3.7 V; absolute maximum 3.9 VHopeRF RFM95/96/97/98(W) datasheet V1.0, p. 12
- Breakout supply (VIN)
- 3.3 V to 6 V, able to supply 150 mA; regulated to 3.3 V on boardAdafruit RFM69HCW and RFM9X guide, Pinouts
- Logic levels
- SCK, MOSI, CS, RST level shifted for 3 V to 5 V; MISO and G0 to G5 are 3.3 V outputsAdafruit RFM69HCW and RFM9X guide, Pinouts
- Range
- About 2 km, depending on obstructions, antenna and powerAdafruit product 3072 page
From the HopeRF RFM95/96/97/98(W) datasheet V1.0, published by HopeRF (module, Semtech SX1276), breakout by Adafruit.
Common mistakes
No antenna, or the wrong length
Without an antenna the radio barely reaches across a room, and transmitting into nothing stresses the power amplifier. Cut a quarter-wave wire for your band (Adafruit gives 7.8 cm for 915 MHz) and solder it to the ANT pad.
Frequency that does not match the hardware
The RFM95W covers 868 MHz and 915 MHz (HopeRF datasheet V1.0, p. 10). A sketch calling LoRa.begin(433E6) on it initialises but never links; 433 MHz needs an RFM96W or RFM98W.
Weak supply
At +20 dBm the module draws about 120 mA (p. 13). A long thin jumper from a busy 3.3 V rail makes packets disappear or the board reset mid-transmission; feed VIN from 5 V on an Uno and keep the wires short.
Settings differ between the two radios
Spreading factor, bandwidth, coding rate and sync word must match. Two radios on different spreading factors both report a successful begin() but never hear each other.
RFM95W LoRa questions
Does the RFM95W work with a 5 V Arduino?
On Adafruit's breakout, yes: VIN takes 3.3 V to 6 V and SCK, MOSI, CS and RST are level shifted for 3 V to 5 V logic (Adafruit RFM9x guide, Pinouts). The bare HopeRF module is 3.3 V only, with a 3.9 V absolute maximum (HopeRF datasheet V1.0, p. 12).
868 MHz or 915 MHz?
Both are the same RFM95W hardware tuned in software (HopeRF datasheet V1.0, p. 10). Use 868 MHz in Europe and 915 MHz in the Americas and Australia, matching your region's licence-free band and any LoRaWAN gateway you want to reach.
What range does the RFM95W reach?
Adafruit quotes about 2 km with simple antennas, depending on obstructions (Adafruit product 3072). With antennas mounted high and clear line of sight, higher spreading factors push LoRa links much further, at a lower data rate.
Which library should I use?
For point-to-point links, the LoRa library by Sandeep Mistry is the simplest. Adafruit's guide uses RadioHead's RH_RF95 for addressed, acknowledged messages, and RadioLib or an LMIC port handles LoRaWAN.
RFM95W or Ra-02?
Both are Semtech LoRa radios with the same register set. The RFM95W (SX1276) is for 868 MHz and 915 MHz; the Ai-Thinker Ra-02 (SX1278) is for 410 MHz to 525 MHz. Two radios only talk if they share a band and settings.
Build something with the RFM95W LoRa
- Build this
LoRa GPS tracker
Send position fixes from a bike or a pet to a base station kilometres away.
- Build this
Field sensor network
Several battery nodes report soil moisture to one receiver.
This page as plain Markdown, for ChatGPT, Claude or your own agent. /components/rfm95w-lora.md