Найти тему

Eint Emotron'а и как его прочитать на LD.

ПЧ Emotron FDU 2.1
ПЧ Emotron FDU 2.1

Добрый день. В ходе наладочных работ на одном из объектов города, я столкнулся с весьма интересным случаем реализации передачи данных формата Float в одном двухбайтовом слове. Преобразователи частоты Emotron серии FDU 2.1, а возможно и другие серии данного производителя, для передачи данных с плавающей запятой используют свой формат данных - Eint. Описание формата из руководства:

"Формат EInt используется только с протоколами Modbus-RTU и Modbus-TCP.
Параметр в формате Eint может быть представлен в двух различных форматах (F). Либо в формате 15-битного целого числа без знака (F= 0), либо в
формате с плавающей запятой Emotron (F=1). Самый старший бит (B15) указывает на используемый формат. Если бит установки формата (В15) равен 0, то все биты можно рассматривать как стандартное
беззнаковое целое число (UInt) Если бит установки формата данных равен 1, тогда данные следует интерпретировать по следующей формуле:
Значение = M * 10^E, где M = m10..m0 — мантисса со знаком в двоичном дополнительном коде; E = e3..e0 — экспонента со знаком в двоичном
дополнительном коде.

Содержимое 16-битного слова для двух различных форматов EInt.
Содержимое 16-битного слова для двух различных форматов EInt.

Как видим инженеры Emotron'а заморочились и упаковали в одно слово вещественную переменную, решение спорное, но ничего не поделаешь. Для нормального отображения считанных данных нам необходима функция пересчета формата Eint в формат Float.

ПЛК, установленный на объекте - Unitronics V700. Какими возможностями обладает данный ПЛК для решения данной задачи:

1. Язык программирования LD, только LD и никакой альтернативы

2. Отсутствие возможности функционального программирования

3. Отсутствие возможности прямого обращения к битам слова

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

Каким образом я бы решал данную задачу на ПЛК с возможностью обращения к битам слова и поддержкой ST. Вообще я сторонник того, что математические и битовые операции проводить в отдельной функции, написанной на ST. А далее по коду в необходимых местах вставлять функцию и менять у нее входные и выходные переменные. ST позволяет уменьшить объем кода, и улучшает визуальное восприятие программы при наладке. Вот пример кода обработки аналоговых датчиков на ST:

Обработка аналоговых датчиков на ST.
Обработка аналоговых датчиков на ST.

Можете попробовать переписать данную функцию на LD или FBD, увидите наглядно объем получившегося кода.

Но ближе к делу. При считывании переменной в ПЛК, ПЛК воспринимает ее как обычную знаковую переменную формата INT. В формате INT бит 15 отвечает за знак числа, а в формате Eint за формат описанный выше. Следовательно, мы знаем какого формата у нас число, в зависимости от знака.

Далее, если знак числа отрицательный, F=1,то мы имеем формат дробного числа и нам необходимо выделить экспоненту со знаком и мантиссу, тоже со знаком.

Начнем с экспоненты. Экспонента занимает биты с 11 по 14. Чтобы получить число формата Int нам необходимо эти биты переместить на места с 0 по 3, а биты с 4 по 15 заполнить нулями либо единицами, в зависимости от знака.

Получение экспоненты
Получение экспоненты

Как видно из изображения, на лицо функция логического сдвига битов. Сначала необходимо сдвинуть все значения на один бит влево, тем самым стерев бит F, а далее сдвинуть результат на 12 бит вправо, причем бит 15 не будет изменяться. Статичность 15-го бита при сдвиге вправо дает нам возможность не отслеживать знак числа в бите E3, тем самым задача упрощается.

-5

В итоге мы получаем число с нужным знаком, применяя всего 2 логические операции.

По аналогии получаем мантиссу. Далее по формуле возводим 10 в степень экспоненты и умножаем на мантиссу. При F = 0 используем первоначальное число. Осталось лишь записать весь алгоритм в формате LD.

Код LD реализованной функции
Код LD реализованной функции

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