
В предыдущей статье я рассказывал о том, как предоставить удалённый доступ к данным измерений метеостанции с помощью модулей Heltec Automation HTIT-WB32LAF V3, объединяющих микроконтроллер ESP32-S3FN8 с LoRa-чипом SX1262. При правильной установке антенн и хороших условиях распространения радиоволн возможна передача данных на километры.
Но что, если нужно передавать данные ещё дальше, а возможности антенн с большим коэффициентом усиления исчерпаны и мощность передатчика повышать нельзя?
Тут помогут ретрансляторы LoRa. С их помощью можно расширить зону покрытия на пересечённой местности, в районах городской застройки, выполнять мониторинг вдоль трубопроводов, ЛЭП, дорог и рек, когда один шлюз не «добьет» до всех узлов. Ретрансляторы пригодятся, если нужно собирать данные на сельскохозяйственных и промышленных объектах большой площади, передавать данные в удалённых или труднодоступных районах.
В этой статье я начну рассказ с адресов и сетей LoRa. Адресация позволяет передавать данные не всем узлам на одном канале, а только нужным. Вооружившись этой информацией, а также способами создания ретрансляторов, вы сможете передавать данные очень далеко. Для этого достаточно установить на пути между передатчиком и приёмником нужное количество узлов ретрансляции. Такие узлы в простейшем случае состоят только из модуля LoRa и источника питания, а могут дополняться микроконтроллерами для обработки данных.
Работая над статьёй, я собрал макеты на базе микроконтроллеров Waveshare esp32-s3-lcd-1.47 и ESP32-S3-N16R8, которые были у меня под рукой, а также модулей EBYTE LoRa E22-900T22D. Микроконтроллеры вы можете взять и другие с учётом особенностей их подключения и программирования. Что же касается модуля E22-900T22D, то я использовал его из-за реализованной в нём аппаратной ретрансляции пакетов данных.
Адреса и сети в модулях LoRa
В модулях EBYTE LoRa предусмотрена аппаратная реализация адресации и сегментации сети. Если настроить фильтрацию «чужих» пакетов при конфигурировании, модуль будет отдавать через UART только адресованные ему данные.
Создавая системы передачи данных на базе LoRa, вы можете использовать прозрачный либо фиксированный режим передачи. В модулях EBYTE серии E22 также включается режим аппаратной ретрансляции пакетов.
Сетевые параметры узла
Каждый модуль EBYTE LoRa задают три параметра в его регистрах конфигурации:
ADDH и ADDL — старший и младший байты 16-разрядного адреса узла (от 0x0000 до 0xFFFF);
CHAN — номер частотного канала, который задаёт смещение от базовой частоты диапазона (для версии 900 МГц базовая частота 850,125 МГц при шаге 1 МГц);
NETID — идентификатор сети для разделения логических групп устройств
Для того чтобы модули могли связаться друг с другом, они должны работать на одной частоте (в одном и том же канале CHAN), и в сети с одинаковым идентификатором NETID.
Замечу, что необходимость одинаковых NETID для работы E22-900T22D не упоминается в даташите и примерах программ. Однако мои собственные эксперименты показали, что даже без применения ретранслятора значения идентификатора сети должны совпадать. Вы также можете почитать обсуждение этого вопроса в сети.
Прозрачная передача
В случае прозрачной передачи (transparent transmission) модуль LoRa отправляет в эфир все данные, полученные через UART в неизменном виде. Эти данные будут приняты всеми устройствами, настроенными на тот же самый канал CHAN (частоту передачи) и расположенными в той же сети NETID (рис. 1).

Здесь узел 1 играет роль передатчика с адресом 0x0001, настроенного на работу в сети 0 и на канале 19 в прозрачном режиме.
Передаваемые этим узлом данные будут получены узлами 2 и 3, настроенными также на работу в сети 0 и на канале 19. При этом адрес узла 2 равен 0x0002, а узла 3 — 0x0110.
Что же касается узлов 4 и 5, то они не примут данные, отправленные в эфир узлом 1. Узел 4 настроен на работу в канале 18 (на другую частоту), а узел 5 работает в другой сети с номером 1.
Таким образом реализуется режим «все слышат всех», удобный для отладки и простых соединений между малым количеством узлов, работающих на одном канале и в одной сети.
Фиксированная передача
В режиме фиксированной передачи модуль отправляет в эфир перед блоком данных префикс длиной три байта, содержащий адрес получателя ADDH и ADDL, а также номер канала CHAN.
При такой адресной отправке данные получит только модуль, адрес которого совпадает с адресом отправки. Также он должен быть сконфигурирован для работы на том же канале и в той же сети NETID, что и передатчик (рис. 2).

