1. Обязательно представиться на русском языке кириллицей (заполнить поле "Имя").
  2. Фиктивные имена мы не приветствуем. Ивановых и Пупкиных здесь уже достаточно.
  3. Не писать свой вопрос в первую попавшуюся тему - вместо этого создать новую тему.
  4. За поиск, предложение и обсуждение пиратского ПО и средств взлома - бан без предупреждения.
  5. Рекламу и частные объявления "куплю/продам/есть халтура" мы не размещаем ни на каких условиях.
  6. Перед тем как что-то написать - читать здесь и здесь, а студентам - обязательно здесь.
  7. Не надо писать в ЛС администраторам свои технические вопросы. Администраторы форума отлично знают как работает форум, а не все-все контроллеры, о которых тут пишут.

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

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

Ответить

Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 193
Зарегистрирован: 25 фев 2013, 07:14
Имя: Шамилов Данис
Страна: Россия
город/регион: Уфа
Благодарил (а): 10 раз
Поблагодарили: 1 раз

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

Сообщение tank_urg »

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

Как отобразить на панели число с форматом, занимающим 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.

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

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

Сообщение Михайло »

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

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

Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 193
Зарегистрирован: 25 фев 2013, 07:14
Имя: Шамилов Данис
Страна: Россия
город/регион: Уфа
Благодарил (а): 10 раз
Поблагодарили: 1 раз

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

Сообщение tank_urg »

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

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

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

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

Сообщение Михайло »

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

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

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

Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 193
Зарегистрирован: 25 фев 2013, 07:14
Имя: Шамилов Данис
Страна: Россия
город/регион: Уфа
Благодарил (а): 10 раз
Поблагодарили: 1 раз

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

Сообщение tank_urg »

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

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

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

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

Alexander
БАН
БАН
Сообщения: 642
Зарегистрирован: 03 июн 2010, 12:26
Имя: Козин Александр Елисеевич
Страна: Украина
город/регион: Одесса
Поблагодарили: 4 раза
Забанен: Бессрочно

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

Сообщение Alexander »

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

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

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

Сообщение Михайло »

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

Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 193
Зарегистрирован: 25 фев 2013, 07:14
Имя: Шамилов Данис
Страна: Россия
город/регион: Уфа
Благодарил (а): 10 раз
Поблагодарили: 1 раз

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

Сообщение tank_urg »

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

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

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

Сообщение Михайло »

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

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

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

Сообщение Михайло »

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

Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 193
Зарегистрирован: 25 фев 2013, 07:14
Имя: Шамилов Данис
Страна: Россия
город/регион: Уфа
Благодарил (а): 10 раз
Поблагодарили: 1 раз

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

Сообщение tank_urg »

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

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

Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 193
Зарегистрирован: 25 фев 2013, 07:14
Имя: Шамилов Данис
Страна: Россия
город/регион: Уфа
Благодарил (а): 10 раз
Поблагодарили: 1 раз

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

Сообщение tank_urg »

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

megavolt86
эксперт
эксперт
Сообщения: 1172
Зарегистрирован: 14 ноя 2013, 20:35
Имя: Анатолий Сергеевич
Страна: Россия
город/регион: Башкортостан
Благодарил (а): 13 раз
Поблагодарили: 65 раз

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

Сообщение megavolt86 »

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

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

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

Сообщение Михайло »

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

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

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

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

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

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

Looker
эксперт
эксперт
Сообщения: 1105
Зарегистрирован: 09 фев 2011, 11:32
Имя: Дитрих Евгений Линусович
город/регион: Донецк
Благодарил (а): 255 раз
Поблагодарили: 184 раза

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

Сообщение Looker »

С установленной мощность под 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
почётный участник форума
почётный участник форума
Сообщения: 193
Зарегистрирован: 25 фев 2013, 07:14
Имя: Шамилов Данис
Страна: Россия
город/регион: Уфа
Благодарил (а): 10 раз
Поблагодарили: 1 раз

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

Сообщение tank_urg »

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

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

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

Автор темы
tank_urg
почётный участник форума
почётный участник форума
Сообщения: 193
Зарегистрирован: 25 фев 2013, 07:14
Имя: Шамилов Данис
Страна: Россия
город/регион: Уфа
Благодарил (а): 10 раз
Поблагодарили: 1 раз

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

Сообщение tank_urg »

Смотря какая точность нужна. Вроде как обычно точность до 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 оставляю за скобками.
Смысл ясен, спасибо. По ходу дела тут без макросов не обойтись.
Аватара пользователя

Jackson
администратор
администратор
Сообщения: 17472
Зарегистрирован: 17 июн 2008, 16:01
Имя: Евгений свет Брониславович
Страна: Россия
город/регион: Санкт-Петербург
Благодарил (а): 749 раз
Поблагодарили: 1278 раз

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

Сообщение Jackson »

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

