WiFi range tops out at ~100 m. LoRa reaches 2–15 km (line of sight) on a CR2032 battery — making it the go-to choice for agriculture sensors, asset tracking, smart meter reading, and any outdoor IoT deployment where WiFi or cellular is impractical.

// What you'll build: A LoRa sensor node (ESP32 + SX1278) that broadcasts soil moisture and temperature every 60 seconds, and a gateway node that receives the packets and prints them to serial — extendable to forward data via MQTT to any server.
NODE 1 ESP32+SX1278 Field sensor NODE 2 ESP32+SX1278 Remote sensor LoRa 433/868/915 MHz up to 15 km LOS GATEWAY ESP32 + SX1278 WiFi + LoRa bridge WiFi / MQTT SERVER HA / AWS IoT Dashboard
// AD SLOT — IN-CONTENT RESPONSIVE

Hardware Required

PartNotes
2× ESP32 DevKitOne transmitter, one gateway/receiver
2× LoRa SX1278 (Ra-02)433 MHz for EU/Asia; use 915 MHz for US
2× Wire antenna~17.3 cm for 433 MHz (quarter-wave)
Soil moisture sensor (optional)Capacitive preferred over resistive

Wiring — SX1278 to ESP32

SX1278 PinESP32 GPIO
VCC3.3V
GNDGND
SCKGPIO 18
MISOGPIO 19
MOSIGPIO 23
NSS (CS)GPIO 5
RSTGPIO 14
DIO0GPIO 2

Library Setup

Install the LoRa library by Sandeep Mistry from the Arduino Library Manager.

Transmitter Node Sketch

// lora_transmitter.ino
#include <SPI.h>
#include <LoRa.h>

#define LORA_SS   5
#define LORA_RST  14
#define LORA_DIO0 2
#define SOIL_PIN  34  // analog soil moisture sensor

int packetCount = 0;

void setup() {
  Serial.begin(115200);
  LoRa.setPins(LORA_SS, LORA_RST, LORA_DIO0);
  if (!LoRa.begin(433E6)) {     // 433 MHz — change to 868E6 or 915E6 as needed
    Serial.println("LoRa init failed!");
    while (true);
  }
  LoRa.setSpreadingFactor(9);   // SF9 — good balance of range vs speed
  LoRa.setSignalBandwidth(125E3);
  LoRa.setCodingRate4(5);
  Serial.println("LoRa transmitter ready.");
}

void loop() {
  int soil = map(analogRead(SOIL_PIN), 4095, 1500, 0, 100); // % moisture
  float temp = (float)(analogRead(35)) * 0.1;               // placeholder

  String payload = String(packetCount) + "," +
                   String(soil) + "," +
                   String(temp, 1);

  LoRa.beginPacket();
  LoRa.print(payload);
  LoRa.endPacket();

  Serial.printf("Sent packet #%d: %s\n", packetCount, payload.c_str());
  packetCount++;
  delay(60000); // transmit every 60 seconds
}

Gateway / Receiver Sketch

// lora_gateway.ino
#include <SPI.h>
#include <LoRa.h>
#include <WiFi.h>
#include <PubSubClient.h>

// Same pin definitions as transmitter
#define LORA_SS 5; #define LORA_RST 14; #define LORA_DIO0 2;

const char* SSID = "YOUR_SSID"; const char* PASSWORD = "YOUR_PASSWORD";
const char* MQTT_HOST = "192.168.1.10";
WiFiClient wifiClient; PubSubClient mqtt(wifiClient);

void setup() {
  Serial.begin(115200);
  WiFi.begin(SSID, PASSWORD);
  while (WiFi.status() != WL_CONNECTED) delay(500);
  mqtt.setServer(MQTT_HOST, 1883);
  LoRa.setPins(5, 14, 2);
  LoRa.begin(433E6);
  LoRa.setSpreadingFactor(9);  // must match transmitter
  Serial.println("Gateway listening...");
}

void loop() {
  if (!mqtt.connected()) { mqtt.connect("lora-gateway"); }
  mqtt.loop();

  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    String received = "";
    while (LoRa.available()) received += (char)LoRa.read();
    int rssi = LoRa.packetRssi();
    Serial.printf("Received: %s  RSSI: %d dBm\n", received.c_str(), rssi);
    mqtt.publish("lora/sensor/data", received.c_str());
    mqtt.publish("lora/sensor/rssi", String(rssi).c_str());
  }
}

Spreading Factor Reference

SFRangeAirtime (10-byte payload)Battery drain
SF7~2 km~56 msLowest
SF9~5 km~370 msMedium
SF12~15 km~2.5 sHighest
// Rule of thumb: Each SF step doubles the range but also doubles the airtime (and power use). Start with SF9 for outdoor field deployments — it is a safe balance. Use SF7 only when nodes are within the same building.
A
Engr. Aamir Aziz Butt
PhD Researcher · IoT Engineer · Founder ESPSTACK

PhD candidate at Muslim Youth University, Islamabad. MS Computer Engineering from COMSATS. 10+ years of IoT development experience across ESP32, Jetson Nano, and cloud platforms.