Возможно ли изменить рабочий диапазон работы ELRS?
Возможно ли изменить рабочий диапазон работы канала приемо-передачи elsr, например, для работы на базовой частоте 750Мгц?
Напоминаем, что все работы связанные с выходом в эфир на нестандартных частотах должны согласовываться и соответствовать местным регуляторным требованиям. Вещание или передача данных без разрешения является нарушением законодательства РФ и может повлечь серьезные штрафы и конфискацию оборудования.
Адрес репозитория: https://github.com/ExpressLRS/ExpressLRS.git - исходный код протокола.
Нас интересует файл FHSS.cpp. Он находится в папке \src\lib\FHSS.
Здесь мы имеем дело с кодом, который реализует механизм Frequency Hopping Spread Spectrum (FHSS) для радиомодуля в проекте ELRS. Код предназначен для работы с разными типами радиомодулей (SX127x, LR1121, SX128x) и разными регулирующими доменами (разные частотные диапазоны и правила).
Исходный код FHSS
#include "FHSS.h"
#include "logging.h"
#include "options.h"
#include <string.h>
#if defined(RADIO_SX127X) || defined(RADIO_LR1121)
#if defined(RADIO_LR1121)
#include "LR1121Driver.h"
#else
#include "SX127xDriver.h"
#endif
const fhss_config_t domains[] = {
{"AU915", FREQ_HZ_TO_REG_VAL(915500000), FREQ_HZ_TO_REG_VAL(926900000), 20, 921000000},
{"FCC915", FREQ_HZ_TO_REG_VAL(903500000), FREQ_HZ_TO_REG_VAL(926900000), 40, 915000000},
{"EU868", FREQ_HZ_TO_REG_VAL(865275000), FREQ_HZ_TO_REG_VAL(869575000), 13, 868000000},
{"IN866", FREQ_HZ_TO_REG_VAL(865375000), FREQ_HZ_TO_REG_VAL(866950000), 4, 866000000},
{"AU433", FREQ_HZ_TO_REG_VAL(433420000), FREQ_HZ_TO_REG_VAL(434420000), 3, 434000000},
{"EU433", FREQ_HZ_TO_REG_VAL(433100000), FREQ_HZ_TO_REG_VAL(434450000), 3, 434000000},
{"US433", FREQ_HZ_TO_REG_VAL(433250000), FREQ_HZ_TO_REG_VAL(438000000), 8, 434000000},
{"US433W", FREQ_HZ_TO_REG_VAL(423500000), FREQ_HZ_TO_REG_VAL(438000000), 20, 434000000},
};
#if defined(RADIO_LR1121)
const fhss_config_t domainsDualBand[] = {
{"ISM2G4", FREQ_HZ_TO_REG_VAL(2400400000), FREQ_HZ_TO_REG_VAL(2479400000), 80, 2440000000}
};
#endif
#elif defined(RADIO_SX128X)
#include "SX1280Driver.h"
const fhss_config_t domains[] = {
{
#if defined(Regulatory_Domain_EU_CE_2400)
"CE_LBT",
#elif defined(Regulatory_Domain_ISM_2400)
"ISM2G4",
#endif
FREQ_HZ_TO_REG_VAL(2400400000), FREQ_HZ_TO_REG_VAL(2479400000), 80, 2440000000}
};
#endif
// Наша таблица FHSS частот
const fhss_config_t *FHSSconfig;
const fhss_config_t *FHSSconfigDualBand;
// Фактическая последовательность скачков
uint8_t FHSSsequence[FHSS_SEQUENCE_LEN];
uint8_t FHSSsequence_DualBand[FHSS_SEQUENCE_LEN];
// Текущая позиция в последовательности
uint8_t volatile FHSSptr;
// Канал для синхронизации
uint_fast8_t sync_channel;
uint_fast8_t sync_channel_DualBand;
// Коррекция частоты
int32_t FreqCorrection;
int32_t FreqCorrection_2;
// Шаг частоты
uint32_t freq_spread;
uint32_t freq_spread_DualBand;
// Переменные для двухдиапазонных радио
bool FHSSusePrimaryFreqBand = true;
bool FHSSuseDualBand = false;
uint16_t primaryBandCount;
uint16_t secondaryBandCount;
void FHSSrandomiseFHSSsequence(const uint32_t seed)
{
FHSSconfig = &domains[firmwareOptions.domain];
sync_channel = FHSSconfig->freq_count / 2;
freq_spread = (FHSSconfig->freq_stop - FHSSconfig->freq_start) * FREQ_SPREAD_SCALE / (FHSSconfig->freq_count - 1);
primaryBandCount = (FHSS_SEQUENCE_LEN / FHSSconfig->freq_count) * FHSSconfig->freq_count;
DBGLN("Setting %s Mode", FHSSconfig->domain);
DBGLN("Number of FHSS frequencies = %u", FHSSconfig->freq_count);
DBGLN("Sync channel = %u", sync_channel);
FHSSrandomiseFHSSsequenceBuild(seed, FHSSconfig->freq_count, sync_channel, FHSSsequence);
#if defined(RADIO_LR1121)
FHSSconfigDualBand = &domainsDualBand[0];
sync_channel_DualBand = FHSSconfigDualBand->freq_count / 2;
freq_spread_DualBand = (FHSSconfigDualBand->freq_stop - FHSSconfigDualBand->freq_start) * FREQ_SPREAD_SCALE / (FHSSconfigDualBand->freq_count - 1);
secondaryBandCount = (FHSS_SEQUENCE_LEN / FHSSconfigDualBand->freq_count) * FHSSconfigDualBand->freq_count;
DBGLN("Setting Dual Band %s Mode", FHSSconfigDualBand->domain);
DBGLN("Number of FHSS frequencies = %u", FHSSconfigDualBand->freq_count);
DBGLN("Sync channel Dual Band = %u", sync_channel_DualBand);
FHSSusePrimaryFreqBand = false;
FHSSrandomiseFHSSsequenceBuild(seed, FHSSconfigDualBand->freq_count, sync_channel_DualBand, FHSSsequence_DualBand);
FHSSusePrimaryFreqBand = true;
#endif
}
/**
Требования к последовательности:
1. Синхроканал каждые N скачков
2. Без повторяющихся каналов
3. Равномерное распределение
4. Псевдослучайность
*/
void FHSSrandomiseFHSSsequenceBuild(const uint32_t seed, uint32_t freqCount, uint_fast8_t syncChannel, uint8_t *inSequence)
{
FHSSptr = 0;
rngSeed(seed);
// Инициализация массива последовательности
for (uint16_t i = 0; i < FHSSgetSequenceCount(); i++)
{
if (i % freqCount == 0) {
inSequence[i] = syncChannel;
} else if (i % freqCount == syncChannel) {
inSequence[i] = 0;
} else {
inSequence[i] = i % freqCount;
}
}
// Перемешивание последовательности
for (uint16_t i = 0; i < FHSSgetSequenceCount(); i++)
{
if (i % freqCount != 0)
{
uint8_t offset = (i / freqCount) * freqCount;
uint8_t rand = rngN(freqCount - 1) + 1;
uint8_t temp = inSequence[i];
inSequence[i] = inSequence[offset+rand];
inSequence[offset+rand] = temp;
}
}
// Отладочный вывод последовательности
for (uint16_t i=0; i < FHSSgetSequenceCount(); i++)
{
DBG("%u ",inSequence[i]);
if (i % 10 == 9)
DBGCR;
}
DBGCR;
}
bool isDomain868()
{
return strcmp(FHSSconfig->domain, "EU868") == 0;
}
Пояснение реализации FHSS
1. Регуляторные домены
Массив domains содержит конфигурации для разных регионов:
Пример:
{"EU868", FREQ_HZ_TO_REG_VAL(865275000), FREQ_HZ_TO_REG_VAL(869575000), 13, 868000000}
Поле | Описание |
---|---|
domain | Название домена (например, "EU868") |
freq_start | Начальная частота диапазона 865275000 |
freq_stop | Конечная частота диапазона 869575000 |
freq_count | Количество каналов 13 |
sync_freq | Центральная частота синхронизации 868000000 |
2. Ключевые функции
Функция | Назначение |
---|---|
FHSSrandomiseFHSSsequence() | Основная инициализация FHSS |
FHSSrandomiseFHSSsequenceBuild() | Генерация псевдослучайной последовательности |
isDomain868() | Проверка европейского диапазона |
3. Алгоритм генерации последовательности
- Инициализация блоками:
- Каждый N-й элемент = синхроканал
- Остальные позиции заполняются последовательно (0,1,2...)
- Перемешивание:
- Для каждого элемента (кроме синхро) в блоке
- Обмен со случайной позицией в том же блоке
Добавление нового диапазона (750 МГц)
Техническая реализация
#if defined(RADIO_SX127X) || defined(RADIO_LR1121)
const fhss_config_t domains[] = {
// ... существующие диапазоны
{"EU750",
FREQ_HZ_TO_REG_VAL(740000000),
FREQ_HZ_TO_REG_VAL(760000000),
20,
750000000}
};
#endif
Проблемы и ограничения
Категория | Проблемы | Решение |
---|---|---|
Аппаратные |
|
|
Регуляторные |
|
|
Программные |
|
|
Рекомендации
- Использовать только для специализированных проектов
- Реализовать как экспериментальный режим
- Обязательная проверка на легальность в целевом регионе
Раздел: Как сделать.., Конспекты, Незаданные вопросы