Здесь — весь путь от «плата лежит на столе» до «мы переписываемся, и интернета нет ни у кого».
Плата должна быть уже прошита: Прошить плату в RNode. То же самое без интерфейса, флагами и curl’ом — Радио из командной строки.
Шаг 1. Подключить радио
Откройте Settings → Radio. Это и есть экран радио целиком, никуда дальше идти не нужно.
- Воткните плату в USB.
- Нажмите Scan for radios.
- В списке найдите строку «an RNode modem» и нажмите attach.
Сканирование занимает около десяти секунд: узел открывает каждый последовательный порт, даёт ему время представиться, а промолчавшие спрашивает второй раз, прежде чем назвать их молчащими. Путь устройства искать и запоминать не нужно — в этом весь смысл сканирования, потому что после сброса путь меняется сам.
На телефоне это устроено иначе
Android не создаёт файлов устройств для USB-периферии: последовательных портов там нет вообще и не появится. Плата доступна только через системную службу USB, и поэтому шаги те же, а механика под ними другая — три отличия, которые видно глазами:
- Нужен OTG-кабель. Телефон должен стать хостом, иначе плата для него не существует.
- Система спросит разрешение на конкретное устройство, один раз. Это её диалог, не наш; отказ — обычный ответ, приложение просто скажет, что модем не разрешили.
- Список показывает USB-устройства, а не порты, и в нём видны в том числе те, которые эта сборка вести не умеет — с причиной. Список, который молча прячет воткнутый модем, не даёт отличить «не воткнут» от «воткнут, но не поддержан», а это разные следующие шаги.
Ещё одно отличие не видно, но объясняет поведение: после перезапуска приложения радио не поднимается само. Разрешение на устройство принадлежит приложению, кабель может быть уже вынут, и переподключение — действие человека. Фраза сегмента при этом не спрашивается второй раз: узел её помнит, выдернутый кабель не считается отсоединением радио.
Какие платы работают: эта сборка ведёт мосты Silicon Labs CP210x — самый частый мост на платах RNode. Если в списке ваша плата помечена как неподдержанная, там же написано, какой у неё мост.
В списке будет не только ваша плата. Каждый порт назван, включая те, которые узел намеренно не стал открывать:
| строка | что это |
|---|---|
| an RNode modem | то, что нужно |
| Meshtastic node | другой носитель — см. Радио в quite.space |
| busy | порт держит другая программа: второй узел, монитор порта, приложение Meshtastic |
| foreign | устройство ответило на чужом протоколе — не наше дело |
| silent | порт открыли, дважды спросили, ответа нет |
| skipped | не открывали вовсе, и рядом написано почему |
Шаг 2. Фраза сегмента
При подключении узел спросит фразу сегмента — слова, которые превращаются в ключ вашего радиосегмента.
- Одинаковые слова на всех радио сегмента. Символ в символ. Разошлись — оба радио передают, и ни одно ничего не слышит, без единой ошибки где-либо.
- Минимум 16 символов. Фраза не обрезается и не дополняется: любая «помощь» здесь дала бы узел, уверенно сидящий на сегменте, где нет никого.
- Сами слова не сохраняются — только выведенный из них ключ. Ничему дальше слова не нужны, а фраза — это как раз та форма секрета, которую человек скорее всего где-то уже использовал.
Одна и та же фраза даёт один и тот же сегмент, откуда бы её ни ввели: с
экрана, флагом --mesh-seed или из приглашения. Вывод ключа в сборке
ровно один, поэтому «мы набрали одинаковое, но не слышим друг друга»
здесь невозможно.
А если фразу не спросили
Значит, сегмент уже известен этому устройству — он приехал вместе с приглашением.
Это не мелочь, а главный сценарий. Когда вы делаете ссылку-приглашение на узле с подключённым радио, описание сегмента (носитель, профиль, ключ) едет внутри запечатанной ссылки. Тот, кого вы пригласили, ничего про радио не знает и знать не должен: он однажды воткнёт плату, нажмёт attach — и его не спросят ничего.
Ради этого всё и делалось: настройка приезжает раньше, чем понадобится. Момент, когда интернет пропал, — это ровно тот момент, когда никто уже никому ничего не может прислать.
Правила при этом строгие:
- сегмент, которого эта сборка не понимает (чужой носитель, незнакомый профиль, другая версия вывода ключа), — отказ с названной причиной;
- другой сегмент, когда один уже настроен, — тоже отказ. Молча перенастроить чужое радио значило бы увести работающую связь в сторону, и единственным симптомом была бы тишина. Хотите сменить — отключите радио и подключите заново, это ваше решение.
Шаг 3. Что теперь происходит
Одно радио на узел. Попытка подключить второе — отказ со словами «a
radio is already connected», и это инвариант рантайма, а не ограничение
экрана. Хотите другую плату — сначала detach this radio.
Подключение переживает перезапуск. Узел сам поднимет то же радио при следующем старте. Если платы на месте не оказалось — это не ошибка и ничего не стирается: кабель вернётся. Состояние честно покажет, что именно не получилось.
Отключить — кнопка detach this radio на том же экране. Она не
только кладёт радио, но и забывает его, иначе следующий старт вернул бы
то, что человек только что выключил.
Радио — последний путь, а не единственный. Пока живы интернет или локальная сеть, узел пользуется ими. Переключение автоматическое и ничего не переспрашивает: связь принадлежит пространству и личности, а не сети, в которой она однажды возникла.
Шаг 4. Встретиться по радио
Это сценарий, ради которого радио вообще есть: два человека, две платы, интернета нет ни у кого, они раньше не были знакомы.
Settings → Radio → meet over the radio.
- say who I am — имя и публичный ключ этого устройства уходят в эфир. Их слышат все в радиусе; именно это нужно другому, чтобы запечатать приглашение лично вам. LoRa медленная — дайте полминуты.
- В списке heard on this segment появится соседнее радио. Всё, что там написано, — это то, что радио заявило о себе. Приглашение запечатывается на объявленный ключ, поэтому назвавшийся чужим именем получит приглашение, которое не сможет открыть.
- check they can hear you — один кадр, спрашивающий, слышат ли вас. Ответ появится в строке соседа. Это дёшево, поэтому идёт первым.
- Когда строка скажет Radio link established — кнопка станет start a line with …. Вот это уже приглашение: шесть кадров, около минуты в эфире, и обратно его не забрать.
- У второго человека приглашение появится в разделе waiting for your answer. До нажатия accept оно не стоило ему ничего: никто не член, ни один ключ не сдвинулся.
- После accept появляется линия — обычное пространство на двоих, просто рождённое без интернета.
Отдельная кнопка or invite them into «…» приглашает соседа в уже открытое у вас пространство вместо новой линии.
Состояния, которые стоит уметь читать
Экран говорит только то, что знает, и разница между строками намеренная:
| строка | значение |
|---|---|
| Radio link established | адресат достижим по радио |
| Direct radio link | то же, и подтверждено, что напрямую, без промежуточных узлов |
| They heard it. Waiting for them to answer. | приглашение доставлено, ответа ещё нет |
| Could not confirm delivery. | отправка не подтвердилась. Это не «не дошло» — оно может уже лежать у них. Повтор не создаст вторую линию |
| They ARE a member here; their device does not know it yet. | они попросились, вы приняли, радио замолчало до того, как ответ дошёл. Отправьте ещё раз, когда они вернутся |
| Nobody answered. | их радио выключено или вне дальности |
Слова «не доставлено» экран не скажет никогда, если на самом деле знает только «не подтвердилось». Это разные вещи, и мы их не смешиваем.
Что радио несёт, а что ждёт
У одного события есть бюджет эфира: 30 секунд. Не влезло — по радио
не пойдёт. Число не выбрано на вкус, оно посчитано по реальной физике
профиля long-fast-ru:
| что | размер | кадров | эфир |
|---|---|---|---|
| короткое сообщение | 340 Б | 1 | 4.6 с |
| реакция | 387 Б | 1 | 4.6 с |
| длинное сообщение | 857 Б | 3 | 13.8 с |
| картинка, превью 2 КиБ | 2.4 КБ | 6 | 27.6 с — на пределе |
| картинка, превью 40 КиБ | 41 КБ | 99 | 7.5 минут, и всё это время не движется больше ничего |
Это настенные часы, а не арифметика по учебнику: в каждом кадре учтены 700 мс, которые модем тратит сверх расчётного времени в эфире. Пока их не считали, потолок предсказывался в 2586 байт, а живая плата вывела 2155 — разницу нашло железо, а не рассуждение.
Отсюда правило: текст, реакции и служебное идут по радио; фотографии, голос, аудио и файлы ждут более широкого пути. Порог одинаков для любого медиа — он про размер события, а не про его тип. Кроме того, узел вообще не раздаёт по радио вложения: файл собирается из кусков, и это десятки минут эфира на одну картинку.
Точный потолок в байтах узел считает сам, спрашивая у носителя, сколько стоит кадр — получается порядка двух килобайт. Быстрый профиль поднимет его без единой правки в коде.
И это видно человеку. Пост или сообщение, которое не влезло, не исчезает и не помечается ошибкой — под ним появляется строка:
Waiting for a wider path — 41 KB, and the radio carries 2.1 KB. It goes as soon as the internet or the local network is back. Nothing is lost.
Отправленное действительно уйдёт, как только появится путь пошире. Молчание вместо этой строки было бы хуже затора: затор кончается, а тишина неотличима от «сообщения не было».
Скорость, честно
LoRa — единицы килобит в секунду на всех сразу, и это физика, а не недоделка. Что это значит на практике:
- сводка по каждому пространству уходит раз в минуту, а не раз в две секунды, как через интернет;
- сообщение в 6.6 КБ — это около полутора минут и 17–18 кадров при теоретическом минимуме в 16;
- знакомство двух узлов — десятки секунд, а не мгновение.
Полторы минуты на сообщение — это плохо ровно до того момента, когда альтернативой становится ноль сообщений.
Если ничего не слышно
Сверху вниз, по частоте причины:
| признак | скорее всего |
|---|---|
| в сканировании нет строки «an RNode modem» | плата не прошита в RNode (Прошить плату в RNode) или кабель без данных |
| busy на нужном порту | порт держит другая программа — второй узел, монитор, приложение Meshtastic |
| радио подключилось, соседа не видно | разные фразы сегмента. Проверять нечем — просто наберите её заново на обоих, символ в символ |
| сосед виден, приглашение не доходит | дальность. Разнесите платы; лежащие вплотную радио иногда глушат друг друга приёмником |
| всё подключено, но сообщения идут не по радио | так и задумано, пока жив интернет или локальная сеть. Чтобы проверить именно эфир — выключите остальное, см. ниже |
| сообщение висит с надписью про «wider path» | оно слишком большое для эфира и ждёт интернета. Это не ошибка |
Как проверить, что работает именно радио
Главная ловушка: два узла на одной машине найдут друг друга по локальной сети за секунду, сообщение долетит мгновенно, и вы решите, что работает радио. Оно при этом может быть даже не подключено.
Поэтому в проверке радио: --no-lan на обоих узлах и ни одного реле в
настройках (у свежей папки данных его и нет). Тогда единственный
оставшийся путь — эфир, и результат означает ровно то, что означает.
Готовый прогон целиком — Радио из командной строки.
И вторая половина проверки, без которой первая ничего не доказывает: отключите радио и убедитесь, что сообщения перестали доходить.