1) Вопрос правильный. Тоже думал об этом. Виноват, что сразу не указал. Время, когда переменная начнет заполнять ячейки третьего регистра, наступит далеко не сразу, т. к. 2 в степени 32 это 4294967296. При максимальной потребляемой мощности установки 100 кВт третий регистр начнет заполняться лет через 5. Но все-таки начнет. Так что желательно использовать все 48 бит.
А ведь можно эту переменную читать как две переменые (16+32 бит) и отдельно и отображать двумя разными полями старшие и младшие регистры. Младшие - 32 бит, старшие - 16 бит. Но думаю лучше взять ModSim и поэкспериментировать.
tank_urg писал(а):Хотя я не совсем понимаю, когда эта переменная принимает отрицательные значения, ведь для подсчета выделенной и потребленной энергии отведены разные области Modbus.
Если Ваша установка только потребляет энергию (нет своей генерации) то в отрицательное значение счетчик перейдёт только тогда когда счётчик подключат неправильно и насчитают в обратную сторону. То есть, если всё правильно, то никогда. Это для активной энергии, о которой и речь. Реактивная энергия может быть и отрицательная - зависит от установки, очень много сейчас потребителей с емкостным косинусом (отдают реактивную мощность в сеть). Но мы говорим об активной мощности.
По вопросам работы Форума можно обратиться по этим контактам.
Аватара пользователя

Looker
эксперт
эксперт
Сообщения: 1105
Зарегистрирован: 09 фев 2011, 11:32
Имя: Дитрих Евгений Линусович
город/регион: Донецк
Благодарил (а): 255 раз
Поблагодарили: 184 раза

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

Сообщение Looker »

TEB писал(а):А ведь можно эту переменную читать как две переменые (16+32 бит) и отдельно и отображать двумя разными полями старшие и младшие регистры. Младшие - 32 бит, старшие - 16 бит. Но думаю лучше взять ModSim и поэкспериментировать.
Нельзя, т.к. к 000004294967295 +1 отобразит 000010000000000, а должно быть 000004294967296
TEB писал(а):
tank_urg писал(а):Хотя я не совсем понимаю, когда эта переменная принимает отрицательные значения, ведь для подсчета выделенной и потребленной энергии отведены разные области Modbus.
Если Ваша установка только потребляет энергию (нет своей генерации) то в отрицательное значение счетчик перейдёт только тогда когда счётчик подключат неправильно и насчитают в обратную сторону. То есть, если всё правильно, то никогда. Это для активной энергии, о которой и речь. Реактивная энергия может быть и отрицательная - зависит от установки, очень много сейчас потребителей с емкостным косинусом (отдают реактивную мощность в сеть). Но мы говорим об активной мощности.
Отрицательное будет очень не скоро, можно посчитать точно - вместо 2^47 Втч будет -2^47.
_______________________________________________
Узкая специализация в широком смысле этого слова ведет к широкой идиотизации в узком смысле этого слова . (С) Бернард Шоу
Аватара пользователя

Jackson
администратор
администратор
Сообщения: 17472
Зарегистрирован: 17 июн 2008, 16:01
Имя: Евгений свет Брониславович
Страна: Россия
город/регион: Санкт-Петербург
Благодарил (а): 749 раз
Поблагодарили: 1278 раз

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

Сообщение Jackson »

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

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

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

Сообщение Михайло »

TEB писал(а):Я и не говорил что просто взять и отобразить. Пересчёт обязательно понадобится. Но мы так делали: читали переменную по частям и каждую часть после пересчёта отображали отдельно в двух соседних полях.
Для этого всего понадобится функция отображения лидирующих нулей, иначе изображение будет примерно такое
0 294967296 вместо 00000294967296
Аватара пользователя

Jackson
администратор
администратор
Сообщения: 17472
Зарегистрирован: 17 июн 2008, 16:01
Имя: Евгений свет Брониславович
Страна: Россия
город/регион: Санкт-Петербург
Благодарил (а): 749 раз
Поблагодарили: 1278 раз

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

Сообщение Jackson »

Михайло писал(а):
TEB писал(а):Я и не говорил что просто взять и отобразить. Пересчёт обязательно понадобится. Но мы так делали: читали переменную по частям и каждую часть после пересчёта отображали отдельно в двух соседних полях.
Для этого всего понадобится функция отображения лидирующих нулей, иначе изображение будет примерно такое
0 294967296 вместо 00000294967296
По простому да. А для красоты можно использовать текстовые строки для старших разрядов, и тогда там даже нуля не будет. но это уже не в операторской панели явно. В операторской панели можно менять цвет текста старших разрядов (делать его таким же как цвет фона) если старшие разряды равны нулю - тогда и функция лидирующих нулей не понадобится.
По вопросам работы Форума можно обратиться по этим контактам.
Аватара пользователя

skr
специалист по WEINTEK
специалист по WEINTEK
Сообщения: 208
Зарегистрирован: 22 мар 2013, 11:52
Имя: Денис Порфирьев
город/регион: Санкт-Петербург
Поблагодарили: 6 раз

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

Сообщение skr »

Если вдруг кому интересен пример макроса для преобразования 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...
Ответить

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