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

Погружной датчик уровня жидкости QDY30А

Добрый день, уважаемые читатели! Сегодня я познакомлю вас с погружным датчиком уровня воды, который позволяет измерять уровень воды над ним в достаточно широком диапазоне глубин и с высокой точностью. Знакомьтесь: гидростатический погружной датчик уровня воды QDY30A, который может использоваться для измерения и мониторинга уровня различных жидкостей в различных резервуарах и скважинах.

Предупреждение! Это не рекламная статья в прямом смысле этого слова – я никак не связан с продавцом и производителем, и товар куплен на мои собственные средства. Ссылку на товар не привожу – они быстро устаревают, но датчик легко ищется по его маркировке – QDY30A. Цена на него довольно “кусачая”, но особых вариантов для измерения уровня жидкости и нет.

Изображение с сайта продавца

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

Где можно применить такой датчик в частном доме:

  • измерение уровня воды в скважине или колодце для защиты насоса от “сухого хода”
  • измерение уровня стоков в септике или накопительном канализационном колодце
  • измерение уровня воды в буферной емкости для полива растений и т.д.

На производстве, как заявляет производитель, подобные сенсоры можно применять для измерения уровня топлива и других жидких продуктов. В общем и целом сфера применения данного сенсора довольно широка – все зависит от вашей фантазии.

Сразу оговорюсь: стоимость данного датчика довольно высока ~30-60$ в зависимости от модификации (то есть примерно от ~3000 до ~6000 рублей на момент написания статьи). Возможно, кто-то посчитает такую сумму неприемлемой для себя – в таком случае вы можете собрать измеритель уровня на поплавковых герконовых датчиках, но точность измерения будет значительно хуже.

 


Варианты исполнения и основные характеристики

Производитель предлагает достаточно много вариантов исполнения датчиков, которые можно разделить на группы по типу выходного сигнала:

  • Токовый выход от 0 до 40mА – такой тип датчиков достаточно широко применяется в промышленности, можно использовать с аналоговым входом микроконтроллера
  • Аналоговый выход с напряжением от 0 до 5В, либо от 0 до 10В, либо от 1 до 5В – датчик с таким выходом вы можете подключить к любому аналоговому входу микроконтроллера (при необходимости примените делитель, чтобы “втиснуть” выходное напряжение датчика в допустимый диапазон микроконтроллера). А можно использовать в аналоговых схемах автоматики без применения микроконтроллеров.
  • Цифровой интерфейс Modbus RTU для шины RS485 – в этом случае данные от датчика поступают полностью в цифровом виде и дополнительная оцифровка не требуется.

Кроме того, датчики поставляются с различными диапазонами максимального уровня жидкости: от 1 до 5 метров (производятся и до 30 метров, но в продаже на ali я пока не встречал), а также с различной длиной соединительного кабеля – трубки. При заказе датчика следует внимательнее отнестись к этим характеристикам, особенно к длине кабеля-трубки – её выходной конец должен находится выше уровня жидкости и быть “открытым”, при этом даже укорачивать трубку не желательно. Точность изменения зависит от диапазона изменений, поэтому заказывать датчик с диапазоном 5 метров для измерения максимального уровня в 0,5 м не имеет смысла – цена будет выше, а точность получится ниже.

Характеристики, полученные из даташита на версию RS485:

Диапазон измерений 0 ~ 5 ~ 500 м H2O (опционально)
Мощность питания 9 ~ 32 VDC (реально работает уже от ~5 VDC)
Выходной сигнал 0 ~ 5В / 0 ~ 10В / 0 ~ 40мА / RS485 Modbus
Погрешность измерения ≤±0.5% FS – стандартная версия, ≤±0.2% FS – высокоточная версия
Время ответа для шины RS485 ≤10 мс (до 90% FS); ≤ 100 мс (выше 90% FS)
Долгосрочная стабильность показаний ±0.2% FS в год
Температура хранения -20 ~ 85 ℃
Рабочая температура -10°C~50°C
Защита от перегрузки 150% FS
Сопротивление изоляции 100MΩ / 250VDC
Температурный дрейф 0.3% FS (на градус ???? – прим. автора)
Дрейф нуля 0.3% FS
Защита IP68
Измерительная среда Различные жидкости, совместимые со сталью SS304
Механические вибрации 20 г (20 ~ 5000 Гц)

