Arduino Nano with RFM95 LoRa SX1276 Module – Long Range Wireless Communication Project

Arduino Nano + RFM95 LoRa SX1276 Tutorial | MakeMindz
Arduino Nano LoRa / RFM95 IoT Wireless

Arduino Nano with RFM95 LoRa (SX1276)
Long-Range Wireless Communication

Build a low-power, long-range wireless communication system using Arduino Nano and the RFM95 LoRa module — perfect for IoT, smart agriculture, and remote monitoring. Includes circuit diagram, full code, and Wokwi simulation.

Beginner–Intermediate
~30 min build time
SPI Interface
LoRa 915 MHz
5+
km range
3.3V
LoRa power
6
SPI pins
915
MHz band
IoT
ready
📡 Project Overview

This project demonstrates a reliable long-range wireless communication system using an Arduino Nano and the RFM95 LoRa (SX1276) module connected via SPI interface. LoRa (Long Range) technology enables low-power data transmission over several kilometres — making it perfect for IoT sensor networks where WiFi or Bluetooth simply don't reach.

The Arduino Nano communicates with the LoRa module using standard SPI pins (MOSI, MISO, SCK) plus three control pins: CS, RST, and DIO0. The RFM95 operates at 3.3V — a critical detail to avoid damaging the module. Once set up, the system sends a packet every 2 seconds, which can be received by any other LoRa node tuned to the same frequency.

📶
Long Range
Transmit data over 5+ km in open areas with minimal power
🔋
Low Power
Ideal for battery-powered remote sensors — runs for months
🔌
SPI Interface
Standard SPI communication — fast and reliable data transfer
🌐
IoT Ready
Works with LoRaWAN gateways for cloud connectivity
Real-time Tx
Transmit sensor data in real-time with packet acknowledgement
🧰 Components Required
#ComponentSpecificationQtyNote
1 Arduino Nano ATmega328P, 5V 1 Main MCU
2 RFM95 LoRa Module SX1276 chip, 915 MHz 1 3.3V only!
3 Jumper Wires Male-to-Male / Female 10+
4 Breadboard 400 or 830 tie points 1 Optional
5 LoRa Antenna 915 MHz wire/PCB antenna 1 Strongly recommended
6 USB Cable Mini-USB for Nano 1 For programming
⚠️
3.3V Warning: The RFM95 module runs on 3.3V. Connecting it directly to the Arduino Nano's 5V pins will permanently damage the module. Use the Nano's 3.3V pin (max 50mA) or a separate 3.3V regulator for the power supply.
Circuit Diagram & Pin Connections
🔌 Arduino Nano ↔ RFM95 LoRa Wiring SPI
✓ Verified
ARDUINO NANO USB D4 CS D2 RST D3 DIO0 D11 MOSI D12 MISO D13 SCK 3V3 3.3V GND GND RFM95 LoRa SX1276 ANT NSS RST DIO0 MOSI MISO SCK 3V3 GND WIRE LEGEND SPI/Control Power/GND Arduino Nano ↔ RFM95 LoRa (SX1276) — SPI Connection @ 3.3V

📌 Complete Pin-to-Pin Wiring Reference

Arduino Nano PinRFM95 LoRa PinFunctionWire Colour
D4 NSS / CS Chip Select (SPI) Orange
D2 RST Hardware Reset Yellow
D3 DIO0 Interrupt / IRQ Purple
D11 (MOSI) MOSI SPI Data Out Green
D12 (MISO) MISO SPI Data In Blue
D13 (SCK) SCK SPI Clock Red
3.3V 3V3 / VCC Power Supply Dark Orange
GND GND Common Ground Black
🪜 Step-by-Step Instructions
1

Install the Arduino IDE & LoRa Library

Download and install the Arduino IDE from arduino.cc/en/software. Once installed, open the Library Manager (Sketch → Include Library → Manage Libraries) and search for "LoRa" by Sandeep Mistry. Click Install.

