Профиль должен быть заполнен на русском языке кириллицей. Заполнение профиля заведомо ложными или некорректными данными - причина возможного отказа в регистрации на форуме.

Нестандартный формат числа (int48)

Модератор: специалисты по Weintek


Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 178
Зарегистрирован: 25 фев 2013, 06:14
Ф.И.О.: Шамилов Данис
Благодарил (а): 6 раз

Нестандартный формат числа (int48)

Сообщение tank_urg » 24 июл 2015, 18:31

Здравствуйте!

Как отобразить на панели число с форматом, занимающим 3 регистра, а именно int48?
Easy Builder во вкладке "Формат чисел" объекта "Числа" предлагает только стандартный набор: 16 бит BCD, 32 бит BCD, 16 бит HEX, 32 бит HEX, 16 бит BIN, 32 бит BIN, 16 бит UNSIGNED, 16 бит SIGNED, 32 бит UNSIGNED, 32 бит SIGNED, 32 бит FLOAT.


Михайло
почётный участник форума
почётный участник форума
Сообщения: 2220
Зарегистрирован: 10 ноя 2009, 04:58
Ф.И.О.: Толмачев Михаил Алексеевич
Благодарил (а): 1 раз
Поблагодарили: 22 раза
Контактная информация:

Re: Нестандартный формат числа (int48)

Сообщение Михайло » 25 июл 2015, 06:34

2 вопроса:
1. Использует ли переменная все 48 бит?
2. Бывают отрицательные значения у переменной?

Больше всего подходит формат "32 бит SIGNED", он должен использоваться в основе преобразования типа "int48->int16+int32".


Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 178
Зарегистрирован: 25 фев 2013, 06:14
Ф.И.О.: Шамилов Данис
Благодарил (а): 6 раз

Re: Нестандартный формат числа (int48)

Сообщение tank_urg » 25 июл 2015, 13:31

Это показания активной энергии, прошедшей через счетчик, в Вт*ч, поэтому:

1) Вопрос правильный. Тоже думал об этом. Виноват, что сразу не указал. Время, когда переменная начнет заполнять ячейки третьего регистра, наступит далеко не сразу, т. к. 2 в степени 32 это 4294967296. При максимальной потребляемой мощности установки 100 кВт третий регистр начнет заполняться лет через 5. Но все-таки начнет. Так что желательно использовать все 48 бит.
2) Производитель указывает для этой переменной - INT, то есть со знаком. Хотя я не совсем понимаю, когда эта переменная принимает отрицательные значения, ведь для подсчета выделенной и потребленной энергии отведены разные области Modbus. Для некоторых других переменных указано UINT.


Михайло
почётный участник форума
почётный участник форума
Сообщения: 2220
Зарегистрирован: 10 ноя 2009, 04:58
Ф.И.О.: Толмачев Михаил Алексеевич
Благодарил (а): 1 раз
Поблагодарили: 22 раза
Контактная информация:

Re: Нестандартный формат числа (int48)

Сообщение Михайло » 25 июл 2015, 13:47

Итак, 48 бит - это шесть байт ABCDEF. В байте A хранится знак. Можно отобразить байты CDEF, используя тип "32 бит UNSIGNED". Байты AB можно отобразить отдельно, используя тип "16 бит SIGNED".
По своему смыслу CDEF - это будет основной счетчик, а AB - это счетчик переполнений + знак. Немного не то, что нужно, но зато просто реализуемо.

Используя вычислительные возможности панели (а они есть?) или ПЛК, можно сделать правильное отображение. Отображать панель будет число с помощью двух числовых индикаторов.

Умеет ли панель отображать в числовых индикаторах лидирующие нули? Ну, например, вот так: "00032,7".


Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 178
Зарегистрирован: 25 фев 2013, 06:14
Ф.И.О.: Шамилов Данис
Благодарил (а): 6 раз

Re: Нестандартный формат числа (int48)

Сообщение tank_urg » 26 июл 2015, 10:14

