Страница 2 из 6 ПерваяПервая 1234 ... ПоследняяПоследняя
Показано с 11 по 20 из 53

Тема: Читаем нестандартный протокол (SysLibCom, SysLibMem)

  1. #11
    Пользователь
    Регистрация
    02.03.2015
    Адрес
    г. Алексеевка
    Сообщений
    65

    По умолчанию

    Yegor, а вы капитально разбираетесь в контроллерах). Сейчас понимаю что мне много еще что познать надо... А может вы мне подскажете по библиотеке NetVar для кдс 2 если вы в ней копались основательно.

  2. #12

    По умолчанию

    Тоже столкнулся с продукцией данной компании, только с датчиком момента и скорости. Естественно, тоже уперся в то, что они называют Модбасом. И что самое удивительное - это действительно Модбас. В протоколе действительно зарезервированы номера функций 101-110 и 66-69 (могу ошибаться в диапазоне) для расширений производителя. А раз так, то нас может выручить блок MB_UNI_IO из Modbus.lib. Но он не выручает, потому как при попытке заменить им блоки MB_RD_* (MB_WR_*) компилятор ругается на конфликт типов данных в ComHandle.
    Выяснилось, что за каким-то лядом все входные переменные в блоке были сделаны VAR_IN_OUT, что и приводило к ошибкам компиляции. Пришлось вскрывать Modbus.lib и править объявление на такое:
    Код:
    FUNCTION_BLOCK MB_UNI_IO
    VAR_INPUT
    	Mode: MB_MODE;						(* Serial Transmission Mode of MODBUS networks *)
    	ComHandle:DWORD;				(*  äåñêðèïòîð ïîñëåäîâàòåëüíîãî ïîðòà áèáëèîòåêè SysLibCom *)
    	TimeOut: TIME; 						(* âðåìÿ òàéì-àóòà [ìñ] - ìàêñ. çàäåðæêà íà îáðàáîòêó çàïðîñà *)
    END_VAR
    VAR_IN_OUT
    	Complete: BOOL;						(* åñëè = TRUE, òî îáìåí çàâåðøåí *)
    	Exception: BYTE;						(* èñêëþ÷åíèÿ ïðîòîêîëà MODBUS *)
    	DataBuf: ARRAY[0..255] OF BYTE;	(* áóôåð äàííûõ êàäðà *)
    	DataSize: BYTE;						(* ðàçìåð êàäðà áåç êîíòðîëüíîé ñóììû *)
    END_VAR
    После этого пример из библиотеки заработал, как это ни странно, с минимальными переделками:
    Код:
    PROGRAM PLC_PRG
    VAR
    	(*Ïðèìåð ðàáîòû ñ ÷àñòîòíûì ïðèâîäîì ÎÂÅÍ Ï× ïî RS-485*)
    	com_num1: PORTS;					(*Íîìåð ïîðòà  íà êîòîðûé ïîäêëþ÷åíî îáîðóäîâàíèå*)
    	com_hndl: DWORD;
    	Settings1: COMSETTINGS;				(*Ïàðàìåòðû ïîðòà *)
    	COM_SERVICE1: COM_SERVICE;			(*Áëîê îòêðûòèÿ è íàñòðîéêè ïîðòà *)
    	com_ready1: BOOL;					(*Ñòàòóñ ïîðòà -  îòêðûò/çàêðûò*)
    	UNI:MB_UNI_IO;
    	i: BYTE;
    	command_word:WORD:=16#847C;
    	RT: R_TRIG;
    	t_zad:TIME:=T#20ms;
    	buffer: ARRAY[0..255] OF BYTE;
    	result: ARRAY[0..255] OF BYTE;
    	id: ARRAY[0..255] OF BYTE;
    	mode: MB_MODE := MB_RTU;
    	data_size: BYTE := 17;
    	compl: BOOL;
    	except: BYTE;
    	port_opened: BOOL;
    	mtype: INT;
    	crc: WORD;
    	crc1: WORD;
    END_VAR
    Код:
    (*****************************************************
    Ïðèìåð ðàáîòû ñ áèáëèîòåêîé SysLibCom
    
    ôîðìèðîâàíèå êîìàíäû â äâîè÷íîì âèäå
    *****************************************************)
    
    
    (*******************************************************
    	Îòêðûâàåì ïîðò
    *******************************************************)
    
    (*Îòêðûâàåì ïåðâûé ïîðò*)
    IF NOT com_ready1 THEN
    (*
    	Íîìåð ïîðòà (com_number):
    	0 - RS-485
    	1 - RS-232
    	4 - RS-232 DEBUG
    *)
    	com_num1 := 0;
    (*
    	Íàñòðîéêè ïîðòà (com_settings):
    	byParity         - Ðåæèì ïðîâåðêè ÷åòíîñòè 0 = íåò, 1 = íå÷åò, 2 = ÷åò
    	byStopBits     - Êîë-âî ñòîïîâûõ áèò 0 =îäèí, 1=ïîëòîðà , 2=äâà
    	dwBaudRate   - Ñêîðîñòü îáìåíà 4800, 9600, 19200, 38400, 57600, 115200 áèò/ñ.
    	dwBufferSize   - Íå èñïîëüçóåòñÿ äîëæíî áûòü =0
    	dwScan          - Íå èñïîëüçóåòñÿ äîëæíî áûòü =0
    	dwTimeout      - Íå èñïîëüçóåòñÿ äîëæíî áûòü =0
    	Port                - Íîìåð ïîðòà â ôîðìàòå ïåðå÷èñëåíèÿ PORTS (com_number)		
    *)
    	Settings1.Port:=com_num1;
    	Settings1.dwBaudRate:=115200;
    	Settings1.byParity:=0;
    	Settings1.dwTimeout:=0;
    	Settings1.byStopBits:=0;
    	Settings1.dwBufferSize:=0;
    	Settings1.dwScan:=0;
    (*
    	Íàñòðîéêà è îòêðûòèå ïîðòà (COM_SERVICE)
    	Ïîêà íà âûõîäå Ready íå áóäåò ñèãíàë TRUE, ñòó÷èìñÿ â ïîðò
    	Ïîðò îòêðûâàåòñÿ ñ íàñòðîéêàìè, óêàçàííûìè â com_settings, 
    	à íà âõîä Task ïîäàþòñÿ ñëåäóþùèå çíà÷åíèÿ:
    	
    	0 - Îòêðûòèå è íàñòðîéêà ïîðòà â ñîîòâåòñòâèè ñ íàñòðîéêàìè â ñòðóêòóðå Settings
    	1 - Èçìåíåíèå íàñòðîåê óæå îòêðûòîãî ïîðòà íà íàñòðîéêè óêàçàííûå â Settings
    	2 - Çàêðûòèå ïîðòà, íîìåð ïîðòà áåðåòñÿ èç Settings.Port																
    *)
    	COM_SERVICE1(Enable:=TRUE , Settings:=Settings1 , Task:=OPEN_TSK  );
    	IF COM_SERVICE1.Ready THEN
    		COM_SERVICE1.Enable := FALSE;
    		com_ready1:=TRUE;
    	END_IF
    END_IF
    
    
    (*******************************************************
    	Ðàáîòà ñ ïîðòîì
    *******************************************************)
    
    IF (com_ready1=TRUE )THEN
    CASE mtype OF
    	0:
    		IF NOT UNI.Active THEN
    			buffer[0] := 1;
    			buffer[1] := 101;
    			buffer[2] := 12;
    			buffer[3] := 0;
    			buffer[4] := 1;
    			buffer[5] := 0;
    			buffer[6] := 0;
    			buffer[7] := 0;
    			buffer[8] := 0;
    			buffer[9] := 0;
    			buffer[10] := 16#F4;
    			buffer[11] := 16#1;
    			buffer[12] := 0;
    			buffer[13] := 0;
    			buffer[14] := 0;
    			crc := MB_CRC(ADR(buffer[0]), 15);
    			SysMemCpy(ADR(buffer[15]), ADR(crc), 2);
    (*			buffer[15] := 145;
    			buffer[16] := 185; *)
    			data_size := 17;
    		END_IF
    		UNI(
    			Mode:=mode ,
    			ComHandle:=com_num1,
    			TimeOut:=t_zad,
    			DataBuf := buffer,
    			DataSize := data_size,
    			Complete := compl,
    			Exception := except
    		);
    
    		RT(CLK:=compl);
    
    		IF rt.Q THEN
    			MB_MOVED(ADR(result[0]), ADR(buffer[0]), data_size+2);
    			IF result[3] = 0 THEN
    				mtype :=1;
    			END_IF
    		END_IF
    
    	1:
    		IF NOT UNI.Active THEN
    			buffer[0] := 1;
    			buffer[1] := 16#67;
    			buffer[2] := 0;
    			crc1 := MB_CRC(ADR(buffer[0]), 3);
    			SysMemCpy(ADR(buffer[3]), ADR(crc1), 2);
    (*			buffer[15] := 145;
    			buffer[16] := 185; *)
    			data_size := 5;
    		END_IF
    		UNI(
    			Mode:=mode ,
    			ComHandle:=com_num1,
    			TimeOut:=t_zad,
    			DataBuf := buffer,
    			DataSize := data_size,
    			Complete := compl,
    			Exception := except
    		);
    
    		RT(CLK:=compl);
    
    		IF rt.Q THEN
    			MB_MOVED(ADR(id[0]), ADR(buffer[0]), data_size+2);
    			mtype :=2;
    		END_IF
    
    	2:
    		IF NOT UNI.Active THEN
    			buffer[0] := 1;
    			buffer[1] := 16#6B;
    			buffer[2] := 0;
    			crc := MB_CRC(ADR(buffer[0]), 3);
    			SysMemCpy(ADR(buffer[3]), ADR(crc), 2);
    (*			buffer[3] := 16#0A;
    			buffer[4] := 16#30;*)
    			data_size := 5;
    		END_IF
    		UNI(
    			Mode:=mode ,
    			ComHandle:=com_num1,
    			TimeOut:=t_zad,
    			DataBuf := buffer,
    			DataSize := data_size,
    			Complete := compl,
    			Exception := except
    		);
    
    		RT(CLK:=compl);
    
    		IF rt.Q THEN
    			MB_MOVED(ADR(result[0]), ADR(buffer[0]), data_size+2);
    			SysMemCpy(ADR(Torque), ADR(result[11]), 4);
    			SysMemCpy(ADR(Speed), ADR(result[19]), 4);
    			SysMemCpy(ADR(Temper), ADR(result[15]), 4);
    		ELSE
    			IF except <> 0 THEN
    				Torque := 0;
    				Speed := 0;
    				Temper := 0;
    			END_IF
    		END_IF
    	END_CASE
    END_IF
    В принципе, в Тилкомовской документации приводятся примеры посылаемых команд даже с контрольной суммой, но я посчитал, что будет правильнее считать её. В коде специально оставил закомментированной контрольную сумму из документации.
    Последний раз редактировалось madiggo; 23.06.2016 в 14:32.

  3. #13
    Пользователь
    Регистрация
    13.10.2011
    Адрес
    Златоуст
    Сообщений
    1,047

    По умолчанию

    В протоколе действительно зарезервированы номера функций 101-110 и 66-69 (могу ошибаться в диапазоне) для расширений производителя.
    Когда все стандартные вещи реализуются через расширения это уже сложно назвать модбасом. Как бы ни было, отличная находка, спасибо.

  4. #14
    Пользователь
    Регистрация
    27.11.2011
    Адрес
    Краснодар
    Сообщений
    7,153

    По умолчанию

    madiggo а вы не могли бы код выложить, чтобы коменты на русском были ?

  5. #15

    По умолчанию

    Цитата Сообщение от melky Посмотреть сообщение
    madiggo а вы не могли бы код выложить, чтобы коменты на русском были ?
    На всякий случай, тут расшифровщик: https://www.artlebedev.ru/tools/decoder/

    Код:
    FUNCTION_BLOCK MB_UNI_IO
    VAR_INPUT
    	Mode: MB_MODE;						(* Serial Transmission Mode of MODBUS networks *)
    	ComHandle:DWORD;				(*  дескриптор последовательного порта библиотеки SysLibCom *)
    	TimeOut: TIME; 						(* время тайм-аута [мс] - макс. задержка на обработку запроса *)
    END_VAR
    VAR_IN_OUT
    	Complete: BOOL;						(* если = TRUE, то обмен завершен *)
    	Exception: BYTE;						(* исключения протокола MODBUS *)
    	DataBuf: ARRAY[0..255] OF BYTE;	(* буфер данных кадра *)
    	DataSize: BYTE;						(* размер кадра без контрольной суммы *)
    END_VAR
    Код:
    PROGRAM PLC_PRG
    VAR
    	(*Пример работы с частотным приводом ОВЕН ПЧВ по RS-485*)
    	com_num1: PORTS;					(*Номер порта  на который подключено оборудование*)
    	com_hndl: DWORD;
    	Settings1: COMSETTINGS;				(*Параметры порта *)
    	COM_SERVICE1: COM_SERVICE;			(*Блок открытия и настройки порта *)
    	com_ready1: BOOL;					(*Статус порта -  открыт/закрыт*)
    	UNI:MB_UNI_IO;
    	i: BYTE;
    	command_word:WORD:=16#847C;
    	RT: R_TRIG;
    	t_zad:TIME:=T#20ms;
    	buffer: ARRAY[0..255] OF BYTE;
    	result: ARRAY[0..255] OF BYTE;
    	id: ARRAY[0..255] OF BYTE;
    	mode: MB_MODE := MB_RTU;
    	data_size: BYTE := 17;
    	compl: BOOL;
    	except: BYTE;
    	port_opened: BOOL;
    	mtype: INT;
    	crc: WORD;
    	crc1: WORD;
    END_VAR
    Код:
    (*****************************************************
    Пример работы с библиотекой SysLibCom
    
    формирование команды в двоичном виде
    *****************************************************)
    
    
    (*******************************************************
    	Открываем порт
    *******************************************************)
    
    (*Открываем первый порт*)
    IF NOT com_ready1 THEN
    (*
    	Номер порта (com_number):
    	0 - RS-485
    	1 - RS-232
    	4 - RS-232 DEBUG
    *)
    	com_num1 := 0;
    (*
    	Настройки порта (com_settings):
    	byParity         - Режим проверки четности 0 = нет, 1 = нечет, 2 = чет
    	byStopBits     - Кол-во стоповых бит 0 =один, 1=полтора , 2=два
    	dwBaudRate   - Скорость обмена 4800, 9600, 19200, 38400, 57600, 115200 бит/с.
    	dwBufferSize   - Не используется должно быть =0
    	dwScan          - Не используется должно быть =0
    	dwTimeout      - Не используется должно быть =0
    	Port                - Номер порта в формате перечисления PORTS (com_number)		
    *)
    	Settings1.Port:=com_num1;
    	Settings1.dwBaudRate:=115200;
    	Settings1.byParity:=0;
    	Settings1.dwTimeout:=0;
    	Settings1.byStopBits:=0;
    	Settings1.dwBufferSize:=0;
    	Settings1.dwScan:=0;
    (*
    	Настройка и открытие порта (COM_SERVICE)
    	Пока на выходе Ready не будет сигнал TRUE, стучимся в порт
    	Порт открывается с настройками, указанными в com_settings, 
    	а на вход Task подаются следующие значения:
    	
    	0 - Открытие и настройка порта в соответствии с настройками в структуре Settings
    	1 - Изменение настроек уже открытого порта на настройки указанные в Settings
    	2 - Закрытие порта, номер порта берется из Settings.Port																
    *)
    	COM_SERVICE1(Enable:=TRUE , Settings:=Settings1 , Task:=OPEN_TSK  );
    	IF COM_SERVICE1.Ready THEN
    		COM_SERVICE1.Enable := FALSE;
    		com_ready1:=TRUE;
    	END_IF
    END_IF
    
    
    (*******************************************************
    	Работа с портом
    *******************************************************)
    
    IF (com_ready1=TRUE )THEN
    CASE mtype OF
    	0:
    		IF NOT UNI.Active THEN
    			buffer[0] := 1;
    			buffer[1] := 101;
    			buffer[2] := 12;
    			buffer[3] := 0;
    			buffer[4] := 1;
    			buffer[5] := 0;
    			buffer[6] := 0;
    			buffer[7] := 0;
    			buffer[8] := 0;
    			buffer[9] := 0;
    			buffer[10] := 16#F4;
    			buffer[11] := 16#1;
    			buffer[12] := 0;
    			buffer[13] := 0;
    			buffer[14] := 0;
    			crc := MB_CRC(ADR(buffer[0]), 15);
    			SysMemCpy(ADR(buffer[15]), ADR(crc), 2);
    (*			buffer[15] := 145;
    			buffer[16] := 185; *)
    			data_size := 17;
    		END_IF
    		UNI(
    			Mode:=mode ,
    			ComHandle:=com_num1,
    			TimeOut:=t_zad,
    			DataBuf := buffer,
    			DataSize := data_size,
    			Complete := compl,
    			Exception := except
    		);
    
    		RT(CLK:=compl);
    
    		IF rt.Q THEN
    			MB_MOVED(ADR(result[0]), ADR(buffer[0]), data_size+2);
    			IF result[3] = 0 THEN
    				mtype :=1;
    			END_IF
    		END_IF
    
    	1:
    		IF NOT UNI.Active THEN
    			buffer[0] := 1;
    			buffer[1] := 16#67;
    			buffer[2] := 0;
    			crc1 := MB_CRC(ADR(buffer[0]), 3);
    			SysMemCpy(ADR(buffer[3]), ADR(crc1), 2);
    (*			buffer[15] := 145;
    			buffer[16] := 185; *)
    			data_size := 5;
    		END_IF
    		UNI(
    			Mode:=mode ,
    			ComHandle:=com_num1,
    			TimeOut:=t_zad,
    			DataBuf := buffer,
    			DataSize := data_size,
    			Complete := compl,
    			Exception := except
    		);
    
    		RT(CLK:=compl);
    
    		IF rt.Q THEN
    			MB_MOVED(ADR(id[0]), ADR(buffer[0]), data_size+2);
    			mtype :=2;
    		END_IF
    
    	2:
    		IF NOT UNI.Active THEN
    			buffer[0] := 1;
    			buffer[1] := 16#6B;
    			buffer[2] := 0;
    			crc := MB_CRC(ADR(buffer[0]), 3);
    			SysMemCpy(ADR(buffer[3]), ADR(crc), 2);
    (*			buffer[3] := 16#0A;
    			buffer[4] := 16#30;*)
    			data_size := 5;
    		END_IF
    		UNI(
    			Mode:=mode ,
    			ComHandle:=com_num1,
    			TimeOut:=t_zad,
    			DataBuf := buffer,
    			DataSize := data_size,
    			Complete := compl,
    			Exception := except
    		);
    
    		RT(CLK:=compl);
    
    		IF rt.Q THEN
    			MB_MOVED(ADR(result[0]), ADR(buffer[0]), data_size+2);
    			SysMemCpy(ADR(Torque), ADR(result[11]), 4);
    			SysMemCpy(ADR(Speed), ADR(result[19]), 4);
    			SysMemCpy(ADR(Temper), ADR(result[15]), 4);
    		ELSE
    			IF except <> 0 THEN
    				Torque := 0;
    				Speed := 0;
    				Temper := 0;
    			END_IF
    		END_IF
    	END_CASE
    END_IF

  6. #16

    По умолчанию

    Отличная ссылка, спасибо.

  7. #17

    По умолчанию

    Отличная статья, спасибо Yegor

  8. #18

    По умолчанию

    Всем доброго дня и с наступающим праздником! спасибо автору действительно отличная статья, но к сожалению в моем случае немного не подходит, не сталкивался ли кто с аналогичной проблемой при использовании СПК? есть ли кого примеры использования библиотеки CAA SerialCom?
    У меня стоит задача подключение стороннего цифрового датчика с протоколом обмена UAI к СПК107, датчик кстати отечественный, однако заводом предусмотрено подключение только к ПК с помощью специального преобразователя, как поделилась тех поддержка производителя обмен происходит по RS232 и в качестве примера выслал несколько команд, меня собственно тоже интересует открытие порта в момент включения и съем показаний пока не снимется питание.

    Командами 37 — чтение и 38 — запись
    пример чтения параметров
    запрос «:01;37;00001E;41405»
    ответ «!1;01;44032»

    Буду очень признателен за любую информацию по теме.

  9. #19
    Супер Модератор Аватар для Евгений Кислов
    Регистрация
    27.01.2015
    Адрес
    Москва
    Сообщений
    6,785

    По умолчанию

    Цитата Сообщение от Svorog Посмотреть сообщение
    Всем доброго дня и с наступающим праздником! спасибо автору действительно отличная статья, но к сожалению в моем случае немного не подходит, не сталкивался ли кто с аналогичной проблемой при использовании СПК? есть ли кого примеры использования библиотеки CAA SerialCom?
    У меня стоит задача подключение стороннего цифрового датчика с протоколом обмена UAI к СПК107, датчик кстати отечественный, однако заводом предусмотрено подключение только к ПК с помощью специального преобразователя, как поделилась тех поддержка производителя обмен происходит по RS232 и в качестве примера выслал несколько команд, меня собственно тоже интересует открытие порта в момент включения и съем показаний пока не снимется питание.

    Командами 37 — чтение и 38 — запись
    пример чтения параметров
    запрос «:01;37;00001E;41405»
    ответ «!1;01;44032»

    Буду очень признателен за любую информацию по теме.
    Добрый день. См. документацию:
    http://ftp.owen.ru/index.html/CoDeSy...cols_v.1.0.pdf

  10. #20

    По умолчанию

    Спасибо, этот документ читал, но к сожалению, ввиду малого опыта, многое моменты остались непонятны. Может есть живой пример на CFC?

Страница 2 из 6 ПерваяПервая 1234 ... ПоследняяПоследняя

Похожие темы

  1. Нестандартный протокол
    от SVVSVA в разделе ПЛК1хх
    Ответов: 2
    Последнее сообщение: 08.09.2011, 15:18
  2. нестандартный протокол
    от niklud19511 в разделе Сетевые технологии
    Ответов: 1
    Последнее сообщение: 05.05.2011, 15:02
  3. Нестандартный протокол
    от Евгений Владимирович в разделе ПЛК1хх
    Ответов: 9
    Последнее сообщение: 28.02.2010, 23:22
  4. Codesys и нестандартный протокол для ПЛК
    от Горшунов Сергей в разделе ПЛК1хх
    Ответов: 4
    Последнее сообщение: 23.10.2008, 18:19
  5. Нестандартный протокол
    от Klik в разделе ПЛК1хх
    Ответов: 36
    Последнее сообщение: 03.03.2008, 13:49

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •