====== DS18B20 Modbus controller ====== Контроллер для опроса 8 датчиков DS18B20 по протоколу Modbus RTU. Каждый датчик подключается к отдельному порту, а не к общей шине, что имеет ряд плюсов: * Более быстрый обмен данными * Не требуется настройка (не нужно указывать уникальные идентификаторы) * Зависание одного датчика не мешает опросу остальных Кроме этого в контроллере предусмотрено управление питанием каждого из датчиков (удаленная перезагрузка в случае зависания) и два релейных выхода (ток до 3 ампер). ===== Карта регистров ===== * Данные типа bool с правами "только чтение": Discrete Inputs. Функция чтения: 0x02. * Данные типа bool с правами "чтение и запись": Coils. Функция чтения: 0x01. Функции записи: 0x05, 0x0F. * Данные типов uint16_t, int16_t, float с правами "только чтение": Input Registers. Функция чтения: 0x04. * Данные типов uint16_t, int16_t, float с правами "чтение и запись": Holding Registers. Функция чтения: 0x03. Функции записи: 0x06, 0x10. ==== Датчики температуры ==== === Измерения === ^ Вход ^ Значение ^ Тип данных ^ Режим ^ Регистр ^ Комментарий ^ | 1 | Текущее значение | int16_t | R | 0 | | | ::: | ::: | float | R | 16 | | | ::: | Фильтрованное значение | int16_t | R | 8 | Среднее арифметическое по 16 последним измерениям | | ::: | ::: | float | R | 32 | | | ::: | Наличие датчика | bool | R | 0 | | | ::: | Ошибка CRC | bool | R | 1 | После нескольких ошибок датчик будет перезагружен по питанию| | ::: | Архив фильтрации заполнен | bool | R | 2 | Архив содержит 16 значений измерения. Пока он не заполнен, фильтрованное значение формируется из уменьшенного числа отчетов. | | ::: | Интервал опроса | uint16_t | R/W | 0 | Не менее одной секунды. | | ::: | Калибровочный коэф. | int16_t | R/W | 8 | | | ::: | ID датчика | String(12) | R | 48 | | | 2 | Текущее значение | int16_t | R | 1 | | | ::: | ::: | float | R | 18 | | | ::: | Фильтрованное значение | int16_t | R | 9 | Среднее арифметическое по 16 последним измерениям | | ::: | ::: | float | R | 34 | | | ::: | Наличие датчика | bool | R | 3 | | | ::: | Ошибка CRC | bool | R | 4 | После нескольких ошибок датчик будет перезагружен по питанию| | ::: | Архив фильтрации заполнен | bool | R | 5 | Архив содержит 16 значений измерения. Пока он не заполнен, фильтрованное значение формируется из уменьшенного числа отчетов. | | ::: | Интервал опроса | uint16_t | R/W | 1 | Не менее одной секунды. | | ::: | Калибровочный коэф. | int16_t | R/W | 9 | | | ::: | ID датчика | String(12) | R | 54 | | | 3 | Текущее значение | int16_t | R | 2 | | | ::: | ::: | float | R | 20 | | | ::: | Фильтрованное значение | int16_t | R | 10 | Среднее арифметическое по 16 последним измерениям | | ::: | ::: | float | R | 36 | | | ::: | Наличие датчика | bool | R | 6 | | | ::: | Ошибка CRC | bool | R | 7 | После нескольких ошибок датчик будет перезагружен по питанию| | ::: | Архив фильтрации заполнен | bool | R | 8 | Архив содержит 16 значений измерения. Пока он не заполнен, фильтрованное значение формируется из уменьшенного числа отчетов. | | ::: | Интервал опроса | uint16_t | R/W | 2 | Не менее одной секунды. | | ::: | Калибровочный коэф. | int16_t | R/W | 10 | | | ::: | ID датчика | String(12) | R | 60 | | | 4 | Текущее значение | int16_t | R | 3 | | | ::: | ::: | float | R | 22 | | | ::: | Фильтрованное значение | int16_t | R | 11 | Среднее арифметическое по 16 последним измерениям | | ::: | ::: | float | R | 38 | | | ::: | Наличие датчика | bool | R | 9 | | | ::: | Ошибка CRC | bool | R | 10 | После нескольких ошибок датчик будет перезагружен по питанию| | ::: | Архив фильтрации заполнен | bool | R | 11 | Архив содержит 16 значений измерения. Пока он не заполнен, фильтрованное значение формируется из уменьшенного числа отчетов. | | ::: | Интервал опроса | uint16_t | R/W | 3 | Не менее одной секунды. | | ::: | Калибровочный коэф. | int16_t | R/W | 11 | | | ::: | ID датчика | String(12) | R | 66 | | | 5 | Текущее значение | int16_t | R | 4 | | | ::: | ::: | float | R | 24 | | | ::: | Фильтрованное значение | int16_t | R | 12 | Среднее арифметическое по 16 последним измерениям | | ::: | ::: | float | R | 40 | | | ::: | Наличие датчика | bool | R | 12 | | | ::: | Ошибка CRC | bool | R | 13 | После нескольких ошибок датчик будет перезагружен по питанию| | ::: | Архив фильтрации заполнен | bool | R | 14 | Архив содержит 16 значений измерения. Пока он не заполнен, фильтрованное значение формируется из уменьшенного числа отчетов. | | ::: | Интервал опроса | uint16_t | R/W | 4 | Не менее одной секунды. | | ::: | Калибровочный коэф. | int16_t | R/W | 12 | | | ::: | ID датчика | String(12) | R | 72 | | | 6 | Текущее значение | int16_t | R | 5 | | | ::: | ::: | float | R | 26 | | | ::: | Фильтрованное значение | int16_t | R | 13 | Среднее арифметическое по 16 последним измерениям | | ::: | ::: | float | R | 42 | | | ::: | Наличие датчика | bool | R | 15 | | | ::: | Ошибка CRC | bool | R | 16 | После нескольких ошибок датчик будет перезагружен по питанию| | ::: | Архив фильтрации заполнен | bool | R | 17 | Архив содержит 16 значений измерения. Пока он не заполнен, фильтрованное значение формируется из уменьшенного числа отчетов. | | ::: | Интервал опроса | uint16_t | R/W | 5 | Не менее одной секунды. | | ::: | Калибровочный коэф. | int16_t | R/W | 13 | | | ::: | ID датчика | String(12) | R | 78 | | | 7 | Текущее значение | int16_t | R | 6 | | | ::: | ::: | float | R | 28 | | | ::: | Фильтрованное значение | int16_t | R | 14 | Среднее арифметическое по 16 последним измерениям | | ::: | ::: | float | R | 44 | | | ::: | Наличие датчика | bool | R | 18 | | | ::: | Ошибка CRC | bool | R | 19 | После нескольких ошибок датчик будет перезагружен по питанию| | ::: | Архив фильтрации заполнен | bool | R | 20 | Архив содержит 16 значений измерения. Пока он не заполнен, фильтрованное значение формируется из уменьшенного числа отчетов. | | ::: | Интервал опроса | uint16_t | R/W | 6 | Не менее одной секунды. | | ::: | Калибровочный коэф. | int16_t | R/W | 14 | | | ::: | ID датчика | String(12) | R | 84 | | | 8 | Текущее значение | int16_t | R | 7 | | | ::: | ::: | float | R | 30 | | | ::: | Фильтрованное значение | int16_t | R | 15 | Среднее арифметическое по 16 последним измерениям | | ::: | ::: | float | R | 46 | | | ::: | Наличие датчика | bool | R | 21 | | | ::: | Ошибка CRC | bool | R | 22 | После нескольких ошибок датчик будет перезагружен по питанию| | ::: | Архив фильтрации заполнен | bool | R | 23 | Архив содержит 16 значений измерения. Пока он не заполнен, фильтрованное значение формируется из уменьшенного числа отчетов. | | ::: | Интервал опроса | uint16_t | R/W | 7 | Не менее одной секунды. | | ::: | Калибровочный коэф. | int16_t | R/W | 15 | | | ::: | ID датчика | String(12) | R | 90 | | Для использования с контроллерами или SCADA системами, у которых количество опрашиваемых регистров ограничено, введены дополнительные регистры, которые объединяют статусы всех каналов в один регистр. Номер бита в регистре соответствует номеру канала. ^ Значение ^ Тип данных ^ Режим ^ Регистр ^ | Наличие датчика | uint16_t | R | 96 | | Ошибка CRC | uint16_t | R | 97 | | Архив фильтрации заполнен | uint16_t | R | 98 | | Датчик в памяти контроллера | uint16_t | R | 104 | === Интервал опроса === Для каждого датчика можно указать интервал опроса. Это время в секундах, через которое контроллер попросит датчик измерить температуру. Отсчет ведется не с времени, когда датчик уже предоставил температуру, а с времени прошлого запроса. Для удобства пользователя можно задать время опроса всем датчикам сразу, записав значение в регистр 25. === Калибровка === Так как все датчики немного приверают, есть возможность выровнять их показания. Для этого датчики погружают в жидкость, где показания должны быть примерно равны. Для более точной корректировки можно использовать жидкость, температура кипения которой точно известна. Для этого указывается целевая температура и запускается процесс калибровки. При значении целевой температуры в 0, контроллер установит коэффициенты относительно среднего значения по всем датчикам. ^ Описание ^ Тип данных ^ Режим ^ Регистр ^ Комментарий ^ | Целевое значение | int16_t | R/W | 16 | Значения типа float будет обновлено после записи в этот регистр | | Целевое значение | float | R/W | 17 | Значения типа int16_t будет обновлено после записи в этот регистр | | Количество датчиков в памяти | uint8_t | R | 103 | Максимальное количество - 120 | | Выполнить калибровку | bool | R/W | 3 | Расчет калибровочных коэф. для всех датчиков и сохранение их. Требует ввод кода подтверждения (защита от случайного срабатывания). Для выравнивания по фильтрованному значению: 4403, по текущему значению: 4437. | | Очистить калибровку | bool | R/W | 4 | Очистка данных калибровки (всех). Требует ввод кода подтверждения 4420 (защита от случайного срабатывания) | | Количество датчиков в памяти | uint16_t | R | 103 | | | Код подтверждения | uint16_t | R/W | 24 | | Сохранение калибровочных данных осуществляется именно для датчика, а не конкретного входа. Так что при переключении датчика в другой вход данные о калибровке автоматически будут подгружены из памяти. Каждый датчик имеет уникальный идентификатор. Контроллер может хранить до 120 штук. Как только количество известных датчиков достигнет этого числа - сохранение новых датчиков будет недоступно. Для очистки памяти есть отдельная команда. Калибровка возможна и вручную. Для каждого подключенного к устройству датчика есть специальный регистр. В нем можно получить текущее значение калибровочного коэффициента и изменить его. Подробнее про сохранение настроек контроллера в разделе "Настройки". ==== Релейные выходы ==== ^ Выход ^ Значение ^ Тип данных ^ Режим ^ Регистр ^ Комментарий ^ | 1 | Текущее значение | bool | R/W | 1 | Значение регистра соответствует состоянию реле| | 2 | ::: | bool | R/W | 2 | ::: | ==== Состояние контроллера ==== ^ Описание ^ Тип данных ^ Режим ^ Регистр ^ Комментарий ^ | Команда на перезагрузку | bool | R/W | 0 | Контроллер перезагружается. | | Uptime | uint32_t | R | 99 | Количество секунд, которое контроллер включен. | | Источник перезагрузки | uint16_t | R | 101 | Причина перезагрузки контроллера. Данный регистр содержит несколько флагов: подача питания (бит 1), внешний сигнал (бит 2), защита от низкого напряжения (бит 3), сторожевой таймер (бит 4) | ==== Настройки ==== Все настройки сохраняются после ввода кода подтверждения и получения команды на перезагрузку контроллера. ^ Описание ^ Тип данных ^ Режим ^ Регистр ^ Комментарий ^ | Команда на перезагрузку | bool | R/W | 0 | Контроллер перезагружается и применяет новые настройки, если те были изменены. | | Адрес | uint16_t | R/W | 19 | Адрес устройства в сети (1-xxx) | | Режим Modbus | uint16_t | R/W | 20 | 0 - RTU, 1 - ASCII | | Скорость сети | uint32_t | R/W | 21 | 9600 - 38400 | | Бит четности | uint16_t | R/W | 23 | 0 - отсутствует, 1 - ODD, 2 - EVEN | | Код подтверждения | uint16_t | R/W | 24 | 4386 - сохранение настроек (сеть, калибровка, интервалы) | На плате контроллера присутствует контактная группа, обозначенная как defalut, при замыкании которой сетевые настройки контроллера будут временно установлены в значения по умолчанию для просмотра настроек или же дальнейшей конфигурации устройства. Замыкать контакты нужно при поданном питании в любое время (не обязательно при включении). Контроллер автоматически перезагружается при отсутствии опроса через Modbus в течение 60 секунд, так что пользователь должен успеть за этот интервал установить соединение с устройством. ==== Файлы для загрузки ==== Исходный код проекта: {{ :arduino_ds18b20.zip |}} Исходный код библиотеки freemodbus нужно положить рядом с папкой проекта. При необходимости поправить Makefile.