12 KiB
MeshCore — Relay + DS18B20 на базе Companion Radio
1. Что это
Модификация прошивки companion_radio из MeshCore. Устройство получает по LoRa-мешу приватные команды и управляет реле, а также отвечает на запросы температуры с DS18B20.
2. Откуда брать проект
git clone --depth 1 https://github.com/meshcore-dev/MeshCore.git
cd MeshCore
3. Что нужно установить
PlatformIO
- Установить Python 3
- Установить PlatformIO:
pip install platformio - Или установить VS Code + расширение PlatformIO
Зависимости (добавить в platformio.ini)
В секцию [arduino_base], в lib_deps добавить:
paulstoffregen/OneWire @ ^2.3.7
milesburton/DallasTemperature @ ^3.11.0
4. Какие файлы править
Базовый проект — examples/companion_radio/.
Файлы для изменения:
| Файл | Что делать |
|---|---|
platformio.ini |
Добавить OneWire и DallasTemperature в lib_deps; для nRF52 добавить env (раздел 7.3) |
examples/companion_radio/MyMesh.h |
Добавить #include, пины, поле OneWire/DallasTemperature, метод readTemperature() |
examples/companion_radio/MyMesh.cpp |
В конструктор — инициализация OneWire, в begin() — _tempSensor.begin(), реализовать readTemperature(), изменить onMessageRecv() |
examples/companion_radio/main.cpp |
В setup() добавить pinMode(RELAY_PIN, OUTPUT) |
Подключение железа (ESP32):
| Пин | Назначение |
|---|---|
| GPIO 4 | Реле (RELAY_PIN) |
| GPIO 5 | DS18B20 Data (ONE_WIRE_BUS) |
| 3.3V | DS18B20 VCC (через 4.7k подтяжку к Data) |
| GND | Общий |
Параметры радио (ESP32)
В platformio.ini в вашей env-секции (например [env:esp32dev_companion_radio_usb]) переопределить:
build_flags = ${arduino_base.build_flags}
-D LORA_FREQ=868.731018
-D LORA_BW=62.5
-D LORA_SF=7
-D LORA_CR=7
Для хэша пути 1 байт в MyMesh.cpp в конструкторе указать:
_prefs.path_hash_mode = 0;
Для nRF52840 (XIAO) пины по умолчанию: RELAY_PIN = D6 (P0.08), ONE_WIRE_BUS = D7 (P0.09) — смотрите раздел 7.2.
Автоматическая отправка advertise каждые 30 минут
В MyMesh.h добавить поле:
float readTemperature();
private:
unsigned long _next_advert_ms;
OneWire _oneWire;
DallasTemperature _tempSensor;
В MyMesh.cpp в конструкторе инициализировать:
MyMesh::MyMesh(...) : BaseChatMesh(...), _oneWire(ONE_WIRE_BUS), _tempSensor(&_oneWire) {
_next_advert_ms = 0;
// ... остальной код ...
}
В MyMesh::loop() (или в main.cpp в loop()) добавить проверку таймера:
void MyMesh::loop() {
BaseChatMesh::loop(); // существующий вызов
// advertise каждые 30 минут (1800000 мс)
if (millisHasNowPassed(_next_advert_ms)) {
advert();
_next_advert_ms = futureMillis(1800000);
}
}
Либо ещё проще — в main.cpp:
void loop() {
static unsigned long next_advert = 0;
the_mesh.loop();
sensors.loop();
// ... остальной код ...
if (millisHasNowPassed(next_advert)) {
the_mesh.advert();
next_advert = futureMillis(1800000);
}
}
5. Команды (приватные сообщения узлу)
| Команда | Ответ | Действие |
|---|---|---|
on1234 |
relay on |
Реле включено |
off1234 |
relay off |
Реле выключено |
temp |
temp: 23.5 C |
Температура с DS18B20 |
state |
temp: 23.5 C, relay: ON |
Температура + состояние реле |
Цифра 1234 — код доступа к реле (можно сменить в RELAY_CODE).
6. Как залить
cd MeshCore
# для конкретной платы, например ESP32:
pio run -e <board_name> -t upload
# или открыть в VS Code + PlatformIO и собрать через IDE
7. Версия для nRF52840 + HT-RA62 (SX1262)
7.1 Что за связка
nRF52840 — популярный MCU с BLE. HT-RA62 — LoRa-модуль на чипе SX1262 (аналог E22-900Mxx).
Можно использовать любую плату на nRF52840 + внешний HT-RA62 по SPI. Самый популярный вариант — Seeed XIAO nRF52840 + HT-RA62 на макетной плате.
7.2 Распиновка XIAO nRF52840 + HT-RA62
| Пин XIAO | GPIO nRF52 | HT-RA62 | Назначение |
|---|---|---|---|
| D0 | P0.02 | NSS | CS (SPI chip select) |
| D1 | P0.03 | DIO1 | IRQ (прерывание) |
| D2 | P0.04 | BUSY | Занятость модуля |
| D3 | P0.05 | RESET | Сброс |
| D4 | P0.06 | RXEN | Включение RX (если есть) |
| D5 | P0.07 | TXEN | Включение TX (если есть) |
| D6 | P0.08 | (свободен) | Реле (RELAY_PIN) |
| D7 | P0.09 | (свободен) | DS18B20 Data (ONE_WIRE_BUS) |
| D8 | P0.10 | SCK | SPI clock |
| D9 | P0.28 | MO | SPI MOSI |
| D10 | P0.02 | MI | SPI MISO |
| 3.3V | — | VCC | 3.3V питание |
| GND | — | GND | Общий |
Важно: У HT-RA62 DIO2 настроен как RF-переключатель, DIO3 — 1.8V для TCXO (задаётся в коде).
Свободные пины XIAO nRF52840 после подключения:
| Пин | Назначение | Можно |
|---|---|---|
| D0 (P0.01) | GPIO | цифровой вход/выход |
| D5 (P0.06) | RXEN (HT-RA62) | да — если RXEN не используется (у HT-RA62 коммутация RF уже через DIO2) |
| A0 (P0.31) | ADC/GPIO | аналоговый или цифровой |
| A1 (P0.29) | ADC/GPIO | аналоговый или цифровой |
| A2 (P0.30) | ADC/GPIO | аналоговый или цифровой |
Занято: D1(IRQ), D2(BUSY), D3(RESET), D4(NSS), D6(реле), D7(DS18B20), D8(SCK), D9(MOSI), D10(MISO) — 9 пинов.
Свободно: 4–5 пинов (D0, D5, A0, A1, A2) для кнопок, светодиодов или доп. датчиков.
7.3 Что добавить в platformio.ini
В конец файла platformio.ini дописать:
; ===== nRF52840 + HT-RA62 (SX1262) =====
[Xiao_nrf52]
extends = nrf52_base
board = seeed-xiao-afruitnrf52-nrf52840
board_build.ldscript = boards/nrf52840_s140_v7.ld
build_flags = ${nrf52_base.build_flags}
-D USE_SX1262
-D LORA_TX_POWER=22
-D ADVERT_NAME="Relay"
-D LORA_FREQ=868.731018
-D LORA_BW=62.5
-D LORA_SF=7
-D LORA_CR=7
[env:Xiao_nrf52_companion_radio_usb]
extends = Xiao_nrf52
build_src_filter = ${nrf52_base.build_src_filter}
+<examples/companion_radio/>
[env:Xiao_nrf52_companion_radio_ble]
extends = Xiao_nrf52
build_flags = ${Xiao_nrf52.build_flags}
-D BLE_PIN_CODE=123456
build_src_filter = ${nrf52_base.build_src_filter}
+<examples/companion_radio/>
Значения по умолчанию в [arduino_base] переопределяются в Xiao_nrf52.
7.3.1 Хэш пути 1 байт
В MyMesh.h перед классом MyMesh добавить:
#define ADVERT_NAME "Relay"
// хэш пути — 1 байт (mode 0)
В конструкторе MyMesh (в MyMesh.cpp) явно установить path_hash_mode:
_prefs.path_hash_mode = 0; // 0 = 1 байт, 1 = 2 байта, 2 = 3 байта
Либо в main.cpp можно задать через define и использовать в platformio.ini:
-D PATH_HASH_MODE=0
а в MyMesh.cpp:
#ifndef PATH_HASH_MODE
#define PATH_HASH_MODE 0
#endif
...
_prefs.path_hash_mode = PATH_HASH_MODE;
7.3.2 Итоговые параметры радио
| Параметр | Значение |
|---|---|
| Частота | 868.731018 МГц |
| Полоса (BW) | 62.5 кГц |
| Spreading Factor | 7 |
| Coding Rate | 7 |
| Хэш пути | 1 байт |
7.4 Как собрать и прошить
export FIRMWARE_VERSION=v1.0.0
# Собрать прошивку (USB Serial)
pio run -e Xiao_nrf52_companion_radio_usb
# Собрать прошивку (BLE)
pio run -e Xiao_nrf52_companion_radio_ble
# После сборки .uf2 файл будет здесь:
# .pio/build/Xiao_nrf52_companion_radio_usb/firmware.uf2
Способы прошивки nRF52840:
| Метод | Описание |
|---|---|
| UF2 (drag-and-drop) | Подключить плату в режиме UF2 (двойной тап по кнопке reset), скопировать .uf2 на появившийся диск |
| pio run -t upload | Через PlatformIO (nrfutil) |
| через J-Link | pio run -e Xiao_nrf52_companion_radio_usb -t upload --upload-port jlink |
| OTA по BLE | Через приложение Adafruit Bluefruit (если собран _ble вариант) |
7.5 Если HT-RA62 подключен к другой плате
Найдите в variants/ свою плату или создайте свою. Для HT-RA62 везде одинаковые настройки SX1262:
#define SX126X_DIO2_AS_RF_SWITCH 1
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define SX126X_CURRENT_LIMIT 140
#define SX126X_RX_BOOSTED_GAIN 1
Пины SPI (SCK, MOSI, MISO) общие с остальной периферией. NSS, DIO1, BUSY, RESET — назначаются индивидуально.
7.6 Альтернативные платформы с nRF52840
Если HT-RA62 уже впаян в готовую плату — проверьте variants/, возможно ваша плата уже там:
| Плата | Вариант | Пример env |
|---|---|---|
| RAK4631 WisBlock | rak4631 |
env:RAK_4631_companion_radio_ble |
| Nologo ProMicro nRF52840 | promicro |
env:ProMicro_repeater |
| Nano G2 Ultra | nano_g2_ultra |
env:Nano_G2_Ultra_companion_radio_ble |
| RAK3401 (1W) | rak3401 |
env:RAK_3401_repeater |
Список всех nRF52-вариантов — в variants/.
8. Структура проекта (кратко)
MeshCore/
├── src/ # ядро библиотеки
│ ├── Mesh.h / .cpp # роутинг, диспетчеризация payload-типов
│ ├── Packet.h / .cpp # формат пакета
│ ├── Dispatcher.h / .cpp # планировщик радио
│ └── helpers/
│ └── BaseChatMesh.h/.cpp # чат-абстракция (родительский класс)
├── examples/
│ └── companion_radio/ # ТО, ЧТО МЫ МОДИФИЦИРУЕМ
│ ├── MyMesh.h / .cpp # основной класс
│ ├── main.cpp # точка входа
│ └── ...
└── platformio.ini # конфиг сборки
9. Как это работает (кратко)
- Узел-отправитель знает публичный ключ устройства с реле (контакт добавлен через advertise)
- Он отправляет
sendMessage(recipient, timestamp, 0, "on1234", ...) - Пакет шифруется AES128+HMAC, летит по mesh (flood routing)
- Устройство-исполнитель получает, расшифровывает,
BaseChatMeshвызываетonMessageRecv() - Мы проверяем текст, управляем реле/читаем температуру и шлём ответ
- Ответ тоже шифрованный, идёт по обратному пути