Примечание: у разных продавцов могут встречаться различные характеристики датчика. Толи они относятся к разному времени производства, то ли из-за разных модификации – не совсем понятно. В любом случае – я привел данные из datasheet-а, который получен от продавца.

Вполне можно приобрести не только датчик, но и готовое устройство с данным датчиком, которое может отображать уровень воды и управлять насосом, например такое:

 


Устройство и принцип работы

Принцип работы датчика довольно прост: сенсор давления внутри корпуса датчика измеряет гидростатическое давления столба воды над собой, а затем эти данные пересчитываются в сантиметры. В качестве чувствительного измерительного элемента используется кремниевый пьезорезистивный датчик давления, который отделен от воды резиновой мембраной.

Затем полученные данные о давлении пересчитываются в высоту столба воды, при этом используется следующая формула:

P = Pатм + pqh

где:

  • P – измеренное давление на датчик
  • Pатм – текущее атмосферное давление
  • p – плотность измеряемой жидкости
  • q – загадочный коэффициент
  • h – высота столба воды на чувствительным элементом

Здесь возникает сразу две проблемы:

На поверхность воды действует переменное атмосферное давление – каким образом одно измеряется? Эта проблема решена достаточно интересным способом – соединительный кабель на самом деле не совсем кабель, а трубка, закрытая пористой заглушкой-фильтром на открытом конце. Через эту трубку внутрь датчика “подается” атмосферное давление для его компенсации при измерениях. И именно поэтому не желательно укорачивать кабель-трубку – иначе вам придется колхозить новую заглушку-фильтр для трубки компенсации давления или переустанавливать старый.

Для корректного расчета необходимо так же знать плотность измеряемой жидкости. Судя по всему, “по умолчанию” датчики на али рассчитаны на плотность воды, но производитель наверняка может выпускать уровнеметры и под другие жидкости.

 


Установка датчика в емкости или скважине

Исходя из принципа работы, предполагается установка датчика на дне резервуара или колода, например так:

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

 


Фотографии

Приведу немного своих фотографий

Корпус самого датчика действительно скорее всего сделан из “нержавейки” – другой такой же датчик проработал почти все лето в металлическом баке с водой у теплицы, про него я уже писал здесь (но не так подробно) – так вот он за лето нисколько не “заржавел” и только немного покрылся налетом от воды.

Размеры моего экземпляра 28 мм * 113 мм (штангенциркуль не в лучшем состоянии, но зато еще батин, родом из СССР):

На корпусе маркировка с указанием модели, измеряемого диапазона глубин и типа выходного сигнала:

Шланг-кабель довольно плотный, диаметром 4 мм с толщиной стенок 0,2мм. Выходной конец трубки закупорен с помощью какого-то фильтра:

Со стороны корпуса датчика шланг довольно хорошо герметизирован и дополнительно закрыт резиновым чехлом:

Однако я видел на али отзывы, что рано или поздно датчики могут протекать. Так это или нет – время покажет, срок эксплуатации одного моего датчика пока слишком небольшой для того, чтобы делать выводы.

 


Подключение датчика к Arduino или ESP

Подключение уровнеметра к микроконтроллеру будет зависеть от того, какой тип датчика вы используете. 

Версия с токовым выходом

Для подключения такого типа датчика удобнее всего использовать специальный преобразователь токового сигнала в напряжение, а затем уже измерять напряжение с помощью любого АЦП:

Но можно соорудить схему измерения и на резисторах, в простейшем случае это может быть что-то подобное (возможно, потребуется подобрать резистор другого номинала):

Правда точность такой схемы будет вряд-ли высокой.

 

Версия с выходом по напряжению

Самый простой способ подключения к Arduino, но нужно учитывать, что обычно диапазон измеряемых напряжений на входах АЦП Arduino или ESP существенно меньше диапазона выходных напряжений датчика. Поэтому, вероятно, придется “втиснуть” выходное напряжение в необходимый диапазон с помощью подстроечного резистора.

