Датчики RS-485 Modbus в Алисе через ESP32 и ESPHome
Оборудование и приложения
ESP32 читает датчики RS-485 Modbus RTU через трансивер RS-485 и компоненты ESPHome uart, modbus и modbus_controller. Значения появляются в Home Assistant как обычные сенсоры, и интеграция Yandex Smart Home передаёт их в «Дом с Алисой». Без карты регистров конкретного датчика ничего не заработает: RS-485 описывает только провода и уровни, а какие числа лежат в каких регистрах, знает лишь производитель. Ниже — полный путь на примере датчика DFRobot SEN0438, у которого карта регистров опубликована.
Что нужно узнать о датчике
Перед покупкой или подключением найдите в инструкции:
- Адрес устройства на шине и как его менять.
- Скорость и формат кадра (бит данных, чётность, стоп-биты).
- Функцию чтения: 0x03 (holding registers) или 0x04 (input registers).
- Адреса регистров, тип значения (со знаком или без, 16 или 32 бита) и масштаб.
- Питание датчика.
Для SEN0438 всё это есть в инструкции производителя:
| Параметр | Значение |
|---|---|
| Питание | 12–36 В постоянного тока |
| Провода | жёлтый — A+, красный — V+, чёрный — GND, белый — B− |
| Скорость | 9600 бод (по умолчанию) |
| Функции | 0x03 — чтение, 0x10 — запись нескольких регистров |
| Регистр 0x0000 | Влажность × 10 |
| Регистр 0x0001 | Температура × 10, со знаком |
| Адрес | задаётся 8-позиционным DIP-переключателем внутри корпуса |
Пример из той же инструкции: ответ 01 03 04 01 D7 00 D6 … означает влажность 0x01D7 = 471 → 47,1 % и температуру 0x00D6 = 214 → 21,4 °C.
Нумерация регистров
По спецификации Modbus регистры в запросе адресуются с нуля: регистры с номерами 1–16 имеют адреса 0–15 (Modbus Application Protocol, IETF draft). У SEN0438 в таблице сразу указаны адреса (0x0000, 0x0001), их можно переносить в ESPHome как есть. Если другой производитель нумерует регистры с единицы, вычтите единицу.
Трансивер и подключение
ESP32 нельзя соединять с линиями A/B напрямую: нужен трансивер, который превращает UART в дифференциальный сигнал RS-485.
| Трансивер | Питание | Совместимость с ESP32 |
|---|---|---|
| MAX485 | 4,75–5,25 В (даташит) | Нужно согласование уровней: трансивер работает от 5 В, а входы ESP32 допускают не выше VDD + 0,3 В (даташит ESP32) |
| MAX3485 | 3,0–3,6 В (даташит) | Питается от той же линии 3,3 В, уровни совпадают |
У обоих трансиверов полудуплексная схема с выводами DE (включение передатчика, активный высокий уровень) и RE (включение приёмника, активный низкий уровень). Их обычно соединяют вместе и подключают к одному GPIO, который ESPHome переключает при передаче. В документации ESPHome это вывод flow_control_pin. На ESP32 его лучше задавать в компоненте uart (аппаратный полудуплекс), а не в modbus (Modbus, UART). Документация ESPHome называет MAX485 примером трансивера без автоматического переключения направления. Модулям с автоматическим переключением flow_control_pin не нужен.
Схема:
- ESP32 TX → DI трансивера, RX ← RO, GPIO управления → DE+RE, 3V3 и GND → питание трансивера.
- A трансивера → A+ датчика (жёлтый), B → B− (белый).
- Датчик питается от своего блока 12–36 В по схеме из инструкции.
- На концах шины ставятся согласующие резисторы 120 Ом по стандарту Modbus. На некоторых трансиверах они уже распаяны, на некоторых устройствах включаются перемычкой или DIP-переключателем (документация ESPHome Modbus).
Конфигурация ESPHome
Добавьте к базовой конфигурации из ESPHome Device Builder (GPIO замените на свои):
uart:
id: rs485
tx_pin: GPIO17
rx_pin: GPIO16
baud_rate: 9600
flow_control_pin: GPIO4
modbus:
id: modbus1
uart_id: rs485
modbus_controller:
- id: sen0438
modbus_id: modbus1
address: 1
update_interval: 30s
sensor:
- platform: modbus_controller
modbus_controller_id: sen0438
name: "Подвал влажность"
register_type: holding
address: 0x0000
value_type: S_WORD
unit_of_measurement: "%"
device_class: humidity
accuracy_decimals: 1
filters:
- multiply: 0.1
- platform: modbus_controller
modbus_controller_id: sen0438
name: "Подвал температура"
register_type: holding
address: 0x0001
value_type: S_WORD
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
filters:
- multiply: 0.1
Почему так (Modbus Controller, Modbus Controller Sensor):
register_type: holdingсоответствует функции 0x03, которую поддерживает датчик. Для функции 0x04 был быinput(синонимread).S_WORD— 16 бит со знаком. Температура SEN0438 может быть отрицательной, поэтому беззнаковыйU_WORDпо умолчанию здесь не подходит.multiply: 0.1переводит «значение × 10» из инструкции в реальные единицы.- Два соседних регистра одного типа ESPHome сам объединяет в один запрос.
- Чётность и стоп-биты в инструкции SEN0438 не указаны. У компонента
uartпо умолчаниюparity: NONEиstop_bits: 1. Если датчик не отвечает, проверьте эти параметры по инструкции своего прибора. device_classиunit_of_measurementзаданы явно: по ним Home Assistant и интеграция Яндекса распознают тип сенсора.
Если не работает
Включите журнал обмена в компоненте uart. С опцией debug ESPHome выводит отправленные и полученные байты в шестнадцатеричном виде (UART):
uart:
# ... параметры выше
debug:
direction: BOTH
| Что видно в журнале | Причина | Что сделать |
|---|---|---|
| Запросы уходят, ответов нет | Не тот адрес или скорость, перепутаны A/B, нет питания датчика | Сверить DIP-адрес, baud_rate, проводку |
| Ответ с кодом ошибки | Датчик отклонил запрос | У SEN0438 коды 0x81, 0x82 и 0x83 означают неподдерживаемую функцию, недопустимый адрес чтения и недопустимую запись |
| Значение в 10 раз больше ожидаемого | Нет масштаба | Добавить multiply: 0.1 |
| Отрицательная температура как 6000+ | Беззнаковый тип | value_type: S_WORD |
| Устройство «пропадает» | Таймауты подряд | После max_cmd_retries + 1 неответов подряд (по умолчанию 5) контроллер помечает устройство offline и пропускает его опрос. Проверка повторяется каждые offline_skip_updates + 1 интервала (по умолчанию на каждом) |
Если вы переносите старую конфигурацию, учтите изменения в актуальной документации ESPHome: custom_command заменён на custom_pdu (без байта адреса устройства), command_throttle больше не действует (вместо него turnaround_time у modbus), force_new_range заменён на reuse_previous_range.
Запись регистров
Начинайте только с чтения. У SEN0438 запись разрешена лишь в регистры 0x000C–0x001E (пороги тревог и поправки), остальные защищены. Перед любой записью в другой прибор сохраните исходное значение и убедитесь по инструкции, что регистр не меняет адрес или скорость обмена: после такой записи связь с устройством пропадёт.
Передача в «Дом с Алисой»
Интеграция Yandex Smart Home распознаёт сенсоры автоматически по device_class: температура (°C, °F, K), влажность (%), давление, CO2, мощность, напряжение, ток и другие из её списка поддерживаемых датчиков. Значения, для которых у Яндекса нет свойства, в Алису не попадут. Например, состояние тревоги датчика можно использовать только в автоматизациях HA.
Чтобы температура и влажность были одним устройством, а не двумя (документация):
yandex_smart_home:
entity_config:
sensor.podval_temperatura:
name: Подвал
properties:
- type: temperature
entity: sensor.podval_temperatura
- type: humidity
entity: sensor.podval_vlazhnost
entity_id подставьте свои. Для передачи выберите только sensor.podval_temperatura. Как подключить Home Assistant к Яндексу, описано в статье Home Assistant и Алиса.
Похожие задачи
Тот же стек uart + modbus использует счётчик энергии PZEM-004T V3, только вместо modbus_controller у него готовый компонент pzemac. Сборка разобрана в статье Счётчик энергии на ESP32 и PZEM-004T. Если Modbus-устройства уже подключены к серверу через USB-адаптер, а не к ESP32, посмотрите вариант с Node-RED.
Источники
- DFRobot SEN0438: инструкция RS485 Temperature & Humidity Sensor
- MODBUS Application Protocol (IETF draft)
- Analog Devices MAX1487–MAX491 (MAX485) Datasheet
- Analog Devices MAX3483–MAX3491 (MAX3485) Datasheet
- ESP32 Series Datasheet (Espressif)
- ESPHome: Modbus Component
- ESPHome: UART Bus
- ESPHome: Modbus Controller
- ESPHome: Modbus Controller Sensor
- Yandex Smart Home: поддерживаемые устройства
- Yandex Smart Home: цифровые датчики