Страница 4 из 6 ПерваяПервая ... 23456 ПоследняяПоследняя
Показано с 31 по 40 из 51

Тема: PLC 110-30 v2 & сокеты

  1. #31

    По умолчанию

    После программного сброса, если нет обработчика события Reset, в котором ресурсы освобождаются, порты, сокеты и пр. ресурсы, выделяемые в программе и не должны работать.
    Тролль-наседка, добрый, нежный и ласковый

  2. #32

    По умолчанию

    Цитата Сообщение от Masteri. Посмотреть сообщение
    Прикладываю пример обмена одного сокета ПЛК110_М02 клиента и сервера ниже.
    Вложение 30631
    Вопрос по серверу. Сейчас сервер работает только на передачу данных клиенту. Подскажите пожалуйста, каким образом я могу осуществить запись данных в сервер (в уже имеющийся массив my_data)? Просто заменить используемую функцию (3 на 16), я так полагаю, недостаточно. Спасибо!

  3. #33

    По умолчанию

    не путайте транспортный уровень (клиент-сервер) и уровень прикладной (мастер-slave ModBus). Мухи отдельно, котлеты отдельно.
    Сервер по ничего о модбасе не знает. добавляйте прикладной уровень для требуемых функций (16 там или 6) и получайте доступ на запись.

    А лучше воспользуйтесь готовыми решениями.
    Тролль-наседка, добрый, нежный и ласковый

  4. #34

    По умолчанию

    Цитата Сообщение от Филоненко Владислав Посмотреть сообщение
    не путайте транспортный уровень (клиент-сервер) и уровень прикладной (мастер-slave ModBus). Мухи отдельно, котлеты отдельно.
    Сервер по ничего о модбасе не знает. добавляйте прикладной уровень для требуемых функций (16 там или 6) и получайте доступ на запись.

    А лучше воспользуйтесь готовыми решениями.
    А можно посмотреть на готовое решение?

  5. #35

    По умолчанию

    Цитата Сообщение от DmitriiAnyushin Посмотреть сообщение
    А можно посмотреть на готовое решение?
    Мой пример, если еще актуально.
    http://www.owen.ru/forum/showthread....l=1#post263012

  6. #36
    Пользователь Аватар для Serhioromano
    Регистрация
    15.09.2015
    Адрес
    Бишкек
    Сообщений
    265

    По умолчанию

    Для тех кто будет искать решение.

    У меня тоже возникла задача читать данные с устройства подключенного через TCP. По сути просто TCP клиент. Я пробовал библиотеку ОСКАТ, но так и не смог ее запустить. Пришлось разбираться с сокетами. Ваня помог, показал пример основного принципа работы с сокетами, плюс на РНР работал с сокетами. В результате получил рабочий код, который опрашивает устройство по заданному адресу и читает заданное число регистров начиная с заданного номера. Проверял на МУ210-401.

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

    Так как весь смысл моей задачи перейти на опрос через код а не через конфигурации, было увеличить скорость опроса, что бы не было задержек. Так что ни какой паузы после чтения нет, вы можете сами вставить дополнительный шаг, если будет нужно.

    Как материал для создания этой функции я использовал статью
    https://www.rtaautomation.com/techno.../modbus-tcpip/

    Код:
    FUNCTION_BLOCK SR_MB_TCP_CLIENT
    VAR
    	xResult: BOOL; (* Результат функции *)
    	fbEnableFall: F_TRIG;
    	bStep: BYTE := 0; (* Текущий шаг *)
    	diSock: DINT;
    	diResult: DINT; (* Результат коммуникации *)
    	diCount: DINT; (* Считаем сколько байтов получено *)
    	fbTimeoutTON: TON;
    	stSocAddr: SOCKADDRESS; 
    	uiTryCount: UINT; (* Количество ошибок подключения сокета перед сбросом *)
    	(* 	0, 1 - Номер транзакции,
    		2, 3 - Протокол. 00 00 - Modbus, 
    		4, 5 - Длина всего что ниже
    		6 - Адрес устройства Modbus *)
    	arbData: ARRAY[0..11] OF BYTE := 00, 01, 00, 00, 00, 06, 01;
    	arbBuffer: ARRAY[0..24] OF BYTE;
    	uiCount: WORD;
    END_VAR
    VAR_INPUT
    	ENABLE: BOOL; (* Блок работает *)
    	PORT: UINT := 502; (* Порт*)
    	IP: DWORD; (* IP Адрес в HEX для пример 192.168.1.99 будет 16#C0A80163 *)
    	TIMEOUT: TIME; (* Время ожидания при переподключении *)
    	REG_START: WORD; (* Начальный регистр *)
    	REG_NUM: WORD; (* Количество регистров *)
    	FC: BYTE; (* функция 03, 04*)
    	RESET: BOOL; (* Сброс ошибки и переподключение *)
    END_VAR
    VAR_OUTPUT
    	_ERR_CODE: BYTE; (* Код ошибки *)
    	_DATA: ARRAY[0..255] OF WORD; (* Выходной массив с данными *)
    END_VAR
    
    fbEnableFall(CLK := ENABLE);
    IF fbEnableFall.Q THEN
    	bStep := 100;
    END_IF;
    
    IF RESET THEN
    	_ERR_CODE := 0;
    	bStep := 100;
    END_IF;
    
    CASE bStep OF
    (* Ожидание включения *)
    0:
    	IF ENABLE AND NOT RESET THEN
    		bStep := 10;
    	END_IF;
    
    
    (* Создаем сокет *)
    10:
    	diSock := SysSockCreate(SOCKET_AF_INET, SOCKET_STREAM, SOCKET_IPPROTO_TCP);
    
    	IF diSock <> SOCKET_INVALID THEN
    		bStep := 20;
    		IF _ERR_CODE = 5 THEN
    			_ERR_CODE := 0;
    		END_IF;
    	ELSE (* если нет создается пробуем еще 3 раза потом сброс *)
    		uiTryCount := uiTryCount + 1;
    		IF uiTryCount > 3 THEN
    			bStep := 100;
    			_ERR_CODE := 5;
    		END_IF
    	END_IF
    
    (* Подключаемся *)
    20:
    	stSocAddr.sin_family	:= SOCKET_AF_INET;
    	stSocAddr.sin_port		:= SysSockHtons(PORT);
    	stSocAddr.sin_addr		:= SysSockHtonl(IP);
    
    	SysSockSetOption(diSock, SOCKET_SOL, 16#1014, 0, 0) ;
    	xResult := SysSockConnect(diSock, ADR(stSocAddr), SIZEOF(stSocAddr));
    
    	IF NOT xResult THEN
    		bStep := 30;
    		IF _ERR_CODE = 10 THEN
    			_ERR_CODE := 0;
    		END_IF;
    	ELSE
    		bStep := 100;
    		_ERR_CODE := 10;
    	END_IF;
    
    
    (* Отправляем запрос *)
    30:
    	arbData[7]  := FC;								(* 7 - функция чтения*)
    	arbData[8]  := WORD_TO_BYTE(SHR(REG_START, 8));	(* 8, 9 - начальный регистр *)
    	arbData[9]  := WORD_TO_BYTE(REG_START);
    	arbData[10] := WORD_TO_BYTE(SHR(REG_NUM, 8));	(* 10, 11 - количество регистров для чтения *)
    	arbData[11] := WORD_TO_BYTE(REG_NUM);
    
    	diResult := SysSockSend(diSock, ADR(arbData), SIZEOF(arbData), SOCKET_MSG_OOB);
    
    	IF _ERR_CODE = 15 THEN
    		_ERR_CODE := 0;
    	END_IF;
    
    	IF diResult = -1 THEN
    		bStep := 100;
    		_ERR_CODE := 15;
    	END_IF
    
    	diCount := diCount + diResult;
    
    	IF diCount >= SIZEOF(arbData) THEN
    		diCount := 0;
    		bStep := 40;
    	END_IF;
    
    (* Получаем данные *)
    40:
    
    	diResult := SysSockRecv(diSock, ADR(arbBuffer), SIZEOF(arbBuffer), SOCKET_MSG_OOB);
    
    	IF _ERR_CODE = 41 THEN
    		_ERR_CODE := 0;
    	END_IF;
    
    	IF diResult = -1 THEN
    		_ERR_CODE := 41;
    		bStep := 100;
    	END_IF
    
    	IF diResult > 0 THEN
    		bStep := 30;
    
    		REPEAT
    			_DATA[uiCount] := BYTE_TO_WORD(arbBuffer[10 + (uiCount * 2)]) OR SHL(BYTE_TO_WORD(arbBuffer[9 + (uiCount * 2)]),8);
    			uiCount := uiCount + 1;
    		UNTIL
    			uiCount >= REG_NUM
    		END_REPEAT;
    		uiCount := 0;
    	END_IF
    
    
    (* Сбрасываем сокет *)
    100:
    	IF diSock > 0 THEN
    		SysSockShutdown(diSock, 2);
    		SysSockClose(diSock);
    	END_IF;
    	uiTryCount := 0;
    	diSock := 0;
    	bStep := 101;
    (* Задержка перед повторным подключением *)
    101:
    	fbTimeoutTON(IN := TRUE, PT := TIMEOUT);
    	IF fbTimeoutTON.Q THEN
    		fbTimeoutTON(IN := FALSE);
    		bStep := 0;
    	END_IF;
    
    END_CASE;

  7. #37

    По умолчанию

    Код:
    xResult := SysSockConnect(diSock, ADR(stSocAddr), SIZEOF(stSocAddr));
    не стоит доверять результату SysSockConnect

  8. #38
    Пользователь Аватар для Serhioromano
    Регистрация
    15.09.2015
    Адрес
    Бишкек
    Сообщений
    265

    По умолчанию

    Цитата Сообщение от monteg Посмотреть сообщение
    Код:
    xResult := SysSockConnect(diSock, ADR(stSocAddr), SIZEOF(stSocAddr));
    не стоит доверять результату SysSockConnect
    Да это я уже понял. Долго не мог понять почему у меня ошибка 10 все время. По этому у меня в коде IF NOT xResult THEN потому что возврата TRUE из этой функции я так и не добился, хотя все работает.

  9. #39

    По умолчанию

    Это разработчики Овен так SysSockConnect реализовали. Наличие соединения определяется по SysSockSend. А если пытаетесь установить соединение с ПЛК М01, лучше после SysSockRecv.

  10. #40
    Пользователь
    Регистрация
    28.11.2013
    Адрес
    Уфа
    Сообщений
    29

    По умолчанию

    Цитата Сообщение от monteg Посмотреть сообщение
    Код:
    xResult := SysSockConnect(diSock, ADR(stSocAddr), SIZEOF(stSocAddr));
    не стоит доверять результату SysSockConnect
    Угу. Не стоит.

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

Похожие темы

  1. ПЛК100 2.17 не работают сокеты
    от murdemon в разделе ПЛК1хх
    Ответов: 6
    Последнее сообщение: 02.07.2018, 21:15
  2. ПЛК100 + Сокеты
    от ribamuka в разделе ПЛК1хх
    Ответов: 4
    Последнее сообщение: 30.08.2017, 11:55
  3. Возможно ли в режиме эмуляции Codesys тестировать работу через сокеты TCP
    от Денис Бердяев в разделе Сетевые технологии
    Ответов: 2
    Последнее сообщение: 09.10.2014, 08:23

Ваши права

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