Стартовая страница › Форумы › Понять, как работает ПО › Правильная настройка под МДВВ
Помечено: МДВВ
- В этой теме 63 ответа, 4 участника, последнее обновление 8 лет, 10 месяцев назад сделано
Mikhail.
-
АвторЗаписи
-
20.07.2016 в 15:48 #2613
djbond07УчастникСпасибо, сработало, команды отправляются. Теперь такой момент.
У меня есть 4 команды, которые активируются либо по сигналу с модуля автоматического управления, либо по нажатию кнопок в веб-приложении. Они раньше были стандартными. Мне сейчас нужно завести ещё один канал управления, с которого фактически будет идти управление МДВВ, и в нём указать формулу: «Если активирована команда N, то к маске выходов прибавить код команды и отправить на выполнение»? Но как в формулах сослаться на канал управления по его номеру? В функциях, которые описаны в документации, привязка к каналам управления не описана.20.07.2016 в 17:03 #2616
MikhailМодераторПопробуйте заменить бинарную команду на стандартную (сначала в Коммуникаторе). Если сработает, то будет проще настраивать.
Посмотрите документацию по формулам, там написано, как с помощью формулы можно изменить значение команды и использовать значение, введённое пользователем. Привязка к каналам управления не нужна, нужно только значение, которое ввёл пользователь при отправке команды и текущие значения входных каналов.
20.07.2016 в 18:12 #2618
djbond07УчастникМодуль не принимает команды кроме бинарной, к сожалению для меня. Даже бинарные принимает только в формате 16-ричных данных и только 4 цифры (то есть 00FF, а не FF, например). Соответственно, я не смогу изменить на стандартную. Я вообще не представляю как это можно сделать, если мы можем обращаться только полностью к маске.
С формулой попробую завтра разобраться. Вам спасибо огромно за помощь =) Нужно собрать сливки форума и издать 4-ю часть руководства =)
21.07.2016 в 10:33 #2621
MikhailМодераторТогда с помощью модуля автоматического управления можно сделать триггер на команду и, получив одну, отправлять другую.
00FF — это 2 байта, так что всё правильно для Модбас.
С помощью стандартной команды можно отправлять до 8 байт. Нужно, чтобы отправляемое число double при переводе в байты превращалось в нужное значение — там будет хитрая формула.21.07.2016 в 11:51 #2622
djbond07УчастникДобрый день! Скажите, пожалуйста, почему тип данных для переменной CmdData — byte[], а не byte? зачем эти квадратные скобочки в конце? В синтаксисе C# они есть разве? Дело в том, что компилятор ругается на неявное преобразование byte в byte[], если задать формулу в таком виде:
public byte Outputs()
{
byte rez=(byte)1;
return rez;
}
В CalcEngine строка
public void CalcCmdData1(ref byte[] cmdData) { try { BeginCalcCmdData(1, 0.0, cmdData); cmdData = Outputs(); } finally { EndCalcCmdData(); }}
генерируется самим сервером, и именно тут присутствует тип byte[].
Если же в формуле изначально использовать тип byte[], то выскакивает та же ошибка, но в этом случае компилятор ругается на саму формулу:
public byte[] Outputs()
{
byte[] rez=(byte)1;
return rez;
}
Как правильно написать?И второй момент. Вы правильно сказали, что расчёт данных КУ нужно делать побитовым сложением маски выходов и данных КУ, которые необходимо внести. Но как быть, если мне нужно будет отключить один выход? побитовое вычитание? тогда нужна будет вторая формула, и как сервер разберётся какую формулу применить при получении данных команды управления? Здесь я не совсем понимаю дальнейшие мои шаги…
-
Ответ изменён 10 лет, 1 месяц назад пользователем
djbond07.
21.07.2016 в 12:24 #2624
djbond07УчастникНасчёт триггера на команду, идея хорошая. так хотя бы не придётся в таблице менять типы команд. И при работе в визуальном интерфейсе пользователю будет проще отправлять команды.
С помощью стандартной команды можно отправлять до 8 байт. Нужно, чтобы отправляемое число double при переводе в байты превращалось в нужное значение — там будет хитрая формула.
Вот тут требуется уточнение. Вы предлагаете сделать триггер на КУ в модуле автоматического управления, и с помощью него отправлять опять же стандартные команды в десятичном формате? И далее завести одну формулу, которая будет побитово складывать эти команды с маской выходов, преобразовывать в 16-чные данные, и отправлять? или я неправильно понял?
21.07.2016 в 14:48 #2626
manjey73Участникbyte[] — это массив байт а не одна штука…
в C# как бы есть и то и то.Потом массив байт надо преобразовать в необходимый тип и уже потом отдавать его на выход.
Насколько понимаю, скорее придется работать со строкой.
Типа вводим 12F34D а формула должна раскидать строку, правильно ее преобразовать в массив байт типа 0х12 0хF3 0x4D и эти байты отправить в команде.Ну или наоборот.
21.07.2016 в 17:56 #2632
djbond07УчастникВ общем слепил формулу для тестирования работы:
public byte[] Outputs()
{
int rez=2|1;
byte[] Out= BitConverter.GetBytes(rez);
return Out;
}Работает, компилятор не ругается. Единственное, что порядок данных не тот. Результат выполнения формулы:
Команда ТУ: тип = Binary, номер КП = 61, данные = 03000000
А мне как раз надо 00000030. Как поменять порядок? Я понимаю, что это вопрос тупо по программированию, я пытаюсь сам сделать, но компилятор ругается то на одно, то на другое =(21.07.2016 в 17:59 #2633
manjey73УчастникЕсть функция, меняющая порядок байт.
Дома гляну, сейчас точно не помню… надо будет добавить в формулу
Только у вас как-то странно. почему 030 а не 003 на конце должно быть ?-
Ответ изменён 10 лет, 1 месяц назад пользователем
manjey73.
22.07.2016 в 08:32 #2636
djbond07УчастникРешил вопрос так:
public byte[] Outputs()
{
short rez=2|1;
byte[] Out= BitConverter.GetBytes(rez);
if (BitConverter.IsLittleEndian)
Array.Reverse(Out);
return Out;
}В итоге вывод 0003, и команда оправляется, выходы активируются. Заменил int на short, чтобы получить 2 байта, а не 4. А то данные 00000003 коммуникатор не понимает, только 0003. Буду дальше разбираться, как увязать сюда данные команды управления, и как реализовать не только включение (через побитовое сложение), но и выключение элементов…
22.07.2016 в 08:44 #2638
manjey73Участникprivate void Reverse_array(byte[] buf_rev, bool out_LE) //out_LE = false — старшим байтом вперед, true — младшим байтом вперед с проверкой архитектуры
{
if (!out_LE & BitConverter.IsLittleEndian) Array.Reverse(buf_rev);
if (out_LE & !BitConverter.IsLittleEndian) Array.Reverse(buf_rev);
}Я вот такую функцию забацал, так как иногда надо и старшим байтом вперед сделать, в том числе с проверкой архитектуры.
22.07.2016 в 10:20 #2640
djbond07УчастникСделал формулу, но она почему-то не отрабатывает.
public byte[] Outputs()
{byte[] Dannye=CmdData;
if (BitConverter.IsLittleEndian)
Array.Reverse(Dannye);
int DannyeInt = BitConverter.ToInt16(Dannye, 0);
short rez=(short)((int)Val(3)|DannyeInt);
byte[] Out=BitConverter.GetBytes(rez);
if (BitConverter.IsLittleEndian)
Array.Reverse(Out);
return Out;
}Данные команды управления отправляет модуль автоматического управления в формате 16-ричных данных.Строчка short rez=(short)((int)Val(3)|DannyeInt); выполняет побитовое сложение маски выходов с данными команды управления. Но почему-то вместо этого в результате просто данные команды управления отправляются на выполнение.
Вот пример: Маска выходов = 6. то есть активированы 2 и 3 выходы. Модуль автоматического управления отправляет команду 0001. После побитового сложения должно получиться 7, и в дополнении к 2 и 3 выходу, активироваться 1-й. Но в результате 2 и 3 выходы выключаются, а первый активируется.
22.07.2016 в 11:31 #2641
MikhailМодераторРекомендую установить Visual Studio 2015 Community Edition и для отладки формул создать простое консольное приложение. В нормальном отладчике Вы быстро найдёте причину.
22.07.2016 в 13:51 #2642
djbond07УчастникЯ как раз этим занимаюсь. В визуал студио всё хорошо, вот что происходит:
Код C#:
static void Main(string[] args)
{
byte[] CmdData = { 0x00, 0x01 };
int Val3 = 6;
byte[] Dannye = CmdData;
if (BitConverter.IsLittleEndian)
Array.Reverse(Dannye);
int DannyeInt = BitConverter.ToInt16(Dannye, 0);
short rez = (short)((int)Val3 | DannyeInt);
byte[] Out = BitConverter.GetBytes(rez);
if (BitConverter.IsLittleEndian)
Array.Reverse(Out);
Console.WriteLine(Out[0]);
Console.WriteLine(Out[1]);
Console.WriteLine(BitConverter.ToString(Out));
Console.ReadLine();
}Имеем: CmdData в формате массива, и Val(3) в int. На выходе получаем массив байтов (Out), равный побитовому сложению этих 2-х переменных.
Вывод программы:
0
7
00-07
Вроде всё хорошо, получили массив с результатом операции. Но в базе данных не работает. Конечная формула такая:public byte[] Outputs()
{byte[] Dannye = CmdData;
if (BitConverter.IsLittleEndian)
Array.Reverse(Dannye);
int DannyeInt = BitConverter.ToInt16(Dannye, 0);
short rez = (short)((int)Val(3) | DannyeInt);
byte[] Out = BitConverter.GetBytes(rez);
if (BitConverter.IsLittleEndian)
Array.Reverse(Out);
return Out;
}Грубо говоря у меня есть канал управления, тип команды бинарная, поле «значение» оставил пустым, поставил галочку, и ввёл формулу «Outputs()». Я на этот канал посылаю команду в формате 16-ричных данных вида «0001». Почему-то эти данные КУ минуют формулу, и сразу идут на выполнение…Не понимаю, почему.
Добавлю скриншоты, чтобы было понятнее. Я чувствую, что какую-то мелочь просто упустил.
https://drive.google.com/open?id=0Bzn5jzldeU-dX0tQZmZ2Zl9KZFE-
Ответ изменён 10 лет, 1 месяц назад пользователем
djbond07.
22.07.2016 в 14:49 #2644
MikhailМодераторЧто касается меня, то могу разработать нужную формулу на коммерческой основе 🙂 Собственно, за счёт оказания связанных услуг и развивается проект.
-
Ответ изменён 10 лет, 1 месяц назад пользователем
-
АвторЗаписи
- Для ответа в этой теме необходимо авторизоваться.