Управление контроллером DSE7320 по modbus

Стартовая страница Форумы Взаимодействие с устройствами Управление контроллером DSE7320 по modbus

Помечено: 

Просмотр 15 сообщений - с 1 по 15 (из 24 всего)
  • Автор
    Записи
  • #28394
    George
    Участник

    Добрый день.
    Имеется контроллер дизель-генератра DeepSea DSE7320.
    С чтением данных вроде разобрался, но столкнулся с проблемой отправки команд на него. Сложность заключается в том, что контроллер реагирует на управление по модбас только при одновременной записи ключей в два регистра, причем во второй регистр ключ должен быть записан в обратном порядке бит.
    Выдержка из мануала
    Я пошел следующим путём:
    1. В шаблоне КП добавил две команды : для регистров 4104 и 4105 с номерами команд кп 1 и 2 соттветственно.
    4104+1
    также во втором отдельном случае пробовал менять код команды 6 на 16 (множественная команда)
    случай2
    2. Создал канал управления для триггера в ModAutoControl команда стоп- канал №8
    3. В автоматическом управлении создал триггер: при канал8 = 1 идёт отправка двух команд ТУ с записью значений в указанные в шаблоне кп регистры:
    команда1
    команда2

    В результате если в шаблоне кп была использована функия 6 для записи в регистр -комуникатор выдавал ошибку связи
    ошибка

    А если в шаблоне кп стояла галочка «множественная команда» (функция 16), то комуникатор возвращал exception 2 illegal data adress. К сожалению скриншот не сохранил.
    В обоих случаях контроллер на команды не реагировал.
    Подскажите, пожалуйста, куда копать?

    #28396
    manjey73
    Участник
    public byte[] WriteSysDt()
    {
    DateTime dt = DateTime.Now;
    var year = BitConverter.GetBytes((ushort)dt.Year);
    byte[] cmdData = new byte[12] {0, (byte)dt.Minute, 0, (byte)dt.Second, 0, (byte)dt.Hour,
    0, (byte)dt.Day, 0, (byte)dt.Month, 0, 0};
    cmdData[10] = year[1];
    cmdData[11] = year[0];
    return cmdData;
    }

    Пример формулы записи времени через несколько регистров. Где секунды, минуты и так далее в виде целочисленных регистров.

    #28397
    manjey73
    Участник

    То есть копайте в отправке модулем формулы, которая будет возвращать byte[]
    а в настройках команды уже сами думайте, будет это набор регистров или это будет одна команда на требуемое количество регистров.

    #28398
    manjey73
    Участник

    Извиняюсь, команда должна быть одна, множественная с требуемы количеством регистров.

    #28401
    Mikhail
    Модератор

    Добрый день!
    Посмотрите здесь в подпапке «Автор неизвестен», может быть что-то полезное найдёте. В KpModbus_DSE86oke.xml, похоже, аналогичная команда используется.

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

    • Ответ изменён 3 года, 1 месяц назад пользователем Mikhail.
    • Ответ изменён 3 года, 1 месяц назад пользователем Mikhail.
    #28407
    George
    Участник

    Действительно, судя по шаблону

    KpModbus_DSE86oke.xml

    нужно отправлять множественной командой в два подряд идущих регистра.
    Но мне не хватает знаний, как это организовать. Ранее использовал команды для изменения конкретных регистров (например чтобы запустить команду запуск в контроллер Datakom — мне нужно в регистре №8193 бит№4 поставить в 1. Для этого я просто использовал команду записи с функцией 6 write holding registers с командой ТУ с формулой 16.)
    Как работать с множественной командой я пока не разобрался.
    На сколько я понял, если бы мне нужно был отправить одинаковое значение (напр. 35700) в два подряд идущих регистра, то я просто отправлял командой ТУ формулу 35700 с множественной командой в шаблоне на адресса 4104-4105. Но как одной командой отправить разные значения в 2 идущих подряд регистра?
    Напр 35700 в регистр 4104 и 29835 в регистр 4105?

    #28408
    manjey73
    Участник

    Множественная команда

    Пример формулы давал выше.
    Учитывая, что у вас всего два регистра, то есть 4 байта, можно команду сделать в виде uint, int и использовать при возврате формулы не byte[] для CmdData а просто Cmd.
    Но это играться… проще наверное использовать CmdData и соответственно ваш код авторизации привести к ushort
    При чем в первом варианте в массив вставить как есть, во втором переставить байты местами ну или вообще развернуть полностью все вплоть до битов. Не знаю как у вас точно должно выглядеть.

    #28409
    manjey73
    Участник

    Судя по вашим значениям у вас просто переставлены байты местами во втором варианте.

    Вы можете использовать пример, который я выложил с ushort но только для количества 2.
    В формуле вам надо будет сделать примерно следующее

    public byte[] PassDSE(ushort val1) // тут вы подаете свое 35700, можете сделать входную как double чтобы забирать из канала а уже тут внутри формулы преобразовать в ushort и дальше обрабатывать
    {
    var valShort = BitConverter.GetBytes(val1); // байтовый массив вашего числа
    byte[] cmdData = new byte[4] {valShort[0], valShort[1], valShort[1], valShort[0]};
    return cmdData;
    }

    з.ы. не проверял, но что-то в этом роде..

    • Ответ изменён 3 года, 1 месяц назад пользователем manjey73.
    #28412
    Mikhail
    Модератор

    Для начала я бы рекомендовал в формуле канала управления вернуть массив из 16 байт со значениями 1, 2,… Посмотреть в журнале линии связи, что фактически отправится и расшифровать пакет с помощью https://rapidscada.net/modbus Скриншоты можете сюда приложить.

    #28415
    George
    Участник

    Уважаемые Mikhail и manjey73, огромное Вам спасибо за уделённое время и помощь. Разобрался как правильно использовать формулы на сколько смог. В итоге всё заработало.
    Использовал следующую формулу:
    public byte[] PassDSE(ushort val1)
    {
    var valShort = BitConverter.GetBytes(val1);
    byte[] cmdData = new byte[16] {
    valShort[0], valShort[1], valShort[1], valShort[0],
    valShort[0], valShort[1], valShort[1], valShort[0],
    valShort[0], valShort[1], valShort[1], valShort[0],
    valShort[0], valShort[1], valShort[1], valShort[0]
    };
    return cmdData;
    }

    При установке в канале управления формулы PassDSE(35700) в онлайн парсере обнаружил что запись в регистры идёт наоборот:

    запрос: 0A 10 10 08 00 02 04 74 8B 8B 74 17 E0

    Part of Data Package Description Value
    0A Slave address 0x0A (10)
    10 Function code 0x10 (16) — Write Multiple Registers
    10 08 Starting address Physical: 0x1008 (4104)
    Logical: 0x1009 (4105)
    00 02 Quantity 0x0002 (2)
    04 Byte count 0x04 (4)
    74 8B 8B 74 Registers value 0x748B (29835), 0x8B74 (35700)
    17 E0 CRC 0x17E0 (6112)

    Изменил PassDSE(35700) на PassDSE(29835) и всё заработало.

    Ещё раз огромное спасибо Вам! Добра, мира и хороших выходных 😉

    #28419
    manjey73
    Участник

    Ого, а почему у вас массив из 16-ти байт? вам надо несколько раз повторять пароль в регистрах ?
    з.ы. можно было просто поменять valShort[0], valShort[1], valShort[1], valShort[0]

    на valShort[1], valShort[0], valShort[0], valShort[1] по идее 🙂

    #28420
    manjey73
    Участник

    Ого, а почему у вас массив из 16-ти байт? вам надо несколько раз повторять пароль в регистрах ?
    з.ы. можно было просто поменять valShort[0], valShort[1], valShort[1], valShort[0]

    на valShort[1], valShort[0], valShort[0], valShort[1] по идее 🙂

    Ну и если сделать входную переменную PassDSE(double val2) то внутри формулы можно сделать
    ushort val1 = (ushort)val2
    и соответственно формулу вызывать как PassDSE(Val(XXX)) где ХХХ — номер канала в котором вы храните пароль

    #28436
    Mikhail
    Модератор

    Что касается моего сообщения, я написал 16 байт с запасом. Используются ли они все или только часть станет видно в журнале при отправке команды.

    Порядок байт можно в настройках команды задать. Но там только от 0-го до 9-го. Надо бы добавить A…F.

    • Ответ изменён 3 года, 1 месяц назад пользователем Mikhail.
    #28448
    George
    Участник

    Здравствуйте,
    действительно, поправил формулу:
    public byte[] PassDSE(ushort val1)
    {
    ushort val2Short = (ushort)(ushort.MaxValue — val1);
    byte[] val1Bytes = BitConverter.GetBytes(val1);
    byte[] val2Bytes = BitConverter.GetBytes(val2Short);
    byte[] cmdData = new byte[4] { val1Bytes[1], val1Bytes[0], val2Bytes[1], val2Bytes[0] };
    return cmdData;
    }
    Теперь работают почти все нужные команды: val1=35700 — ok,
    val1=35701 — ok,
    val1= 35705 -ok,
    val1= 35706 -ok,
    val1= 35734 — ok,

    но при val1= 35702 в логе коммуникоатора происходит следующее:
    2023-05-08 12:17:44 Команда КП 1 «d500», тип: KpModbus, адрес: 10
    Команда «Key»
    Отправка (13): 0A 10 10 08 00 02 04 00 00 00 02 9B 2C
    Приём (5/5): 0A 90 02 BC 03
    Ошибка устройства: [02] ILLEGAL DATA ADDRESS!

    В modbus parser расшифровка:
    Part of Data Package Description Value
    0A Slave address 0x0A (10)
    10 Function code 0x10 (16) — Write Multiple Registers
    10 08 Starting address Physical: 0x1008 (4104)
    Logical: 0x1009 (4105)
    00 02 Quantity 0x0002 (2)
    04 Byte count 0x04 (4)
    00 00 00 02 Registers value 0x0000 (0), 0x0002 (2)
    9B 2C CRC 0x9B2C (39724)

    Почему-то записывает 0,2 вместо 35702, 29833.

    Вот пример правильной сработки при val1=35701:
    Коммуникоатор:
    Команда «Key»
    Отправка (13): 0A 10 10 08 00 02 04 8B 75 74 8A 86 74
    Приём (5/5): 0A 10 10 08 00
    Приём (3/3): 02 C5 B1
    OK!

    Online parser:
    Part of Data Package Description Value
    0A Slave address 0x0A (10)
    10 Function code 0x10 (16) — Write Multiple Registers
    10 08 Starting address Physical: 0x1008 (4104)
    Logical: 0x1009 (4105)
    00 02 Quantity 0x0002 (2)
    04 Byte count 0x04 (4)
    8B 75 74 8A Registers value 0x8B75 (35701), 0x748A (29834)
    86 74 CRC 0x8674 (34420)

    • Ответ изменён 3 года, 1 месяц назад пользователем George.
    #28453
    manjey73
    Участник

    А не проще было обойтись без ushort.MaxValue? просто кинув по разному байты в массив?

Просмотр 15 сообщений - с 1 по 15 (из 24 всего)
  • Для ответа в этой теме необходимо авторизоваться.