Перейти к содержимому

XY-MD02 или SHT20 over RS485 Modbus

Добрый день, уважаемый читатель! Предлагаю вашему вниманию мини-обзорчик датчика температуры и влажности XY-MD02, полученный мною на днях из поднебесной, который я заказал для одного из своих проектов.

Это один из двух датчиков RS485, которые я получил, есть ещё один с SHT30, поинтереснее, но о нем будет другая статья.

 

Итак, что это за чудо такое? Эта коробочка представляет собой сенсор температуры и влажности SHT20, упакованный в пластиковый корпус на DIN-рейку и снабженный интерфейсом RS-485 с просто огромной дальностью связи (до 1000 м). Это позволяет использовать его там, где нельзя использовать шину I2C из-за больших расстояний. Однако вместе с этим мы теряем и некоторый функционал, который присутствует в обычном сенсоре.

Приобрести сиё чудо китайской электроники можно на ali по ссылке: https://aliexpress.com/item/1005001475675808.html. Стоит такой вариант существенно дороже обычного варианта, но иногда оно того стоит.

Характеристики

Продавец обещает следующие характеристики:

  • Источник питания: 5-30В постоянного тока
  • Потребляемая мощность : ≤0,2 Вт
  • Точность температуры: ± 0,5 ℃ (25 ℃)
  • Точность влажности: ±3,0 %RH (max ±5,0 %RH)
  • Рабочий диапазон влажности: 0%~80% RH
  • Температурное разрешение: 0,1 ℃
  • Разрешение влажности: 0,1% RH
  • Интерфейс: RS485, протокол Modbus-RTU
  • Адрес на шине: по умолчанию 1, можно установить 1-247
  • Скорость передачи данных: настраиваемая (по умолчанию 9600): 8-бит, 1 стоп бит, без контроля четности

Как можно заметить, разрешение (шаг) изменения занижено по сравнению с обычным ( I2C ) интерфейсом, но это проблема интерфейса, а не самого датчика.

SHT20 – это младшая модель в серии датчиков SHT2x от Sensirion. Серия SHT2x состоит из недорогой версии с датчиком влажности SHT20, стандартной версии с датчиком влажности SHT21 и высококачественной версии с датчиком влажности SHT25. Говоря простыми словами – SHT25 это выбранные на производстве сенсоры с наилучшими характеристиками, SHT21 – это то, что вписывается в допустимые стандарты, а SHT20 – третий сорт не брак.

Серия датчиков влажности SHT2x содержит датчик влажности емкостного типа и датчик температуры с запрещенной зоной. Нормальный рабочий диапазон сенсора влажности: 0–80% относительной влажности, за пределами этого предела датчик может иметь обратимое смещение с медленной кинетикой (<3% относительной влажности через 200 часов при 90% относительной влажности). Погрешность изменений представлена на рисунках ниже:

 

Установка и подключение

Как я уже написал, корпус датчика подходит для установки на DIN-рейку. Но вместе с этим имеются два монтажных отверстия, с помощью которых сенсор может быть закреплен на любой поверхности. Устанавливать его лучше разъемом вверх, так его показания будут точнее. Почему – станет понятно из следующего раздела.

Корпус имеет разъем с винтовыми зажимами (это именно разъем, а не просто винтовые зажимы), поэтому временно отключить датчик можно и без применения отвертки, что несомненно, удобно.

Подключение стандартное для интерфейса RS485:

Сенсор прекрасно работает от 5В, что как раз и является оптимальным вариантом – так будет меньше греться внутренний стабилизатор, а значит будет меньше паразитный нагрев самого датчика. При большем напряжении питания может наблюдаться завышение показаний температуры и занижение данных влажности.

Внутреннее устройство

Датчик довольно легко разбирается, достаточно сжать нижнюю часть корпуса сбоку и ларчик откроется.

Как видите, чип сенсора здесь распаян на основной плате, поэтому тепло, выделяемое стабилизатором и микросхемами интерфейса может его нагревать. Поэтому располагать его лучше разъемом вверх – так хотя бы стабилизатор будет находится над сенсором и поток нагретого воздуха не будет сильно влиять на его показания. Впрочем – это все равно его не спасает, но об этом чуть ниже.

Сенсор прекрасно работает от 5В, что для него как раз и является оптимальным вариантом – так будет меньше греться внутренний стабилизатор, а значит будет меньше паразитный нагрев самого датчика. При большем напряжении питания может наблюдаться завышение показаний температуры и занижение данных влажности.

Радует, что интерфейс RS485 здесь распаян полностью, вместе с этим датчиком я получил еще один, так там китайцы сэкономили и запаяли половину интерфейса перемычками (нет никакой схемы защиты).

Регистры Modbus RTU

Сенсор имеет два INPUT регистра для чтения данных о температуре и влажности воздуха, и четыре HOLDING регистра для изменения его параметров (адрес, скорость передачи и данные коррекции):

То есть можно прочитать данные с сенсора с точностью до одного знака после запятой и … по сути это всё. Нельзя выполнить программный сброс сенсора, нельзя включить / отключить встроенный нагреватель, нельзя изменить режим работы сенсора. Есть ещё пара настроек (их действительно только две – скорость и адрес, подробнее см. ниже).

Для начала я попробовал подключить его к компьютеру через преобразователь интерфейса RS485 <-> USB и попробовал получить с него данные его через программу Modbus Poll. Сенсор без каких-либо проблем отозвался и начал исправно передавать данные:

Как видите, данные приходят в виде целого 16-битного числа. Чтобы получить реальное ( float ) значение, нужно просто поделить их на 10. На картинке выше температура 27,6 ℃, влажность 43,3%.