Узел 3 не примет данные, так как у него другой адрес 0x0110. Узел 4 не получит данные из-за несоответствия адреса и номера канала, а узел 5 — из-за несоответствия адреса и номера сети.
Если в качестве адреса получателя указать 0xFFFF (широковещательный адрес), сообщение примут все модули, настроенные на этот канал и расположенные в той же сети, независимо от их собственного адреса (рис. 3).

Узел 4 не примет пакеты данных, так как настроен на работу в другом канале, а узел 5 — из-за другого номера сети.
Режим ретранслятора
Хотя с помощью LoRa можно передавать данные на километры, иногда хочется увеличить дальность связи ещё больше. Конечно, можно наращивать мощность передатчика, устанавливать антенны с большим коэффициентом усиления и выбирать для установки антенн место как можно выше.
Но при увеличении мощности передатчика приходится учитывать ограничения законодательства. Кроме того, если нет прямой видимости между антеннами, это тоже уменьшает дальность связи.
Между тем есть простое решение этой проблемы — установка ретрансляторов на пути передачи сигналов.
На сегодня есть два способа построения ретранслятора — программный и аппаратный.
Первый из них предполагает наличие в узле одного или двух модулей LoRa и микроконтроллера. В этом случае модуль LoRa принимает пакет, передавая его микроконтроллеру, а тот, возможно, после обработки, отправляет его дальше, но уже по другому адресу. Если узел ретранслятора оборудован двумя модулями LoRa на разные частотные диапазоны (например, 868 МГц и 433 МГц), то приём может вестись в одном диапазоне, а передача — в другом.
Такой подход с одним микроконтроллером и одним модулем LoRa я описывал в статье «DIY: ретранслятор на micro:bit и радиомодуле LoRa увеличивает дальность связи». В конце этой статьи я расскажу о реализации программного ретранслятора на базе микроконтроллера ESP32-S3-N16R8 и модуля EBYTE LoRa E22-900T22D.
Аппаратный ретранслятор можно построить вообще без микроконтроллера, всего лишь на одном модуле. Сейчас этот режим доступен в серии EBYTE E22, а также в промышленной линейке E90-DTU. Чтобы его включить, необходимо соответствующим образом настроить конфигурацию модуля.
В режиме ретранслятора поля адреса ADDH и ADDL служат меткой сети NETID для пересылки пакетов. Например, если у модуля ретранслятора ADDH и ADDL выставлены как 05 и 07, то сигнал, отправленный первым узлом из сети 05, пересылается в сеть 07, где его примет второй узел (рис. 4).

Ретрансляторы можно каскадировать, значительно увеличивая дальность передачи пакетов. Например, если поля второго ретранслятора ADDH и ADDL выставлены как 7 и 11, то он будет пересылать пакеты от первого ретранслятора в сеть 11 (рис. 5).

Здесь узел 2 получает данные от первого ретранслятора, так как у него адрес 0x0002, и он находится в сети 7. Узел 4 настроен на такой же адрес, но работает в сети 11, и получает данные от второго ретранслятора.
Узел 3 не принимает пакеты данных, так как у него адрес 0x0110, а передатчик отправляет данные на адрес 0x0002.
Узел 5 сконфигурирован для работы на адресе 0x0002, однако он работает в сети 8, а не 7 или 11.
Замечу, что ретрансляторы работают в обе стороны.
Работаем в фиксированном режиме
В практической части статьи я расскажу, как реализовать фиксированный режим для передачи текстовой строки, а также как сделать аппаратный и программный ретрансляторы.
Узлы нашей небольшой сети будут собраны на базе микроконтроллера Waveshare ESP32-S3-LCD-1.47B-M и модуля EBYTE LoRa E22-900T22D. Этот микроконтроллер оборудован LCD-экраном, что удобно для отладки.
В статье «Метеостанция на LoRa и ESP32, которая годами работает от батарейки» я рассказывал про использование компактных модулей Heltec Automation HTIT-WB32LAF V3, которые уже содержат «на борту» LoRa-модуль на базе SX1262.
Отдельные модули E22-900T22D дают гибкость при выборе архитектуры, так как их можно подключить к любому микроконтроллеру или микрокомпьютеру.
Встроенный в E22-900T22D микроконтроллер упрощает код приёмника и передатчика. А в режиме ретранслятора E22-900T22D может работать вообще без внешнего микроконтроллера.
Отдельный блок питания для E22-900T22D повышает нагрузочную способность при большой выходной мощности.
Собираем макеты приёмника и передатчика
Макеты на базе модуля E22-900T22D и микроконтроллера Waveshare ESP32-S3-LCD-1.47B-M показаны на рис. 6. Слева расположен приёмник, а справа — передатчик.

Обратите внимание, что я подаю 3,3 В на модули LoRa от отдельных источников питания. При этом микроконтроллеры питаются через USB. В рабочей схеме при передаче с большой мощностью рекомендуется для уменьшения выбросов шунтировать питание модуля LoRa керамическим конденсатором 100 нФ и электролитом 470–1000 мкФ, расположив их рядом с модулем.
На рис. 7 показано подключение модуля E22-900T22D к микроконтроллеру ESP32-S3-LCD-1.47B-M.

