Стартовая страница › Форумы › Понять, как работает ПО › Использование формул › Дата время (BCD)
- В этой теме 58 ответов, 4 участника, последнее обновление 2 года, 6 месяцев назад сделано VylegzhaninD.
-
АвторСообщения
-
16.04.2022 в 16:00 #23070VylegzhaninDУчастник
Здравствуйте!
Ситуация следующая: прибор имеет ряд значений времени, описаны производителем как:
Register Size Mode/Access Data Type Description полученное
(Reg) значение
0 1 Только чтение uint16 текущая дата, ДДММ(BCD) 5636
1 1 Только чтение uint16 текущая дата, ГГ(BCD) 8226
2 1 Только чтение uint16 текущее время, ЧЧММ(BCD) 5926
9 1 Только чтение uint16 дата конфигурации, ДДММ(BCD) 5380
10 1 Только чтение uint16 дата конфигурации, ГГ(BCD) 8226
11 1 Только чтение uint16 время конфигурации, ЧЧММ(BCD) 5144
22 2 Только чтение uint32 Наработка 6480
23Как я понимаю BCD — это двоично-десятичный код
В программе производителя это описано так:
private float GetFloatFrom2SHORT(ushort high, ushort low)
{
var hbytes = BitConverter.GetBytes(high);
var lbytes = BitConverter.GetBytes(low);
byte[] blist = new byte[4];
blist[0] = hbytes[0];
blist[1] = hbytes[1];
blist[2] = lbytes[0];
blist[3] = lbytes[1];
return BitConverter.ToSingle(blist, 0);
}private uint GetUint32From2SHORT(ushort high, ushort low)
{
var hbytes = BitConverter.GetBytes(high);
var lbytes = BitConverter.GetBytes(low);
byte[] blist = new byte[4];
blist[0] = hbytes[0];
blist[1] = hbytes[1];
blist[2] = lbytes[0];
blist[3] = lbytes[1];
return BitConverter.ToUInt32(blist, 0);
}public void GetCommon()
{
ushort[] receive;
try
{
receive = mdbs.ReadHoldingRegisters(1, indxMDBS_COMMON, LEN_MDBS_COMMON);
}
catch { isConnected = false; return; }ushort DD, MM, hh, mm, YY;
int op_indx = indxMDBS_COMMON;
DD = (ushort)((receive[op_indx + indx_MDBS_COMMON_CURR_DDMM] >> 8) & 0x00FF);
MM = (ushort)((receive[op_indx + indx_MDBS_COMMON_CURR_DDMM] >> 0) & 0x00FF);
YY = receive[op_indx + indx_MDBS_COMMON_СURR_YY];
hh = (ushort)((receive[op_indx + indx_MDBS_COMMON_CURR_hhmm] >> 8) & 0x00FF);
mm = (ushort)((receive[op_indx + indx_MDBS_COMMON_CURR_hhmm] >> 0) & 0x00FF);dateTime = $»{hh.ToString(«X2»)}:{mm.ToString(«X2»)} {DD.ToString(«X2»)}.{MM.ToString(«X2»)}.{YY.ToString(«X4″)}»;
DD = (ushort)((receive[op_indx + indx_MDBS_COMMON_CONF_DDMM] >> 8) & 0x00FF);
MM = (ushort)((receive[op_indx + indx_MDBS_COMMON_CONF_DDMM] >> 0) & 0x00FF);
YY = receive[op_indx + indx_MDBS_COMMON_CONF_YY];
hh = (ushort)((receive[op_indx + indx_MDBS_COMMON_CONF_hhmm] >> 8) & 0x00FF);
mm = (ushort)((receive[op_indx + indx_MDBS_COMMON_CONF_hhmm] >> 0) & 0x00FF);dateTimeConf = $»{hh.ToString(«X2»)}:{mm.ToString(«X2»)} {DD.ToString(«X2»)}.{MM.ToString(«X2»)}.{YY.ToString(«X4″)}»;
}(на чем написано не знаю, про наработку тоже не нашёл код)
Помогите, пожалуйста, с формулой для придания данным даты и времени человеческого вида?
16.04.2022 в 16:31 #23072MikhailМодераторДобрый день!
Синтаксис C#. Только в формулах Rapid SCADA не поддерживается ключевое слово var. Нужно явно писать тип.
Т.к. формулы довольно сложные, я бы рекомендовал установить Visual Studio 2022 Community, создать простейшее консольное приложение и сначала отладить эти формулы. Затем вставить в таблицу формул.
Написать и проверить готовые формулы — платная услуга. На форуме смогу подсказать по синтаксису.
16.04.2022 в 16:32 #23073MikhailМодератор0 1 Только чтение uint16 текущая дата, ДДММ(BCD) 5636
Что означает эта фраза на человеческом языке?
Вот Вы допустим считали значение регистра 16-бит. Как из него получить день и месяц?16.04.2022 в 17:15 #23077manjey73УчастникС трудом себе представляю 56 день и 36 месяц или наоборот.
А так же 8226 год…16.04.2022 в 17:46 #23079VylegzhaninDУчастник5636 — это значение в два байта, так? А по BCD я так понимаю надо каждый байт разбирать отдельно и отдельно переводить в десятичную систему…
16.04.2022 в 17:51 #23080VylegzhaninDУчастникИз википедии:
Двоично-десятичный код (англ. binary-coded decimal), BCD, 8421-BCD — форма записи рациональных чисел, когда каждый десятичный разряд числа записывается в виде его четырёхбитного двоичного кода. Таким образом, каждая тетрада двоично-десятичного числа может принимать значения от 00002 (010) до 10012 (910).Например, десятичное число 31110 будет записано в двоичной системе счисления в двоичном коде как 1 0011 0111, а в двоично-десятичном коде как 0011 0001 0001.
16.04.2022 в 18:29 #23081manjey73УчастникBCD формат, это когда в тетраде может быть число от 0 до 9 и никаких A-F
То есть число 99 и в байте будет выглядеть как 99h
А у вас производитель что-то напридумывал свое, но при этом ни в одном примере в числах нет букв A-F
Очень странно все это…
17.04.2022 в 11:51 #23086MikhailМодераторДДММ(BCD) 5636
Рассмотрим 5636.
В двоичном коде это 0001 0110 0000 0100
То есть 16.04Формулы для таблицы формул будут примерно такие:
public double GetDay(double val) { ushort x = (ushort)val; int d1 = (x >> 12) & 0x0F; int d2 = (x >> 8) & 0x0F; return d1 * 10 + d2; } public double GetMonth(double val) { ushort x = (ushort)val; int d1 = (x >> 4) & 0x0F; int d2 = x & 0x0F; return d1 * 10 + d2; }
Затем используйте их в формуле канала. Код не проверял.
17.04.2022 в 12:31 #23087manjey73УчастникОфигеть, в примерах в десятичном виде 🙂 а если в HEX посмотреть то действительно BCD
18.04.2022 в 11:29 #23100MikhailМодераторНепонятно, зачем разработчики контроллера усложняют жизнь инженеров.
16.04 — в BCD использует 2 байта.
16 (байт) + 04 (байт) также было бы 2 байта, если каждое число записать в полрегистра Модбас, но формула была бы проще.18.04.2022 в 11:30 #23101MikhailМодератор@vylegzhanind, какой это контроллер?
18.04.2022 в 12:29 #23107manjey73УчастникУсложнения могут быть связаны с отображением на экране прибора например.
18.04.2022 в 19:41 #23127VylegzhaninDУчастникэто расходомер сточных вод ВоСток
18.04.2022 в 22:17 #23128VylegzhaninDУчастникВсе формулы которые мной использовались ранее я вводил прямо в строке столбца «Формула» во входных каналах или каналах управления.
В этот раз я задаю в «Справочники» — «Формулы»
Номер: 13
Наименование: BCD
Исходный код: копирую из сообщения #23086Далее во входных каналах в «формула» пишу «BCD» и ставлю флаг использовать формулу. Так ли это надо сделать или как-то иначе?
По результату манипуляций Кп не работает.
18.04.2022 в 23:10 #23129a80808УчастникНу во первых там две формулы — GetDay(val) и GetMonth(val). Соответственно и в таблице Скриптов тоже должно быть их две.
Соответственно вызов формулы в канале должно выглядеть как
GetDay(vvv)
или
GetMonth(vvv)
В зависимости от того, что вы хотите получить в канале — день или месяцгде vvvv — это то, что вы получаете от контроллера.
Ну и смотрите Журнал сервера — там лог компиляции формул.
-
АвторСообщения
- Вы должны авторизироваться для ответа в этой теме.