Страница 2 из 3 ПерваяПервая 123 ПоследняяПоследняя
Показано с 11 по 20 из 21

Тема: ПЛК63 + МВ110-8АС + МУ110-8И + МК110-8ДН-4Р опрос по modbus

  1. #11

    По умолчанию

    Спасибо, заработало)

  2. #12

    По умолчанию

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

  3. #13

    По умолчанию

    приложите проект со скопированным кодом
    Инженер по продуктам «ПЛК и модули»
    e-mail: i.masterenko@owen.ru | skype: i.masterenko_owen

  4. #14

    По умолчанию

    Я пользуюсь таким алгоритмом чтения:

    PHP код:
    PROGRAM GET_MB
    VAR
        (*
    TON*)
        
    HavePause            :TON;

        (*
    FB*)
        
    GetModbus             MB_RD_HOLD_REGS;
        
    ComService            COM_SERVICE;

        (*
    BOOL*)
        
    ES                BOOL := TRUE;
        
    EndSendStored            BOOL;

        (*
    BYTE*)
        
    ComPortState             BYTE := 0;
        
    Addr                BYTE := 2;
        
    RegQuant            BYTE := 24;

        (*
    INT*)
        
    MB110_8AC_1CH_STS        INT;
        
    MB110_8AC_2CH_STS        INT;
        
    MB110_8AC_3CH_STS        INT;
        
    MB110_8AC_4CH_STS        INT;
        
    MB110_8AC_5CH_STS        INT;
        
    MB110_8AC_6CH_STS        INT;
        
    MB110_8AC_7CH_STS        INT;
        
    MB110_8AC_8CH_STS        INT;

        (*
    WORD*)
        
    DataSize            WORD;
        
    RegAddr                WORD := 280;

        (*
    REAL*)
        
    MB110_8AC_1CH_VAL        REAL;
        
    MB110_8AC_2CH_VAL        REAL;
        
    MB110_8AC_3CH_VAL        REAL;
        
    MB110_8AC_4CH_VAL        REAL;
        
    MB110_8AC_5CH_VAL        REAL;
        
    MB110_8AC_6CH_VAL        REAL;
        
    MB110_8AC_7CH_VAL        REAL;
        
    MB110_8AC_8CH_VAL        REAL;

        (*
    TIME*)
        
    TimeOut1            TIME := T#50ms;
        
    TimeOut2            TIME := T#250ms;

        
    (*STRUCT*)
        
    Settings             COMSETTINGS;

        (*
    TYPES*)
            
    ComNum                PORTS := 0;

        (*ARRAY*)
        
    Buffer                : ARRAY [0..255OF BYTE;

        (*
    POINTER*)
        
    Ptb                POINTER TO BYTE;

    END_VAR

        
    (*Настройки COM-порта*)
        IF 
    ComPortState=0 THEN
            Settings
    .Port:=ComNum;          (*номер COM-порта*)
            
    Settings.dwBaudRate:=115200;    (*скорость*)
            
    Settings.byParity:=0;
            
    Settings.dwTimeout:=0;
            
    Settings.byStopBits:=1;
            
    Settings.dwBufferSize:=0;
            
    Settings.dwScan:=0;
        
    END_IF
        
    (*_______________________________________________________________*)

        (*
    Открываем COM-порт*)
        
    ComService(ENABLE := ComPortState 0SETTINGS := SettingsTASK := OPEN_TSK);
        (*
    _______________________________________________________________*)

        (*
    Готовность COM-порта к обмену данными*)
        IF 
    ComService.Ready THEN
            ComPortState 
    := 2;
        
    END_IF
        
    (*_______________________________________________________________*)

        (*
    Если COM-порт открытто запускаем обмен данными*)
        IF 
    ComPortState=2 THEN
            GetModbus
    (
            
    Enable := ES,
            
    Mode := MB_RTU,
            
    DevAddr := Addr,
            
    FirstAddr := RegAddr,
            
    Quantity := RegQuant,
            
    ComHandle := Settings.Port,
            
    TimeOut := TimeOut1,
            
    Buffer := Buffer,
            
    ByteCnt => DataSize);
            
    ES := FALSE;
            (*
    Если прием данных завершен*)
            IF 
    GetModbus.Complete THEN
                
    (*и без ошибок,*)
                IF 
    GetModbus.Exception 0 THEN
                    
    (*то читаем их из Buffer в соответствующие переменные*)
                    (*
    Статусы результатов измерений модулей MB110 8AC*)
                    (*
    Первый канал*)
                    
    Ptb := ADR(MB110_8AC_1CH_STS);
                    
    Ptb^ := Buffer[1];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[0];
                    (*
    Второй канал*)
                    
    Ptb := ADR(MB110_8AC_2CH_STS);
                    
    Ptb^ := Buffer[3];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[2];
                    (*
    Третий канал*)
                    
    Ptb := ADR(MB110_8AC_3CH_STS);
                    
    Ptb^ := Buffer[5];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[4];
                    (*
    Четвертый канал*)
                    
    Ptb := ADR(MB110_8AC_4CH_STS);
                    
    Ptb^ := Buffer[7];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[6];
                    (*
    Пятый канал*)
                    
    Ptb := ADR(MB110_8AC_5CH_STS);
                    
    Ptb^ := Buffer[9];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[8];
                    (*
    Шестой канал*)
                    
    Ptb := ADR(MB110_8AC_6CH_STS);
                    
    Ptb^ := Buffer[11];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[10];
                    (*
    Седьмой канал*)
                    
    Ptb := ADR(MB110_8AC_7CH_STS);
                    
    Ptb^ := Buffer[13];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[12];
                    (*
    Восьмой канал*)
                    
    Ptb := ADR(MB110_8AC_8CH_STS);
                    
    Ptb^ := Buffer[15];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[14];
                    (*
    Измеренные значения модуля MB110 8AC*)
                    (*
    Первый канал*)
                    
    Ptb := ADR(MB110_8AC_1CH_VAL);
                    
    Ptb^ := Buffer[19];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[18];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[17];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[16];
                    (*
    Второй канал*)
                    
    Ptb := ADR(MB110_8AC_2CH_VAL);
                    
    Ptb^ := Buffer[25];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[24];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[23];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[22];
                    (*
    Третий канал*)
                    
    Ptb := ADR(MB110_8AC_3CH_VAL);
                    
    Ptb^ := Buffer[31];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[30];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[29];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[28];
                    (*
    Четвертый канал*)
                    
    Ptb := ADR(MB110_8AC_4CH_VAL);
                    
    Ptb^ := Buffer[37];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[36];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[35];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[34];
                    (*
    Пятый канал*)
                    
    Ptb := ADR(MB110_8AC_5CH_VAL);
                    
    Ptb^ := Buffer[43];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[42];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[41];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[40];
                    (*
    Шестой канал*)
                    
    Ptb := ADR(MB110_8AC_6CH_VAL);
                    
    Ptb^ := Buffer[49];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[48];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[47];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[46];
                    (*
    Седьмой канал*)
                    
    Ptb := ADR(MB110_8AC_7CH_VAL);
                    
    Ptb^ := Buffer[55];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[54];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[53];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[52];
                    (*
    Восьмой канал*)
                    
    Ptb := ADR(MB110_8AC_8CH_VAL);
                    
    Ptb^ := Buffer[61];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[60];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[59];
                    
    Ptb := Ptb 1;
                    
    Ptb^ := Buffer[58];
                
    END_IF
                EndSendStored 
    := TRUE;
            
    END_IF
            
    (*Временная задержка*)
            
    HavePause(IN := EndSendStoredPT := TimeOut2);
            IF 
    HavePause.Q THEN
                ES 
    := TRUE;
                
    EndSendStored := FALSE;
            
    END_IF
        END_IF 
    Можно "поиграться" с таймаутами. Никаких ошибок, при условии правильной настройки мастера и слэйва.
    Последний раз редактировалось Spawn; 01.08.2018 в 11:28.

  5. #15
    Пользователь
    Регистрация
    23.09.2008
    Адрес
    Центророссийск
    Сообщений
    2,259

    По умолчанию

    Цитата Сообщение от Spawn Посмотреть сообщение
    Я пользуюсь таким алгоритмом чтения:....
    Массивы/структуры не ?

  6. #16

    По умолчанию

    Всем спасибо, с записью проблема решилась переписыванием кода в новый пустой проект, видимо в конфигурации ПЛК что-то накрутил ненужного) Теперь пытаюсь разобраться с записью значений в МУ110-8И. Подскажите, где посмотреть порядок и номера байт для записи в модуль? или их высчитывать нужно? вот сам код опроса/записи:

    PHP код:
    FUNCTION_BLOCK mudb
    VAR_INPUT
    (*Çíà÷åíèÿ äëÿ çàïèñè â ÌÓ110-8È À3*)
        
    y1:WORD; (*Çàïèñûâàåìûé ïàðàìåòð òèïà WORD*)
        
    y2:WORD; (*Çàïèñûâàåìûé ïàðàìåòð òèïà WORD*)
        
    y3:WORD; (*Çàïèñûâàåìûé ïàðàìåòð òèïà WORD*)
        
    y4:WORD; (*Çàïèñûâàåìûé ïàðàìåòð òèïà WORD*)
        
    y5:WORD; (*Çàïèñûâàåìûé ïàðàìåòð òèïà WORD*)
        
    y6:WORD; (*Çàïèñûâàåìûé ïàðàìåòð òèïà WORD*)



    (*Áèòîâàÿ ìàñêà âûõîäîâ ìîäóëÿ ÌÊ1108ÄÍ*)
        
    mk_mask_in:WORD;
    END_VAR
    VAR_OUTPUT

        
    (*ñ÷èòàííîå çíà÷åíèå ñ ÌÂ110-8ÀÑ À2*)
        
    real1:  REAL;
        
    real2:  REAL;
        
    real3:  REAL;
        
    real4:  REAL;
        
    real5:  REAL;
        
    real6:  REAL;
        
    real7:  REAL;
        
    real8:  REAL;

    (*&
    #194;õîäû  ìîäóëÿ ÌÊ1108ÄÍ*)
        
    A4_in1BOOL;
        
    A4_in2BOOL;
        
    A4_in3BOOL;
        
    A4_in4BOOL;
        
    A4_in5BOOL;
        
    A4_in6BOOL;
        
    A4_in7BOOL;
        
    A4_in8BOOL;

    END_VAR
    VAR
        
    get3_modbusMB_RD_HOLD_REGS;    (*ôóíêöèÿ 03 - ÷òåíèå ïàðàìåòðà òèïà INT*)

        
    send2_modbusMB_WR_REGS;                   (*ÌÓ110.8È*)  (*ôóíêöèÿ 16 - çàïèñü ïàðàìåòðîâ float*)

        
    Buffer: ARRAY[0..255OF BYTE;            (* áàéòîâûé áóôåð äàííûõ *)

             
    cmplBOOL;                                 (*ïðèçíàê çàâåðøåííîñòè ðàáîòû ôóíêöèè*)
        
    port_opened:  BYTE := 0;                     (*ðåçóëüòàò îòêðûòèÿ ïîðòà*)
        
    Settings:COMSETTINGS;                    (* íàñòðîéêè ïîñëåäîâàòåëüíîãî ïîðòà *)
              
    com_numPORTS:=0;                    (*RS-485RS-232*)
        
    enableBOOL;                            (*ñîñòîÿíèå ðàáîòû áëîêà*)
        
    errINT;                                    (*íîìåð îøèáêè*)
        
    TimeOutTIME:=T#100ms;                    (*òàéìàóò*)

        
    DataSizeWORD;                            (*êîë-âî ñ÷èòàííûõ áàéòîâ *)
        
    ptr_byte:POINTER TO BYTE;                 (*óêàçàòåëü íà òèï byte*)
        
    COM_SERVICE1COM_SERVICE;
        
    stateWORD := 0;                            (*ñîñòîÿíèå*)

        
    iWORD := 0;                                (*äîï. ïåðåìåííàÿ*)
        
    t:WORD;                                     (*÷èñëî îøèáîê*)

        
    dwDI                :    WORD;                                    (* Áèòîâàÿ ìàñêà âõîäîâ ìîäóëÿ À4*)
    END_VAR 
    PHP код:
    (*Óñòàíàâëèâàåì íàñòðîéêè 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  );
    (*&
    #197;ñëè COM-ïîðò îòêðûò, òî ïåðåõîäèì ê ïðèåìó è ïåðåäà÷è äàííûõ *)
    IF COM_SERVICE1.ready THEN
        port_opened
    :=2;
    END_IF


    CASE state OF
    0
    :
    enable:=1;
    IF 
    port_opened=2 THEN (*Óäà÷íî ïðîèíèöèàëèçèðîâàëè*)
     
    (* ôóíêöèÿ 03 ôëîàò - ÔÁ ñ÷èòûâàåò çíà÷åíèå ïàðàìåòðà  òèïà int16 èç ïðèáîðà ñ àäðåñîì 22 c ðåãèñòðà ñ íîìàðîì 0dec ïî ïðîòîêîëó Modbus-RTU*)
    get3_modbus(
        
    Enable:=enable,            (* ðàçðåøåíèå ðàáîòû áëîêà *)
        
    Mode:=MB_RTU ,            (*ðåæèì ïåðåäà÷è*)
        
    DevAddr:=32 ,                (*àäðåñ*)
        
    FirstAddr:=288 ,            (*íîìåð ðåãèñòðà*)
        
    Quantity:=24,                (*êîëè÷åñòâî ðåãèñòðîâ*)
        
    ComHandle:=Settings.Port ,(*íîìåð COM-ïîðòà*)
        
    TimeOut:=TimeOut ,         (*Òàéìàóò T#50ms*)
        
    Buffer:=Buffer ,            (* áóôåð äàííûõ *)
        
    Complete=>cmpl ,        (* ñêîïèðîâàòü ïðèçíàê çàâåðøåíèÿ îïåðàöèè *)
        
    Exception=>err ,            (* ñêîïèðîâàòü ðåãèñòð îøèáîê *)
        
    ByteCnt=>DataSize );        (*êîë-âî ñ÷èòàííûõ áàéòîâ *)
    (*åñëè óñòàíîâëåí ïðèçíàê çàâåðøåíèÿ îïåðàöèè, òî *)


    IF cmpl THEN
        
    IF err=0 THEN (*Åñëè íåò îøèáîê, òî ïîëó÷àåì  äàííûå èç áóôåðà, ôîðìèðóåì ïåðåìåííûå*)
            
    (*ìîäóëü ïåðåäàåò çíà÷åíèÿ ñòàðøèì ñëîâîì âïåðåä äëÿ Float32 è ñòàðøèì áàéòîì âïåðåä äëÿ Int16*)
            
    (*ïîýòîìó ïåðåìåííûå ñîáèðàåì "ñïðàâà-íàëåâî" *)
            
    (*âõîä1*)
            
    ptr_byte:=ADR(real1);
            
    ptr_byte^:=buffer[3];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[2];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[1];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[0];

            
    ptr_byte:=ADR(real2);
            
    ptr_byte^:=buffer[9];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[8];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[7];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[6];

            
    ptr_byte:=ADR(real3);
            
    ptr_byte^:=buffer[15];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[14];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[13];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[12];

            
    ptr_byte:=ADR(real4);
            
    ptr_byte^:=buffer[21];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[20];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[19];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[18];

            
    ptr_byte:=ADR(real5);
            
    ptr_byte^:=buffer[27];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[26];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[25];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[24];


            
    ptr_byte:=ADR(real6);
            
    ptr_byte^:=buffer[33];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[32];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[31];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[30];

            
    ptr_byte:=ADR(real7);
            
    ptr_byte^:=buffer[39];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[38];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[37];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[36];

            
    ptr_byte:=ADR(real8);
            
    ptr_byte^:=buffer[45];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[44];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[43];
            
    ptr_byte:=ptr_byte+1;
            
    ptr_byte^:=buffer[42];

            
    state:=1;
            
    enable:=0;
        ELSE 
    t:=t+1;
                
    state:=1;
        
    END_IF
    END_IF
    END_IF

    1
    : (*äàëüíåéøåå çàâèñèò îò ïîëüçîâàòåëÿ*)
        
    (*î÷èñòèì áóôåð*)

        
    FOR i:=0 TO 255 DO
        
    buffer[i]:=0;
        
    END_FOR
        
    (*âåðíåìñÿ îïÿòü â ñîñòîÿíèå 0*)
        
    state:=2;

    2:

    (*&
    #231;àïèñü â áóôôåð ïàðàìåòðà òèïà Float*)

    enable:=1;
    ptr_byte:=ADR(y1);
         
    buffer[5] := ptr_byte^;
         
    ptr_byte:=ptr_byte+1;
         
    buffer[4] := ptr_byte^;
         
    ptr_byte:=ptr_byte+1;
         
    buffer[7] := ptr_byte^;
         
    ptr_byte:=ptr_byte+1;
         
    buffer[6] := ptr_byte^;



    send2_modbus(
           
    Enable:= enable,            (* ðàçðåøåíèå ðàáîòû áëîêà *)
        
    Mode:=MB_RTU ,        (*ðåæèì ïåðåäà÷è*)
        
    DevAddr:=48 ,                 (*àäðåñ*)
        
    FirstAddr:= 0,                 (*íîìåð ðåãèñòðà*)
        
    Quantity:= 8,                   (*êîëè÷åñòâî çàïèñûâàåìûõ ðåãèñòðîâ*)
        
    ComHandle:=Settings.Port ,(*íîìåð ñîì-ïîðòà*)
        
    TimeOut:=TimeOut ,        (*òàéìàóò T#50ms*)
        
    Buffer:=buffer ,            (* áóôåð äàííûõ *)
        
    Complete=>cmpl ,        (* ñêîïèðîâàòü ïðèçíàê çàâåðøåíèÿ îïåðàöèè *)
        
    Exception=>err ,            (* ñêîïèðîâàòü ðåãèñòð îøèáîê *)
        
    RegCnt=> DataSize);        (*êîë-âî ñ÷èòàííûõ áàéòîâ *)
    (*åñëè óñòàíîâëåí ïðèçíàê çàâåðøåíèÿ îïåðàöèè, òî *)
    IF cmpl THEN
        state
    :=3;(*ïåðåõîäèì ê âûïîëíåíèþ ñëåäóþùåãî áëîêà*)
    END_IF

    3
    :

    FOR 
    i:=0 TO 255 DO
        
    buffer[i]:=0;
        
    END_FOR
        
    (*âåðíåìñÿ îïÿòü â ñîñòîÿíèå 0*)
        
    state:=4;
    enable:=0;


    4:

    enable:=1;
    IF 
    port_opened=2 THEN (*Óäà÷íî ïðîèíèöèàëèçèðîâàëè*)
    get3_modbus(
        
    Enable:= enable,            (* ðàçðåøåíèå ðàáîòû áëîêà *)
        
    Mode:=MB_RTU ,        (*ðåæèì ïåðåäà÷è*)
        
    DevAddr:=64 ,                (*àäðåñ*)
        
    FirstAddr:=51 ,                (*íîìåð ðåãèñòðà*)
        
    Quantity:=,                (*êîëè÷åñòâî ðåãèñòðîâ*)
        
    ComHandle:= Settings.Port,(*íîìåð COM-ïîðòà*)
        
    TimeOut:=TimeOut  ,         (*Òàéìàóò T#50ms*)
        
    Buffer:=buffer ,            (* áóôåð äàííûõ *)
        
    Complete=>cmpl ,        (* ñêîïèðîâàòü ïðèçíàê çàâåðøåíèÿ îïåðàöèè *)
        
    Exception=>err ,            (* ñêîïèðîâàòü ðåãèñòð îøèáîê *)
        
    ByteCnt=> DataSize);        (*êîë-âî ñ÷èòàííûõ áàéòîâ *)
    (*åñëè óñòàíîâëåí ïðèçíàê çàâåðøåíèÿ îïåðàöèè, òî *)

    IF cmpl THEN
        
    IF err=0 THEN (*Åñëè íåò îøèáîê, òî ïîëó÷àåì äàííûå èç áóôåðà òèïà INT*)
            
    dwDI:=BYTE_TO_WORD(buffer[1]) OR SHL(BYTE_TO_WORD(buffer[0]),8);
        
    END_IF
            state
    :=5;
            
    END_IF
    END_IF
    5
    :

    FOR 
    i:=0 TO 255 DO
        
    buffer[i]:=0;
        
    END_FOR
        
    (*âåðíåìñÿ îïÿòü â ñîñòîÿíèå 0*)
        
    state:=6;
    enable:=0;


    6:
    enable:=1;
            (*&
    #207;èøåì â áóôåð îòïðàâêè áèòîâóþ ìàñêó*)
            
    ptr_byte:=ADR(mk_mask_in);
            
    buffer[1]:=ptr_byte^;
            
    ptr_byte:=ptr_byte+1;
            
    buffer[0]:=ptr_byte^;
            (*&
    #194;ûïîëíÿåì îòïðàâêó*)
            
    send2_modbus(
                
    Enable:= enable,            (* ðàçðåøåíèå ðàáîòû áëîêà *)
                
    Mode:=MB_RTU ,        (*ðåæèì ïåðåäà÷è*)
                
    DevAddr:=64 ,                (*àäðåñ*)
                
    FirstAddr:=50 ,                (*íîìåð ðåãèñòðà*)
                
    Quantity:=,                (*êîëè÷åñòâî ðåãèñòðîâ*)
                
    ComHandle:= Settings.Port,(*íîìåð COM-ïîðòà*)
                
    TimeOut:=TimeOut  ,         (*Òàéìàóò T#50ms*)
                
    Buffer:=buffer ,            (* áóôåð äàííûõ *)
                
    Complete=>cmpl ,        (* ñêîïèðîâàòü ïðèçíàê çàâåðøåíèÿ îïåðàöèè *)
                
    Exception=>err ,            (* ñêîïèðîâàòü ðåãèñòð îøèáîê *)
                
    RegCnt=> DataSize);        (*êîë-âî ñ÷èòàííûõ áàéòîâ *)
            
    (*åñëè óñòàíîâëåí ïðèçíàê çàâåðøåíèÿ îïåðàöèè, òî *)
    IF cmpl THEN
        state
    :=7;(*ïåðåõîäèì ê âûïîëíåíèþ ñëåäóþùåãî áëîêà*)
    END_IF

    IF  enable FALSE THEN
         enable 
    := TRUE;
    END_IF

    IF  err <> 0 THEN
         enable 
    := FALSE;
    END_IF
    (*&#208;àçáèðàåì áèòîâóþ ìàñêó âõîäîâ ÌÊ110.8ÄÍ.4Ð*)
        
    A4_in1:=dwDI.0;
        
    A4_in2:=dwDI.1;
        
    A4_in3:=dwDI.2;
        
    A4_in4:=dwDI.3;
        
    A4_in5:=dwDI.4;
        
    A4_in6:=dwDI.5;
        
    A4_in7:=dwDI.6;
        
    A4_in8:=dwDI.7;

    7:
    FOR 
    i:=0 TO 255 DO
        
    buffer[i]:=0;
        
    END_FOR
        
    (*&#226;åðíåìñÿ îïÿòü â ñîñòîÿíèå 0*)
        
    state:=0;

    END_CASE 
    Дискретные входы/выходы и считываются и записываются нормально

  7. #17
    Пользователь
    Регистрация
    23.09.2008
    Адрес
    Центророссийск
    Сообщений
    2,259

    Thumbs down

    Ой, пля.. Сначала немного теории:

    Нюанс модбаса
    В модбас сетевой порядок байт в словах (регистрах) отличается порядка байт в словах (вордах) на местном плк. На плк порядок байт 12, сетевой 21.
    Важно ! Та биб-ка (модбас.либ) нифига не удосуживается приводить данные из/в сетевого порядка.

    Отсюда - что при отправке, что при чтении данные нужно приводить самому.
    (Местный релиз ntohw/htonw сводится к единой функции перестановки байтов попарно)

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

    Общий нюанс всех модулей Овен :
    Все 32-битное на модулях (дворды, реалы) имеет другой порядок расположения слов. На плк байты 1234, там 3412
    Т.е. при чтении сначала приводим из сетевого, после этого для всех 32-х битных меняем порядок слов.
    При записи сначала (если есть 32-битное) приводит дабл-слова к порядку модуля, после - полученное приводим в сетевой порядок.

    Теперь ньюанс конкретно 8АС/2AC
    Автор таблицы регистров был пьян, поэтому реализовал таблицу кривом виде совершенно не учитывая невозможность обращения к 32-битному значению с адреса некратного 4-ем байтам. Автор не подозревает что данные можно читать все за раз.
    Но это, так сказать, родовая болезнь овен-реализаторов.

    Код:
    fblock  mu8i
    var_input
      out : array[1..8] of real;  //например для 0..100%
    end_var
    var_in_out
      buf : array[0..255] of byte; //отправлять на регистр 0, 8 регистров
    end_var
    var
      p : pointer to array[1..8] of word;
    ---------------------------------------------
    p := adr(buf);
    for i := 1 to 8 do
      p^[i] := real_to_word(limit(0, out[i] * 10, 1000));  // !! 0..100%
    end_for
    ntohw(adr(buf),sizeof(p^)); //несложная функция для самостоятельного релиза

    Теперь 8ac. Читать - так все.
    Код:
    //не поленится описать типы, чтоб после не писать тупых коментов в коде.
    
    enum ai_status(
      status_ok := 0,
      status_unready := 16#f006,
      status_off := 16#f007,
      status_break := 16#f00d,
      ...
    );
    
    struct ai_struct(
      status : ai_status := status_unready,
      cyclic : word;
      value : real;
    );
    
    
    fblock mv8ac
    var_in_out
       buf : array[0..255] of byte;  //читать с регистра 16#118, 32 регистра
    end_var
    var_output
       ai : array[1..8] of struct_ai;
    end_var
    var
      srd : pointer to array[1..8] of word;
      read : pointer to array[1..8, 1..3] of word;
      p : pointer to array[1..2] of word;
    end_var
    ------------------------------
    ntohw(adr(buf),sizeof(ai)); //все та же несложная функция для самостоятельного релиза
    srd := adr(buf);
    read := adr(buf) + sizeof(srd^);
    for i := 1 to 8 do
      p := adr(ai[i].value);
      ai[i].status := srd^[i];
      ai[i].cyclic := read^[i,3];
      p^[1] := read^[i,2];
      p^[2] := read^[i,1];
    end_for

  8. #18

    По умолчанию

    Массивы/структуры не ?
    Не, мне пока и так нравится. Вполне себе рабочий алгоритм. Да он не похож на Ваш, но как по мне, он и не обязан быть похожим - сколько людей столько и мнений. Вы пользуетесь своими методами/алгоритмами, кто-то другой может пользоваться своими методами/алгоритмами.

    На счет
    //не поленится описать типы, чтоб после не писать тупых коментов в коде.
    . Комментарий - он прежде всего комментарий, а уже потом все остальное. Если Ваши исходники ни кто не читает, то это не значит, что у всех остальных будет такая же ситуация. Как говорит мой знакомый, цитирую "Инструкция должна быть написана для обезьяны. Чтобы обезьяна читала и понимала что, где и как.", поэтому дополнительный комментарий, на мой взгляд, в теле кода лишним не будет (если, конечно, это не анекдот, хотя и он может быть полезен - поспособствует кратковременному "снижению температуры мозга"), даже с учетом использования типов, структур и массивов.

  9. #19
    Пользователь
    Регистрация
    23.09.2008
    Адрес
    Центророссийск
    Сообщений
    2,259

    По умолчанию

    Никто же не говорит что индуский код не работает. Работает. И ему да - обязательно нужны коменты )))
    Я привел общее решение для приведения модбасных данных. Причем не только для Овена.
    Кто как делает - мне побоку.
    Жду очередной плач на форуме что никак не видно данных, например из 2A

  10. #20

    По умолчанию

    Я привел общее решение для приведения модбасных данных. Причем не только для Овена.
    За пример, от меня лично, спасибо. Реальная помощь с Вашей стороны.

    Никто же не говорит что индуский код не работает. Работает. И ему да - обязательно нужны коменты )))
    А вот сарказм и грубость, товарищ Валенок, здесь неуместны, и к делу никакого отношения не имеют.

    Жду очередной плач на форуме что никак не видно данных, например из 2A
    Так Вы возьмите и помогите нуждающимся, если есть возможность и желание, вместо того чтобы оскорблять. Начинающие (и не только) пользователи продукции ОВЕН могут не иметь глубоких познаний всех тонкостей и нюансов ее работы, поэтому каждый раз, всё снова и снова, через неопределенные (а может и нет) временные интервалы, в тех или иных ветках форума, будут появляться всё те же вопросы, нуждающиеся во всё тех же ответах.

Страница 2 из 3 ПерваяПервая 123 ПоследняяПоследняя

Похожие темы

  1. Ответов: 2
    Последнее сообщение: 13.03.2015, 01:00
  2. ПЛК63 не получается опрос по ModBus
    от Кольцов Сергей в разделе ПЛК63/73
    Ответов: 2
    Последнее сообщение: 21.11.2012, 14:22
  3. Ответов: 5
    Последнее сообщение: 06.01.2012, 23:32
  4. Ответов: 9
    Последнее сообщение: 17.03.2011, 05:48
  5. Ответов: 16
    Последнее сообщение: 23.04.2010, 15:33

Ваши права

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