Перед включением питания сверьтесь со списком коммутаций модуля E22-900T22D и платы микроконтроллера ESP32-S3-LCD-1.47B-M:
TXD — GPIO8, RX для Serial1;
RXD — GPIO9, TX для Serial1;
AUX — GPIO4, статус готовности модуля E22-900T22D;
M0 — GPIO5, выбор режима;
M1 — GPIO2, выбор режима
Обратите внимание, что контакты RXD и TXD микроконтроллера никак не задействованы. Это выводы аппаратного UART0. Они идут на USB-UART-чип для прошивки. Поэтому контакты TXD и RXD модуля E22-900T22D подключаются к выводам с номерами 8 (GPIO8) и 9 (GPIO9) микроконтроллера ESP32-S3-LCD-1.47B-M, соответственно.
Эта коммутация выводов должна совпадать с настройками в программах приёмника и передатчика:
#define E22_RXD_PIN 8 // ESP32 RX <- E22 TX #define E22_TXD_PIN 9 // ESP32 TX -> E22 RX #define E22_AUX_PIN 4 #define E22_M0_PIN 5 #define E22_M1_PIN 2
Проверка макетов
После сборки макетов приёмника и передатчика нужно убедиться в их работоспособности. Для этого я подготовил программу e22_config_display, которая читает конфигурацию модуля E22-900T22D и выводит ее на LCD-монитор (рис. 8).

Также эта конфигурация выводится в отладочную консоль Arduino IDE:
ESP-ROM:esp32s3-20210327 Success ---------------------------------------- AddH : 0 AddL : 2 NetID: 0 Chan : 19 -> 869.125MHz Parity : 8N1 (Default) UART baud: 9600bps (default) Air rate : 2.4kbps (default) SubPacket: 240bytes (default) TX Power : 22dBm (Default) RSSI Amb : Enabled WOR period: 2000ms (default) WOR TRX : WOR Receiver (default) LBT : Enabled RSSI byte : Enabled Repeater : Disabled (default) Fixed TX : Fixed transmission (first three bytes can be used as high/low address and channel) ----------------------------------------
Как видно из листинга, программа успешно прочитала и вернула текущую конфигурацию. Адрес устройства равен 0x0002 (AddH=0, AddL=2), сетевой идентификатор NetID установлен в 0, а рабочий канал 19 соответствует частоте 869,125 МГц, попадающей в разрешённый поддиапазон 868,7–869,2 МГц.
Параметры UART заданы по умолчанию — скорость 9600 бод, формат 8N1. При этом скорость передачи по радиоэфиру составляет 2,4 кбит/с, а максимальный размер пакета, который передаётся через эфир без разделения на части, составляет 240 байт.
Мощность передачи равна 22 дБм (158,5 мВт).
Из дополнительных функций включены измерение фонового шума (RSSI Ambient), добавление байта RSSI к принимаемым пакетам и режим прослушивания эфира перед передачей (LBT), что помогает избегать коллизий с другими устройствами в эфире.
Модуль также сконфигурирован в режиме WOR-приёмника с периодом пробуждения 2000 мс. Режим аппаратной ретрансляции (Repeater) отключен, а установленный тип передачи — фиксированный (Fixed transmission). В этом режиме первые три байта каждого пакета задают адрес получателя и канал, что необходимо для адресной доставки сообщений в сети из нескольких узлов.
В режиме WOR-приёмника модуль периодически (по умолчанию каждые 2000 мс) кратковременно включает приёмный тракт для проверки наличия сигнала в эфире, экономя энергию по сравнению с постоянным приёмом. Передающая сторона при этом должна предварять пакет удлинённой преамбулой, чтобы её гарантированно уловил просыпающийся приёмник.
Программа чтения конфигурации
Рассмотрим кратко исходный текст программы e22_config_display.
Функция setup инициализирует порт Serial и дисплей, а также вызывает функцию LoRaSerial.begin, передавая ей параметры последовательного порта, а также номера контактов, к которым подключен UART модуля E22-900T22D:
LoRaSerial.begin(9600, SERIAL_8N1, LORA_RX_PIN, LORA_TX_PIN);
Эта функция открывает второй аппаратный UART, через который плата общается с модулем E22-900T22D.
Функция e22.begin инициализирует объект библиотеки LoRa_E22, после чего вызывается функция e22.getConfiguration, читающая из энергонезависимой памяти текущие параметры модуля: частоту, мощность, скорость эфира, адрес и канал:
e22.begin(); ResponseStructContainer c = e22.getConfiguration();
Результат чтения сохраняется в переменную c типа ResponseStructContainer. При этом c.status.code содержит код ответа. При успехе этот код равен 1. В этом случае полный дамп параметров пишется в Serial функцией printParametersSerial.
Сокращённая версия дампа параметров выводится на экран функцией showConfiguration:
if (c.status.code == 1 /* E22_SUCCESS */) { Configuration cfg = *(Configuration*) c.data; Serial.println(c.status.getResponseDescription()); printParametersSerial(cfg); showConfiguration(cfg); } else { Serial.println(c.status.getResponseDescription()); showError(c.status.getResponseDescription()); }
Если код ответа не равен 1, значит, возникла ошибка обмена по UART, не отвечает модуль, использована неверная распиновка или возникла другая проблема. В этом случае текстовое описание ошибки выводится и в Serial, и на дисплей функцией showError.
Функция c.close завершает вызов. Этот вызов, обязательный в большинстве версий библиотеки LoRa_E22, освобождает память.
Функция getFreqDescription900 рассчитывает частоту по номеру канала для модуля E22-900T22D:
String getFreqDescription900(uint8_t chan) { float freq = 850.125f + (float)chan; return String(freq, 3) + "MHz"; }
Для этого модуля базовая частота — 850,125 МГц. Частота вычисляется по номеру канала исходя из того, что на один канал берётся шаг 1 МГц.
Заметим, что модуль Heltec Automation HTIT-WB32LAF V3 позволяет устанавливать рабочую частоту намного точнее. В нём эта частота задаётся с точностью до Гц, а не до 1 МГц через номер канала.
Подготовка Arduino IDE
Чтобы транслировать программы из этой статьи, установите Arduino IDE. Далее добавьте микроконтроллер (Board) c названием Waveshare ESP32-S3-LCD-1.69 (рис. 9).