Этот же вариант можно легко использовать в аналоговых схемах управления уровнем воды “на транзисторах”, без использования микроконтроллеров в принципе.

 

Версия с цифровым выходом 

Самый сложный в реализации вариант подключения, но и самый точный – ведь в этом случае мы получаем данные непосредственно в цифровом виде, без каких либо АЦП-преобразований и связанных с этим погрешностей. Но нам понадобится любой RS485 – TTL конвертор, например такой:

Собственно конвертор в этом случае подключается к любому свободному UART-порту на микроконтроллере. Я предпочитаю этот вариант, тем более что к одному конвертору (шине) можно подключить много самых разнообразных датчиков и устройств.

 

Питание

Производитель заявляет, что уровнеметр нормально работает при напряжении питания от 12 до 36 вольт включительно. Между тем, датчик вполне работоспособен уже с 5В, по крайней мере при включении через преобразователь интерфейса для компьютера USB – RS485 с напряжением 5В на выходе датчик “отзывается” и вполне нормально работает.

 


Протокол Modbus RTU

Для версии с выходом RS485 используется протокол связи MODBUS RTU. При этом шина RS485 работает в полудуплексном режиме.

Параметры последовательного порта:

  • Данные: 8 бит, без проверки, 1 стоповый бит
  • Скорость передачи: 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 бит/с
  • Полином для проверки CRC: 0xA001

Параметры по умолчанию: 9600, N,8,1 (9600 бит/с, без проверки, 8 бит)

Регистры

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

Функция Адрес Длина Допустимые значения Описание
Команда 0x03 – чтение данных
0x03 0x0000 2 1-255 Чтение адреса устройства на шине
0x03 0x0001 2 0 – 1200
1 – 2400
2 – 4800
3 – 9600
4 – 19200
5 – 38400
6 – 57600
7 – 115200
Скорость передачи данных по шине
0x03 0x0002 2 0 – не определено
1 – сантиметры
2 – миллиметры
3 – MPa
4 – Pa
5 – KPa
6 – MA
Единица измерения выходных данных
0x03 0x0003 2 0 – ####
1 – ###.#
2 – ##.##
3 – #.###
Формат выходных данных (позиция десятичной точки)
0x03 0x0004 2 -32768 – 32767 Выходное (измеренное) значение
0x03 0x0005 2 -32768 – 32767 Значение для минимального измеряемого значения (zero)
0x03 0x0006 2 -32768 – 32767 Значение для максимального измеряемого значения (full)
Команда 0x06 – запись данных
0x06 0x0000 2 1-255 Изменение адреса устройства на шине
0x06 0x0001 2 0 – 1200
1 – 2400
2 – 4800
3 – 9600
4 – 19200
5 – 38400
6 – 57600
7 – 115200
Скорость передачи данных по шине

Как видим, ни единицу измерения, ни размерность данных (положение десятичной точки) мы сами определять, увы, не можем. Перед измерением мы должны будем один раз прочитать содержимое регистров 0x0002 и 0x0003, дабы определиться с типом данных, а потом пересчитывать полученные значения из регистра 0x0004 в соответствии с ними. 

Не совсем понятно, зачем нужны отрицательные “выходные” значения, на мой взгляд можно было бы и беззнаковым целым вполне обойтись. Но производителю виднее.

 


Испытания

Для начала я подключил датчик к преобразователю RS485 – USB и подключил его к контуперу. Тестирование будем производить с использованием популярной в народе программы Modbus Poll. Как я уже и писал, датчик вполне адекватно заработал при напряжении питания 5В от USB-порта компьютера:

Как видим, в настоящий момент адрес датчика равен 1, скорость настроена как 3 (то есть это 9600 бит/с), выдает данные датчик в сантиметрах с одной точкой после запятой. На открытом воздухе он показывает уровень в 2~3 миллиметра, что вполне допустимо (допустимая ошибка – 0,2% от 300 см, то есть 6 мм). Точка нуля настроена на 0, точка максимума на 3 метра, что соответствует заявленным характеристикам.