Михайло писал(а):Итак, 48 бит - это шесть байт ABCDEF. В байте A хранится знак. Можно отобразить байты CDEF, используя тип "32 бит UNSIGNED". Байты AB можно отобразить отдельно, используя тип "16 бит SIGNED".
По своему смыслу CDEF - это будет основной счетчик, а AB - это счетчик переполнений + знак. Немного не то, что нужно, но зато просто реализуемо.

Используя вычислительные возможности панели (а они есть?) или ПЛК, можно сделать правильное отображение. Отображать панель будет число с помощью двух числовых индикаторов.

Умеет ли панель отображать в числовых индикаторах лидирующие нули? Ну, например, вот так: "00032,7".


Просто так разделить это десятичное число на 2 части поразрядно не получится, ведь оно к нам приходит в двоичной системе, а потом уже преобразуется.

Получится только поставить 2 окошка и подписать: "Значение потребленной активной энергии равно числу в левом окошке, умноженному на 4294967296, плюс число в правом окошке, Вт*ч".
Так сделать конечно можно, но как-то не очень красиво получается.
Или я что-то не так понял.


Alexander
БАН
БАН
Сообщения: 642
Зарегистрирован: 03 июн 2010, 11:26
Ф.И.О.: Козин Александр Елисеевич
Благодарил (а): 2 раза
Поблагодарили: 5 раз
Забанен: Бессрочно

Re: Нестандартный формат числа (int48)

Сообщение Alexander » 26 июл 2015, 11:19

Здесь невольно напрашивается нескромный вопрос - а кого интересуют ватты, потребленные 5 лет назад с точностью 10 знаков? Есть такие люди? Тогда чудны дела твои, Господи....


Михайло
почётный участник форума
почётный участник форума
Сообщения: 2220
Зарегистрирован: 10 ноя 2009, 04:58
Ф.И.О.: Толмачев Михаил Алексеевич
Благодарил (а): 1 раз
Поблагодарили: 22 раза
Контактная информация:

Re: Нестандартный формат числа (int48)

Сообщение Михайло » 26 июл 2015, 19:26

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


Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 178
Зарегистрирован: 25 фев 2013, 06:14
Ф.И.О.: Шамилов Данис
Благодарил (а): 6 раз

Re: Нестандартный формат числа (int48)

Сообщение tank_urg » 26 июл 2015, 19:54

Здесь невольно напрашивается нескромный вопрос - а кого интересуют ватты, потребленные 5 лет назад с точностью 10 знаков? Есть такие люди? Тогда чудны дела твои, Господи....


Для того чтобы подсчитать суточный/недельный/месячный/годовой расход электроэнергии нужно от сегодняшних показаний отнять показания в начале соответствующего промежутка.
Во всяком случае таково требование заказчика.
У меня вот в квартире счетчик тоже каждый месяц не сбрасывается, а потребленную энергию я вычисляю, отняв предыдущие показания от текущих.
Это по-моему вполне нормально.


Михайло
почётный участник форума
почётный участник форума
Сообщения: 2220
Зарегистрирован: 10 ноя 2009, 04:58
Ф.И.О.: Толмачев Михаил Алексеевич
Благодарил (а): 1 раз
Поблагодарили: 22 раза
Контактная информация:

Re: Нестандартный формат числа (int48)

Сообщение Михайло » 26 июл 2015, 19:58

Ну значит
Михайло писал(а):Можно отобразить байты CDEF, используя тип "32 бит UNSIGNED".


Про байты A, B можно забыть, дабы не смущать нестандартным подходом. В момент перехода счетчика через 0 (переполнение) нужно будет придерживаться правила "вычти 4 миллиарда" )))


Михайло
почётный участник форума
почётный участник форума
Сообщения: 2220
Зарегистрирован: 10 ноя 2009, 04:58
Ф.И.О.: Толмачев Михаил Алексеевич
Благодарил (а): 1 раз
Поблагодарили: 22 раза
Контактная информация:

Re: Нестандартный формат числа (int48)

Сообщение Михайло » 26 июл 2015, 20:06