Температура в комнате при этом составляла ~ 25,7℃, влажность около 47% (по данным двух других гигрометров). То есть этот сенсор завышает показания температуры и занижает показания влажности. Причем такое поведение наблюдается не только у меня, но и у других покупателей, судя по отзывам в интернете. Причем величина ошибки не линейная и простой коррекцией, как пишут, не обойдешься. На обычном I2C сенсоре SHT20 такого не происходит. Почему такое может быть?

Во-первых, может сказываться паразитный нагрев от других деталей на общей плате, о чем я уже писал выше. Но 1,9 градуса вроде бы слишком много для этого.

Во вторых – нагревательный элемент внутри сенсора, который как раз повышает данные с сенсора температуры на несколько градусов. Если обратиться с datasheet-у на SHT20, то там можно прочитать примерно следующее (вольный перевод):

SHT20 оснащен внутренним нагревателем, который предназначен для проверки достоверности сенсора температуры и самопросушки сенсора влажности. Увеличение температуры, достигаемое нагревателем, зависит от различных параметров и лежит в диапазоне нескольких градусов по Цельсию. Его можно включать и выключать по команде.

Есть у меня сильное подозрение, что на данном сенсоре включен внутренний нагревательный элемент. Доказать я, конечно, не могу, но сильно подозреваю, что китайцы при создании данного устройства задействовали этот самый нагреватель. Зачем? Остается только гадать… Либо просто из-за ошибки или чтобы предотвратить выход из строя измеритель влажности в условиях повышенной влажности. Как отключить? Да никак! Может быть и есть незадокументированный регистр для управления нагревателем, но мне об этом не известно.

Постойте, у нас же есть регистры коррекции:

Сенсор имеет 4 регистра настроек:

  1. Адрес сенсора на шине (0x0101)
  2. Скорость данных (0x0102)
  3. Коррекция температуры в целом виде без знака (умноженное на 10)
  4. Коррекция влажности в целом виде без знака (умноженное на 10)

Попробуем воспользоваться:

И… ничего… совсем… ничего! Значения в регистрах изменились, но на выходные значения это никак не повлияло. Зачем они тогда вообще нужны? Непонятно.

Подключение к ESP32 или Arduino

Для подключения к микроконтроллеру потребуется вот такая недорогая платка преобразователя интерфеса:

К ESP32 я подключал её к 16 и 17 GPIO, но это не принципиально:

ESP-IDF имеет в своем составе все необходимые библиотеки для работы с RS485 и modbus, поэтому получение данных с сенсора выполняется ну очень просто:

  • добавляем необходимые библиотеки в проект: #include “mbcontroller.h”
  • инициализируем modbus и rs485
#define SENSOR_MODBUS_PORT 1
#define SENSOR_MODBUS_SPEED 9600
#define SENSOR_MODBUS_PIN_RXD 16
#define SENSOR_MODBUS_PIN_TXD 17
#define SENSOR_MODBUS_PIN_RTS -1
#define SENSOR_MODBUS_PIN_CTS -1

static void sensorsInitModbus()
{
  rlog_i(logTAG, "Modbus initialization");
  // Инициализация RS485 и Modbus
  RE_OK_CHECK(mbc_master_init(MB_PORT_SERIAL_MASTER, &_modbus), return);
  // Configure Modbus
  mb_communication_info_t comm;
  memset(&comm, 0, sizeof(comm));
  comm.mode = MB_MODE_RTU;
  comm.port = SENSOR_MODBUS_PORT;
  comm.baudrate = SENSOR_MODBUS_SPEED;
  comm.parity = UART_PARITY_DISABLE;
  RE_OK_CHECK(mbc_master_setup((void*)&comm), return);
  // Set UART pins
  RE_OK_CHECK(uart_set_pin(SENSOR_MODBUS_PORT, SENSOR_MODBUS_PIN_TXD, SENSOR_MODBUS_PIN_RXD, SENSOR_MODBUS_PIN_RTS, SENSOR_MODBUS_PIN_CTS), return);
  // Start Modbus
  RE_OK_CHECK(mbc_master_start(), return);
  // Set UART mode
  RE_OK_CHECK(uart_set_mode(SENSOR_MODBUS_PORT, UART_MODE_RS485_HALF_DUPLEX), return);
}

где

// Usage: RE_OK_CHECK(esp_create_timer(...), return false);
#define RE_OK_CHECK(a, action) do { \
  esp_err_t __err = (a); \
  if (__err != ESP_OK) { \
  ESP_LOGE(logTAG, "\"%s\"::%d failed with code %d (%s)", __FUNCTION__, __LINE__, __err, esp_err_to_name(__err)); \
  action; \
}; \
} while (0);
  • когда всё готово – читаем нужные регистры и делим полученное значение на 10
/**
* Read humidity and temperature data
* */
sensor_status_t xyMD02::readRawData()
{
  uint16_t value[2];

  mb_param_request_t _request = {
    .slave_addr = _address,
    .command = 4, // MB_FUNC_READ_INPUT_REGISTER,
    .reg_start = 0x0001,
    .reg_size = 2
  };
  esp_err_t err = mbc_master_send_request(&_request, &value[0]);

  if (err != ESP_OK) {
    rlog_e(logTAG, RSENSOR_LOG_MSG_READ_DATA_FAILED, _name, err, esp_err_to_name(err));
    return convertEspError(err);
  };

  // Store values in sensors
  return setRawValues((float)value[1]/10.0, (float)value[0]/10.0);
};

Как видите, для получения данных достаточно всего одной команды: mbc_master_send_request().

Скачать готовый драйвер для данного сенсора можно с моего GitHub: https://github.com/kotyara12/reSensors/tree/master/reMD02

 

👉 Каталог статей канала – здесь есть ещё много интересного

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *