А так не получается.
Вид для печати
Вложение 66217со справки начинайте всегда искать причины
Добрый день знатокам!
Работаю над реализацией функционального блока для взаимодействия с сервоприводом. Сервоприводов будет несколько но не суть.
В проекте использую OwenCommunication обмен данными идет по шине Modbus RS485
На данный момент обмен реализовал через стек, в стек загружаются данные. примерно так:
fbComControl : OCL.COM_Control;
fbSerialRequest : OCL.MB_SerialRequest;
hCom : OCL.CAA.HANDLE;
fbComControl
(
xEnable := TRUE,
udiComPort := 1,
udiBaudRate := 115200,
udiByteSize := 8,
eParity := OCL.COM_PARITY.NONE,
eStopBit := OCL.COM_STOPBIT.ONE,
hCom => hCom
);
fbSerialRequest
(
xExecute := TRUE,
hCom := hCom,
tTimeout := T#100MS,
usiRetry := 3,
xIsAsciiMode:= FALSE,
usiSlaveId := fbAxisDrives[iAxisIndex].usiSlaveId,
eFuncCode := fbAxisDrives[iAxisIndex].stStack.eFuncCode,
uiDataAddr := fbAxisDrives[iAxisIndex].stStack.uiDataAddr,
uiDataCount := fbAxisDrives[iAxisIndex].stStack.uiDataCount,
pData := fbAxisDrives[iAxisIndex].stStack.pData,
szSize := fbAxisDrives[iAxisIndex].stStack.szSize
);
Все в таком виде вполне работоспособно, но!!! Не очень эстетично. Я бы хотел инкапсулировать OCL.MB_SerialRequest; в функциональный блок взаимодействия с устройством. Но в таком случае получается что будет запущено несколько экземпляров OCL.MB_SerialRequest; используя один и тот-же OCL.CAA.HANDLE; для Com-порта.
Допустимо ли такое?
В документации указано что можно запускать до 20 экземпляров в рамках одного цикла работы контроллера. Меня это вполне устроило бы
Заранее признателен за консультацию
Добрый день.
Если вы напишите арбитр, который будет контролировать, что в каждый момент времени вызывается только один из экземпляров вашего ФБ - то да.Цитата:
Допустимо ли такое?
RS-485 - это последовательный интерфейс. В каждый момент времени на шине должна осуществляться передача только одной посылки.Цитата:
В документации указано что можно запускать до 20 экземпляров в рамках одного цикла работы контроллера.
Поэтому достаточно объявить один экземпляр ФБ и последовательно вызывать его с разными аргументами (адресами слэйвов, адресами регистров и т.д.).
Ну вобщем я так и думал что так не будет работать, а жаль. Было бы гораздо красивееЦитата:
Если вы напишите арбитр, который будет контролировать, что в каждый момент времени вызывается только один из экземпляров вашего ФБ - то да.
Я же могу в своем ФБ выставлять флаг Com занят/свободен. если свободен, другой экземпляр моего ФБ может начать передачу и выставить флаг Занят до окончатия приема/передачи. Ведь так?
Но все-же как же это в документации правильно интерпретировать?
Цитата:
8.2 Ограничения, связанные с библиотекой CAA AsyncManager
Библиотеки, включающие в себя асинхронно выполняемые функциональные блоки (к таким
библиотекам, например, относятся CAA SerialCom, CAA NetBaseServices, CAA File и др.),
используют в своей реализации библиотеку CAA AsyncManager.
Данная библиотека имеет следующее ограничение: в каждый момент времени (в пределах
одного цикла контроллера) в программе может вызываться не более 20 экземпляров
асинхронно выполняемых функциональных блоков.
Безусловно, в своем коде вы можете делать всё, что считаете нужным.Цитата:
Я же могу в своем ФБ выставлять флаг Com занят/свободен. если свободен, другой экземпляр моего ФБ может начать передачу и выставить флаг Занят до окончатия приема/передачи. Ведь так?
Именно так, как написано. В документации этому моменту посвящена целая страница, на которой приведены конкретные примеры.Цитата:
Но все-же как же это в документации правильно интерпретировать?
Подскажите, с чем может быть связана ошибка? Скриншот делался без подключения к ПЧ, также эта ошибка высвечивается если виртуальным контроллером подключиться к реальному ПЧ и связь установлена (зеленые стрелочки).
Добрый день. Прошу помощи в поиске путей решения следующей задачи:
Есть некоторое оборудование, производящее изделия, т.е. процесс работы не непрерывный. Требуется выводить на печать на внешний ПК (для этой машины он предусмотрен отдельный) графики параметров работы - температуры, давления, технологических настроек и т.п. для конкретных изделий.
Я представляю это примерно так - по запуску цикла работы оборудования запускается архивирование, по завершению - останавливается. Вероятнее всего с сохранением в отдельный файл, очень желательно и график, и таблица. При необходимости оператор каким-либо образом должен иметь возможность найти данные по конкретному изделию и распечатать по нему отчет. Идентификатор изделия наверное должен и быть теми данными, по которым осуществляется поиск файла архива или же поиск в базе данных
Планирую использовать, скорее всего, СПК107. Возможно ли реализовать подобный режим архивирования? Или же нужно применить какую-либо SCADA? если второй вариант, то какую именно? Или же существует некоторое готовое решение в виде отдельного архиватора, позволяющее такое реализовать?
Если пишу не в той теме, прошу указать, где лучше разместить вопрос
Напишите этот вопрос на support@owen.ru, пожалуйста - вас проконсультируют по настройке AFD-E для управления по интерфейсу.
Но навскидку - функцию надо выбрать WRITE_SINGLE_REGISTER.
https://owen.ru/forum/showthread.php...l=1#post402051
Тогда - технически это реализуемо на СПК, но потребует определенных усилий.
Описание отдельных аспектов текстом заняло бы много времени; я предлагаю обсудить это голосом.
Напишите мне в личку ваш контактный телефон (и укажите, привязан ли к нему telegram) и во сколько с вами в понедельник можно будет связаться.
Я писал по поводу Com-порта и до сих пор ответа нету, только Вы ответили.
с этой функцией не работает, при опросе в Owen OPC Server используется WRITE_MULTIPLE_REGISTERS и меня смущает параметр xDone, если я правильно понимаю при правильной записи должен принять TRUE. И в Owen OPC Server есть параметр включен в работу, может в коде надо еще что-то передать?
Можно и WRITE_MULTIPLE_REGISTERS использовать, но по документации - WRITE_SINGLE_REGISTER тоже подходит.
Судя по новым скриншотам - у вас блок нигде не вызывается.
Для вызова надо в строке 42 (указал ее для примера) сделать так:
Код:fbMbSerialRequest();
После этого наблюдайте за значениями выходов ФБ.
Я ведь правильно понимаю, что значение eState вы пока вручную для отладки меняете, а не пытаетесь им манипулировать где-то в коде, который не попал на скриншоты?
Выкладываю код, в этом виде ПЧ запускается на 1с, не у верен что правильно поставил fbMbSerialRequest() и хотелось бы понять куда правильнее его установить.
Код://Проверка привода на готовоность
fbComControl1
(
xEnable := TRUE,
udiComPort := 5,
udiBaudrate := 9600,
udiByteSize := 8,
eParity := OCL.COM_PARITY.NONE,
eStopBit := OCL.COM_STOPBIT.ONE
);
IF fbComControl1.xActive THEN
IF xKnop THEN
eState := 20;
END_IF
IF xStop THEN
eState := 40;
END_IF
CASE eState OF
10: // Опрос состояния AFD-E
20: // запуск AFD-E
fbMbSerialRequest();
wCmdWord := 22;
fbMbSerialRequest.xExecute := TRUE;
fbMbSerialRequest.hCom := fbComControl1.hCom;
fbMbSerialRequest.xIsAsciiMode := FALSE;
fbMbSerialRequest.usiSlaveId := 15; //адрес слейва
fbMbSerialRequest.eFuncCode := OCL.MB_FC.WRITE_SINGLE_REGISTER ; //функция
fbMbSerialRequest.uiDataAddr := 4864; // адрес начального запроса
fbMbSerialRequest.uiDataCount := 1; //число регистров
fbMbSerialRequest.pData := ADR(wCmdWord);
fbMbSerialRequest.szSize := SIZEOF(wCmdWord);
//fbMbSerialRequest.xError := xError;
//fbMbSerialRequest.eError := wError;
xLampRab := TRUE;
xLampOff := FALSE;
30: // Реверс
wCmdWord := 54;
fbMbSerialRequest.usiSlaveId := 15; //адрес слейва
fbMbSerialRequest.eFuncCode := OCL.MB_FC.WRITE_SINGLE_COIL; //функция
fbMbSerialRequest.uiDataAddr := 4864; // адрес начального запроса
fbMbSerialRequest.uiDataCount := 1; //число регистров
fbMbSerialRequest.pData := ADR(wCmdWord);
fbMbSerialRequest.szSize := SIZEOF(wCmdWord);
xLampRab := TRUE;
xLampOff := FALSE;
40: // Стоп
wCmdWord := 166;
fbMbSerialRequest.usiSlaveId := 15; //адрес слейва
fbMbSerialRequest.eFuncCode := OCL.MB_FC.WRITE_SINGLE_COIL; //функция
fbMbSerialRequest.uiDataAddr := 4864; // адрес начального запроса
fbMbSerialRequest.uiDataCount := 1; //число регистров
fbMbSerialRequest.pData := ADR(wCmdWord);
fbMbSerialRequest.szSize := SIZEOF(wCmdWord);
xLampRab := FALSE;
xLampOff := TRUE;
IF fbMbSerialRequest.xDone OR fbMbSerialRequest.xError THEN
//xCommand := FALSE;
END_IF
END_CASE
ELSE
;
END_IF
Начните с этого:
Код:VAR
...
fbKnopTrig: R_TRIG;
END_VAR
// Проверка привода на готовность
fbComControl1
(
xEnable := TRUE,
udiComPort := 5,
udiBaudrate := 9600,
udiByteSize := 8,
eParity := OCL.COM_PARITY.NONE,
eStopBit := OCL.COM_STOPBIT.ONE
);
IF fbComControl1.xActive THEN
fbKnopTrig(CLK := xKnop);
IF fbKnopTrig.Q THEN
eState := 20;
END_IF
CASE eState OF
0: // ожидание команды
10: // Опрос состояния AFD-E
20: // запуск AFD-E
wCmdWord := 22;
fbMbSerialRequest.xExecute := TRUE;
fbMbSerialRequest.hCom := fbComControl1.hCom;
fbMbSerialRequest.xIsAsciiMode := FALSE;
fbMbSerialRequest.usiSlaveId := 15; // адрес слейва
fbMbSerialRequest.eFuncCode := OCL.MB_FC.WRITE_SINGLE_REGISTER; // функция
fbMbSerialRequest.uiDataAddr := 4864; // адрес начального запроса
fbMbSerialRequest.uiDataCount := 1; // число регистров
fbMbSerialRequest.pData := ADR(wCmdWord);
fbMbSerialRequest.szSize := SIZEOF(wCmdWord);
fbMbSerialRequest();
// fbMbSerialRequest.xError := xError;
// fbMbSerialRequest.eError := wError;
IF fbMbSerialRequest.xDone OR fbMbSerialRequest.xError THEN
fbMbSerialRequest(xExecute := FALSE);
eState := 0;
END_IF
END_CASE
END_IF
Спасибо дело сдвинулось с мертвой точки)
С Вашим кодом двигатель запускается на 1с, я правильно понимаю что бы запуск был постоянным надо постоянно отправлять запрос?
так будет правильно или есть более правильное написание кода с отправкой команды?Код:IF fbMbSerialRequest.xDone OR fbMbSerialRequest.xError THEN
fbMbSerialRequest(xExecute := FALSE);
eState := 20;
END_IF
Это должны специалисты по ПЧВ из нашей техподдержки пояснить. По моим воспоминаниям - при корректной настройке ПЧВ должно быть достаточно однократной отправки команды.Цитата:
С Вашим кодом двигатель запускается на 1с, я правильно понимаю что бы запуск был постоянным надо постоянно отправлять запрос?
При отсутствии запросов от мастера ПЧ уходит в безопасный режим?
Евгений Кислов, если Вам не сложно могли бы Вы объяснить почему в конце перечисления добавили fbMbSerialRequest()
На канале ОВЕНа в Ютубе есть вебинар по работе с библиотекой OwenCommunication и там при записи или считывании опускаютКод:wCmdWord := 22;
fbMbSerialRequest.xExecute := TRUE;
fbMbSerialRequest.hCom := fbComControl1.hCom;
fbMbSerialRequest.xIsAsciiMode := FALSE;
fbMbSerialRequest.usiSlaveId := 15; // адрес слейва
fbMbSerialRequest.eFuncCode := OCL.MB_FC.WRITE_SINGLE_REGISTER; // функция
fbMbSerialRequest.uiDataAddr := 4864; // адрес начального запроса
fbMbSerialRequest.uiDataCount := 1; // число регистров
fbMbSerialRequest.pData := ADR(wCmdWord);
fbMbSerialRequest.szSize := SIZEOF(wCmdWord);
fbMbSerialRequest();
есть ли какие-то условия в указании этих переменных?Код:fbMbSerialRequest.xExecute := TRUE;
fbMbSerialRequest.hCom := fbComControl1.hCom;
fbMbSerialRequest.xIsAsciiMode := FALSE;
и в руководстве по Modbus пишут следующим образом
я правильно понимаю что это равнозначное написание или все таки есть разница?Код:wCmdWord := 22;
fbMbSerialRequest
(
xExecute := TRUE;
hCom := fbComControl1.hCom;
xIsAsciiMode := FALSE;
usiSlaveId := 15; // адрес слейва
eFuncCode := OCL.MB_FC.WRITE_SINGLE_REGISTER; // функция
uiDataAddr := 4864; // адрес начального запроса
uiDataCount := 1; // число регистров
pData := ADR(wCmdWord);
szSize := SIZEOF(wCmdWord);
);
Это вызов экземпляра ФБ.Цитата:
если Вам не сложно могли бы Вы объяснить почему в конце перечисления добавили fbMbSerialRequest()
Без него было примерно так - "погрузили все вещи в машину, но на газ не нажали".
Действительно, блоки кода 1 и 3 из вашего поста - семантически эквивалентны.Цитата:
я правильно понимаю что это равнозначное написание или все таки есть разница?
В вебинаре показан еще один подход ("лаконичный"), когда вызов экземпляра ФБ происходит только в одном месте (и вот там как раз ему передаются значения на входы xExecute, hCom и xIsAsciiMode), а на шагах CASE другим его входам присваиваются параметры конкретного запроса (адрес устройства, адрес регистра и т.д.).
Я рекомендую вам использовать тот подход, который для вас более понятен.
День добрый.
Подскажите пожалуйста, как в CoDeSys организовано развёртывание проекта на множество устройств? Желательно без использования самой IDE CoDeSys, автономно.
Добрый день.
Типовое решение, предлагаемое CODESYS - их Automation Server.
https://www.automation-server.com/en/
А есть варианты нетиповых решений?
Не могу вам ничего готового автоматизированного предложить, извините.
Можно попробовать в сторону скриптового движка CODESYS IDE посмотреть (но тогда на ПК все равно потребуется ее установить):
https://content.helpme-codesys.com/e...tart_page.html
возможно Вы про это спрашиваете https://youtu.be/dJf4FMQoi0o?t=204
Ссылка на пост где ссылаются на видео https://owen.ru/forum/showthread.php...l=1#post401847
Вложение 66342