tank_urg писал(а):плюс число в правом окошке, Вт*ч".

Кому вообще нужны ватт-часы даже сегодняшние? Показывать только киловатт-часы. Это к тому, что можно показывать только байты BCDE, а малозначащие биты F обрезать.


Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 178
Зарегистрирован: 25 фев 2013, 06:14
Ф.И.О.: Шамилов Данис
Благодарил (а): 6 раз

Re: Нестандартный формат числа (int48)

Сообщение tank_urg » 26 июл 2015, 20:22

Кому вообще нужны ватт-часы даже сегодняшние? Показывать только киловатт-часы. Это к тому, что можно показывать только байты ABCD, а малозначащие EF обрезать.


Понятное дело. Только чтобы вывести в кВт*ч нужно сначала получить число в Вт*ч, а потом уже разделить на 1000.
Например, чтобы значение 248123456 Вт*ч вывести как 248123 кВт*ч (с этим проблем нет, в ПО панели стандартная функция), нужно обработать код:
в регистрах A-B нули (позже тоже начнут заполняться), E: 0000111011001010, F: 0001000001000000.

Что вы здесь предлагаете обрезать?


Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 178
Зарегистрирован: 25 фев 2013, 06:14
Ф.И.О.: Шамилов Данис
Благодарил (а): 6 раз

Re: Нестандартный формат числа (int48)

Сообщение tank_urg » 26 июл 2015, 20:25

Получится только поставить 2 окошка и подписать: "Значение потребленной активной энергии равно числу в левом окошке, умноженному на 4294967296, плюс число в правом окошке, Вт*ч".


Здесь Вт*ч относится ко всему полученному числу, а не только к правому окошку.

Аватара пользователя

megavolt86
специалист
специалист
Сообщения: 627
Зарегистрирован: 14 ноя 2013, 19:35
Ф.И.О.: Анатолий Сергеевич
Откуда: Башкортостан
Благодарил (а): 3 раза
Поблагодарили: 6 раз

Re: Нестандартный формат числа (int48)

Сообщение megavolt86 » 26 июл 2015, 21:43

Чтото прям путаница какаято...
Я как понял Михаил предлагает получаемое значение разбить на три слова. Два слова выводить в одно поле на экране, а третье в другое поле.
Модбас это вполне позволяет вроде)
Подсчет не нужен никакой, как только четыре байта заполнятся они обнулятся, а пятый байт примет значение 1. Самое путевое решение на мой взгляд.
:ext_secret:


Михайло
почётный участник форума
почётный участник форума
Сообщения: 2220
Зарегистрирован: 10 ноя 2009, 04:58
Ф.И.О.: Толмачев Михаил Алексеевич
Благодарил (а): 1 раз
Поблагодарили: 22 раза
Контактная информация:

Re: Нестандартный формат числа (int48)

Сообщение Михайло » 27 июл 2015, 05:55

tank_urg писал(а):Что вы здесь предлагаете обрезать?

Смотря какая точность нужна. Вроде как обычно точность до 0,1 кВт*ч.
Частично обрезать F, там находятся значения от 0 до 255 Вт*ч. Обрезать A, как так там нули надолго. EF использовать для вычисления значения кВт*ч после запятой. BCDE использовать для вычисления значения кВт*ч перед запятой.

Итак, на экране отображаем два числа:
до_запятой, после_запятой

Запятая - это будет простой текстовый объект.

после_запятой = (EF mod 1000) div 10
mod - это функция, вычисляющая остаток от деления
div - целочисленное деление

до_запятой = BCDE * 256 / 1000

Надо подумать, как аккуратно вычислить до_запятой...

Аватара пользователя

Looker
осмотрелся
осмотрелся
Сообщения: 189
Зарегистрирован: 09 фев 2011, 11:32
Ф.И.О.: Дитрих Евгений
Откуда: Донецк
Благодарил (а): 22 раза
Поблагодарили: 5 раз

Re: Нестандартный формат числа (int48)

Сообщение Looker » 27 июл 2015, 12:04

