Данное руководство описывает подключение модуля реле к ПК через адаптер USB-RS485 и работу с ним через программу-терминал (например, SSCOM, Hercules, PuTTY).
Формат команд для ручного режима (Manual mode). Вводите эти команды в поле отправки и нажимайте «Отправить».
| Действие | Отправить (HEX) | Ожидаемый ответ (HEX) |
|---|---|---|
| Включить реле 1 | FF 05 00 00 FF 00 99 E4 |
FF 05 00 00 FF 00 99 E4 |
| Выключить реле 1 | FF 05 00 00 00 00 D8 14 |
FF 05 00 00 00 00 D8 14 |
| Включить реле 2 | FF 05 00 01 FF 00 C8 24 |
FF 05 00 01 FF 00 C8 24 |
| Выключить реле 2 | FF 05 00 01 00 00 89 D4 |
FF 05 00 01 00 00 89 D4 |
| Включить все реле | FF 0F 00 00 00 08 01 FF 30 1D |
FF 0F 00 00 00 08 01 FF 30 1D |
| Выключить все реле | FF 0F 00 00 00 08 01 00 70 5D |
FF 0F 00 00 00 08 01 00 70 5D |
Примечание: при управлении через функцию 0x05 и 0x0F модуль возвращает точно такой же набор байт (эхо-ответ).
Модуль поддерживает чтение текущего состояния, адреса и настроек. Команды также отправляются в HEX-режиме.
| Действие | Отправить (HEX) | Пример ответа (HEX) | Расшифровка ответа |
|---|---|---|---|
| Чтение адреса устройства | 00 03 00 00 00 01 85 DB |
00 03 02 00 FF C5 C4 |
5-й байт (FF) в ответе — это текущий адрес устройства. |
| Чтение состояния реле | FF 01 00 00 00 08 28 12 |
FF 01 01 01 A1 A0 |
4-й байт (01) содержит состояние реле. Бит 0 отвечает за реле 1, бит 7 — за реле 8. 0 = реле замкнуто (включено), 1 = реле разомкнуто (выключено). |
| Чтение состояния входов оптопары | FF 02 00 00 00 08 6C 12 |
FF 02 01 01 51 A0 |
4-й байт (01) показывает состояние входов IN1-IN8. 0 = низкий уровень (low), 1 = высокий уровень (high). |
| Чтение скорости передачи (Baud rate) | FF 03 03 E8 00 01 11 A4 |
FF 03 02 00 04 90 53 |
5-й байт в ответе указывает на текущую скорость. 0x02 = 4800, 0x03 = 9600, 0x04 = 19200. |
0x01 (двоичное 0000 0001), это означает, что реле 1 разомкнуто, а остальные (если есть) замкнуты.
0x05).
Импульсный режим позволяет включить реле на заданное время, после чего оно автоматически
вернётся в исходное состояние. Время задаётся в 10-м и 11-м байтах команды
(с дискретностью 0.1 секунды). Внутри модуля импульс хранится в регистре с адресом
0x0003 (два регистра: действие и время).
| Байт | Значение | Описание |
|---|---|---|
| 1 | FF | Адрес модуля (по умолчанию 0xFF = 255) |
| 2 | 10 | Код функции: запись нескольких регистров |
| 3-4 | 00 03 | Адрес первого регистра (для реле 1 — всегда 0x0003) |
| 5-6 | 00 02 | Количество регистров = 2 |
| 7 | 04 | Количество байт данных = 4 |
| 8-9 | 00 04 (вкл) / 00 02 (выкл) | Действие |
| 10-11 | 00 XX | Время импульса: XX = секунды × 10 |
| 12-13 | CRC_L CRC_H | CRC-16/MODBUS, младший байт первый |
Пример 1. Включить реле 1 на 1.0 секунду.
Расчёт времени: 0x000A = 10; 10 × 0.1 = 1.0 сек.
Через 1 секунду после включения реле автоматически вернётся в исходное состояние.
Пример 2. Включить реле 1 на 2.0 секунды.
Расчёт времени: 0x0014 = 20; 20 × 0.1 = 2.0 сек.
Пример 3. Выключить реле 1 на 3.0 секунды (затем автоматически включится).
Расчёт времени: 0x001E = 30; 30 × 0.1 = 3.0 сек.
0x10 модуль отвечает не эхом команды, а стандартным
8-байтовым ответом Modbus RTU:
FF 10 00 03 00 02 A4 16
Это те же самые первые 6 байт команды (адрес, функция, адрес регистра, количество регистров),
к которым добавлены 2 байта CRC. Все байты данных (значение действия и время) в ответе
не передаются. Это нормальное поведение — не путайте его с ошибкой.
| Байт | Значение | Описание |
|---|---|---|
| 1 | FF | Адрес модуля |
| 2 | 10 | Код функции (эхо) |
| 3-4 | 00 03 | Адрес первого регистра (эхо) |
| 5-6 | 00 02 | Количество регистров (эхо) |
| 7-8 | A4 16 | CRC-16/MODBUS |
Если вы пишете свою программу, ожидаемый ответ можно сформировать так:
def expected_write_multiple_response(address: int, start: int, count: int) -> bytes:
"""Стандартный ответ Modbus RTU на функцию 0x10 (8 байт)."""
data = bytes([
address, 0x10,
(start >> 8) & 0xFF, start & 0xFF,
(count >> 8) & 0xFF, count & 0xFF,
])
return data + crc16_modbus(data)
# Для включения реле 1 на 1 секунду с адресом FF:
print(expected_write_multiple_response(0xFF, 0x0003, 2).hex(' ').upper())
# Выведет: FF 10 00 03 00 02 A4 16
Если вы хотите изменить адрес модуля, используйте команду на базе функции 0x10:
00 10 00 00 00 01 02 00 01 6A 0001, а не FF.
Как и у импульсной команды, ответ на смену адреса — стандартные 8 байт:
То есть в ответе вы увидите: адрес, 0x10, 00 00
(начальный регистр), 00 01 (количество регистров) и 2 байта CRC.
0x10 всегда отвечает 8 байтами, а не эхом.0x05.Расчёт CRC (Cyclic Redundancy Check) в протоколе Modbus RTU — это стандартная процедура. Разберём её на примере команды включения 1-го реле.
Команда, которую мы отправляем:
FF 05 00 00 FF 00 99 E4
FF — Адрес устройства (255)05 — Код функции (Запись одного дискретного выхода)00 00 — Адрес регистра (Реле 1)FF 00 — Значение (0xFF00 означает «Включить»)99 E4 — Это и есть CRCFF 05 00 00 FF 00. Последние два байта (99 E4) — это результат, который мы должны получить.
В Modbus используется алгоритм CRC-16 с полиномом 0xA001 и начальным значением 0xFFFF.
Пошаговый процесс (упрощённо):
0xFFFF.0xA001.0xE499, мы отправляем 99 E4.Вот готовая функция, которая рассчитывает CRC для Modbus RTU:
def crc16_modbus(data: bytes) -> bytes:
crc = 0xFFFF
for byte in data:
crc ^= byte
for _ in range(8):
if crc & 0x0001:
crc = (crc >> 1) ^ 0xA001
else:
crc >>= 1
# Возвращаем младший байт, затем старший
return bytes([crc & 0xFF, (crc >> 8) & 0xFF])
# Наши данные (без CRC)
command = bytes.fromhex('FF 05 00 00 FF 00')
crc = crc16_modbus(command)
print(f"CRC: {crc.hex().upper()}") # Выведет: 99E4
В документации к модулю указана ссылка на калькулятор: http://www.ip33.com/crc.html.
Как им пользоваться:
FF 05 00 00 FF 00.0xA001, init 0xFFFF).E499 или 99E4. В протоколе Modbus правильным считается порядок Low Byte First (младший байт вперёд), поэтому в команду мы пишем 99 E4.99 E4?