В поле Additional boards manager URLs (рис. 10), доступном при выборе строки Preferences меню File, введите строку:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

Далее установите библиотеки lvgl, EByte_LoRa_E22_Library (автор Renzo Mischianti), а также "GFX Library for Arduino".
Чтобы заработала консоль отладки, переключите через меню Tools режим USB CDC On Boot в состояние Enabled.
При необходимости воспользуйтесь руководствами «Arduino Board Managers Tutorial» и «Arduino Library Manager Tutorial».
Программы приёма и передачи текстовой строки
Для демонстрации режима фиксированной передачи соберём простейшую сеть с идентификатором NETID, равным нулю (рис. 11).

Рис. 11. Узлы в сети с NETID 0 для передачи текстовой строки
Адрес узла передатчика здесь равен 0x0001, адрес узла приёмника — 0x0002. Передача идет на канале 19 в сети 0.
Для успешной передачи в приёмнике и в передатчике должны использоваться одинаковые номера каналов CHAN, а также одинаковые номера сети NETID.
Передатчик должен отправлять данные на адрес приёмника 0x0002, при этом собственный адрес передатчика значения не имеет.
Приведу краткое описание исходных текстов программ приёма и передачи текстовой строки.
Приёмник
Для приёма текстовой строки я подготовил программу e22_lcd_receiver.
Функция setup инициализирует UART, к которому подключен модуль E22-900T22D, и объект библиотеки LoRa_E22:
E22_UART.begin(9600, SERIAL_8N1, E22_RXD_PIN, E22_TXD_PIN); e22ttl.begin();
Далее вызывается функция configureE22, которая задаёт нужную конфигурацию для модуля LoRa:
bool ok = configureE22();
В начале работы она вызывает функцию e22ttl.getConfiguration для получения текущих настроек.
ResponseStructContainer c = e22ttl.getConfiguration(); if (c.status.code != 1) { Serial.print("getConfiguration failed: "); Serial.println(c.status.getResponseDescription()); return false; } Configuration configuration = (Configuration )c.data;
В структуре Configuration содержится много полей, после получения текущих значений изменяются только нужные поля:
#define MY_ADDH 0x00 #define MY_ADDL 0x02 #define LORA_CHANNEL 19 // 850.125 + 19*1 = 869.125 МГц … configuration.ADDH = MY_ADDH; configuration.ADDL = MY_ADDL; configuration.CHAN = LORA_CHANNEL; configuration.NETID = 0x00; configuration.SPED.uartBaudRate = UART_BPS_9600; configuration.SPED.airDataRate = AIR_DATA_RATE_010_24; configuration.SPED.uartParity = MODE_00_8N1; configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_ENABLED; configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION; configuration.TRANSMISSION_MODE.enableRSSI = RSSI_ENABLED;
Здесь задаётся адрес устройства (ADDH и ADDL), канал, скорость UART и эфирная скорость передачи, а также чётность. Кроме этого, включается мониторинг RSSI-шума эфира, режим фиксированной передачи и добавление RSSI-байта к принятым пакетам.
Обратите внимание, как здесь указывается адрес приёмника и номер канала, на котором он принимает данные, а также номер сети.
Изменённая конфигурация записывается обратно в модуль с сохранением при отключении питания:
ResponseStatus rs = e22ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_SAVE);
Основной цикл loop ничего не делает, пока в UART не появятся данные из эфира:
void loop() { if (e22ttl.available() > 1) { ResponseContainer rc = e22ttl.receiveMessageRSSI(); if (rc.status.code == 1) { rxCount++; String text = rc.data; int rssi = (int)rc.rssi - 256; drawReceived(text, rssi, rxCount); Serial.printf("RX #%lu: \"%s\" RSSI=%d dBm\r\n", (unsigned long)rxCount, text.c_str(), rssi); } else { Serial.printf("RX error: %s\r\n", rc.status.getResponseDescription().c_str()); } } }
Как только они будут приняты, данные разбираются на поля, выводятся в консоль отладки, а также на LCD-экран модуля (рис. 12):

Передатчик
Макет передатчика выглядит точно так же, как и макет приёмника (рис. 13).

Для передатчика используется программа e22_lcd_sender.
Функция setup выполняет инициализацию таким же образом, что и в приёмнике:
drawStatus("LoRa TX", "Init E22...", ""); E22_UART.begin(9600, SERIAL_8N1, E22_RXD_PIN, E22_TXD_PIN); e22ttl.begin(); bool ok = configureE22(); drawStatus("LoRa TX", ok ? "E22 config OK" : "E22 config FAIL", "Ready to send..."); delay(1000);
Отличия здесь в тексте, который выводится на консоль отладки и на LCD-экран микроконтроллера.
Функция конфигурирования модуля LoRa дополнительно устанавливает выходную мощность передатчика и режим LBT_ENABLED:
#define MY_ADDH 0x00 #define MY_ADDL 0x01 #define DEST_ADDH 0x00 #define DEST_ADDL 0x02 #define LORA_CHANNEL 19 // 850.125 + 19*1 = 869.125 МГц configuration.ADDH = MY_ADDH; configuration.ADDL = MY_ADDL; configuration.CHAN = LORA_CHANNEL; configuration.NETID = 0x00; //configuration.OPTION.transmissionPower = POWER_22; configuration.OPTION.transmissionPower = POWER_10; configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_ENABLED; configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION; configuration.TRANSMISSION_MODE.enableLBT = LBT_ENABLED; configuration.TRANSMISSION_MODE.enableRSSI = RSSI_ENABLED; ResponseStatus rs = e22ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_SAVE);
Здесь MY_ADDH и MY_ADDL задают адрес передатчика, равный 0x0001.
Константа POWER_10 задаёт минимально возможный уровень мощности 10 мВт, а POWER_22 — максимальный 0,158 Вт. При этом POWER_13 соответствует 20 мВт, а POWER_17 — 50 мВт. Устанавливая уровень мощности, учитывайте ограничения законодательства в вашей стране.
Передатчик будет отправлять пакеты данных на адрес, заданный в DEST_ADDH и DEST_ADDL как 0x0002. Этот адрес должен совпадать с адресом модуля LoRa приёмника. Также через configuration.NETID задан номер сети, который должен быть такой же, как у приёмника.
В каждом проходе loop проверяется, прошло ли пять секунд после последней отправки, и, если нет — функция сразу завершается, не выполняя лишней работы.
Как только интервал истекает, время последней отправки обновляется, счётчик переданных пакетов txCount увеличивается на единицу, и на его основе формируется текстовое сообщение вида «Hello LoRa #N», которое записывается в буфер txbuf и оборачивается в объект String.
Перед отправкой на дисплей выводится статус с меткой «LoRa TX» и текстом отправляемого сообщения, сопровождаемый пометкой «Sending...».
Отправляет данные метод sendFixedMessage библиотеки Lora_e22. Это адресная передача, при которой пакет отправляется конкретному получателю по адресу из DEST_ADDH и DEST_ADDL, на канале LORA_CHANNEL.
После завершения передачи экран обновляется. В зависимости от кода ответа rs.code статус сменяется либо на «Send OK», либо на «Send FAIL».
Параллельно в Serial-порт выводится строка с отправленным текстом и описанием статуса, что удобно для отладки и логирования на этапе разработки.
Поскольку lastSend объявлена как static и инициализируется нулём, первая отправка происходит не сразу после включения устройства, а лишь спустя пять секунд. Это время соответствует интервалам между последующими передачами.
Добавляем аппаратный ретранслятор
После того как вы отладили работу узла приёмника и передатчика, добавим узел аппаратного ретранслятора на базе модуля E22-900T22D. Этот модуль, будучи однажды сконфигурирован как аппаратный ретранслятор, сможет работать в этом режиме без внешнего микроконтроллера. Это снижает стоимость ретранслятора и его энергопотребление.
Наш ретранслятор работает на канале 19 и передаёт пакеты из сети с идентификатором 0x02 в сеть 0x10 (рис. 14).