С установленной мощность под 100 кВт, нужна ли индикация с точностью до 1 Втч? По мне - хватит и 1 кВтч.
Для удобства вычислений дельты за период, с учетом перехода через "0" можно индикацию ограничить
в диапазоне 0...999 999.9 кВтч (человеку легче считать при переходе), недоучет текущего периода
компенсируется в следующем периоде. Отображать стоит с ведущими нулями (неявная подсказка когда
будет переход). Число до 999 999.9 укладывается во Float32.

Код: Выделить всё

indication:= (CDEF mod 10000000)/1000

Если бы хватило 1 кВтч (0...9 999 999), тогда так:

Код: Выделить всё

indication:= (BCDE*0.256) mod 10000000

Как получить BCDE из AB и CDEF оставляю за скобками.


Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 178
Зарегистрирован: 25 фев 2013, 06:14
Ф.И.О.: Шамилов Данис
Благодарил (а): 6 раз

Re: Нестандартный формат числа (int48)

Сообщение tank_urg » 27 июл 2015, 15:58

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


По-моему это неверно.
Для примера можно представить более простую ситуацию: пусть регистры будут двухбитные, и нам необходимо считать с устройства число 61. Устройство пишет это число в 3 регистра (11 11 01), а панель может отображать число с 2 регистров максимум. Вы предлагаете поставить 2 окошка: в первом пересчитывать 11, во втором - 11 01. По Вашему предложению панель будет отображать "3" в первом окошке и "13" - во втором. А не "61", как это требуется.

Здесь правильно будет подписать: для получения конечного результата нужно число в левом окошке умножить на 16 (2 в степени 4) плюс число в правом окошке.

Вот как панели объяснить последнее предложение - непонятно.


Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 178
Зарегистрирован: 25 фев 2013, 06:14
Ф.И.О.: Шамилов Данис
Благодарил (а): 6 раз

Re: Нестандартный формат числа (int48)

Сообщение tank_urg » 27 июл 2015, 16:17

Смотря какая точность нужна. Вроде как обычно точность до 0,1 кВт*ч.
Частично обрезать F, там находятся значения от 0 до 255 Вт*ч. Обрезать A, как так там нули надолго. EF использовать для вычисления значения кВт*ч после запятой. BCDE использовать для вычисления значения кВт*ч перед запятой.

Итак, на экране отображаем два числа:
до_запятой, после_запятой

Запятая - это будет простой текстовый объект.

после_запятой = (EF mod 1000) div 10
mod - это функция, вычисляющая остаток от деления
div - целочисленное деление

до_запятой = BCDE * 256 / 1000

Надо подумать, как аккуратно вычислить до_запятой...


С установленной мощность под 100 кВт, нужна ли индикация с точностью до 1 Втч? По мне - хватит и 1 кВтч.
Для удобства вычислений дельты за период, с учетом перехода через "0" можно индикацию ограничить
в диапазоне 0...999 999.9 кВтч (человеку легче считать при переходе), недоучет текущего периода
компенсируется в следующем периоде. Отображать стоит с ведущими нулями (неявная подсказка когда
будет переход). Число до 999 999.9 укладывается во Float32.
КОД: ВЫДЕЛИТЬ ВСЁ
indication:= (CDEF mod 10000000)/1000

Если бы хватило 1 кВтч (0...9 999 999), тогда так:
КОД: ВЫДЕЛИТЬ ВСЁ
indication:= (BCDE*0.256) mod 10000000

Как получить BCDE из AB и CDEF оставляю за скобками.


Смысл ясен, спасибо. По ходу дела тут без макросов не обойтись.

Аватара пользователя

TEB
специалист по DEIF
специалист по DEIF
Сообщения: 7896
Зарегистрирован: 17 июн 2008, 15:01
Ф.И.О.: Евгений свет Брониславович
Благодарил (а): 36 раз
Поблагодарили: 63 раза
Контактная информация:

Re: Нестандартный формат числа (int48)

Сообщение TEB » 28 июл 2015, 12:32

