93. LoRa: радио, модуль SX1276, дальность
В разделе 89 LoRa — строка в таблице и формула времени в эфире. Здесь — устройство изнутри: почему LoRa слышно ниже уровня шума, во что обходится каждая ступень SF, как посчитать дальность и как подключить самый распространённый модуль к F103 и F407.
Проверено: демодулятор на C работает в модели с шумом, а порог независимо пересчитан на numpy. Драйвер SX1276 гоняется на модели микросхемы, порт SPI собран для обоих камней. Сеть LoRaWAN поверх этого радио — раздел 94.
Как это называется в документации
Оригинал Перевод chirp, upchirp, downchirp чирп — сигнал с линейно меняющейся частотой; растущий, падающий chirp spread spectrum (CSS) расширение спектра чирпами spreading factor (SF) коэффициент расширения: бит на символ bandwidth (BW) полоса coding rate (CR) избыточность кода: 4/5…4/8 sync word слово синхронизации explicit / implicit header явный / неявный заголовок low data rate optimization (LDRO) оптимизация низкой скорости processing gain выигрыш обработки sensitivity, noise figure (NF) чувствительность, шум-фактор link budget, path loss бюджет линии, потери на трассе RSSI, SNR мощность принятого сигнала, отношение сигнал/шум PA_BOOST выход мощного усилителя передатчика
93.1 Чирп: символ — это сдвиг
Чирп — сигнал, частота которого за время символа равномерно проходит всю полосу снизу вверх. Один чирп сам по себе ничего не несёт. Символ — это сдвиг начала: чирп стартует не с нижней частоты, а с одной из 2^SF точек и, дойдя до верха, продолжается снизу. У SF7 таких точек 128, значит, символ несёт 7 бит; у SF12 — 4096 точек и 12 бит.
Длительность символа — 2^SF / BW: на полосе 125 кГц у SF7 это 1,024 мс, у SF12 — 32,768 мс. Каждая ступень SF удваивает символ и добавляет всего один бит, поэтому скорость почти вдвое падает. С избыточностью 4/5 SF7 даёт 5469 бит/с.
Символ и его приём в модели на C — отсчёты с частотой, равной полосе:
/* Фаза опорного чирпа в долях π/N: (k² − N·k) mod 2N — в целых, без потери точности */
static uint32_t chirp_phase(uint32_t k, uint32_t n)
{
return (k * k + 2u * n - (n * k) % (2u * n)) % (2u * n);
}
/* Символ s: опорный чирп, сдвинутый по кругу на s отсчётов; n = 2^sf отсчётов
* на частоте, равной полосе */
void lora_symbol(float *re, float *im, unsigned sf, unsigned s)
{
uint32_t n = 1u << sf;
for (uint32_t k = 0; k < n; k++) {
float ph = LORA_PI * (float)chirp_phase((k + s) % n, n) / (float)n;
re[k] = cosf(ph);
im[k] = sinf(ph);
}
}
/* Демодуляция: умножить на сопряжённый опорный чирп — символ превращается
* в чистый тон на частоте s, — и найти самый сильный отсчёт спектра.
* re/im портятся: на их месте остаётся спектр. */
unsigned lora_demod(float *re, float *im, unsigned sf)
{
uint32_t n = 1u << sf;
for (uint32_t k = 0; k < n; k++) {
float ph = -LORA_PI * (float)chirp_phase(k, n) / (float)n;
float c = cosf(ph), s = sinf(ph);
float r = re[k] * c - im[k] * s;
im[k] = re[k] * s + im[k] * c;
re[k] = r;
}
fft(re, im, n);
unsigned best = 0;
float peak = -1.0f;
for (uint32_t k = 0; k < n; k++) {
float p = re[k] * re[k] + im[k] * im[k];
if (p > peak) {
peak = p;
best = k;
}
}
return best;
}
fft — обычное быстрое преобразование Фурье на месте. Фаза считается в
целых. Само k² при SF12 во float ещё помещается точно
(4095² = 16 769 025 < 2^24), но угол π·k·(k − N)/N доходит до тысяч
радиан: шаг float на таком угле — десятитысячные доли радиана, а sinf
и cosf от большого аргумента теряют ещё больше. Приведение по модулю 2N
в целых держит угол в пределах от 0 до 2π.
Главное здесь — демодулятор. Умножение на опорный чирп «снимает» с символа наклон частоты, и сдвиг s превращается в чистый тон с частотой s. Преобразование Фурье показывает этот тон одним пиком, а номер пика и есть символ. Микросхема делает то же самое аппаратно. Тот же код собран для F407 с FPU и занимает 160 байт стека, но в приборе эту работу берёт на себя радиомодуль.
93.2 Почему LoRa слышно ниже шума
Преобразование Фурье собирает энергию всех 2^SF отсчётов символа в один отсчёт спектра, а шум остаётся размазанным по всем. Выигрыш — 10·lg 2^SF: 21,1 дБ у SF7 и 36,1 дБ у SF12. Поэтому приёмник LoRa разбирает сигнал, который слабее шума в полосе, — отношение сигнал/шум отрицательное.
Модель на C: для каждого SF — тысяча случайных символов в шуме, SNR снижается шагами по 0,5 дБ, пока ошибок не станет больше 1 %. Тот же опыт независимо повторён на numpy со своим генератором шума, и пороги совпали с точностью до шага, 0,5 дБ:
| SF | Символ | Порог модели | Порог для расчётов |
|---|---|---|---|
| 7 | 1,024 мс | −9,0 дБ | −7,5 дБ |
| 8 | 2,048 мс | −11,5 дБ | −10,0 дБ |
| 9 | 4,096 мс | −14,5 дБ | −12,5 дБ |
| 10 | 8,192 мс | −17,0 дБ | −15,0 дБ |
| 11 | 16,384 мс | −20,0 дБ | −17,5 дБ |
| 12 | 32,768 мс | −22,5 дБ | −20,0 дБ |
Каждая ступень SF даёт 2,5–3 дБ. Настоящий приёмник ещё ищет начало пакета и подстраивается под уход частоты кварца, поэтому его пороги на 1,5–2,5 дБ хуже идеальной модели. В расчётах дальности берут пороги из документации на микросхему — правый столбец.
Пакеты с разными SF на одном канале почти не мешают друг другу, и шлюз принимает их одновременно. Отсюда приём сети LoRaWAN: приборы у шлюза работают на SF7, приборы на краю — на SF12, и все делят один канал.
93.3 Параметры пакета
| Параметр | Значения | Что даёт | Чем платим |
|---|---|---|---|
| SF | 7–12 | 2,5–3 дБ на ступень | вдвое больше время в эфире |
| полоса | 125, 250, 500 кГц | шире — быстрее | каждое удвоение — 3 дБ чувствительности |
| избыточность | 4/5…4/8 | исправление ошибок | пакет длиннее |
| преамбула | 8 символов и ещё 4,25 | приёмник ловит начало пакета | время |
| слово синхронизации | 0x34 — LoRaWAN, 0x12 — частные сети | чужие сети отсеиваются | — |
| заголовок | явный или неявный | явный сообщает длину и избыточность | неявный — обе стороны знают их заранее |
| CRC | включён | битый пакет отбраковывается | 2 байта |
| оптимизация низкой скорости | SF11–12 на 125 кГц | устойчивость длинных символов к уходу частоты | обязана совпадать на обеих сторонах |
Частота, SF, полоса, слово синхронизации и оптимизация низкой скорости должны совпадать у передатчика и приёмника. Не совпало хоть что-то — пакет не будет принят, и никакой ошибки об этом не будет.
Полоса — второй рычаг после SF. Пакет с 10 байтами данных LoRaWAN на SF7 занимает 61,7 мс на 125 кГц и 15,4 мс на 500 кГц. Но каждое удвоение полосы стоит 3 дБ чувствительности: шума в широкой полосе больше.
93.4 Бюджет линии: сколько километров
Тепловой шум — −174 дБм на каждый герц полосы. В полосе 125 кГц это −174 + 10·lg 125 000 = −123,0 дБм. Приёмник добавляет свой шум (шум-фактор, возьмём 6 дБ), а демодулятору нужен ещё порог SNR:
| SF | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|
| чувствительность, дБм | −124,5 | −127,0 | −129,5 | −132,0 | −134,5 | −137,0 |
Бюджет линии — это мощность передатчика плюс усиление антенн минус потери в кабелях и минус чувствительность. При 14 дБм и антеннах без усиления это 138,5 дБ на SF7 и 151,0 дБ на SF12. Столько сигнал может потерять по дороге.
Мощность 14 дБм, то есть 25 мВт, — предел в Европе для основных полос 868,0–868,6 МГц (при 1 % эфира) и 868,7–869,2 МГц (при 0,1 %). В полосе 869,4–869,65 МГц можно 500 мВт (27 дБм) при 10 % эфира: там работает второе окно приёма LoRaWAN, и 17 дБм на 869,525 МГц из опыта 93.5 в предел укладываются. Предел считают по излучаемой мощности: антенна с усилением съедает часть разрешённого, и мощность на выходе микросхемы уменьшают на столько же. Правила конкретной страны смотрят в её частотном регламенте.
В свободном пространстве 151 дБ на 868 МГц — почти 1000 км. У земли получаются километры: мешают кривизна Земли, рельеф, дома, лес и стены. Кроме того, нужен запас 10 дБ и больше на замирания. Как измерить реальные потери на месте — раздел 92.
Два правила пригодятся при любой оценке:
- в свободном пространстве каждые 6 дБ удваивают дальность, так что 12,5 дБ между SF7 и SF12 — это дальность ×4,2; у земли потери растут с расстоянием быстрее, и выигрыш меньше;
- каждый децибел на счету: антенна-«пружинка» вместо штыря в 8,6 см (раздел 89), лишний метр тонкого кабеля, металлический корпус.
93.5 🔧 Модуль SX1276 по SPI
Модули RFM95 и подобные собраны на микросхеме SX1276. Подключение к F103 и F407 одинаковое:
| Вывод модуля | STM32 | Назначение |
|---|---|---|
| NSS | PA4 | выбор микросхемы, активный ноль |
| SCK | PA5 | такт SPI1 |
| MISO | PA6 | данные от модуля |
| MOSI | PA7 | данные в модуль |
| RESET | PB0 | сброс, активный ноль |
| DIO0 | PB1 | событие: передача окончена или пакет принят |
| 3,3 В, GND | — | питание только 3,3 В |
⚠️ Без антенны не передавать. Мощность, отражённая от неподключённого выхода, повреждает усилитель передатчика. И проверьте диапазон модуля: одни модули сделаны на 868–915 МГц, другие — на 433 МГц; прошивкой это не исправить.
SPI — режим 0, не быстрее 10 МГц. У F103 шина APB2 работает на 72 МГц, делитель 8 даёт 9 МГц. У F407 на APB2 84 МГц: делитель 8 даст 10,5 МГц, а это больше предела, поэтому делитель 16 — 5,25 МГц:
void sx_port_init(void)
{
#if defined(STM32F10X_MD)
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_SPI1EN;
/* PA7, PA5 — альтернативная функция 50 МГц (1011), PA6 — вход (0100), PA4 — выход (0011) */
GPIOA->CRL = (GPIOA->CRL & 0x0000FFFFu) | 0xB4B30000u;
/* PB1 — вход (0100), PB0 — выход с открытым стоком (0111): «1» отпускает RESET */
GPIOB->CRL = (GPIOB->CRL & 0xFFFFFF00u) | 0x00000047u;
/* APB2 72 МГц / 8 = 9 МГц: у SX1276 предел 10 МГц; режим 0 */
SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_BR_1 | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_SPE;
SysTick_Config(72000000u / 1000u);
#elif defined(STM32F407xx)
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN;
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
/* PA7–PA5 — альтернативная функция 5 (SPI1), PA4 — выход */
GPIOA->MODER = (GPIOA->MODER & ~0x0000FF00u) | 0x0000A900u;
GPIOA->AFR[0] = (GPIOA->AFR[0] & ~0xFFF00000u) | 0x55500000u;
/* PA5–PA7 — быстрые фронты (10): после сброса скорость низкая, не выше 4 МГц */
GPIOA->OSPEEDR = (GPIOA->OSPEEDR & ~0x0000FC00u) | 0x0000A800u;
/* PB1 — вход, PB0 — выход с открытым стоком: «1» отпускает RESET */
GPIOB->OTYPER |= 1u;
GPIOB->MODER = (GPIOB->MODER & ~0x0000000Fu) | 0x00000001u;
/* APB2 84 МГц / 16 = 5,25 МГц: делитель 8 дал бы 10,5 МГц — выше предела */
SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_BR_1 | SPI_CR1_BR_0 | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_SPE;
SysTick_Config(168000000u / 1000u);
#endif
sx_select(0);
sx_reset_pin(1);
}
void sx_select(int on)
{
if (on) {
GPIOA->BSRR = 1u << (4 + 16); /* PA4 = 0: микросхема выбрана */
} else {
while (SPI1->SR & SPI_SR_BSY) { } /* дождаться хвоста посылки (раздел 18.5) */
GPIOA->BSRR = 1u << 4;
}
}
uint8_t sx_spi(uint8_t b)
{
while (!(SPI1->SR & SPI_SR_TXE)) { }
SPI1->DR = b;
while (!(SPI1->SR & SPI_SR_RXNE)) { }
return (uint8_t)SPI1->DR;
}
Сброс — открытым стоком. Пока микросхема сама проходит сброс при
включении питания, её вывод NRESET по документации оставляют свободным,
а двухтактная «1» на нём этому мешает. Поэтому PB0 — выход с открытым
стоком: «0» тянет вывод к земле, «1» отпускает его. Ручной сброс —
ноль не короче 100 мкс, отпустить и подождать 5 мс; sx_init держит
ноль 1 мс и ждёт 10.
Скорость фронтов у F407. После сброса у PA5–PA7 скорость низкая: не
выше 4 МГц при нагрузке 50 пФ, фронты до 100 нс, а такт здесь 5,25 МГц.
У F103 скорость задана в коде явно (50 МГц), у F407 её поднимают
в OSPEEDR.
Остальное в порте — вывод сброса, задержка по SysTick и чтение DIO0. Драйвер над ним переносимый: он знает только четыре функции порта.
Регистры, которые нужны драйверу:
| Регистр | Адрес | Что в нём |
|---|---|---|
| RegFifo | 0x00 | окно в буфер пакета на 256 байт |
| RegOpMode | 0x01 | бит 7 — LoRa; биты 2–0 — сон, ожидание, передача, приём |
| RegFrf | 0x06–0x08 | частота, шаг 61,035 Гц |
| RegPaConfig | 0x09 | выход PA_BOOST и мощность |
| указатели FIFO | 0x0D–0x10 | текущий, начало передачи, начало приёма, последний пакет |
| RegIrqFlags | 0x12 | TxDone, RxDone, ошибка CRC — сбрасываются записью единиц |
| RegRxNbBytes | 0x13 | длина принятого пакета |
| RegPktSnr, RegPktRssi | 0x19, 0x1A | SNR и мощность пакета |
| RegModemConfig1, 2, 3 | 0x1D, 0x1E, 0x26 | полоса и избыточность; SF и CRC; оптимизация и AGC |
| RegSyncWord | 0x39 | слово синхронизации |
| RegDioMapping1 | 0x40 | какое событие выводить на DIO0 |
| RegVersion | 0x42 | 0x12 у всего семейства SX1276…SX1279 — проверка, что на шине микросхема этого семейства; диапазон модуля (868 или 433 МГц) она не отличает |
Адрес с нулевым старшим битом — чтение, с единичным — запись. К FIFO обращаются одним адресом 0x00: указатель внутри сам растёт с каждым байтом.
struct sx_cfg {
uint32_t freq_hz; /* например, 868 100 000 */
uint8_t sf; /* 7…12 */
uint8_t bw; /* код полосы: 7 — 125 кГц, 8 — 250, 9 — 500 */
uint8_t cr; /* 1…4 — избыточность 4/5…4/8 */
uint8_t sync; /* 0x34 — LoRaWAN, 0x12 — частные сети */
int8_t power_dbm; /* 2…17 на выходе PA_BOOST */
};
/* Вернёт 0 или −1, если на шине не SX1276: регистр версии обязан быть 0x12 */
int sx_init(const struct sx_cfg *c)
{
sx_reset_pin(0);
sx_delay_ms(1);
sx_reset_pin(1);
sx_delay_ms(10);
if (sx_read(REG_VERSION) != 0x12)
return -1;
sx_write(REG_OP_MODE, MODE_SLEEP); /* режим LoRa меняют только во сне */
sx_write(REG_OP_MODE, MODE_LORA | MODE_SLEEP);
uint32_t frf = (uint32_t)(((uint64_t)c->freq_hz << 19) / 32000000u); /* шаг 61,035 Гц */
sx_write(REG_FRF_MSB, (uint8_t)(frf >> 16));
sx_write(REG_FRF_MSB + 1, (uint8_t)(frf >> 8));
sx_write(REG_FRF_MSB + 2, (uint8_t)frf);
sx_write(REG_PA_CONFIG, (uint8_t)(0x80 | (c->power_dbm - 2))); /* PA_BOOST: 2 + N дБм */
sx_write(REG_FIFO_TX_BASE, 0);
sx_write(REG_FIFO_RX_BASE, 0);
sx_write(REG_MODEM_CONFIG1, (uint8_t)((c->bw << 4) | (c->cr << 1))); /* заголовок явный */
sx_write(REG_MODEM_CONFIG2, (uint8_t)((c->sf << 4) | 0x04)); /* CRC включён */
int ldro = (c->bw == 7 && c->sf >= 11) || (c->bw == 8 && c->sf == 12); /* символ > 16 мс */
sx_write(REG_MODEM_CONFIG3, (uint8_t)((ldro ? 0x08 : 0) | 0x04)); /* и AGC */
sx_write(REG_PREAMBLE_MSB, 0);
sx_write(REG_PREAMBLE_LSB, 8);
sx_write(REG_SYNC_WORD, c->sync);
sx_write(REG_OP_MODE, MODE_LORA | MODE_STDBY);
return 0;
}
/* Отправить пакет и дождаться конца передачи; 0 или −1 по таймауту.
* После передачи микросхема сама возвращается в ожидание. */
int sx_send(const uint8_t *buf, uint8_t n, unsigned timeout_ms)
{
sx_write(REG_OP_MODE, MODE_LORA | MODE_STDBY);
sx_write(REG_FIFO_ADDR_PTR, 0);
sx_fifo_write(buf, n);
sx_write(REG_PAYLOAD_LENGTH, n);
sx_write(REG_DIO_MAPPING1, 0x40); /* DIO0 — «передача окончена» */
sx_write(REG_IRQ_FLAGS, 0xFF); /* флаги сбрасывают записью единиц */
sx_write(REG_OP_MODE, MODE_LORA | MODE_TX);
while (!(sx_read(REG_IRQ_FLAGS) & IRQ_TX_DONE)) {
if (timeout_ms-- == 0)
return -1;
sx_delay_ms(1);
}
sx_write(REG_IRQ_FLAGS, IRQ_TX_DONE);
return 0;
}
/* Забрать пакет: длина, 0 — ничего не пришло, −1 — ошибка CRC.
* Мощность — в дБм (вход выше 779 МГц), SNR — в четвертях децибела. */
int sx_receive(uint8_t *buf, uint8_t cap, int *rssi_dbm, int *snr_q)
{
uint8_t f = sx_read(REG_IRQ_FLAGS);
if (!(f & IRQ_RX_DONE))
return 0;
sx_write(REG_IRQ_FLAGS, f);
if (f & IRQ_CRC_ERROR)
return -1;
uint8_t n = sx_read(REG_RX_NB_BYTES);
if (n > cap)
n = cap;
sx_write(REG_FIFO_ADDR_PTR, sx_read(REG_FIFO_RX_CURRENT));
sx_fifo_read(buf, n);
int snr = (int8_t)sx_read(REG_PKT_SNR);
int rssi = -157 + sx_read(REG_PKT_RSSI);
if (snr < 0)
rssi += snr / 4; /* ниже шума мощность уточняют по SNR */
*rssi_dbm = rssi;
*snr_q = snr;
return n;
}
sx_listen включает непрерывный приём и переключает DIO0 на «пакет
принят». Вместо опроса флагов DIO0 заводят на прерывание EXTI (раздел 7).
Под ядром обработчик прерывания будит задачу радио, а сам ничего не
читает по SPI.
Частота — в 64 битах. 868 100 000 · 2^19 не помещается в 32 бита.
Посчитанный в uint32_t регистр частоты молча переполнится, и модуль
уйдёт на чужую частоту.
Проверка на модели. Микросхемы на столе нет, поэтому драйвер работает с моделью SX1276 на C. Модель хранит регистры, FIFO с растущим указателем и флаги, которые сбрасываются единицами, и соблюдает правило «бит LoRa меняется только во сне»:
| Что проверено | Результат |
|---|---|
| запись 0x81 в RegOpMode не во сне | режим 0x01: бит LoRa проигнорирован, модуль остался в FSK |
sx_init: 868,1 МГц, SF7, 125 кГц, 4/5, 14 дБм |
Frf D9 06 66, PaConfig 8C, ModemConfig 72 74 04, SyncWord 34 |
| 869,525 МГц, SF12, 17 дБм | Frf D9 61 99, PaConfig 8F, ModemConfig2 C4, ModemConfig3 0C — оптимизация включена |
| на шине другая микросхема | sx_init вернула −1 |
sx_send 11 байт |
байты ушли из FIFO, флаг сброшен, микросхема вернулась в ожидание |
| пакет ниже шума | SNR −7,5 дБ, мощность −124 дБм |
| ошибка CRC | −1, флаги сброшены, следующий пакет принят |
Байты настройки независимо пересчитаны на Python.
93.6 RSSI и SNR: как читать
Микросхема сообщает о каждом пакете два числа. SNR — в четвертях децибела со знаком. Мощность — это −157 плюс значение регистра для входа выше 779 МГц; у модулей на 433 МГц смещение другое, −164. Когда SNR отрицательный, мощность уточняют на четверть SNR: сигнал ниже шума, и регистр мощности видит в основном шум.
Для оценки связи SNR важнее мощности. Мощность −110 дБм в тихом поле и в цеху с частотными преобразователями — две разные связи, а SNR это различие покажет. Запас до порога SF — главный показатель: пакет на SF7 с SNR −6 дБ дошёл, но до порога осталось полтора децибела. Оба числа записывают при радиообследовании (раздел 92). По ним же сеть LoRaWAN выбирает прибору SF (раздел 94).
93.7 Грабли
Модуль молчит, RegVersion читается как 0x00 или 0xFF. Перепутаны MISO и MOSI, не тот режим SPI или NSS не опускается.
Модуль не передаёт, хотя все регистры записаны. Бит LoRa записан не во сне — микросхема его проигнорировала и осталась в FSK.
Передатчик на чужой частоте. Регистр частоты посчитан в 32 битах или
через float с округлением.
На F407 сбоит SPI. Делитель 8 от 84 МГц даёт 10,5 МГц — выше предела
микросхемы. Или у PA5–PA7 осталась низкая скорость фронтов после сброса:
её поднимают в OSPEEDR.
Пакеты не доходят, ошибок нет. У передатчика и приёмника разные SF, полоса, слово синхронизации или оптимизация низкой скорости.
После первого пакета приём замолчал. Флаги не сброшены записью единиц в RegIrqFlags.
Обрезан последний бит команды. NSS снят до сброса BSY.
Выход передатчика повреждён. Передача шла без антенны.
Батарейка прибора на краю зоны тает на глазах. Он работает на SF12: пакет длится 1,48 с против 61,7 мс на SF7 (раздел 89).
93.8 Итоги
- Символ LoRa — сдвиг чирпа. SF бит на символ, длительность — 2^SF / BW: 1,024 мс на SF7 и 32,768 мс на SF12 при полосе 125 кГц.
- Приёмник снимает чирп и находит пик спектра. Выигрыш — 10·lg 2^SF, поэтому LoRa разбирает сигнал ниже шума: в модели порог от −9 дБ на SF7 до −22,5 дБ на SF12, у реальных микросхем — от −7,5 до −20 дБ.
- Каждая ступень SF — это 2,5–3 дБ и вдвое больше времени в эфире; каждое удвоение полосы — вдвое быстрее и на 3 дБ хуже.
- Бюджет линии при 14 дБм — 138,5 дБ на SF7 и 151 дБ на SF12. Сколько это километров, решает местность (раздел 92).
- SX1276 подключается по SPI1 одинаково к F103 и F407; частоту считают в 64 битах, бит LoRa включают во сне, флаги сбрасывают единицами, без антенны не передают.
Дальше: раздел 93а «nRF24L01: радио 2,4 ГГц на SPI — адреса, каналы, Enhanced ShockBurst, подтверждения и повторы».