Also ensure the SPI library is available — it comes bundled with Arduino IDE by default, so no extra install needed.

ℹ️
You can also use the RadioHead library (by Mike McCauley) as an alternative — it supports more LoRa features like frequency hopping.
2

Connect RFM95 to Arduino Nano

Place your Arduino Nano and RFM95 module on a breadboard. Wire them up exactly as shown in the pin table above. Double-check every connection before powering on.

Critical connections: D11→MOSI, D12→MISO, D13→SCK, D4→NSS, D2→RST, D3→DIO0.

🚫
Never connect VCC to 5V! The RFM95 is a 3.3V device. Use the Nano's 3.3V pin. Powering it with 5V will destroy the module instantly.
💡
Attach a 915 MHz antenna to the ANT pad before transmitting. Running LoRa without an antenna can permanently damage the RF circuitry of the module.
3

Configure Pin Definitions in Code

Open the Arduino IDE and create a new sketch. At the top, define the three control pins that are not part of the standard SPI bus:

Arduino C++
// Pin definitions — change these if you rewire
#define RFM95_CS   4   // NSS — Chip Select
#define RFM95_RST  2   // RST — Hardware Reset
#define RFM95_INT  3   // DIO0 — Interrupt
ℹ️
The SPI pins (MOSI=D11, MISO=D12, SCK=D13) are fixed on the Arduino Nano hardware — the LoRa library uses them automatically. Only CS, RST and DIO0 are user-configurable.
4

Initialize LoRa in setup()

In setup(), begin Serial at 9600 baud for debugging, perform a hardware reset on the module (LOW→HIGH pulse), then call LoRa.begin(915E6) to initialise at 915 MHz. If it fails to initialise, the code halts and prints an error to Serial Monitor.

💡
Frequency note: Use 915E6 for US/AU, 868E6 for Europe, or 433E6 for Asia. India commonly uses 865–867 MHz. Check your local regulations before deploying.
5

Send LoRa Packets in loop()

In loop(), call LoRa.beginPacket() to open a packet, use LoRa.print() to write your payload (text, sensor data, etc.), then call LoRa.endPacket() to transmit. Add a delay(2000) to send every 2 seconds.

💡
To receive packets on another LoRa node, use LoRa.parsePacket() and LoRa.read(). A two-node setup lets you build a complete bidirectional link.
6

Upload, Test & Monitor

Select Board: Arduino Nano and the correct COM port under Tools. Click Upload. Open Serial Monitor at 9600 baud. You should see:

Serial Monitor Output
Initializing LoRa module...
LoRa initialization successful.
Sending packet...
Sending packet...
Sending packet...

If you see "Starting LoRa failed!" — check your wiring, especially CS and RST pins, and verify 3.3V power.

💡
Use a second Arduino + LoRa setup as a receiver to confirm packets arrive. You can also use a Raspberry Pi with a LoRa HAT as the gateway.
💻 Full Arduino Code

Complete sketch for Arduino Nano + RFM95 LoRa transmitter. Copy, paste into Arduino IDE and upload.

arduino_nano_lora_tx.ino
/*
 * Arduino Nano with RFM95 LoRa (SX1276) — Transmitter
 * Tutorial by MakeMindz: www.makemindz.com
 *
 * Hardware:
 *   Arduino Nano  ←→  RFM95 LoRa Module
 *   D4            ←→  NSS (Chip Select)
 *   D2            ←→  RST (Reset)
 *   D3            ←→  DIO0 (Interrupt)
 *   D11 (MOSI)    ←→  MOSI
 *   D12 (MISO)    ←→  MISO
 *   D13 (SCK)     ←→  SCK
 *   3.3V          ←→  VCC  ⚠️ 3.3V ONLY!
 *   GND           ←→  GND
 *
 * Required Library: "LoRa" by Sandeep Mistry
 *   Install via: Sketch → Include Library → Manage Libraries
 */

#include <SPI.h>
#include <LoRa.h>

