Страница 1 из 2 12 ПоследняяПоследняя
Показано с 1 по 10 из 16

Тема: Не могу подружить 2 устройства через modbus.lib

  1. #1

    По умолчанию Не могу подружить 2 устройства через modbus.lib

    На столе ПЛК100+расходомер взлет + ОВЕН мк110.8дн.4р

    Тестовая программа:
    Код:
    (*Устанавливаем настройки COM-порта*)
    IF port_opened=0 THEN
    		Settings.Port:=com_num;               (*номер COM-порта*)
    		Settings.dwBaudRate:= 115200;    (*скорость*)
    		Settings.byParity:=0;
    		Settings.dwTimeout:=0;
    		Settings.byStopBits:=0;
    		Settings.dwBufferSize:=0;
    		Settings.dwScan:=0;
    END_IF
    
    COM_SERVICE1(Enable:=(port_opened=0) , Settings:=Settings , Task:=OPEN_TSK  );
    (*Если COM-порт открыт, то переходим к приему и передачи данных *)
    IF COM_SERVICE1.ready THEN
    	port_opened:=2;
    END_IF
    
    IF port_opened=2 THEN (*Удачно проинициализировали*)
    
    CASE master1 OF
    
    0: 
    get1_modbus(
    	Enable:=Enable:= NOT get1_modbus.Complete,		(* разрешение работы блока *)
    	Mode:=MB_RTU,		(*режим передачи*)
    	DevAddr:=8 ,				(*адрес*)
    	FirstAddr:=2 ,				(*номер регистра*)
    	Quantity:=1,				(*количество регистров*)
    	ComHandle:=Settings.Port , (*номер COM-порта*)
    	TimeOut:=TimeOut , 		(*Таймаут T#50ms*)
    	Buffer:=Buffer_out,			(* буфер данных *)
    	Complete=>cmpl ,		(* скопировать признак завершения операции *)
    	Exception=>err ,			(* скопировать регистр ошибок *)
    	ByteCnt=>DataSize );		(*кол-во считанных байтов *)
    (*если установлен признак завершения операции, то *)
    IF cmpl THEN
    	IF err=0 THEN (*Если нет ошибок, то получаем данные из буфера типа INT*)
    		x:=BYTE_TO_WORD(BUFFER_out[1]) OR SHL(BYTE_TO_WORD(BUFFER_out[0]),8);
    	ELSE
    		errcount:=errcount +1;
    	END_IF
    	master1 := 3;
    END_IF
    
    
    2:  get1_modbus(
    	Enable:= NOT get1_modbus.Complete ,			(* разрешение работы блока *)
    	Mode:=MB_RTU,		(*режим передачи*)
    	DevAddr:=48 ,				(*адрес*)
    	FirstAddr:=50 ,				(*номер регистра*)
    	Quantity:=1,				(*количество регистров*)
    	ComHandle:=Settings.Port , (*номер COM-порта*)
    	TimeOut:=TimeOut , 		(*Таймаут T#50ms*)
    	Buffer:=Buffer_out,			(* буфер данных *)
    	Complete=>cmpl ,		(* скопировать признак завершения операции *)
    	Exception=>err ,			(* скопировать регистр ошибок *)
    	ByteCnt=>DataSize );		(*кол-во считанных байтов *)
    (*если установлен признак завершения операции, то *)
    IF cmpl THEN
    	IF err=0 THEN (*Если нет ошибок, то получаем данные из буфера типа INT*)
    		x:=BYTE_TO_WORD(BUFFER_out[1]) OR SHL(BYTE_TO_WORD(BUFFER_out[0]),8);
    	ELSE
    		errcount:=errcount +1;
    	END_IF
    	master1 := 3;
    END_IF
    
    
    3:
     TimeOut2(IN :=TRUE,PT:=T#50ms);
     TimeOut2;
     IF TimeOut2.Q THEN
    	g:=g+1;
    	master1 := 0;
     	(*IF g/2 = TRUNC(g/2) THEN
    		 master1 := 2; 
    	END_IF*)
    	TimeOut2.IN := FALSE;
    	TimeOut;
    END_IF
    
    END_CASE
    
    END_IF
    В таком виде программа работает, опрашивается Взлет, ошибок 0. Убираю комментирование в 3м кейсе (подключаю второй модуль ОВЕН) и у Взлета каждая вторая ошибка 255. Что я делаю не так? Через конфигуратор оба работают нормально с редкими ошибками.
    Последний раз редактировалось Атаман; 03.03.2017 в 10:38.

  2. #2
    Пользователь Аватар для capzap
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,248

    По умолчанию

    поправить надо бибку модбасовскую, есть там проблемы с буфферным массивом
    Bad programmers worry about the code. Good programmers worry about data structures and their relationships

    среди успешных людей я не встречала нытиков
    Барбара Коркоран

  3. #3

    По умолчанию

    Как здесь написано? Не помогло.

  4. #4
    Пользователь Аватар для capzap
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,248
    Bad programmers worry about the code. Good programmers worry about data structures and their relationships

    среди успешных людей я не встречала нытиков
    Барбара Коркоран

  5. #5

    По умолчанию

    Цитата Сообщение от capzap Посмотреть сообщение
    Поменял MB_RD_HOLD_REGS из моей программы на READ_MULTIPLE_REGISTERS из примера. ПЛК сразу ушел в перезагрузку.

  6. #6
    Пользователь Аватар для capzap
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,248

    По умолчанию

    всмысле, при компиляции не на что не ругалась, обе бибки добавлены?
    Bad programmers worry about the code. Good programmers worry about data structures and their relationships

    среди успешных людей я не встречала нытиков
    Барбара Коркоран

  7. #7

    По умолчанию

    Код:
    (*Устанавливаем настройки COM-порта*)
    IF port_opened=0 THEN
    		Settings.Port:=com_num;               (*номер COM-порта*)
    		Settings.dwBaudRate:= 115200;    (*скорость*)
    		Settings.byParity:=0;
    		Settings.dwTimeout:=0;
    		Settings.byStopBits:=0;
    		Settings.dwBufferSize:=0;
    		Settings.dwScan:=0;
    END_IF
    
    COM_SERVICE1(Enable:=(port_opened=0) , Settings:=Settings , Task:=OPEN_TSK  );
    (*Если COM-порт открыт, то переходим к приему и передачи данных *)
    IF COM_SERVICE1.ready THEN
    	port_opened:=2;
    	Buffer_out := ADR(Buffer1);
    END_IF
    
    IF port_opened=2 THEN (*Удачно проинициализировали*)
    
    CASE master1 OF
    
    0: (* функция 03 инт  - ФБ считывает значение параметра  типа int из прибора с адресом162 в регистр с номером 48 по протоколу Modbus-RTU*)
    
    get1_modbus(
    	Enable:= NOT get1_modbus.Complite,			(* разрешение работы блока *)
    	UnitID:=8 ,				(*адрес*)
    	REF:=2 ,				(*номер регистра*)
    	Count:=1,				(*количество регистров*)
    	Handle:=Settings.Port , (*номер COM-порта*)
    	Delay:=TimeOut , 		(*Таймаут T#50ms*)
    	PNTFF:=Buffer_out,			(* буфер данных *)
    	Complite=>cmpl ,		(* скопировать признак завершения операции *)
    	ErrCode=>err ,			(* скопировать регистр ошибок *)
    	 );		(*кол-во считанных байтов *)
    (*если установлен признак завершения операции, то *)
    IF cmpl THEN
    	IF err=0 THEN (*Если нет ошибок, то получаем данные из буфера типа INT*)
    		n:=n+1;
    		(*x:=BYTE_TO_WORD(BUFFER_out[1]) OR SHL(BYTE_TO_WORD(BUFFER_out[0]),8);*)
    	ELSE
    		errcount:=errcount +1;
    	END_IF
    	master1 := 3;
    END_IF
    
    
    2:  get1_modbus(
    	Enable:= NOT get1_modbus.Complite,  (*разрешение работы блока *)
    	UnitID:=48 ,				(*адрес*)
    	REF:=50 ,				(*номер регистра*)
    	Count:=1,				(*количество регистров*)
    	Handle:=Settings.Port , (*номер COM-порта*)
    	DELAY:=TimeOut , 		(*Таймаут T#50ms*)
    	PNTFF:=Buffer_out,			(* буфер данных *)
    	Complite=>cmpl ,		(* скопировать признак завершения операции *)
    	ErrCode=>err ,			(* скопировать регистр ошибок *)
    	 );		(*кол-во считанных байтов *)
    (*если установлен признак завершения операции, то *)
    IF cmpl THEN
    	IF err=0 THEN (*Если нет ошибок, то получаем данные из буфера типа INT*)
    		n:=n+1;
    	 (*	x:=BYTE_TO_WORD(BUFFER_out[1]) OR SHL(BYTE_TO_WORD(BUFFER_out[0]),8);*)
    	ELSE
    		errcount:=errcount +1;
    	END_IF
    	master1 := 3;
    END_IF
    
    
    3:
     TimeOut2(IN :=TRUE,PT:=T#100ms);
     TimeOut2;
     IF TimeOut2.Q THEN
    	g:=g+1;
    	master1 := 0;
     	(*IF g/2 = TRUNC(g/2) THEN
    		 master1 := 2; 
    	END_IF *)
    	TimeOut2.IN := FALSE;
    	TimeOut;
    END_IF
    
    END_CASE
    
    END_IF
    Буфер инициализировал, ошибка 60 теперь какая то постоянно. Modbus RTU в бибке? Переключателя не увидел.

  8. #8

    По умолчанию

    Ставлю точки останова на строки после IF err=0 THEN ... и вручную переключаю между запросами кнопкой f5 - всё работает, 0 ошибок. Что за ерунда?

  9. #9
    Пользователь Аватар для capzap
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,248

    По умолчанию

    TimeOut2(IN :=TRUE,PT:=T#100ms);
    TimeOut2;
    IF TimeOut2.Q THEN
    g:=g+1;
    master1 := 0;
    (*IF g/2 = TRUNC(g/2) THEN
    master1 := 2;
    END_IF *)
    TimeOut2.IN := FALSE;
    TimeOut;
    END_IF
    я бы переписал на такое
    Код:
    TimeOut2(IN :=TRUE,PT:=T#100ms);
    IF TimeOut2.Q THEN
    	g:=g+1;
    	master1 := 0;
    	TimeOut2(IN := FALSE);
    END_IF
    а то лишний код добавляет и лишние ошибки, типа отсутствие двойки на конце переменной
    Если с точками останова всё работает, значит мал таймаут в опросе
    Последний раз редактировалось capzap; 03.03.2017 в 12:52.
    Bad programmers worry about the code. Good programmers worry about data structures and their relationships

    среди успешных людей я не встречала нытиков
    Барбара Коркоран

  10. #10

    По умолчанию

    Цитата Сообщение от capzap Посмотреть сообщение
    Если с точками останова всё работает, значит мал период опроса
    Чот вообще не пойму, что происходит.

    После IF complete добавил вызов get1_modbus c Enable := FAlse; Ошибок таймаута теперь нет,но значение регистра (переменная x) во взлете неправильное, 2051, хотя на самом деле 2

Страница 1 из 2 12 ПоследняяПоследняя

Похожие темы

  1. Ответов: 23
    Последнее сообщение: 19.08.2016, 11:49
  2. Как узнать базовый ModBus адрес устройства для ModBus ASCII?
    от Александр Подыман в разделе Сервисное ПО
    Ответов: 3
    Последнее сообщение: 03.03.2016, 12:49
  3. Ответов: 2
    Последнее сообщение: 08.12.2015, 10:33
  4. Ответов: 3
    Последнее сообщение: 26.11.2014, 15:18
  5. Не могу подружить ДТС и НПТ-2
    от _Rookie_ в разделе Эксплуатация
    Ответов: 5
    Последнее сообщение: 14.11.2014, 13:39

Ваши права

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