Займёмся конфигурированием модуля ретранслятора, а затем напишем программы передатчика и приёмника для работы через ретранслятор.
Настройка модуля ретранслятора
Для однократной настройки модуля E22-900T22D в режим ретранслятора вы можете воспользоваться программой e22_set_repeater_mode.
Перед её запуском временно установите модуль E22-900T22D, предназначенный для работы в качестве ретранслятора, в один макетов (приёмника или передатчика), либо соберите отдельный макет.
Параметры адреса модуля репитера REPEATER_ADDH и REPEATER_ADDL задают идентификаторы NETID сети источника и сети приёмника, соответственно. Также необходимо задать номер канала REPEATER_CHAN, на котором будут работать наши сети:
#define REPEATER_ADDH 0x02 // NETID сети TX (сеть-источник) #define REPEATER_ADDL 0x10 // NETID сети RX (сеть-приёмник) #define REPEATER_CHAN 19
Собственный NETID репитера не используется, записываем значение 0:
configuration.NETID = 0x00;
Чтобы включить аппаратный ретранслятор, устанавливаем флаг enableRepeater:
configuration.TRANSMISSION_MODE.enableRepeater = REPEATER_ENABLED;
После этого устанавливаем и сохраняем конфигурацию в энергонезависимой памяти модуля:
ResponseStatus rs = e22.setConfiguration(configuration, WRITE_CFG_PWR_DWN_SAVE);
Для проверки программа читает новую конфигурацию функцией e22.getConfiguration и выводит её в окно отладки:
ESP-ROM:esp32s3-20210327 === Чтение текущей конфигурации E22 === Конфигурация прочитана, применяю режим репитера... Результат записи: Success Код: 1 Готово! Конфигурация репитера сохранена в модуле. Теперь достаточно держать M0=LOW, M1=LOW и подавать питание — MCU для работы репитера больше не требуется. === Проверка после записи === ADDH: 0x2 ADDL: 0x10 CHAN: 19 Repeater: Enabled
Таким образом модуль сконфигурирован для работы в качестве ретранслятора. Установите его на отдельную макетную плату с возможностью подачи питания (рис. 15).

После сохранения конфигурации контакты M0 и M1 должны быть соединены с землёй.
Питание на модуль ретранслятора нужно подавать постоянно — приёмник репитера всегда должен быть готов к работе.
Передатчик для работы через ретранслятор
Программа передатчика e22_tx_via_repeater инициализирует модуль функцией configureE22 следующим образом:
#define MY_ADDH 0x00 #define MY_ADDL 0x01 #define DEST_ADDH 0x00 #define DEST_ADDL 0x02 #define LORA_CHANNEL 19 // 850.125 + 19*1 = 869.125 МГц #define MY_NETID 0x02 … configuration.ADDH = MY_ADDH; configuration.ADDL = MY_ADDL; configuration.NETID = MY_NETID; configuration.CHAN = LORA_CHANNEL;
Как и раньше, когда мы отправляли данные без репитера, в передатчике был указан адрес приёмника как 0x0002. Однако теперь задан идентификатор сети MY_NETID, равный 0x02. Как раз в этой сети будет «слушать» наш репитер.
Напомню, что репитер сконфигурирован так, чтобы он передавал данные из сети 0x02 в сеть 0x10.
Приёмник для работы через ретранслятор
Программа приёмника e22_rx_via_repeater настраивает модуль LoRa для приёма данных по адресу 0x0002. При этом она получает данные только в том случае, если они пришли в канале 19 из сети 0x10, то есть от нашего репитера:
#define MY_ADDH 0x00 #define MY_ADDL 0x02 #define LORA_CHANNEL 19 // 850.125 + 19*1 = 869.125 МГц #define MY_NETID 0x10 … configuration.ADDH = MY_ADDH; configuration.ADDL = MY_ADDL; configuration.NETID = MY_NETID; configuration.CHAN = LORA_CHANNEL;
В консоли отладки приёмника видны полученные данные:
ESP-ROM:esp32s3-20210327 RX #1: "Hello LoRa #1" RSSI=-14 dBm RX #2: "Hello LoRa #2" RSSI=-17 dBm RX #3: "Hello LoRa #3" RSSI=-17 dBm RX #4: "Hello LoRa #4" RSSI=-14 dBm RX #5: "Hello LoRa #5" RSSI=-13 dBm RX #6: "Hello LoRa #6" RSSI=-14 dBm
Также они выводятся на LCD-экран приёмника.
Пример программного ретранслятора
Если нужен контроль прохождения данных через ретранслятор, можно использовать вместо аппаратного программный ретранслятор. В этом случае к модулю LoRa нужно добавить микроконтроллер, который будет обрабатывать принятые пакеты данных и отправлять их в модуль LoRa дальше, на другие узлы.
Сборка макета программного ретранслятора
В качестве микроконтроллера для программного ретранслятора я использовал ESP32-S3-N16R8, подключив к нему модуль LoRa E22-900T22D (рис. 16).

