Wi-Fi — отличная штука. Пока вы в 30 метрах от роутера. А датчик влажности стоит на поле в 3 километрах от дома. GPS-трекер уехал на дальнее поле — 8 километров. Метеостанция — на холме за лесом. Wi-Fi там нет и не будет. Мобильный интернет — 150 ₽/месяц на каждый датчик (SIM-карта), а на дальнем поле и мобильная связь-то не везде ловит.
LoRa решает эту проблему. Это технология радиосвязи, которая передаёт данные на расстояние 5–15 километров при мощности меньше батарейки от часов. Один модуль стоит 250–400 ₽. Никаких SIM-карт, никаких провайдеров, никакой абонентской платы — навсегда.
Что такое LoRa и чем оно отличается от WiFi
LoRa (Long Range) — это модуляция радиосигнала, разработанная компанией Semtech. Не путайте с LoRaWAN — это протокол сети поверх LoRa (как HTTP поверх TCP). В этой статье мы работаем с «голой» LoRa: точка-точка, без шлюзов, серверов и регистрации.
Сравнение с WiFi:
- Дальность: WiFi — 30–100 м, LoRa — 5 000–15 000 м (в прямой видимости)
- Скорость: WiFi — 100+ Мбит/с, LoRa — 0,3–50 Кбит/с. Для фото — не годится, для «температура=24.5» — идеально
- Энергопотребление: WiFi — 150–300 мА при передаче, LoRa — 20–40 мА. В 5–10 раз экономичнее
- Инфраструктура: WiFi нужен роутер, LoRa — ничего. Два модуля общаются напрямую
- Стоимость: WiFi-модуль ESP32 — 350 ₽, LoRa-модуль SX1278 — 250 ₽ (но нужен ESP32 для управления — итого 600 ₽)
Вывод: LoRa — это «медленный Wi-Fi на 10 км». Для IoT-датчиков этого более чем достаточно.
Что понадобится
Для передатчика (в поле):
- ESP32 — 350 ₽ (любая модификация: DevKit, NodeMCU-32S)
- LoRa-модуль SX1278 (433 МГц) — 250 ₽. Именно 433 МГц — это разрешённая в России частота для устройств малой мощности без лицензии
- Антенна 433 МГц — 50 ₽ (пружинная) или 150 ₽ (штыревая с SMA-разъёмом — лучше для дальности)
- Провода — 30 ₽
Для приёмника (дома/на базе):
- Такой же набор: ESP32 + SX1278 + антенна
Итого: ~600 ₽ за передатчик + ~600 ₽ за приёмник = 1 200 ₽ за полноценный радиоканал на 10 км. Каждый следующий передатчик — ещё 600 ₽.
Подключение SX1278 к ESP32
SX1278 общается по шине SPI. Подключение:
- SX1278 → ESP32
- VCC → 3.3V (НЕ 5V! Модуль сгорит)
- GND → GND
- SCK → GPIO18
- MISO → GPIO19
- MOSI → GPIO23
- NSS (CS) → GPIO5
- RST → GPIO14
- DIO0 → GPIO2
Антенна: обязательно подключите антенну перед включением! SX1278 без антенны может выйти из строя — выходной каскад перегревается без нагрузки. Припаяйте пружинную антенну к пину ANT, или подключите SMA-антенну через разъём.
Код передатчика
Используем библиотеку LoRa от Sandeep Mistry (устанавливается через Arduino Library Manager):
#include <SPI.h>
#include <LoRa.h>
// Пины подключения SX1278
#define SS_PIN 5
#define RST_PIN 14
#define DIO0_PIN 2
// Интервал отправки (5 минут)
#define SEND_INTERVAL 300000
// ID этого датчика (у каждого — свой)
const String SENSOR_ID = "field_1";
void setup() {
Serial.begin(115200);
// Инициализация LoRa
LoRa.setPins(SS_PIN, RST_PIN, DIO0_PIN);
if (!LoRa.begin(433E6)) { // 433 МГц
Serial.println("LoRa init FAILED!");
while (1);
}
// Настройки для максимальной дальности
LoRa.setSpreadingFactor(10); // 7-12
LoRa.setSignalBandwidth(125E3);
LoRa.setCodingRate4(8); // 5-8
LoRa.setTxPower(17); // до 20 dBm
Serial.println("LoRa transmitter ready");
}
void loop() {
// Читаем данные с датчика
// (замените на реальное чтение с вашего датчика)
float temperature = readTemperature();
float humidity = readHumidity();
float soilMoisture = readSoilMoisture();
float batteryVoltage = readBattery();
// Формируем пакет
// Формат: ID|T=24.5|H=67|SM=42|V=3.85
String packet = SENSOR_ID
+ "|T=" + String(temperature, 1)
+ "|H=" + String(humidity, 0)
+ "|SM=" + String(soilMoisture, 0)
+ "|V=" + String(batteryVoltage, 2);
// Отправляем
LoRa.beginPacket();
LoRa.print(packet);
LoRa.endPacket();
Serial.println("Sent: " + packet);
// Спим 5 минут (deep sleep для экономии батареи)
esp_sleep_enable_timer_wakeup(
SEND_INTERVAL * 1000ULL);
esp_deep_sleep_start();
}
// Заглушки — замените на реальные функции
float readTemperature() { return 24.5; }
float readHumidity() { return 67.0; }
float readSoilMoisture() { return 42.0; }
float readBattery() {
// Делитель напряжения на GPIO34
int raw = analogRead(34);
return raw / 4095.0 * 3.3 * 2; // ×2 из-за делителя
}
Код приёмника
#include <SPI.h>
#include <LoRa.h>
#include <WiFi.h>
#include <HTTPClient.h>
#define SS_PIN 5
#define RST_PIN 14
#define DIO0_PIN 2
// WiFi (приёмник стоит дома — WiFi есть)
const char* WIFI_SSID = "ВашаСеть";
const char* WIFI_PASS = "ВашПароль";
// InfluxDB (из статьи про Grafana)
const char* INFLUX_URL =
"http://farm-server.local:8086";
const char* INFLUX_TOKEN = "ВАШ_ТОКЕН";
void setup() {
Serial.begin(115200);
// Подключаемся к WiFi
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
Serial.println("WiFi connected");
// Инициализация LoRa (те же настройки!)
LoRa.setPins(SS_PIN, RST_PIN, DIO0_PIN);
if (!LoRa.begin(433E6)) {
Serial.println("LoRa init FAILED!");
while (1);
}
LoRa.setSpreadingFactor(10);
LoRa.setSignalBandwidth(125E3);
LoRa.setCodingRate4(8);
Serial.println("LoRa receiver ready");
}
void loop() {
int packetSize = LoRa.parsePacket();
if (packetSize) {
String packet = "";
while (LoRa.available()) {
packet += (char)LoRa.read();
}
int rssi = LoRa.packetRssi();
float snr = LoRa.packetSnr();
Serial.printf("Received: %s [RSSI=%d, SNR=%.1f]\n",
packet.c_str(), rssi, snr);
// Парсим пакет: field_1|T=24.5|H=67|SM=42|V=3.85
parseAndSend(packet, rssi, snr);
}
}
void parseAndSend(String packet, int rssi, float snr) {
// Извлекаем ID датчика
int sep = packet.indexOf('|');
if (sep < 0) return;
String sensorId = packet.substring(0, sep);
String data = packet.substring(sep + 1);
// Формируем строки InfluxDB Line Protocol
// lora,sensor=field_1 temperature=24.5,
// humidity=67,soil_moisture=42,
// battery=3.85,rssi=-67,snr=9.5
String line = "lora,sensor=" + sensorId + " ";
bool first = true;
// Парсим пары K=V
while (data.length() > 0) {
sep = data.indexOf('|');
String pair = (sep > 0)
? data.substring(0, sep)
: data;
data = (sep > 0)
? data.substring(sep + 1) : "";
int eq = pair.indexOf('=');
if (eq < 0) continue;
String key = pair.substring(0, eq);
String val = pair.substring(eq + 1);
// Маппинг коротких ключей
String field;
if (key == "T") field = "temperature";
else if (key == "H") field = "humidity";
else if (key == "SM") field = "soil_moisture";
else if (key == "V") field = "battery";
else field = key;
if (!first) line += ",";
line += field + "=" + val;
first = false;
}
// Добавляем RSSI и SNR
line += ",rssi=" + String(rssi);
line += ",snr=" + String(snr, 1);
// Отправляем в InfluxDB
sendToInflux(line);
}
void sendToInflux(String lineData) {
HTTPClient http;
String url = String(INFLUX_URL)
+ "/api/v2/write?org=farm"
+ "&bucket=sensors&precision=s";
http.begin(url);
http.addHeader("Authorization",
"Token " + String(INFLUX_TOKEN));
http.addHeader("Content-Type", "text/plain");
int code = http.POST(lineData);
Serial.printf("InfluxDB: %d\n", code);
http.end();
}
Настройки дальности: что крутить
LoRa — это компромисс между дальностью, скоростью и энергопотреблением. Три ключевых параметра:
Spreading Factor (SF): от 7 до 12. Чем выше — тем дальше бьёт, но медленнее. SF7 — 300 м в городе, 2 км в поле. SF12 — 2 км в городе, 15 км в поле. Для фермы рекомендую SF10 — золотая середина: 5–10 км при нормальной скорости.
Bandwidth (BW): 125, 250 или 500 кГц. Меньше — дальше и медленнее. 125 кГц — стандарт для максимальной дальности.
Coding Rate (CR): от 4/5 до 4/8. Добавляет избыточность для коррекции ошибок. 4/8 — максимальная надёжность, теряем 50% скорости, но пакет дойдёт даже при сильных помехах.
Практический рецепт для фермы (5–10 км):
LoRa.setSpreadingFactor(10); // SF10
LoRa.setSignalBandwidth(125E3); // 125 кГц
LoRa.setCodingRate4(8); // CR 4/8
LoRa.setTxPower(17); // 17 dBm
При этих настройках пакет «field_1|T=24.5|H=67|SM=42|V=3.85» (40 байт) передаётся за 0,4 секунды. При отправке раз в 5 минут — радиоканал занят 0,13% времени. Можно подключить десятки датчиков без конфликтов.
Антенна: главный фактор дальности
Модуль SX1278 выдаёт сигнал. Но без правильной антенны он никуда не улетит. Разница между плохой и хорошей антенной — в 3–5 раз по дальности:
Пружинная антенна (50 ₽): припаивается прямо к плате. Дальность: 1–3 км. Для ближних датчиков — нормально.
Штыревая антенна с SMA (150 ₽): подключается через разъём, длина 17 см (четвертьволновая для 433 МГц). Дальность: 3–8 км. Оптимальный выбор.
Направленная антенна Yagi (500–800 ₽ или самодельная): для конкретного направления. Дальность: 10–20 км. Имеет смысл, если датчик далеко и всегда в одном месте.
DIY-антенна: кусок медного провода длиной 16,4 см (четверть длины волны на 433 МГц), припаянный вертикально к пину ANT. Бесплатно, работает на 2–5 км. Главное — вертикально и без изгибов.
Высота установки критичнее типа антенны. Антенна на высоте 3 метра (на столбе) бьёт в 2 раза дальше, чем на земле. Формула Френеля: на расстоянии 5 км первая зона Френеля требует прямой видимости с запасом 18 м — то есть между двумя точками не должно быть деревьев или зданий выше 18 м.
Автономное питание: сколько проработает
Передатчик в поле — это батарея + ESP32 + SX1278. Считаем:
- ESP32 в deep sleep: 10 мкА
- Пробуждение + чтение датчиков: 80 мА × 0,5 с = 40 мА·с
- LoRa-передача: 120 мА × 0,4 с = 48 мА·с
- Суммарно за 5 минут: 10 мкА × 300 с + 88 мА·с = 3 + 88 = 91 мА·с ≈ 0,025 мА·ч/цикл
- 288 циклов/сутки × 0,025 = 7,2 мА·ч/сутки
Аккумулятор 18650 (3 000 мА·ч): 3000 / 7,2 = 416 дней. Больше года на одной батарейке! На практике — 6–8 месяцев (саморазряд, мороз, КПД стабилизатора). Но даже 6 месяцев — это поставил весной, забрал осенью.
Для вечной работы: солнечная панель 1W (300 ₽) + TP4056 (контроллер заряда, 40 ₽) + 18650. Панель заряжает днём, датчик работает круглосуточно. Даже зимой в пасмурную погоду 1W-панель даёт достаточно для 7 мА·ч/сутки.
Адресация: когда датчиков больше одного
LoRa — это радио. Все слышат всех на одной частоте. Как различать датчики? В нашем протоколе — по ID в начале пакета: field_1|..., field_2|..., sklad_1|.... Приёмник парсит ID и раскладывает по разным measurement в InfluxDB.
Но если датчиков больше 10 — возможны коллизии (два датчика передают одновременно → оба пакета теряются). Решения:
- Разнести по времени: датчик 1 шлёт в :00, :05, :10... Датчик 2 — в :01, :06, :11... Сдвиг 1 минута. С 10 датчиками — отправка каждую минуту, но каждый конкретный — раз в 5 минут
- Случайная задержка: перед отправкой —
delay(random(0, 5000)). Простите, не гарантия, но при 10 датчиках вероятность коллизии ~2% - TDMA: приёмник передаёт «слот» — порядковый номер, датчик слушает и отвечает в свой слот. Сложнее, но надёжнее
Для фермы с 5–15 датчиками хватает рандомной задержки. Потерялся один пакет из 288 за день — не страшно, следующий придёт через 5 минут.
Шифрование: ваши данные — ваши
«Голая» LoRa передаёт открытым текстом. Любой с таким же модулем на 433 МГц может слушать. Для температуры на поле — не критично. Но если передаёте GPS-координаты техники или данные о весе урожая — стоит зашифровать.
Простое решение — AES-128 шифрование на ESP32 (встроенная аппаратная поддержка):
#include "mbedtls/aes.h"
// Общий ключ (16 байт) — одинаковый на TX и RX
const unsigned char KEY[16] = {
0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
};
void encrypt(unsigned char* input,
unsigned char* output, int len) {
mbedtls_aes_context aes;
mbedtls_aes_init(&aes);
mbedtls_aes_setkey_enc(&aes, KEY, 128);
// Шифруем блоками по 16 байт
for (int i = 0; i < len; i += 16) {
mbedtls_aes_crypt_ecb(&aes,
MBEDTLS_AES_ENCRYPT,
input + i, output + i);
}
mbedtls_aes_free(&aes);
}
Ключ прошивается в оба устройства. Без ключа перехваченный пакет — мусор.
Легальность: можно ли просто так взять и передавать
В России частота 433 МГц разрешена для бытовых устройств малой мощности без лицензии. Условия: мощность излучения до 10 мВт (на практике SX1278 на 17 dBm = 50 мВт — формально выше разрешённого). Однако:
- Частотные группы 433,075–434,79 МГц выделены для ISM-устройств (Решение ГКРЧ 07-20-03-001)
- На практике контроля за маломощными устройствами нет — эфир на 433 МГц забит автосигнализациями, метеостанциями, пультами ворот
- Для легального использования на повышенной мощности — есть диапазон 868 МГц (до 25 мВт без лицензии). Модули SX1276 на 868 МГц стоят столько же
Рекомендация: для фермы используйте 433 МГц на стандартной мощности. Если нужна сертификация (для продажи продукта) — переходите на 868 МГц.
Отладка: пакет не доходит — что проверять
LoRa — радио, а радио капризно. Чек-лист, если приёмник молчит:
1. Антенна подключена? Без антенны SX1278 передаёт на 5–10 метров и может перегреться. Проверьте пайку. Если используете SMA — закрутите разъём до упора.
2. Частота совпадает? На обоих устройствах должно быть ровно 433E6. Модули с маркировкой «868 MHz» на 433 не работают — у них другой фильтр на плате.
3. Настройки SF/BW/CR идентичны? Если на передатчике SF10, а на приёмнике SF7 — пакет не декодируется. Все три параметра должны совпадать.
4. ESP32 не перезагружается? Если deep sleep настроен неправильно, ESP32 может уходить в sleep до отправки пакета. Добавьте delay(100) после LoRa.endPacket() — дайте радио время фактически отправить данные перед засыпанием.
5. RSSI на приёмнике. Нормальные значения: от −30 (рядом) до −120 (предел чувствительности). Если RSSI ниже −115 — сигнал на грани. Поднимите антенну выше, уберите препятствия, увеличьте SF.
6. Помехи на 433 МГц. Автосигнализации, метеостанции, пульты — всё это шумит на 433 МГц. Если рядом парковка или гараж — попробуйте другую частоту: 433.5E6 или 434E6. Допустимый диапазон: 433–434.8 МГц.
Полезный инструмент: RTL-SDR (USB-приёмник за 800 ₽) + программа CubicSDR или SDR# — видите весь радиоэфир на экране. Ваш пакет виден как горизонтальный «чирп» — если его нет, проблема в передатчике.
Что дальше: от точка-точка к сети
Сейчас у нас: один передатчик → один приёмник. Это простейший случай. В следующей статье соберём полноценный LoRa-шлюз на Raspberry Pi, который:
- Принимает данные от 10-20 датчиков одновременно
- Пишет в InfluxDB (из статьи про Grafana)
- Поддерживает подтверждение доставки (ACK)
- Мониторит качество связи (RSSI/SNR по каждому датчику)
- Отправляет алерт, если датчик замолчал
А пока — начните с простого: передатчик + приёмник. Подключите к метеостанции из третьей статьи, замените WiFi-отправку на LoRa — и метеостанция работает в 5 км от дома без единого провода.
Системы вроде ТерраКвант используют промышленные LoRaWAN-шлюзы и сертифицированные датчики с гарантией дальности. Но для старта — наш вариант за 1 200 ₽ покрывает 90% задач фермера-самодельщика.