У агрегата есть еще три загадочных регистра с адресами 0x0007-0x0009, в которых имеются какие-то данные – что это, для меня загадка. Если вы вдруг знаете, что это за регистры и для чего используются – милости просим в комментарии. Ну а все остальные адреса с 0x000A и выше выдают только неинтересные ноли.

Попробуем опустить датчик в воду.

Рулетка “показывает” 13.6 cм водного столба, датчик – 13.3 см. Погрешность измерения не превышает 3 мм, что на мой взгляд очень даже неплохо. 

 

Как показала летняя практика в бочке с водой – эта погрешность более-менее сохраняется почти во всем диапазоне измерений. Но в проекте с теплицей такая точность  была даже избыточна, да и в большинстве “бытовых” задач – тоже. Удобство применения здесь играет гораздо более важное значение, чем точность.

 


Изменение параметров датчика

Как я написал в таблице выше, изменять мы можем только параметры порта: адрес на шине и скорость передачи данных. Сделать это можно с помощью команды 0x06 Write Single Register. Только учтите, что передавать нужно не скорость в бит/с, а ее условный номер из таблицы выше.

Я также попытался изменить содержимое регистров 0x0002 и 0x0003, чтобы повлиять на тип и размерность выходных данных. Содержимое регистров таки изменилось, даже сохранилось после перезагрузки, но… выходные данные как были в сантиметрах с одной цифрой после запятой, так и остались. Похоже эти регистры служат только для индикации настроек, сделанных на заводе.

А вот содержимое недокументированных регистров 0x0007 – 0x0009, наоборот, напрямую влияют на показания датчика. Вероятнее всего это какие-то калибровочные коэффициенты. Я немного поигрался ими и вернул “как было”.

 


Получение данных с датчика на ESP32

Я использую фреймворк ESP-IDF для своих устройств, поэтому пример обмена данными с уровнеметром приведу для ESP-IDF и ESP32. Для ESP-IDF это выполняется очень просто, так как в нем имеется готовое к употреблению API для Modbus. Мой драйвер вы можете найти здесь.

Первым делом нужно настроить UART-порт для работы с RS485-шиной:

