Meshtastic ретранслятор на базе STM32L051C8T6 и NiceRF LoRa1276 (Semtech RF SX1276).
LIS3DH
| Номер пина | Порт | Выбранная функция |
|---|---|---|
| 33 | PA12 | — |
| 32 | PA11 | — |
| 26 | PB13 | I2C2_SCL |
| 27 | PB14 | I2C2_SDA |
| Pin Name | Function | STM32 |
|---|---|---|
| GND | Ground | GND |
| SCK | SPI Clock | 15 PA5 |
| MISO | SPI Data Out | 16 PA6 |
| MOSI | SPI Data In | 17 PA7 |
| NSS | Chip Select | 14 PA4 |
| DIO2 | Digital I/O | 18 PB0 |
| DIO1 | 19 PB1 | |
| DIO0 | 20 PB2 | |
| VCC | Power | 3V3 |
| NRESET | Reset | 28 PB15 |
| Название | Порт | Описание |
|---|---|---|
| V_BATT | PA3 | Напряжение батареи через мегаомный делитель (1/2) |
| LED_PIN | PA15 | Статус светодиод, горит когда активен прием/передача/UART |
На основе анализа истории коммитов (commit-stats.csv), ниже приведена стоимость различных функций в байтах Flash памяти (STM32L051C8Tx, 64KB Flash):
| Функция / Модуль | Размер (байт) | Коммит | Описание |
|---|---|---|---|
| Базовая прошивка | ~9 400 | 2ef7de0 |
HAL + Blink на PA15/PA9 |
| Arduino Core & Serial | +6 192 | aa476f2 |
Инициализация Arduino framework и работа с Serial |
| I2C Scanner | +10 444 | 455e9ad |
Добавление Wire и логики сканирования (частично оптимизировано позже на -5кб) |
| Deep Sleep (STM32LowPower) | +7 224 | 02d7806 |
Библиотека энергосбережения и логика сна |
| Meshtastic + RadioLib | +25 696 | 5915c6a |
Базовый прием пакетов Meshtastic через RadioLib |
| Packet Insight (Debug) | +7 456 | e66b99a |
Детальный разбор заголовков и вывод в Serial |
| Decryption (AES-CTR) | +1 300 | fb2f622 |
Реализация расшифровки пакетов (tiny-aes) |
| LTO & Оптимизации | -8 608 | 84fd8b8 |
Включение Link Time Optimization и флагов размера |
| Battery Monitoring | +2 180 | 1469d8c |
Чтение ADC и расчет напряжения батареи |
| Packet Cache | +592 | 85802b4 |
Фильтрация дубликатов и кэширование ID пакетов |
- I2C/Wire: Занимает довольно много места (~5-10кб), требует аккуратного использования.
- Floating Point: Использование
floatвSerial.printзначительно увеличивает размер. В коммите7dc1be5замена на fixed-point позволила сэкономить место при добавлении новых фич. - RadioLib: Модульная структура позволяет отключать неиспользуемые протоколы, что экономит память.
- LTO: Самый эффективный способ вернуть ~15% Flash памяти на критических этапах разработки.
На текущий момент (e942133, использовано ~58 КБ):
- Машинный код (~85% / 49 КБ):
- RadioLib Stack (~20 КБ): Драйверы SX1276, управление частотами, модуляцией и аппаратными прерываниями.
- Arduino Core & HAL (~14 КБ): Базовая системная обвязка (GPIO, SPI, Таймеры, Serial).
- Meshtastic Logic (~10 КБ): Парсинг Protobuf, кэширование пакетов, управление очередями и логика Mesh.
- Crypto (AES) (~3 КБ): Реализация AES-CTR и управление ключами (Tiny-AES).
- Low Power (~2 КБ): Библиотека STM32LowPower и логика глубокого сна.
- Строковые константы (~10% / 6 КБ): Отладочные сообщения в Serial, названия портов и текстовые метки. Использование
F()макроса обязательно для экономии RAM, но Flash они всё равно занимают. - Таблицы и системные данные (~5% / 3 КБ): Таблицы векторов прерываний, константы AES (S-Box) и настройки конфигурации.
Важно: Использование printFixedPoint вместо стандартного Serial.print(float) экономит около 4 КБ, так как не подтягивает тяжелую реализацию printf с плавающей точкой.
Вместо использования стандартных библиотек вроде Nanopb, в проекте реализован минималистичный парсер "на лету" (pbReadVarint, pbSkipField). Это осознанное решение для экономии ресурсов:
- Объем кода: Ядро Nanopb и сгенерированные структуры для Meshtastic (которые очень объемны) заняли бы от 5 до 10 КБ Flash. Текущий ручной парсер занимает всего ~300 байт.
- Экономия RAM: Ручной парсинг не требует создания полных C-структур в памяти. Данные извлекаются напрямую из буфера пакета только тогда, когда они нужны для вывода.
- Избирательность: Для целей мониторинга нам нужно всего 5-7 полей из сотен доступных в протоколе Meshtastic. Ручной подход позволяет игнорировать всё лишнее без затрат памяти на описание этих полей.
Для настройки параметров устройства без перепрошивки реализован минималистичный текстовый интерфейс через UART.
Важно: Для стабильного пробуждения микроконтроллера из глубокого сна (Stop mode) по входящим данным, скорость UART установлена в 57600 baud. При более высоких скоростях (например, 115200) контроллер не всегда успевает стабилизировать тактирование для корректного приема первого байта.
Интерфейс работает в режиме "молчания", чтобы не засорять лог пакетов.
Интерфейс поддерживает:
- Установку значения:
ключ=значение - Чтение значения: просто введите
ключ
Команды завершаются символом \n или \r.
| Ключ | Описание | Пример |
|---|---|---|
freq |
Частота LoRa (МГц) | freq=869.085 |
sf |
Spreading Factor (7-12) | sf=11 |
bw |
Bandwidth (кГц) | bw=250.0 |
cr |
Coding Rate (5-8) | cr=5 |
sw |
Sync Word (int) | sw=0x2B |
pre |
Preamble Length | pre=16 |
adc |
Множитель АЦП для вольтметра | adc=0.00175 |
batt |
Порог отключения батареи (В) | batt=3.5 |
key |
AES ключ (32 HEX символа) | key=d4f1bb3a20290759f0bcffabcf4e6901 |
log |
Уровень логирования (0-2) | log=1 |
dlrl |
Задержка ретрансляции пакетов (мс). -1 = отключено, 0+ = задержка в миллисекундах | dlrl=1000 |
Параметр dlrl управляет автоматической ретрансляцией принятых пакетов. Значение -1 отключает ретрансляцию, 0 и более — задержка в миллисекундах перед отправкой копии пакета в эфир. Устройство проверяет загруженность канала перед отправкой и ожидает, если канал занят. Это позволяет расширить покрытие сети Meshtastic.
apply— Сохранить текущие параметры в EEPROM и перезагрузить устройство.
Важно: Для применения любых настроек в ПЗУ необходимо в конце отправить команду apply. При успешной установке параметра устройство отвечает Set <ключ>=<новое_значение> OK. При запросе значения устройство выводит ключ=значение.
Уровень логирования напрямую влияет на энергопотребление устройства за счет времени работы UART-периферии и процессора в активном режиме.
log=0(None): Минимальное потребление. Вывод в Serial практически отсутствует.log=1(Packets): Вывод только краткой информации о новых и дублирующих пакетах.log=2(Insight): Максимальный уровень (дефолтный). Подробный разбор каждого пакета черезprintPacketInsight. Рекомендуется только для отладки.