tank_urg писал(а):Это показания активной энергии, прошедшей через счетчик, в Вт*ч, поэтому:

1) Вопрос правильный. Тоже думал об этом. Виноват, что сразу не указал. Время, когда переменная начнет заполнять ячейки третьего регистра, наступит далеко не сразу, т. к. 2 в степени 32 это 4294967296. При максимальной потребляемой мощности установки 100 кВт третий регистр начнет заполняться лет через 5. Но все-таки начнет. Так что желательно использовать все 48 бит.

А ведь можно эту переменную читать как две переменые (16+32 бит) и отдельно и отображать двумя разными полями старшие и младшие регистры. Младшие - 32 бит, старшие - 16 бит. Но думаю лучше взять ModSim и поэкспериментировать.

tank_urg писал(а):Хотя я не совсем понимаю, когда эта переменная принимает отрицательные значения, ведь для подсчета выделенной и потребленной энергии отведены разные области Modbus.

Если Ваша установка только потребляет энергию (нет своей генерации) то в отрицательное значение счетчик перейдёт только тогда когда счётчик подключат неправильно и насчитают в обратную сторону. То есть, если всё правильно, то никогда. Это для активной энергии, о которой и речь. Реактивная энергия может быть и отрицательная - зависит от установки, очень много сейчас потребителей с емкостным косинусом (отдают реактивную мощность в сеть). Но мы говорим об активной мощности.
По вопросам работы Форума можно обратиться ко мне, или по этим контактам.

Аватара пользователя

Looker
осмотрелся
осмотрелся
Сообщения: 189
Зарегистрирован: 09 фев 2011, 11:32
Ф.И.О.: Дитрих Евгений
Откуда: Донецк
Благодарил (а): 22 раза
Поблагодарили: 5 раз

Re: Нестандартный формат числа (int48)

Сообщение Looker » 28 июл 2015, 14:17

TEB писал(а):А ведь можно эту переменную читать как две переменые (16+32 бит) и отдельно и отображать двумя разными полями старшие и младшие регистры. Младшие - 32 бит, старшие - 16 бит. Но думаю лучше взять ModSim и поэкспериментировать.

Нельзя, т.к. к 000004294967295 +1 отобразит 000010000000000, а должно быть 000004294967296

TEB писал(а):
tank_urg писал(а):Хотя я не совсем понимаю, когда эта переменная принимает отрицательные значения, ведь для подсчета выделенной и потребленной энергии отведены разные области Modbus.

Если Ваша установка только потребляет энергию (нет своей генерации) то в отрицательное значение счетчик перейдёт только тогда когда счётчик подключат неправильно и насчитают в обратную сторону. То есть, если всё правильно, то никогда. Это для активной энергии, о которой и речь. Реактивная энергия может быть и отрицательная - зависит от установки, очень много сейчас потребителей с емкостным косинусом (отдают реактивную мощность в сеть). Но мы говорим об активной мощности.
Отрицательное будет очень не скоро, можно посчитать точно - вместо 2^47 Втч будет -2^47.

Аватара пользователя

TEB
специалист по DEIF
специалист по DEIF
Сообщения: 7896
Зарегистрирован: 17 июн 2008, 15:01
Ф.И.О.: Евгений свет Брониславович
Благодарил (а): 36 раз
Поблагодарили: 63 раза
Контактная информация:

Re: Нестандартный формат числа (int48)

Сообщение TEB » 28 июл 2015, 14:37

Looker писал(а):Нельзя, т.к. к 000004294967295 +1 отобразит 000010000000000, а должно быть 000004294967296

Я и не говорил что просто взять и отобразить. Пересчёт обязательно понадобится. Но мы так делали: читали переменную по частям и каждую часть после пересчёта отображали отдельно в двух соседних полях.
По вопросам работы Форума можно обратиться ко мне, или по этим контактам.