Подключение E22-900T22D к микроконтроллеру ESP32-S3-N16R8 выполнено следующим образом:
VCC — контакт 3V3 микроконтроллера ESP32-S3-N16R8;
GND — контакт GND микроконтроллера ESP32-S3-N16R8;
TXD — GPIO17 (RX микроконтроллера);
RXD — GPIO18 (TX микроконтроллера);
AUX — GPIO16, статус готовности модуля E22-900T22D;
M0 — GPIO5, выбор режима;
M1 — GPIO6, выбор режима
Обратите внимание, что здесь для упрощения схемы я подключил питание модуля LoRa к контакту 3V3 микроконтроллера ESP32-S3-N16R8. Это допустимо только при минимальном уровне выходной мощности передатчика. Но если вы настраиваете передатчик ретранслятора на большую мощность, используйте для E22-900T22D отдельный источник питания и шунтирующие конденсаторы.
На плате ESP32-S3-N16R8 есть два разъёма, обозначенные как COM и USB. Для подключения к компьютеру я использовал разъём COM.
Проверка макета
Для проверки макета можно использовать программу E22_ReadConfig.ino чтения конфигурации модуля. Если всё собрано правильно, программа выведет в отладочную консоль Arduino IDE такую информацию:
ESP-ROM:esp32s3-20210327 === Чтение конфигурации E22-900T22D === ---------------------------------------- HEAD (bin): 11000001 0 1001 Адрес модуля (ADDH+ADDL): 02 NET ID: 2 --- SPEED --- Air data rate: 2 -> 2.4kbps (default) UART parity: 0 -> 8N1 (Default) UART baud rate: 3 -> 9600bps (default) --- OPTION --- Transmission power: 3 -> 10dBm RSSI ambient noise enable: 1 -> Enabled Subpacket setting: 0 -> 240bytes (default) Канал (CHAN): 19 -> 869.125 МГц --- TRANSMISSION_MODE --- WOR period: 3 -> 2000ms (default) WOR transceiver control: 0 -> WOR Receiver (default) Enable LBT: 1 -> Enabled Enable repeater: 0 -> Disabled (default) Fixed transmission (адресный режим): 1 -> Fixed transmission (first three bytes can be used as high/low address and channel) Enable RSSI: 1 -> Enabled Crypt (KEY): 00 ----------------------------------------
Режим аппаратного ретранслятора Enable repeater отключен и для программной ретрансляции он не нужен.
Когда будете запускать эту программу, можете столкнуться с тем, что в отладочную консоль не будут выведены никакие данные. В этом случае через меню Tools переведите флаг USB CDC On Boot в состояние Disabled.
Дело в том, что плата микроконтроллера была подключена к компьютеру через порт, обозначенный как COM. Этот порт ведёт не к нативному USB-контроллеру ESP32-S3, а к аппаратному мосту USB-UART CH343, связанному с UART0. Если оставить USB CDC On Boot в состоянии Enabled, вывод Serial будет направляться в нативный USB CDC-стек чипа, а не на UART0. В этом случае он не попадёт на порт COM. Вызов Serial.print в этом случае пропадёт без ошибок компиляции и без зависаний, просто данные будут «уходить» не в тот канал, который вы слушаете.
Если же микроконтроллер подключить через разъём, обозначенный на плате ESP32-S3-N16R8 как USB, флаг USB CDC On Boot должен быть в состоянии Enabled.
Перед компиляцией программы укажите в Arduino IDE порт, к которому подключена плата, а также выберите через меню Tools в списке esp32 плату ESP32S3 Dev Module.
Исходный код программы E22_ReadConfig.ino я оставлю вам на самостоятельное изучение.
Программа ретранслятора
Программа ретранслятора e22_soft_repeater задаёт режим работы модуля E22-900T22D как обычного узла с фиксированной адресацией своим адресом ADDH-ADDL, равным 0x0002.
Приняв пакет от передатчика, программа выводит его содержимое и RSSI через Serial в отладочную консоль Arduino IDE. Далее она на секунду зажигает светодиод RGB, расположенный на плате микроконтроллера, установив для него зелёный цвет. После этого принятый пакет пересылается по адресу 0x0003 (рис. 17).