static void sensorsInitModbus()
{
  ESP_LOGI(logTAG, "Modbus initialization");
  // Инициализация RS485 и Modbus
  RE_OK_CHECK_EVENT(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_EVENT(mbc_master_setup((void*)&comm), return);
  // Set UART pins
  RE_OK_CHECK_EVENT(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_EVENT(mbc_master_start(), return);
  // Set UART mode
  RE_OK_CHECK_EVENT(uart_set_mode(SENSOR_MODBUS_PORT, UART_MODE_RS485_HALF_DUPLEX), return);
}

Затем последовательно читаем регистры 3 и 4 и вычисляем результат измерения:

esp_err_t reQDY30A::callModbusRegister(uint8_t cmd, uint16_t reg, int16_t* value)
{
  mb_param_request_t _request = {
    .slave_addr = _address,
    .command    = cmd,
    .reg_start  = reg,
    .reg_size   = 1
  };
  return mbc_master_send_request(&_request, (void*)value);
}

sensor_status_t reQDY30A::readRawData()
{
  int16_t value, precs = 0;
  esp_err_t err = ESP_OK;

  if (_item) {
    err = callModbusRegister(0x03, 0x0004, &value);
    if (err != ESP_OK) {
      err = callModbusRegister(0x03, 0x0003, &precs);
    };
  };

  // Check exit code
  if (err != ESP_OK) {
    ESP_LOGE(logTAG, "Failed to read data from sensor: %d %s", err, esp_err_to_name(err));
    return convertEspError(err);
  };

  switch (precs) {
    case 1:  return setRawValues((value_t)value/10.0);    // 1-###.#
    case 2:  return setRawValues((value_t)value/100.0);   // 2-##.##
    case 3:  return setRawValues((value_t)value/1000.0);  // 3-#.###
    default: return setRawValues((value_t)value);         // 0-####
  }
};

Вот, в общем то и все хитрости чтения данных. Примера для Arduino у меня, увы, на текущий момент нет.

 


Мой опыт использования

В целом и общем большинство отзывов на aliexpress на данный датчик положительные. Но мне попался и такой отзыв: “… это не первый мой датчик предыдущее все со временем протекали надеюсь этот прослужит долго …“.

У меня точно такой же уровнеметр все лето проболтался в металлической бочке со немного ржавой водой – использовался он в системе контроля за уровнем воды для полива теплицы. Несколько летних месяцев (с конца мая по октябрь) – срок не большой, но за этот период он показал с себя только с хорошей стороны. “Глюкнул” (выдал неверные данные) только один раз за все лето, и при этом я не уверен, что это был не сбой буфера UART. Корпус не начал ржаветь и не протек, хотя и покрылся налетом от достаточно грязной воды в бочке. В общем с задачей справился полностью.

Поэтому я решил оснастить точно таким-же приемную емкость канализации, дабы было понятно – когда вызывать машину для откачки. Но увы, почта потеряла посылку на полтора месяца, а за это время наступила зима. Что ж, зато я написал сей опус, надеюсь он будет вам полезен. Благодарю за внимание.

 

🔶 Полный архив статей вы найдете здесь


Пожалуйста, оцените статью:
[ 5 из 5, всего 1 оценок ]

8 комментариев для “Погружной датчик уровня жидкости QDY30А”

  1. Аркадий

    Интересная штука. Дорогая, конечно, но если подумать, сколько сил и времени потратишь, чтобы сделать такое же изделие самому, то так уже не кажется. Можно, конечно, поспорить, нужна ли такая точность для измерения воды в поливальном резервуаре.
    Кстати, кажется у вас эта ёмкость – цилиндр лежащий на боку. Соответственно, чтобы знать объём воды в ней мало знать высоту водяного столба, нужно произвести более сложные чем умножение на коэффициент вычисления.
    И ещё, вы пишете, что при обращении к адресам выше 0x000A датчик выдаёт нули. Видимо, авторы датчика совсем упростили протокол, поскольку при обращении к несуществующим адресам по протоколу Modbus должно приходить исключение. А регистры 7-9 – скорее всего содержат калибровочные данные, а не закрыли их опять же по причине упрощения.
    И ещё, если попробовать записать в регистры 2, 3, что будет? Скорее всего запись будет проигнорирована.

    1. Добрый день. В данном случае соглашусь с каждым из ваших утверждений.

      Действительно, высокая точность в случае с теплицей не особо и важна, да и бочка лежит на боку – все правильно вы описали. Но мне нужны были уровни не только “пустой” и “полный”, но и промежуточные, чтобы определить – хватит тепленькой воды на полив чего либо еще или пора открывать кран для наполнения. Кроме того, кран наполнения закрывается примерно секунд 20, поэтому я выдаю команду на закрытие немного раньше 100%. Это первая причина. Вторая причина – если бы я стал “колхозить” уровнеметр на поплавковых датчиках с герконами, то далеко не факт, что они нормально бы отслужили все лето в мутной водичке.

      По поводу регистров – многие китайские поделия так сделаны – отзываются аж 128 или 255 регистров, только данных там нет. Они никогда не заморачиваются со стандартами.

      Я попытался изменить содержимое регистров 0x0002 и 0x0003, чтобы повлиять на тип и размерность выходных данных. Содержимое регистров таки изменилось, даже сохранилось после перезагрузки, но… выходные данные как были в сантиметрах с одной цифрой после запятой, так и остались. Похоже эти регистры служат только для индикации настроек, сделанных на заводе. А вот содержимое недокументированных регистров 0x0007 – 0x0009, наоборот, напрямую влияют на показания датчика. Вероятнее всего это действительно какие-то калибровочные коэффициенты. Я немного поигрался ими и вернул “как было”.

  2. Уважаемый Александр! Вы непрерывно повышаете уровень технической осведомленности любителей и профессионалов. Спасбо Вам и удачи!
    Ваш ученик старшего возраста Виктор.

      1. А почему Вы думаете, что не подойдёт? Если делать измерения 10 раз в секунду (судя по описанию, датчик это позволяет делать), то вполне можно. Волна не быстро меняется. Собираем статистику в течение, например, 10 секунд, находим минимум и максимум, вычитаем первое из второго и получаем ответ. Или у Вас есть другие соображения по этому поводу?

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

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

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

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