NanoVNA-H и NanoVNA-H4 — это очень компактные переносные приборы класса Vector Network Analyzer (VNA — векторный анализатор цепей). Они представляют собой автономные портативные устройства с дисплеем Liquid Crystal Display (LCD — жидкокристаллический индикатор) и аккумулятором.
Поддержкой NanoVNA-X занимается @momentics (https://github.com/momentics/). Проект оптимизирован под STM32F072 и STM32F303 с ограниченными ресурсами памяти и сегодня представляет собой независимую архитектуру, ориентированную на отзывчивость, чёткие границы подсистем и детерминированную работу свипа. Прошивка распространяется под лицензией GNU GPLv3, поэтому каждый участник — от авторов исходной NanoVNA до нынешних разработчиков — сохраняет свои права.
Этот репозиторий содержит исходные тексты улучшенной прошивки NanoVNA-H и NanoVNA-H4, используемой в проекте NanoVNA-X. Документация описывает процесс сборки и прошивки в среде macOS или Linux (Debian либо Ubuntu); другие дистрибутивы Linux (а также BSD) обычно ведут себя аналогично.
- Отдельная благодарность @edy555 и @DiSlord за открытый релиз исходной NanoVNA. Именно их работа дала старт всему сообществу.
- NanoVNA-X активно развивается и сознательно уходит от монолитного дизайна оригинала - свип, UI и подсистемы ввода теперь минимально связаны и синхронизируются через события ChibiOS и тайм-ауты.
- Цель проекта — сохранить привычный интерфейс NanoVNA и при этом построить поддерживаемый, модульный стек с полноценной поддержкой карт microSD (калибровки, S1P/S2P, BMP/RLE-TIFF, дампы, скрипты и форматирование).
- Многоуровневая среда выполнения вместо монолитного
main.c. Поток свипа, консоль и сервисы собираются вsrc/runtime/через явные порты, поэтому управляющая логика читается и тестируется, а не скрывается внутриapp_main. - Конвейер свипа без лишнего копирования (zero-copy). Управление ВЧ-трактом (RF-orchestration) строится вокруг снимков состояния (снапшотов)
sweep_service_snapshot_tи координатораmeasurement_engine, что позволяет UI, USB-CLI и заданиям SD-карты потреблять уже захваченные буферы без повторных измерений. - Инфраструктура в
sys/. Шина событий, кооперативный планировщик, сервис конфигурации/калибровки и менеджер состояния с автосохранением заменяют жёстко впаянные глобальные переменные из v0.9.1, делая фоновую работу предсказуемой и восстановимой. - Чистые интерфейсы. CLI, USB-транспорт, UI-хуки и DSP-хелперы описаны в соответствующих модулях, что устраняет практику
#include "*.c"и чётко показывает, где находится транспорт-независимая логика. - Переработанный UI и ввод. Компоненты интерфейса (presenters), контроллеры, адаптеры ввода, шрифты и иконки живут в
src/ui/, благодаря чему реализованы браузер SD-карты, удалённый десктоп и улучшенные сообщения без правок драйверов железа. - Обновлённые инструменты и документация. Единый файл
VERSIONобслуживает сборку и релизы, Makefile знает новый план каталогов, а русские/английские документы описывают расхождения, чтобы форки понимали, чем современное дерево отличается от ветки DiSlord. - Предсказуемая событийная архитектура. Механизм управления развёрткой (свипом), UI, USB CDC-оболочка и DSP взаимодействуют через шину событий ChibiOS и сторожевые тайм-ауты. Зависший кодек, синтезатор или ПК-хост больше не могут «подвесить» прибор во время калибровки.
- DMA зарезервирован под измерения. Передачи SPI LCD и приём данных TLV320 по I²S выполняются через DMA, а UART-консоль сознательно переведена на драйвер прерываний, чтобы каналы DMA всегда были доступны критичным трактам измерений.
- Уникальный USB-серийный номер по умолчанию. Каждое устройство теперь объявляется с номером, вычисленным по уникальному идентификатору микроконтроллера (при необходимости его всё ещё можно отключить в System -> Device -> MORE -> USB DEVICE UID).
- Полностью интегрированная работа с картой microSD. Меню SD CARD поддерживает сохранение и восстановление калибровок, экспорт S1P/S2P, получение скриншотов (BMP или компактный RLE-TIFF), выгрузку образа прошивки, запуск командных сценариев и форматирование карты контролируемой командой
FORMAT SD, что соответствует сервисным процедурам Keysight и Rohde & Schwarz.
Прошивка переписана на многослойной архитектуре ChibiOS, уделяющей максимум внимания отклику устройства, автономной работе и стабильности измерений на ограниченном железе.
Ядро прошивки было переработано. Вместо блокирующих вызовов теперь используется полностью асинхронная, событийно-ориентированная архитектура на основе примитивов ChibiOS (почтовые ящики, события и семафоры).
-
Неблокирующий USB. Стек USB CDC (виртуальный COM-порт) теперь полностью асинхронен. Прошивка больше не зависает, если хост-компьютер подключается, отключается или "тормозит" во время передачи данных. Это решает самую частую причину зависаний прибора.
-
Восстановление по таймаутам. Критически важные подсистемы, включая измерительный движок и шину I²C, защищены таймаутами. "Зависшая" операция больше не блокирует все устройство; вместо этого подсистема пытается корректно восстановить свою работу.
-
Параллелизм на основе RTOS. Циклы ожидания (busy-wait) и постоянные опросы были заменены на эффективные сигнальные механизмы RTOS, что снижает нагрузку на процессор и увеличивает время работы от батареи. Измерительный поток, пользовательский интерфейс и стек USB теперь работают согласованно, без гонок состояний и взаимоблокировок.
-
- Сохранение состояния. Выделенный модуль
sys/state_managerотслеживает лимиты свипа, флаги UI и активный слот калибровки. Изменения автоматически сбрасываются во flash после паузы редактирования (или мгновенно через пункт меню SAVE CONFIG), поэтому корректировки диапазонов переживают выключение без лишних циклов записи.
- Сохранение состояния. Выделенный модуль
-
Синхронизация интерфейса и измерений. Пользовательский интерфейс и измерительный движок теперь разделены. Интерфейс остается отзывчивым даже во время сложных вычислений, а данные на экране всегда синхронизированы с состоянием измерений.
-
Прицельная оптимизация памяти. Потребление статической ОЗУ было значительно сокращено, особенно для STM32F072 (NanoVNA-H) с 16 КБ памяти. Это было достигнуто путем настройки размеров буферов, отключения таких функций, как кэширование трасс на моделях с малым объемом памяти, и перемещения ключевых буферов в CCM RAM на STM32F303.
-
Стратегическое использование DMA. Архитектура Direct Memory Access (DMA — прямой доступ к памяти) была доработана для повышения стабильности измерений. DMA используется для самых требовательных путей данных:
- Интерфейс дисплея (SPI). Обеспечивает плавную и быструю отрисовку интерфейса и графиков.
- Измерительный конвейер (I²S). Гарантирует доставку сэмплов от кодека без потерь.
- Чтобы освободить каналы DMA для этих критических задач, консоль UART была намеренно переведена на драйвер, работающий на прерываниях (без DMA). Это предотвращает конфликты ресурсов и ставит в приоритет целостность измерений.
Измерения выполнены на серийном NanoVNA-H с типичным свипом из 101 точки:
| Сценарий | Эффективный поток точек |
|---|---|
| Диапазон 50 кГц–300 МГц без гармонических перебросов | 175–178 точки в секунду, разброс задаёт время стабилизации PLL Si5351. |
| Полный диапазон 50 кГц–2,7 ГГц с гармоническими перебросами (50–300 / 300–600 / 600–900 МГц и соответствующие гармоники) | 223–232 точки в секунду благодаря конвейерному движку свипа и оптимизированному расписанию IF-полосы. |
NanoVNA-H4 на STM32F303 работает быстрее за счёт большего объёма SRAM, однако приведённые значения задают гарантированный минимум для наименее мощной платформы.
Технически платформа STM32F303 значительно превосходит STM32F072:
- Частота SPI дисплея: 36 МГц (F303) против 24 МГц (F072), что ускоряет отрисовку в 1.5 раза.
- Математика (DSP): работает более чем в 10 раз быстрее за счёт аппаратного FPU.
Однако "полезная работа" (расчёты и вывод) занимает менее 5% времени, поэтому реальная разница в скорости свипа невелика (~9%):
- Главный цикл измерения (
sweep_orchestrator.c) вызываетsweep_service_wait_for_capture(), ожидая наполнения буфера аудио-АЦП. - Конфигурация: Частота дискретизации 192 кГц, размер буфера 48 сэмплов (см.
nanovna.h). - Это вызывает прерывание каждые 0.25 мс.
- Для обеспечения базовой точности (полоса 1 кГц) прибор ожидает около 4 буферов, что даёт минимум 1.0 мс чистого ожидания на каждую точку.
Итоговое время на точку:
- F072: 1.0 мс (ожидание) + 0.1 мс (расчёт/вывод) = 1.1 мс/точка.
- F303: 1.0 мс (ожидание) + 0.01 мс (расчёт/вывод) = 1.01 мс/точка.
- Разница: ~9% (примерно 111 мс против 102 мс на 101 точку).
Хотя скорость сканирования ограничена физикой процесса измерения, больший объём памяти STM32F303 позволяет обрабатывать в 4 раза больше точек за один проход.
-
Стабилизация PLL. Последовательность программирования синтезатора Si5351 была оптимизирована для уменьшения выбросов и дрейфа частоты, что повышает повторяемость измерений, особенно в начале сканирования.
-
Детерминированный USB-нумератор. Режим USB DEVICE UID теперь включён по умолчанию, поэтому каждое устройство сразу объявляется с устойчивым серийным номером, распознаваемым NanoVNA-App, NanoVNA Saver и другими утилитами.
-
Автоматическое версионирование. Версия прошивки теперь автоматически встраивается в процессе сборки из единого файла
VERSION. -
Улучшенный CI/CD. Рабочие процессы GitHub Actions были оптимизированы для более быстрых и надежных сборок с улучшенным кэшированием.
-
Генерация DFU-файлов. В процесс выпуска релизов интегрирован скрипт на Python для создания файлов прошивки, совместимых с DfuSe.
NanoVNA-X использует многослойную архитектуру, разделяющую этапы загрузки, аппаратную интеграцию, обработку измерений и пользовательский интерфейс. Такой подход позволяет поддерживать сопровождаемость и вписываться в строгие ограничения по объему флэш-памяти и оперативной памяти на микроконтроллерах STM32F072 и STM32F303.
- Загрузка и выполнение приложения. Прошивка стартует в
src/runtime/main.c, где управление передается функцииruntime_main(). Вся логика верхнего уровня сосредоточена вsrc/runtime/runtime_entry.c. Здесь инициализируется ChibiOS/RT, настраиваются USB-консоль и драйверы синтезатора, поднимается измерительный конвейер и запускается выделенный поток опроса, координирующий измерения, обновление интерфейса и обработку команд консоли. - Аппаратная абстракция. Модуль
src/driver/platform_hal.cобращается к таблице драйверов, зарегистрированной вsrc/driver/, чтобы каждая поддерживаемая плата предоставляла структуруPlatformDriversс инициализацией и описаниями периферии. Это изолирует ядро приложения от различий между NanoVNA-H (STM32F072) и NanoVNA-H4 (STM32F303). - Слой сервисов. Общая инфраструктура расположена в каталоге
src/sys/. Шина событий реализует механизм публикации/подписки с фиксированным набором тем и при наличии буферов использует почтовый ящик, чтобы код из обработчиков прерываний мог отложенно доставлять сообщения. Хелпер планировщика оборачивает создание и завершение потоков ChibiOS, а сервис конфигурации отвечает за сохранение настроек пользователя и слотов калибровки во флэш-памяти с контролем целостности. - Измерительный конвейер и DSP. Файл
src/rf/pipeline.cвыступает тонкой прослойкой между платформенными драйверами и измерительными процедурами вsrc/rf/sweep/. Он делегирует выполнение свипа прикладному уровню и предоставляет текущую маску каналов. Численные помощники и математические алгоритмы калибровки вынесены вsrc/processing/, чтобы изолировать ресурсоемкий код от прямого доступа к оборудованию. - Драйверы и промежуточное ПО. Низкоуровневые взаимодействия с железом реализованы в
src/driver/— здесь находятся драйверы дисплея, синтезатора Si5351, кодека TLV320 и USB-интерфейса. Каталогsrc/sys/содержит небольшие интеграционные прослойки, например привязкуchprintfк потокам ChibiOS. ChibiOS поставляется вместе с проектом в каталогеthird_party/и конфигурируется через заголовки вconfig/и файлы верхнего уровняchconf.h/halconf.h. - Пользовательский интерфейс. Поток опроса инициализирует инструментарий UI (
src/ui/), обрабатывает аппаратный ввод, обновляет графики и отмечает области экрана для перерисовки. Шрифты и пиктограммы, используемые отрисовкой, хранятся вsrc/ui/resources/. - Менеджер состояния. Модуль
src/sys/state_manager.cзанимает нишу между сервисом конфигурации и прикладным кодом. Он поддерживает таблицы значений по умолчанию, восстанавливает backup-регистры, отслеживает «грязное» состояние и планирует отложенные записи во flash. UI и консоль обращаются к нему через заголовокinclude/sys/state_manager.h, поэтому логика автосохранения сосредоточена в одном месте.
Публичные заголовки вынесены в include/, а поддержка плат, скрипты компоновки и стартовый код находятся в каталоге boards/. Такая структура позволяет использовать единые механизмы измерений и пользовательского интерфейса на обеих аппаратных платформах, ограничиваясь лишь точечными переопределениями.
Чтобы упростить ориентацию в дереве исходников и отойти от линейного портирования старых форков, проект структурирован следующим образом.
| Путь | Назначение |
|---|---|
include/runtime, src/runtime |
Публичные API верхнего уровня — точка входа, фичефлаги, консоль и координация свипов. |
include/rf, src/rf |
Свип-движок, измерительный конвейер и вспомогательная аналитика. |
include/processing, src/processing |
DSP и математические помощники, используемые измерениями и UI. |
include/sys, src/sys |
Повторно используемая инфраструктура (шина событий, конфигурация, планировщик, управление состоянием). |
include/driver, src/driver |
Реализации драйверов для аппаратных компонентов (LCD, Si5351, TLV320, USB). |
include/ui, src/ui |
Отрисовка, контроллеры, ввод и ресурсы (шрифты/иконки). |
src/driver, boards/STM32F072/STM32F303 |
Платы и аппаратно-зависимый код, общий с ChibiOS. |
При переносе патчей из наследованных деревьев важно сопоставлять функциональность с подходящим модулем, а не копировать файл целиком — теперь зависимость легко прослеживается по каталогу.
Шина событий (sys/event_bus.[ch]) — это компактный помощник публикации/подписки без динамического выделения памяти. event_bus_init() принимает статический массив подписок, опциональные буферы почтового ящика (msg_t-очередь и длину) и набор узлов для очереди. Если заданы буферы, event_bus_publish() помещает сообщения в почтовый ящик, после чего отдельный поток вызывает event_bus_dispatch() и рассылает их подписчикам. При отсутствии почтового ящика уведомления доставляются синхронно. Обработчики прерываний должны пользоваться event_bus_publish_from_isr(), который резервирует узлы очереди с учётом блокировок. Предопределённые темы (EVENT_SWEEP_STARTED, EVENT_SWEEP_COMPLETED, EVENT_TOUCH_INPUT, EVENT_STORAGE_UPDATED, EVENT_CONFIGURATION_CHANGED, EVENT_USB_COMMAND_PENDING) покрывают текущие сценарии; для расширения шины нужно добавить элементы в перечисление event_bus_topic_t.
Планировщик (sys/scheduler.[ch]) содержит фиксированный пул из четырёх слотов поверх chThdCreateStatic()/chThdTerminate(). Вызов scheduler_start() возвращает дескриптор со ссылкой на слот, чтобы позже можно было остановить задачу через scheduler_stop(). Планировщик не реализует собственное распределение квантов — приоритеты и тайминги остаются на стороне ChibiOS.
Основные целевые MCU — STM32F072xB и STM32F303 (NanoVNA-H/H4); плата F072 использует 8 МГц кварц, линии USB, SPI, I²C и I²S для дисплея, кодека и сенсора, как описано в board.h.
Тактовый генератор Si5351A (или совместимый) управляет выходными синтезаторами, а также формирует опорные частоты для аудио АЦП; драйвер реализует кэширование частот, управление мощностью и инициализацию PLL по I²C.
TLV320AIC3204 служит двухканальным аудио АЦП/ЦАП (I²S), с конфигурацией PLL и маршрутизацией входов; прошивка управляет им через I²C и выводит рабочий поток по SPI/I²S.
Дисплейные контроллеры ILI9341/ST7789 (320×240) и ST7796S (480×320) выбираются по плате; поддерживается DMA, регулировка яркости (для H4), инверсия и тени текста для повышения читаемости.
Дополнительные функции включают RTC, сохранение конфигурации и калибровок во внутренней флэш-памяти, USB UID, дистанционное управление, модуль измерений (LC matching, анализ кабеля и резонансов).
NanoVNA-X использует стандартный процесс на основе GNU Make и компилятора Arm GNU GCC.
Полное руководство приведено в файле doc/building.md
Существует несколько качественных программных инструментов для персонального компьютера (ПК), созданных сторонними разработчиками.
- GoVNA. Надёжная и безопасная библиотека Go для управления векторными анализаторами цепей NanoVNA. Поддерживаются несколько протоколов (V1, V2/LiteVNA), автоматическое определение устройств и оптимизирована для высокопроизводительных серверных приложений.
- PyVNA. Многопротокольная библиотека Python для NanoVNA V1/V2/LiteVNA, созданная на основе GoVNA для высокопроизводительных и безопасных серверных приложений. Поддерживает автоматическое определение, надёжное объединение устройств в пул и комплексную обработку данных.
- NanoVNA-App software от OneOfEleven
- 12-точечная калибровка (RU) — подробная инструкция по 12-точечной калибровке.
- Поддержка 50/75 Ом (PORT-Z) (RU) — инструкция по ренормализации импеданса.
- Структура меню NanoVNA-X (RU) — подробное древо пунктов меню на русском языке.
- NanoVNA-X menu structure — англоязычное дерево актуального меню NanoVNA-X.
- NanoVNA-X menu & user workflow reference — англоязычное описание сценариев работы с меню.
- NanoVNA User Guide (ja) от cho45. (en: google translate)
- Группа пользователей NanoVNA на портале groups.io.
Материалы по аппаратной части опубликованы, чтобы предотвратить появление некачественных копий. Если у вас есть собственный экземпляр, пожалуйста, сообщите об этом.