Результат отправки выводится на консоль:
=== Программный LoRa-репитер (ESP32-S3-N16R8) === Конфигурация модуля: OK Свой адрес: 00:02, NETID: 02, канал: 19 Пересылка на адрес: 00:03 Ожидание пакетов... ---------------------------------------- [1] RX <- "Hello LoRa #2707" (RSSI -46 dBm) [1] TX -> 00:03 "Hello LoRa #2707" : Success (ok=1, fail=0) ---------------------------------------- [2] RX <- "Hello LoRa #2708" (RSSI -46 dBm) [2] TX -> 00:03 "Hello LoRa #2708" : Success (ok=2, fail=0) ---------------------------------------- [3] RX <- "Hello LoRa #2763" (RSSI -44 dBm) [3] TX -> 00:03 "Hello LoRa #2763" : Success (ok=3, fail=0) ----------------------------------------
Приёмник
Программа приёмника e22_rx_via_soft_repeater получает пакеты данных от программного репитера. Он настроен на получение данных на адрес 0x0003 — как раз по этому адресу программный репитер отправляет свои пакеты.
Все три узла принадлежат одной и той же сети NETID.
Передатчик
Для демонстрации программного ретранслятора я использовал программу e22_tx_via_repeater, приведённую в разделе, посвящённом аппаратному ретранслятору. Она отправляет текстовую строку на адрес 0x0002 в сети 2, где ее ожидает наш программный ретранслятор.
Сравнение аппаратного и программного ретрансляторов
Как видите, реализация аппаратного ретранслятора очень проста. Включив режим Enable repeater с помощью программы конфигурации, вы получаете готовый модуль ретрансляции, не нуждающийся в микроконтроллере. Модуль будет сам принимать и передавать дальше пакет по указанному адресу и в сети с заданным номером.
В качестве других преимуществ можно отметить минимальную задержку, простоту реализации, возможность объединять сети с разным NETID. Так как для узла аппаратного ретранслятора не нужен микроконтроллер, это положительно сказывается на стоимости узла и на потреблении энергии.
Из недостатков — процесс ретрансляции происходит полностью внутри самого модуля E22-900T22D. При этом невозможно контролировать количество пересылок одного и того же пакета (число хопов), блокировать многократную пересылку одних и тех же пакетов, полученных от разных передающих узлов. Также невозможно управлять приоритетами для отправки критичных данных в первую очередь и собирать статистику передачи пакетов.
В программном ретрансляторе в приёме и передаче пакетов данных принимает участие микроконтроллер. Программа может разбирать пакет, принимать решение о необходимости его передачи. Это даёт полный контроль над маршрутизацией — можно ограничивать количество хопов, получать статистику, реализовать интеграцию с LBT и приоритизацию и выполнять другие необходимые действия.
При необходимости можно создать программный ретранслятор с двумя или несколькими модулями LoRa, например, работающими в разных диапазонах частот.
Следует, однако, учитывать, что программный ретранслятор даёт задержку на каждом хопе и потребляет больше энергии за счет микроконтроллера.
Для простой линейной сети с минимальной задержкой больше подойдёт аппаратный режим. Если же нужно создавать mesh-сети с защитой от петель, адаптивной маршрутизацией и другими «наворотами», то лучше использовать программные ретрансляторы.
Итоги
В этой статье я продолжил рассказ об увлекательном мире LoRa, начатый в статьях «Дальняя связь на модулях LoRa: принимаем сигнал ниже уровня шума» и «Метеостанция на LoRa и ESP32, которая годами работает от батарейки». Теперь вы узнали, как устроена адресация модулей LoRa, позволяющая вам создавать изолированные сети, а также как увеличивать покрытие за счёт добавления аппаратных и программных ретрансляторов.
В планах — статьи о создании простейшей системы передачи текстовых сообщений через LoRa, о настройке удалённого доступа в интернет и о других применениях LoRa . Пишите в комментариях, о чём вам было бы интересно узнать в плане передачи данных на большие расстояния на базе этой технологии.
Автор @AlexandreFrolov
НЛО прилетело и оставило здесь промокод для читателей нашего блога:
-15% на заказ нового VDS — HABRFIRSTVDS.
tklim
Вот только эта "адресация" реализована каким-то проприетарным образом и касается исключительно этих моделей конкретно этого производителя.
Есп32 как и Ардуино в целом позволяет подключать sx12xx без этой лишней прослойки. (Есть разные библиотеки). И делать свои ретрансляторы и прочее без лишней минуя закрытый ведорский код.
Ну а так можно постепенно изобрести lorawan.
AlexandreFrolov
Согласен, это проприетарная прошивка EBYTE, а не открытый протокол. На голом SX12xx адресацию и ретрансляцию всё равно придётся писать самому, хоть и с использованием готовых библиотек. Нужно будет перенести ту же логику в код микроконтроллер. Но E22 умеет ретранслировать пакеты вообще без микроконтроллера, «на одном модуле», а с голым чипом так не получится.
Что до LoRaWAN, то здесь простая point-to-point адресация без шифрования, join-процедуры и серверной архитектуры, до LoRaWAN тут как до Луны)