Показано с 1 по 8 из 8

Тема: ПЛК 110-32М смена скорости порта

  1. #1

    По умолчанию ПЛК 110-32М смена скорости порта

    Здравствуйте.

    В сети RS-485 есть множество устройств, часть из них работает на скорости 115200 (модули ввода/вывода) и часть на скорости 19200 (частотники, сторонние контроллеры). В мастер сеть все теги не влазят, поэтому приходится вести обмен данными вручную через библиотеки.

    Собственно трудность: на одной скорости чтение и запись по RS не представляет сложности, но вот перейти на другую скорость обмена у меня не получается. Прошу помощи опытных специалистов, как лучше и правильнее менять скорость порта?

    Я пытаюсь это делать путём закрытия порта и открытия его с новыми настройками. Однако данный манёвр приводит к полному отсутствию связи с каким-либо устройством.

    Программа выгляди так:

    IF port_opened=0 THEN
    Settings.Port:=0;
    Settings.dwBaudRate:=115200;
    Settings.byParity:=0;
    Settings.dwTimeout:=0;
    Settings.byStopBits:=1;
    Settings.dwBufferSize:=0;
    Settings.dwScan:=0;
    END_IF

    COM_SERVICE1(Enable:=(port_opened=0) , Settings:=Settings , Task:=OPEN_TSK );

    IF COM_SERVICE1.ready THEN
    port_opened:=2;
    END_IF

    IF port_opened=2 THEN

    CASE master1 OF

    0:
    get1_modbus(
    Enable:=enabl ,
    Mode:=MB_RTU ,
    DevAddr:=150 ,
    FirstAddr:=520 ,
    Quantity:=1,
    ComHandle:=Settings.Port ,
    TimeOut:=TimeOut ,
    Buffer:=Buffer ,
    Complete=>cmpl ,
    Exception=>err ,
    ByteCnt=>DataSize );
    IF cmpl THEN
    IF err=0 THEN
    x1:=BYTE_TO_WORD(BUFFER[1]) OR SHL(BYTE_TO_WORD(BUFFER[0]),8);
    END_IF
    master1:=0;
    END_IF


    Как правильно перенастроить или переоткрыть порт с новыми настройками?

  2. #2
    Banned
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,664

    По умолчанию

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

  3. #3

    По умолчанию

    Цитата Сообщение от capzap Посмотреть сообщение
    не увидел в коде, а где Вы закрываете порт, может ошибка где то в этом кроется
    во вторых считаю что это плохая затея, прибор видя что идут данные на другой скорости может в линию отправлять мусор, что помешает принять качественный ответ от опрашиваемого прибора
    Закрывать пытаюсь вот так:

    COM_SERVICE1(Enable:=(port1_opened=2) , Settings:=Settings , Task:=CLOSE_TSK );
    IF COM_SERVICE1.ready=0 THEN
    port1_opened:=0;

    Чисто интуитивно поменял условия (обозначил красным), но думаю, что всё должно быть как-то по другому, но вот не знаю как.

    Затем меняю настройки порта

    Settings.Port:=0;
    Settings.dwBaudRate:=19200;
    Settings.byParity:=0;
    Settings.dwTimeout:=0;
    Settings.byStopBits:=1;
    Settings.dwBufferSize:=0;
    Settings.dwScan:=0;

    и снова открываю его с новыми настройками

    COM_SERVICE1(Enable:=(port2_opened=0) , Settings:=Settings , Task:=OPEN_TSK );
    IF COM_SERVICE1.ready THEN
    port2_opened:=2;
    END_IF

    Насчёт плохой затеи - это вынужденная мера, так как настроить все устройства на одну высокую скорость нереально, единственное можно настроить все на минимально возможную 19200, но это приведёт к замедлению процесса обмена, а устройств 17 штук, на каждое ожидание в 50 мс в идеале, а то и более если несколько запросов делать, и того до секунды цикл опроса вырастает.

    Думаю нужно просто грамотно переоткрыть порт или сменить скорость в открытом. Вопрос КАК?

  4. #4
    Banned
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,664

    По умолчанию

    мне кажется должно пройти некоторое время(несмотря на деление по модулю), пока сам физический порт закроется, чтоб его можно использовать повторно, это в Вашем случае
    А если посмотрите исходник блока http://www.owen.ru/forum/showthread....l=1#post131822 то можно увидеть что RESET_TSK пытается применить новые настройки, сам лично не пробовал, но автор же не зря так написал

  5. #5

    По умолчанию

    Да, судя по всему RESET_TASK помогает, код программы такой, полный код:

    t:=t+1;
    IF (t MOD 1000)=0 THEN
    A := A + 1;
    t := 0;
    IF A > 999 THEN
    A := 0;
    END_IF
    END_IF


    (*Óñòàíàâë èâàåì íàñòðîéê&# 232; COM-ïîðòà*)
    IF port1_opened =0 THEN
    Settings.Port:=0; (*íîìåð COM-ïîðòà*)
    Settings.dwBaudRate:=115200; (*ñêîðîñòü *)
    Settings.byParity:=0;
    Settings.dwTimeout:=0;
    Settings.byStopBits:=1;
    Settings.dwBufferSize:=0;
    Settings.dwScan:=0;
    END_IF

    COM_SERVICE1(Enable:=(port1_opened=0) , Settings:=Settings , Task:=OPEN_TSK );
    (*Åñëè COM-ïîðò îòêðûò, òî ïåðåõîäè&# 236; ê ïðèåìó è ïåðåäà÷&#232 ; äàííûõ *)
    IF COM_SERVICE1.ready THEN
    port1_opened:=2;
    END_IF

    IF port1_opened=2 THEN (*Óäà÷íî ïðîèíèöè&# 224;ëèçèðîâ&#22 4;ëè*)

    CASE master1 OF

    0: (* ôóíêöèÿ 03 èíò - ÔÁ ñ÷èòûâàå&# 242; çíà÷åíè&#229 ; ïàðàìåòð&# 224; òèïà int èç ïðèáîðà ñ àäðåñîì 10 èç ðåãèñòð&#224 ; ñ íîìåðîì 51 ïî ïðîòîêîë&# 243; Modbus-RTU*)
    get1_modbus(
    Enable:=enabl , (* ðàçðåøåí&# 232;å ðàáîòû áëîêà *)
    Mode:=MB_RTU , (*ðåæèì ïåðåäà÷&#232 ;*)
    DevAddr:=150 , (*àäðåñ*)
    FirstAddr:=520 , (*íîìåð ðåãèñòð&#224 ;*)
    Quantity:=1, (*êîëè÷åñò âî ðåãèñòðî&# 226;*)
    ComHandle:=Settings.Port , (*íîìåð COM-ïîðòà*)
    TimeOut:=TimeOut , (*Òàéìàóò T#50ms*)
    Buffer:=Buffer , (* áóôåð äàííûõ *)
    Complete=>cmpl , (* ñêîïèðîâ&# 224;òü ïðèçíàê çàâåðøåí&# 232;ÿ îïåðàöè&#232 ; *)
    Exception=>err , (* ñêîïèðîâ&# 224;òü ðåãèñòð îøèáîê *)
    ByteCnt=>DataSize ); (*êîë-âî ñ÷èòàííû&# 245; áàéòîâ *)
    (*åñëè óñòàíîâë&# 229;í ïðèçíàê çàâåðøåí&# 232;ÿ îïåðàöè&#232 ;, òî *)
    IF cmpl THEN
    IF err=0 THEN (*Åñëè íåò îøèáîê, òî ïîëó÷àå&#236 ; äàííûå èç áóôåðà òèïà INT*)
    x1:=BYTE_TO_WORD(BUFFER[1]) OR SHL(BYTE_TO_WORD(BUFFER[0]),8);
    END_IF
    master1:=1; (*ïåðåõîäè ì ê âûïîëíåí&# 232;þ ñëåäóþùå&# 227;î ÔÁ*)
    END_IF

    1: (* ôóíêöèÿ 16 - çàïèñü ïàðàìåòð&# 238;â òèïà Int (ðåãèñòð 4) è Real (ðåãèñòð 6) â ïðèáîð ñ àäðåñîì 2 *)
    (*çàïèñü â áóôôåð ïàðàìåòð&# 224; òèïà INT*)
    Buffer[1] := DINT_TO_BYTE(A);
    Buffer[0] := DINT_TO_BYTE( SHR(A,8));
    Buffer[3] := DINT_TO_BYTE( SHR(A,16));
    Buffer[2] := DINT_TO_BYTE( SHR(A,24));

    send2_modbus(
    Enable:= enabl, (* ðàçðåøåí&# 232;å ðàáîòû áëîêà *)
    Mode:=MB_RTU , (*ðåæèì ïåðåäà÷&#232 ;*)
    DevAddr:=150 , (*àäðåñ*)
    FirstAddr:= 520, (*íîìåð ðåãèñòð&#224 ;*)
    Quantity:= 1, (*êîëè÷åñò âî çàïèñûâà&# 229;ìûõ ðåãèñòðî&# 226;*)
    ComHandle:=Settings.Port ,(*íîìåð ñîì-ïîðòà*)
    TimeOut:=TimeOut , (*òàéìàóò T#50ms*)
    Buffer:=Buffer , (* áóôåð äàííûõ *)
    Complete=>cmpl , (* ñêîïèðîâ&# 224;òü ïðèçíàê çàâåðøåí&# 232;ÿ îïåðàöè&#232 ; *)
    Exception=>err , (* ñêîïèðîâ&# 224;òü ðåãèñòð îøèáîê *)
    RegCnt=> DataSize); (*êîë-âî ñ÷èòàííû&# 245; áàéòîâ *)
    (*åñëè óñòàíîâë&# 229;í ïðèçíàê çàâåðøåí&# 232;ÿ îïåðàöè&#232 ;, òî *)
    IF cmpl THEN
    master1:=2;(*ïåðåõî& #228;èì ê âûïîëíåí&# 232;þ ñëåäóþùå&# 227;î áëîêà*)
    END_IF
    2:
    Settings.Port:=0; (*íîìåð COM-ïîðòà*)
    Settings.dwBaudRate:=19200; (*ñêîðîñòü *)
    Settings.byParity:=0;
    Settings.dwTimeout:=0;
    Settings.byStopBits:=1;
    Settings.dwBufferSize:=0;
    Settings.dwScan:=0;

    port1_opened:=0;

    COM_SERVICE1(Enable:=(port1_opened=0) , Settings:=Settings , Task:=RESET_TSK );
    (*Åñëè COM-ïîðò îòêðûò, òî ïåðåõîäè&# 236; ê ïðèåìó è ïåðåäà÷&#232 ; äàííûõ *)
    IF COM_SERVICE1.ready THEN
    port1_opened:=2;
    END_IF

    get1_modbus(
    Enable:=enabl , (* ðàçðåøåí&# 232;å ðàáîòû áëîêà *)
    Mode:=MB_RTU , (*ðåæèì ïåðåäà÷&#232 ;*)
    DevAddr:=10 , (*àäðåñ*)
    FirstAddr:=51 , (*íîìåð ðåãèñòð&#224 ;*)
    Quantity:=1, (*êîëè÷åñò âî ðåãèñòðî&# 226;*)
    ComHandle:=Settings.Port , (*íîìåð COM-ïîðòà*)
    TimeOut:=TimeOut , (*Òàéìàóò T#50ms*)
    Buffer:=Buffer , (* áóôåð äàííûõ *)
    Complete=>cmpl , (* ñêîïèðîâ&# 224;òü ïðèçíàê çàâåðøåí&# 232;ÿ îïåðàöè&#232 ; *)
    Exception=>err , (* ñêîïèðîâ&# 224;òü ðåãèñòð îøèáîê *)
    ByteCnt=>DataSize ); (*êîë-âî ñ÷èòàííû&# 245; áàéòîâ *)
    (*åñëè óñòàíîâë&# 229;í ïðèçíàê çàâåðøåí&# 232;ÿ îïåðàöè&#232 ;, òî *)
    IF cmpl THEN
    IF err=0 THEN (*Åñëè íåò îøèáîê, òî ïîëó÷àå&#236 ; äàííûå èç áóôåðà òèïà INT*)
    x2:=BYTE_TO_WORD(BUFFER[1]) OR SHL(BYTE_TO_WORD(BUFFER[0]),8);
    END_IF
    master1:=3; (*ïåðåõîäè ì ê âûïîëíåí&# 232;þ ñëåäóþùå&# 227;î ÔÁ*)
    END_IF

    IF enabl = FALSE THEN
    enabl := TRUE;
    END_IF

    IF err <> 0 THEN
    enabl := FALSE;
    END_IF
    3:
    port1_opened:=0;
    master1:=0;
    END_CASE
    IF enabl = FALSE THEN
    enabl := TRUE;
    END_IF
    IF err <> 0 THEN
    enabl := FALSE;
    END_IF
    END_IF

    но работает нестабильно, опрос модуля на 19200 стабилен, а запись и чтения модуля на 115200 проходит один раз в несколько десятков секунд. Не могу понять в чём причина, вроде везде есть подтверждение включения порта и только потом работа с ним, явные задержки времени не требуются, но не работает стабильно.

  6. #6

    По умолчанию

    COM_SERVICE все делает ну очень медленно (почему то, до 100 циклов ПЛК тратит на функцию!) ну ее нафиг, в SysLibCom вполне достаточно. Обмен на библиотеках тем и хорош что все происходит быстрее таймаутов по 50 мс - получили ответ -> начинаем новый сеанс.
    А используя разную скорость вы догружаете периферийные устройства анализом посылок, которые они гарантированно не поймут, а возможно и поймут неправильно и попытаются ответить не вовремя.

  7. #7

    По умолчанию

    Цитата Сообщение от Дмитрий Артюховский Посмотреть сообщение
    COM_SERVICE все делает ну очень медленно (почему то, до 100 циклов ПЛК тратит на функцию!) ну ее нафиг, в SysLibCom вполне достаточно. Обмен на библиотеках тем и хорош что все происходит быстрее таймаутов по 50 мс - получили ответ -> начинаем новый сеанс.
    А используя разную скорость вы догружаете периферийные устройства анализом посылок, которые они гарантированно не поймут, а возможно и поймут неправильно и попытаются ответить не вовремя.
    Дайте, пожалуйста, пример реализации обмена данными через SysLibCom.

  8. #8

    По умолчанию

    IF NOT port_opened_scan THEN (* если порт не открыт *)
    com_handle_scan := SysComOpen( com_num_scan ); (* открываем его *)
    IF com_handle_scan <> 16#FFFFFFFF THEN (* если порт открыт удачно - ставим флаг *)
    port_init_scan := TRUE;
    ELSE
    SysComClose( com_num_scan ); (* иначе закрываем порт *)
    com_handle_scan := SysComOpen( com_num_scan ); (* и открываем его повторно *)
    port_init_scan := TRUE; (* ставим флаг открытия *)
    END_IF
    (* настраиваем порт *)
    com_set_scan.Port := com_num_scan;
    com_set_scan.dwBaudRate := 19200; (* 9600; 38400; 57600 *)
    com_set_scan.byParity := 0;
    com_set_scan.dwTimeout := 0;
    com_set_scan.byStopBits := 0;
    com_set_scan.dwBufferSize := 1024;
    com_set_scan.dwScan := 0;
    res_scan := SysComSetSettings( com_num_scan, ADR( com_set_scan ) ); (* применить настройки порта *)
    IF NOT res_scan THEN
    port_opened_scan := TRUE; (* порт успешно открыт *)
    END_IF
    SCANTIME := T#45MS;
    END_IF

    COM_SERVICE внутри себя ведет счетчик циклов ПЛК и собственно выполняется на сотом, зачем это сделано совершенно не понятно, а учитывая, что у многих цикл ПЛК выставлен много больше 1 мс -> порты открываются (и закрываются) минутами!!

Похожие темы

  1. ПРОБЛЕММА С ОВЕН ПЛК110-32М
    от kelbik в разделе ПЛК1хх
    Ответов: 21
    Последнее сообщение: 07.01.2018, 11:36
  2. Программная смена IP адреса ПЛК
    от AlexPC1 в разделе ПЛК1хх
    Ответов: 8
    Последнее сообщение: 10.07.2017, 17:13
  3. Ответов: 14
    Последнее сообщение: 14.06.2013, 18:39
  4. смена порта для обращения
    от ikmir в разделе ПЛК1хх
    Ответов: 7
    Последнее сообщение: 23.10.2009, 09:33

Ваши права

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