Михайло
почётный участник форума
почётный участник форума
Сообщения: 2220
Зарегистрирован: 10 ноя 2009, 04:58
Ф.И.О.: Толмачев Михаил Алексеевич
Благодарил (а): 1 раз
Поблагодарили: 22 раза
Контактная информация:

Re: Нестандартный формат числа (int48)

Сообщение Михайло » 29 июл 2015, 05:10

TEB писал(а):Я и не говорил что просто взять и отобразить. Пересчёт обязательно понадобится. Но мы так делали: читали переменную по частям и каждую часть после пересчёта отображали отдельно в двух соседних полях.

Для этого всего понадобится функция отображения лидирующих нулей, иначе изображение будет примерно такое
0 294967296 вместо 00000294967296

Аватара пользователя

TEB
специалист по DEIF
специалист по DEIF
Сообщения: 7896
Зарегистрирован: 17 июн 2008, 15:01
Ф.И.О.: Евгений свет Брониславович
Благодарил (а): 36 раз
Поблагодарили: 63 раза
Контактная информация:

Re: Нестандартный формат числа (int48)

Сообщение TEB » 29 июл 2015, 11:25

Михайло писал(а):
TEB писал(а):Я и не говорил что просто взять и отобразить. Пересчёт обязательно понадобится. Но мы так делали: читали переменную по частям и каждую часть после пересчёта отображали отдельно в двух соседних полях.

Для этого всего понадобится функция отображения лидирующих нулей, иначе изображение будет примерно такое
0 294967296 вместо 00000294967296

По простому да. А для красоты можно использовать текстовые строки для старших разрядов, и тогда там даже нуля не будет. но это уже не в операторской панели явно. В операторской панели можно менять цвет текста старших разрядов (делать его таким же как цвет фона) если старшие разряды равны нулю - тогда и функция лидирующих нулей не понадобится.
По вопросам работы Форума можно обратиться ко мне, или по этим контактам.

Аватара пользователя

skr
специалист по WEINTEK
специалист по WEINTEK
Сообщения: 205
Зарегистрирован: 22 мар 2013, 10:52
Ф.И.О.: Денис Порфирьев
Откуда: Санкт-Петербург
Поблагодарили: 4 раза
Контактная информация:

Re: Нестандартный формат числа (int48)

Сообщение skr » 30 июл 2015, 14:11

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

Код: Выделить всё

macro_command main()

unsigned short indata[3] //int48
//старшее слово - indata[0], если нужно в обратном порядке, поменять местами indata[0] и indata[2]

//hardcoded пример значения
indata[0]=0x7FFF
indata[1]=0xFFFF
indata[2]=0xFFFF

bool minus = false
if (0 <> (indata[0] & 0x8000)) then
   minus = true
end if

if minus then
   indata[0] = indata[0] ^ 0xFFFF
   indata[1] = indata[1] ^ 0xFFFF
   indata[2] = (indata[2] ^ 0xFFFF) + 1
   if (indata[2] == 0) then
      indata[1] = indata[1] + 1
      if (indata[1] == 0) then
         indata[0] = indata[0] + 1
      end if
   end if
end if

unsigned int r
char deststring[17]
int pos = 16
deststring[pos] = 0 //конец строки

while pos > 0
   r = indata[0]

   indata[0] = r / 10
   r = ((r % 10) << 16) + indata[1]

   indata[1] = r / 10
   r = ((r % 10) << 16) + indata[2]

   indata[2] = r / 10
   r = r % 10

   pos = pos - 1
   deststring[pos] = r + '0'
   
   if indata[0]==0 and indata[1]==0 and indata[2]==0 then
      break
   end if
wend

if minus and pos > 0 then
   pos = pos - 1
   deststring[pos] = '-'
end if

int len
len = 17-pos
SetData(deststring[pos], "Local HMI", LW, 0, len)

end macro_command

В примере вручную заданное значение 0x7FFFFFFFFFFF (140737488355327) преобразуется в строку и результат сохраняется в LW0...
"ФАМ-Электрик" - официальный дистрибьютор Weintek в России http://www.rusavtomatika.com


Вернуться в «Операторские панели»



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей