Модем uWave имеет габариты 41 на 45 мм и массу 0,16 кг, а с управляющей системой общается по обычному UART. Поэтому подключить его к Arduino и другим микроконтроллерам несложно: нужны четыре-пять проводов и библиотека, которая разбирает текстовый протокол модема. В статье разберём, что для этого понадобится, как соединить модем с платой, как получить библиотеку uWAVE_ALib и какие задачи она решает.
Что понадобится
- Модем uWave или uWave Max. Модемы семейства uWave используют один и тот же интерфейс сопряжения: UART 9600 бит/с и протокол NMEA 0183 PUWV. Другие устройства для передачи данных — в категории «Передача данных».
- Плата, совместимая с Arduino Uno или Nano: именно такая плата указана в списке оборудования примеров библиотеки.
- Питание модема 5–12 В.
- Второй модем, если нужно запрашивать данные у удалённого абонента или передавать пакеты.
Как модем общается с контроллером
Физический интерфейс — UART с напряжением линий данных 3,3 В. Настройки по умолчанию: 9600 бит/с, 8 бит данных, 1 стоп-бит, без контроля чётности и аппаратного управления потоком. Обмен идёт текстовыми предложениями NMEA 0183 вида $PUWV0,1,0*hh с контрольной суммой. Без повторителей и преобразователей интерфейса корректная работа гарантируется на кабеле не длиннее 2 м.
У модема два режима, и разница между ними важна:
- Прозрачный канал доступен сразу после включения: всё, что вы записали в UART, без анализа уходит в гидроакустический канал и в неизменном виде выдаётся принимающим модемом. Достаточно подключить модем к последовательному порту.
- Командный режим: модем разбирает входные данные как команды. Он нужен для настройки, кодовых запросов удалённым модемам (глубина, температура, напряжение питания) с измерением времени распространения сигнала и для пакетного режима с гарантированной доставкой. Включается уровнем на жиле Service/CMD; в примерах библиотеки эту жилу ведёт вывод Arduino.
Две оговорки из документации. Жилу Service/CMD можно подтягивать только к уровню 3–5 В или к земле: более высокое напряжение приведёт к неустранимой негарантийной поломке. А перед включением питания эта жила должна быть притянута к земле, иначе модем войдёт в режим обновления программного обеспечения.
Схема подключения
У кабеля uWave две версии, отличающиеся цветами жил: свою версию определите по схеме подключения в документации. Функции жил одинаковы. Вот как их соединяют с платой Arduino Nano в примерах библиотеки:
| Функция | Кабель версии 1 | Кабель версии 2 | Вывод Arduino Nano |
|---|---|---|---|
| Питание +5…+12 В | зелёная | красная | VIN |
| UART Tx модема | чёрная | зелёная | D2 |
| UART Rx модема | белая или прозрачная | белая или прозрачная | D3 |
| Service / CMD | коричневая | жёлтая | D4 |
| GND | экран | экран | GND |
Tx модема идёт на приёмный вывод программного порта (D2), Rx модема — на передающий (D3). Связь с модемом ведётся через SoftwareSerial, а аппаратный Serial остаётся для монитора порта. У uWave Max интерфейс сопряжения такой же (UART 9600 бит/с, NMEA 0183 PUWV, питание 5–12 В), но цвета жил для своей модели сверьте с документацией.
Про питание и уровни. В примерах Arduino и модем питаются от USB-порта компьютера. Учтите, что в режиме передачи uWave потребляет 6 Вт (uWave Max — 15 Вт) против 0,33 Вт на приёме, а максимальная выходная мощность у uWave Max достигается только при напряжении 12 В. Кроме того, линии данных модема работают на уровне 3,3 В, а плата Nano — на 5 В. В примерах согласование уровней не описано, поэтому для постоянной установки предусмотрите его сами: плата на 3,3 В или преобразователь уровней.
Установка библиотеки
Библиотека uWAVE_ALib имеет открытый исходный код, лицензия GPL-3.0. Исходный код лежит на GitHub, есть зеркало на GitVerse. В репозитории нет релизов и файла library.properties, а в индексе менеджера библиотек Arduino IDE её нет, поэтому установка ручная:
- Скачайте репозиторий (Code → Download ZIP) или клонируйте его.
- Создайте новый скетч и скопируйте в его папку два файла из каталога
src:uWAVE_ALib.hиuWAVE_ALib.cpp. - Подключите в скетче
SoftwareSerial.hи"uWAVE_ALib.h".
В каталоге examples лежат два готовых скетча. Перед запуском кода полезно убедиться, что модем отвечает: подключите его к компьютеру через преобразователь UART-USB, включите командный режим и отправьте запрос информации об устройстве $PUWV?,0*27, добавив в конец символы CR LF. Этот пример приведён в спецификации протокола.
Пример: запрос к удалённому модему
Первый пример из репозитория («всё в одном») показывает почти все приёмы работы с модемом и выводит запросы и результаты в монитор порта. Ниже фрагмент, сокращённый и упрощённый по мотивам этого примера: убраны комментарии, начальная настройка и разбор остальных событий. Источник: examples/uWAVE_ALib_example_1.ino, github.com/ucnl/uWAVE_ALib, лицензия GPL-3.0.
#include <SoftwareSerial.h>
#include "uWAVE_ALib.h"
#define SPEED_OF_SOUND (1500)
#define REMOTE_MODEM_TX_ID (0)
#define REMOTE_MODEM_RX_ID (0)
#define REMOTE_REQUEST_PERIOD_MS (5000)
#define uWAVE_RX_PIN (3)
#define uWAVE_TX_PIN (2)
#define uWAVE_CMD_PIN (4)
long rem_req_ts = 0;
SoftwareSerial uWavePort(uWAVE_TX_PIN, uWAVE_RX_PIN);
uWAVE uWrapper(&uWavePort, uWAVE_CMD_PIN);
uWAVE_EVENT_Enum result;
void setup()
{
uWavePort.begin(9600);
Serial.begin(9600);
uWrapper.enable();
}
void loop()
{
result = uWrapper.process();
if (result != uWAVE_NONE)
{
if (result & uWAVE_REMOTE_RESPONSE_RECEIVED)
{
Serial.print(F("propagation time, s="));
Serial.println(uWrapper.getRem_propTime_s());
Serial.print(F("Slant range, m="));
Serial.println(uWrapper.getRem_propTime_s() * SPEED_OF_SOUND);
Serial.print(F("value="));
Serial.println(uWrapper.getRem_value());
}
}
else if (!uWrapper.isWaitingLocal() && !uWrapper.isWaitingRemote() &&
(millis() - rem_req_ts >= REMOTE_REQUEST_PERIOD_MS))
{
if (uWrapper.queryRemoteModem(REMOTE_MODEM_TX_ID, REMOTE_MODEM_RX_ID, RC_DPT_GET))
rem_req_ts = millis();
}
}
Как это работает:
enable()поднимает уровень на жиле CMD, то есть включает командный режим.process()нужно вызывать как можно чаще. Функция читает данные из порта и возвращает набор флагов событий: подтверждение команды, ответ удалённого модема, тайм-аут, доставка пакета и другие.queryRemoteModem()отправляет кодовый запрос удалённому модему, а не возвращает данные сразу. Ответ придёт событиемuWAVE_REMOTE_RESPONSE_RECEIVEDсо временем распространения сигнала и запрошенным значением. ДляRC_DPT_GETэто глубина удалённого модема. Одновременно выполняется один запрос: поэтому в условии проверяютсяisWaitingLocal()иisWaitingRemote().- Наклонная дальность — время распространения, умноженное на скорость звука. Пример берёт 1500 м/с. Разрешение по времени 0,0001 с даёт при такой скорости 0,15 м по дальности, но реальная скорость звука зависит от температуры, солёности и глубины. Для расчёта скорости звука есть онлайн-калькулятор: там же собраны и другие утилиты, например калькулятор контрольной суммы NMEA 0183, удобный при ручной отладке.
Типовые задачи
Телеметрия и дальность. Запросы RC_DPT_GET, RC_TMP_GET, RC_BAT_V_GET возвращают глубину, температуру и напряжение питания удалённого модема, а по времени ответа считается расстояние до него. Свои показатели модем с датчиком давления и температуры выдаёт после настройки функцией queryForAmbientDataConfig(): глубина, давление, температура воды и напряжение питания, однократно или с периодом от 0,5 до 60 с.
Удалённое управление. У модема девять пользовательских кодовых команд, RC_USR_CMD_000 … RC_USR_CMD_008. Второй пример из репозитория связывает их с девятью выводами Arduino (D5–D13): при получении команды на соответствующем выводе на 500 мс появляется высокий уровень. К выводам можно подключить светодиоды через резистор 200–300 Ом или реле. Так можно управлять автономным подводным устройством без кабеля.
Пакетная передача данных. В пакетном режиме модем передаёт до 64 байт с гарантированной доставкой (ALO, at-least-once) и уведомлением о получении. Адресация — от 0 до 254, адрес 255 используется для широковещательных сообщений без подтверждения. В библиотеке отправку выполняет queryForPktSend(), а исход приходит событиями uWAVE_PKT_DELIVERED с числом попыток, uWAVE_PKT_SEND_FAILED и uWAVE_PKT_RECEIVED с адресом отправителя. Для работы в этом режиме модемы переводят в командный режим, подробности — в спецификации протокола.
Прозрачный канал. Если нужно просто передавать байты, библиотека не нужна: данные, записанные в UART, уходят в гидроакустический канал как есть. Так можно связать два микроконтроллера.
Ссылки
- Документация: спецификация протокола, схема подключения uWave, спецификация uWave Max.
- Библиотека uWAVE_ALib: GitHub, GitVerse. Старые примеры для Arduino: uWAVE_Arduino.
- Образовательные проекты и онлайн-утилиты UC&NL: diy.unavlab.com.
Нужна помощь с интеграцией модема в ваше устройство? Напишите нам.