// ── Pin definitions ──────────────────────────────────────────
#define RFM95_CS   4    // NSS / Chip Select
#define RFM95_RST  2    // Hardware Reset
#define RFM95_INT  3    // DIO0 Interrupt

// ── Frequency: 915E6 (US/AU), 868E6 (EU), 865E6 (India) ────
#define LORA_FREQ  915E6

int packetCount = 0;    // Track packets sent

void setup() {
  Serial.begin(9600);
  while (!Serial);       // Wait for Serial Monitor to open

  Serial.println("MakeMindz — Arduino Nano LoRa Transmitter");
  Serial.println("Initializing RFM95 LoRa module...");

  // Configure chip select and reset pins
  LoRa.setPins(RFM95_CS, RFM95_RST, RFM95_INT);

  // Perform hardware reset
  pinMode(RFM95_RST, OUTPUT);
  digitalWrite(RFM95_RST, LOW);
  delay(10);
  digitalWrite(RFM95_RST, HIGH);
  delay(10);

  // Initialise LoRa at chosen frequency
  if (!LoRa.begin(LORA_FREQ)) {
    Serial.println("❌ LoRa init failed! Check wiring and power.");
    while (1);             // Halt — do not continue
  }

  // Optional: set transmit power (2–20 dBm)
  LoRa.setTxPower(17);

  Serial.println("✅ LoRa initialised successfully!");
  Serial.print("   Frequency: ");
  Serial.print(LORA_FREQ / 1E6);
  Serial.println(" MHz");
  Serial.println("   Sending packets every 2 seconds...");
  Serial.println("─────────────────────────────────────────");
}

void loop() {
  packetCount++;

  Serial.print("📡 Sending packet #");
  Serial.println(packetCount);

  // Build and transmit a LoRa packet
  LoRa.beginPacket();
  LoRa.print("Hello from MakeMindz! Packet #");
  LoRa.print(packetCount);
  LoRa.endPacket();

  Serial.print("   ✓ Sent: Hello from MakeMindz! Packet #");
  Serial.println(packetCount);

  delay(2000);  // Wait 2 seconds before next transmission
}
📌
Key improvement: This code includes LoRa.setPins() which properly tells the library which pins to use for CS, RST and IRQ — making it more portable than hardcoding. Also added LoRa.setTxPower(17) for better range.
🔬 Wokwi Online Simulation
🧪
Online Simulator
Test Without Hardware — Free!
Run this exact circuit in Wokwi's browser-based Arduino simulator. No hardware needed. Paste the diagram.json above, add the code, and click Play to see packets transmitting in real-time in the Serial Monitor.

How to run the simulation:

1

Open Wokwi → New Arduino Nano Project

Click "Open in Wokwi Simulator" above. Create a new project selecting Arduino Nano.

2

Paste diagram.json

Click the diagram.json tab in Wokwi editor. Select all and replace with the JSON from the section above. Save.

3

Paste the Arduino Sketch

Click the sketch.ino tab and paste the full code from above. Save.

Click the green Play button

The simulation compiles and runs. Open the Serial Monitor panel at the bottom — you'll see "LoRa initialised successfully!" and packets being sent every 2 seconds.

🌍 Applications & Use Cases

Once your LoRa link is working, here's what you can build with it.

🌾Smart Agriculture
🌦️Wireless Weather Station
🏭Industrial IoT
🏠Home Automation
📡Remote Monitoring
🛰️GPS Asset Tracking
🔬Environmental Sensors
🏙️Smart City Networks
🚀
Next steps: Try adding a DHT22 temperature/humidity sensor and transmitting real sensor readings instead of a static message. Then add a second Arduino Nano + LoRa as a receiver node — you'll have a complete wireless sensor link!
📚 More Arduino Tutorials on MakeMindz
Inspiring the next generation of makers & builders in India — one project at a time.
© 2026 MakeMindz — www.makemindz.com

Comments

try for free