PLCNEXT#AXL SE 485を使ってSchneider PLCと通信しよう

今回の記事ではPhoenixContactのAXL SE RS485とModbus_RTUライブラリの組わせてModbus RTU Masterを立ち上げ、SchneiderのTM221にあるModbus RTU Slaveと通信します。

さ、はじめよう!

AXL SE RS485

このSmart Elementは、バス・システム上でシリアル・インタフェース(RS485)を持つ標準I/Oデバイスとして使用されます。

  • RS-485形式のシリアル入出力チャンネル
  • 伝送速度は230,400bpsまで設定可能
  • データビット数、ストップビット数、パリティを設定可能

Internal circuit diagram

こちらはAXL SE RS485の内部構成図です。

Layout

こちらはAXL SE RS485モジュールのLayoutです。

LED

こちらはAXL SE RS485モジュールのLEDが持つ意味です。

Wiring Example

RS-485では、2本の信号線で構成される既存のネットワークを利用して、複数の機器によるネットワークを構築することができます。デバイスの接続には、twisted-pairの共通シールドデータケーブルを使用し、そしてRS-485ネットワークの両端のデータケーブルに終端抵抗を取り付けます。

このためには、Smart Elementに内蔵された終端抵抗を、接続R+とR-を介して使用することができます。

注意するのは、AXL SE RS485は半二重伝送にのみ対応していることです。複数の機器から同時にデータが送信されないようにしてください。

Smart Element as the network endpoint

AXL SE RS485がネットワークのEndpointデバイスとして使用する場合の配線例です。

Smart Element in the middle of a network

AXL SE RS485がネットワークの中間デバイスとして使用する場合の配線例です。

Download Library

下記のLinkからPLCNEXT StoreにModbus RTUのライブラリをDownloadしましょう。

https://www.plcnextstore.com/us/app/1432

Downloadボタンをクリックします。

ライセンスに同意しライブラリをDownloadします。

このようなZip FileがDownloadされました。

Function Block/Data Types

ライブラリに含まれているすべてのFunction Blockを説明するのは無理なので、今回記事で使用したFunction Blockのみ説明します。

MB_UDT_RTU_FC_DIAG

MB_UDT_RTU_SND_DIAG : STRUCT
 iState : INT;
 wDiagCode : WORD;
 wAddDiagCode : WORD;
 bControlByte0 : BYTE;
 bStatusByte0 : BYTE;
END_STRUCT;

MB_UDT_AXL_SE_RS485_DIAG_MASTER 

MB_UDT_AXL_SE_RS485_DIAG_MASTER : STRUCT
 udtMB_AXL_RS_UNI_REC_Diag : MB_UDT_RTU_REC_DIAG;
 udtMB_AXL_RS_UNI_SND_Diag : MB_UDT_RTU_SND_DIAG;
 udtMB_RTU_Master_Diag : MB_UDT_RTU_MASTER_DIAG;
END_STRUCT;

MB_UDT_RTU_REC_DIAG 

MB_UDT_RTU_REC_DIAG : STRUCT
 iState : INT;
 wDiagCode : WORD;
 wAddDiagCode : WORD;
 bControlByte0 : BYTE;
 bStatusByte0 : BYTE;
END_STRUCT;

MB_UDT_RTU_SND_DIAG 

MB_UDT_RTU_SND_DIAG : STRUCT
 iState : INT;
 wDiagCode : WORD;
 wAddDiagCode : WORD;
 bControlByte0 : BYTE;
 bStatusByte0 : BYTE;
END_STRUCT;

MB_UDT_RTU_MASTER_DIAG 

MB_UDT_RTU_MASTER_DIAG : STRUCT
 iState : INT;
 wDiagCode : WORD;
 wAddDiagCode : WORD;
END_STRUCT;

arrModbus2_W_1_125 

arrModbus2_W_1_125 : ARRAY [1..125] OF WORD;

arrModbus2_W_1_123 

arrModbus2_W_1_123 : ARRAY [1..123] OF WORD;

MB2_AXL_RSUNI2_ARR_B_0_19 

MB2_AXL_RSUNI2_ARR_B_0_19 : ARRAY [0..19] OF BYTE

udtModbus2_Data

udtModbus2_Data : STRUCT
 (* Modbus handling *)
 (* Send Modbus request *)
 xSendRequest : BOOL;
 (* Indicates FC wants to send a Modbus request *)
 xNDR : BOOL; (* New modbus response received *)
 xBusy : BOOL; (* FC only operates if not busy *)
 xReset : BOOL; (* Reset from input on master FB *)
 tTimeout : TIME; (* Input tTimeout of the Modbus_Master FB*)
 (* General Modbus data *)
 uiSlaveAddress : UINT; (* Address of the Modbus slave *)
 iFunctionCode : INT; (* Function Code by the Master *)
 uiStartAddress : UINT;
 (* Starting address in the Modbus register table *)
 iSndDataCount : INT; (* Required data length from FC *)
 iExpDataCount : INT; (* Expected data length depending
 of the function code number OF bits or words *)
 uiRcvdDataCount : UINT; (* Received bytes from Serial IF
 / UINT for the range higher than 127 *)
 arrData : arrModbus2_W_1_125; (* Modbus telegram *)
 (* Failure handling (master outputs) *)
 xMasterActive : BOOL; (* Interface is ready *)
 xMasterBusy : BOOL; (* Interface is busy *)
 xMasterError : BOOL; (* Error indication *)
 wMasterDiagCode : WORD; (* Diagnostics code *)
 wMasterAddDiagCode : WORD; (* Additional diagnostics code *)
 xMB_Error : BOOL; (* Exception Code Response *)
 xFC_Busy : BOOL; (* FC catches bit IF request and not
xFC_Busy *)
END_STRUCT;

MB_RTU_FC4

このFunction Blockは Modbus SlaveからInput Registerを読み取ります。

VAR_INPUT

Variable NameTypeDescription
xActivate BOOL True=FBを有効する
xSendRequest BOOL 立ち上がりでマスター・ブロックへの送信リクエストを送ります立ち下がり信号は現在のModbusエラーを削除し、なおかつFB出力をResetします。
xEnablePoll BOOL 立ち上げ信号でサイクル・ポーリングを始めます。
tPollIntervall TIME xEnablePollが有効な場合の送信時間間隔
uiSlaveAddress UINT 通信するSlave IDを指定する(1~255)
uiStartAddress UINT Slaveで読み出しの開始アドレスを指定する
iDataCount INT Skaveで読み出すデバイス数を指定する(1~2000)

VAR_OUTPUT

Variable NameTypeDescription
xActive BOOL True=FBを有効してる
xBusy BOOL True=FBが実行中
xDone BOOL True=リクエストが送信され、スレーブからのレスポンスが正常に受信される
xError BOOL True=FBがエラーあり、詳しくはwDiagCodeとwAddDiagCodeに参照
wDiagCode WORD FB診断情報
wAddDiagCodeWORD FB診断情報2
udtDiag MB_UDT_RTU_FC_DIAG診断用の内部変数を持つ構造体変数

VAR_INOUT

Variable NameTypeDescription
arrReadData arrModbus2_W_1_125Modbus データが含まれている構造体になります
udtMBData udtModbus2_Data MB_AXL_SE_RS485_Masterと通信するInterface

MB_RTU_FC16

このFunction Blockはデータを Modbus のMultiple Holding Registerに書き込みます。

VAR_INPUT

Variable NameTypeDescription
xActivate BOOL True=FBを有効する
xSendRequest BOOL 立ち上がりでマスター・ブロックへの送信リクエストを送ります立ち下がり信号は現在のModbusエラーを削除し、なおかつFB出力をResetします。
xEnablePoll BOOL 立ち上げ信号でサイクル・ポーリングを始めます。
tPollIntervall TIME xEnablePollが有効な場合の送信時間間隔
uiSlaveAddress UINT 通信するSlave IDを指定する(0~255)
uiStartAddress UINT Slaveで読み出しの開始アドレスを指定する
iDataCount INT Skaveで読み出すデバイス数を指定する(1~123)

VAR_OUTPUT

Variable NameTypeDescription
xActive BOOL True=FBを有効してる
xBusy BOOL True=FBが実行中
xDone BOOL True=リクエストが送信され、スレーブからのレスポンスが正常に受信される
xError BOOL True=FBがエラーあり、詳しくはwDiagCodeとwAddDiagCodeに参照
wDiagCode WORD FB診断情報
wAddDiagCodeWORD FB診断情報2
udtDiag MB_UDT_RTU_FC_DIAG診断用の内部変数を持つ構造体変数

VAR_INOUT

Variable NameTypeDescription
arrReadData arrModbus2_W_1_123長さ123 Wordの配列で、Multiple Holding Registerに書き込むための変数
udtMBData udtModbus2_Data MB_AXL_SE_RS485_Masterと通信するInterface

MB_AXL_SE_RS485_Master

.このFunction Blockは、指定されたモジュール(今回はAXL SE RS485)の Modbus Masterを実装するために使用されます。

VAR_INPUT

Variable NameTypeDescription
xActivate BOOL True=Function Blockを有効する
tModbus_Timeout TIME Modbus RTUとSlaveの通信Timeout時間Default=TIME#5s
tPD_TimeoutTIME PLCとモジュール(今回はAXL SE RS485)のProcess Data通信Timeout時間
xReset BOOL True=FBをリセットする(注意するのは内部のFC Blocksも含めてリセットされる)

VAR_OUTPUT

Variable NameTypeDescription
xActive BOOL True=FBを有効してる
xBusy BOOL True=FBが実行中
uiRequestsCounter UINT 送信リクエスト数
uiResponsesCounter UINT 受信リクエスト数
udtDiag  MB_UDT_AXL_SE_RS485_DIAG_MASTER 診断情報の構造体

VAR_INOUT

Variable NameTypeDescription
udtMBData udtModbus2_Data MB_AXL_SE_RS485_Masterが他のMB_RTU_FCXX Blockと通信するInterface
arrInputData MB2_AXL_RSUNI2_ARR_B_0_19AXL SE RS485モジュールのProcess Input Data
arrOutputData MB2_AXL_RSUNI2_ARR_B_0_19AXL SE RS485モジュールのProcess Output Data

Implementation

Schneider Side

Modbus RTU Slave Configuration

EcoStruxure Machine Expert Basicを立ち上げ、Configuration>SL1を開いてシリアル通信Portを設定します。

Serial line configuration

ProtocolをModbusに設定し、なおかつ通信速度なども設定しましょう。

Modbus Configuration

次はTM221をModbus Slaveとして立ち上げたいので、SL1>Modbusを開きます。

Tranmission ModeをRTUにし、AddressingをSlaveを選択し、Addressを設定しましょう。

Program

次は検証用のプログラムを作成します。Modbus RTU Masterから受信したデータをそのままFeedbackするようなLoop-Backプログラムです。

PLCNEXT Side

Import Library

先程PLCNEXT StoreからDownloadしたライブラリを解凍し、中にDocumentsとFilesのFolderがあり、DocumentsはライブラリのManualで、Filesはライブラリの本体や使用例が格納されています。

ライブラリの本体はPCWLX Fileで、そのFileを下記のPathに複製してください。

C:\Users\Public\Documents\PLCnext Engineer\Libraries

PLCNEXT Engineeringを起動し、COMPONENTS>右クリック>Add User Libraryでライブラリを追加します。

先程複製したPCWLX Fileを開きましょう。

Done!Modbus_RTUライブラリがプロジェクトに追加されました。

ProgrammingにもModbus_RTUのFolderが追加され、中にPLCNEXTのシリアル通信のライブラリが入っています。

今回はSmart ElementsのRS485モジュールからModbus RTU Masterを立ち上げるので、MB_AXL_SE_RS485_Masterを使用することになります。

Add Module

プロジェクトにAXL SE RS485モジュールを追加するため、Axioline Fをダブルクリックします。

Device List画面が表示されます。

今回はSlot3にAXL SE RS485がインストールされたので、#3のType Fieldをクリックし>AXL SE RS485を選択しましょう。

Done!

Data ListにはAXL SE RS485モジュールの関連変数も自動的に宣言されました。

Settings

次はAXL SE RS485のモジュール設定を行います。

AXL SE RS485の通信パラメータをSchneider PLC側のModbus RTU Slaveに合わせて設定していきましょう。

Data Types

DUT_ModbusRTU

DUT_ModbusRTUは今回記事で使用する構造体をまとめるためのData Type定義Sheetです。

DUT_MB_RTU_MASTER 

こちらの構造体はMB_AXL_SE_RS485_Master Function Blockに使用するINPUT/OUTPUT/INOUTパラメータをまとめて定義します。

    DUT_MB_RTU_MASTER    : STRUCT
    //Inputs
        xActivate            : BOOL;
        xReset               : BOOL;
        xMode                : BOOL;
        tModbus_Timeout      : TIME;
        tPD_Timeout          : TIME;
    //Output
        xActive              : BOOL;
        xBusy                : BOOL;
        uiRequestsCounter    : UINT;
        uiResponsesCounter   : UINT;
        xError               : BOOL;
    //InOut
        udtDiag                : MB_UDT_AXL_SE_RS485_DIAG_MASTER;
    END_STRUCT
DUT_MB_RTU_FC16 

こちらの構造体はMB_RTU_FC16 Function Blockに使用するINPUT/OUTPUT/INOUTパラメータをまとめて定義します。

    DUT_MB_RTU_FC16    : STRUCT
    //Inputs
        xActivate       : BOOL;
        xSendRequest    : BOOL;
        xEnablePoll     : BOOL;
        tPollInterval   : TIME;
        uiSlaveAddress  : UINT;
        uiStartAddress  : UINT;
        iDataCount      : INT;
    //Outputs
        xActive          : BOOL;
        xBusy            : BOOL;
        xDone            : BOOL;
        xError           : BOOL;
        wDiagCode        : WORD;
        wAddDiagCode     : WORD;
        udtDiag          : MB_UDT_RTU_FC_DIAG;
    //InOut
        arrRegisterValues        : arrModbus2_W_1_123;
    END_STRUCT;
DUT_MB_RTU_FC4 

こちらの構造体はMB_RTU_FC4 Function Blockに使用するINPUT/OUTPUT/INOUTパラメータをまとめて定義します。

    DUT_MB_RTU_FC4  : STRUCT
    //Inputs
        xActivate       : BOOL;
        xSendRequest    : BOOL;
        xEnablePoll     : BOOL;
        tPollInterval   : TIME;
        uiSlaveAddress  : UINT;
        uiStartAddress  : UINT;
        iDataCount      : INT;
    //Outputs
        xActive          : BOOL;
        xBusy            : BOOL;
        xDone            : BOOL;
        xError           : BOOL;
        wDiagCode        : WORD;
        wAddDiagCode     : WORD;
        udtDiag          : MB_UDT_RTU_FC_DIAG;
    //InOut
        arrRegisterValues        : arrModbus2_W_1_125;
    END_STRUCT
DUT_MB_Modbus_RTU 

こちらの構造体は先程定義したものをまとめた構造体です。

    DUT_MB_Modbus_RTU    : STRUCT
        iState                        : INT;
        udtMBData                    : udtModbus2_Data;
        udtMB_AXL_SE_RS485_Master    : DUT_MB_RTU_MASTER;
        udtMB_RTU_FC16                : DUT_MB_RTU_FC16;
        udtMB_RTU_FC4                : DUT_MB_RTU_FC4;
    END_STRUCT;

Program

次はプログラムを作成します。

Flow

VAR

今回使用する変数をMainプログラムに定義します。

AXL_SE_RS485_MasterAXL SE RS485にModbus RTU Masterを立ち上げするためのInstance
RTU_Master先程定義した構造体で、Function Blockのパラメータに割り付ける変数が含まれています
arrInputPDAXL SE RS485モジュールのProcess Input Data
arrOutputPDAXL SE RS485モジュールのProcess Output Data
RTU_FC16Modbus RTU Function Code 16を発行するInstnace
RTU_FC4Modbus RTU Function Code 4を発行するInstnace
iCounterPLCNEXT側がSchneider PLCに書き込むのデータ
xRTUErrorModbus RTU通信エラー発生のFlag
xRTUResetModbus RTUプログラムをリセットするデバイス
arrRegisterValuesSchneider PLCから読み取ったデータを格納するBuffer
iLoopFOR Loop用のCounter

Code

こちらは実際のプログラムです。

i16_w_Int:=i16_w_Int+1;

r32_w_real:=r32_w_real+0.01;

if r32_w_real>=10000.0 THEN

    r32_r_Real:=0.0;

end_if;

case RTU_Master.iState OF

    0:

        //Parameters Init

            RTU_Master.udtMB_AXL_SE_RS485_Master.tModbus_Timeout:=T#5s;

            RTU_Master.udtMB_AXL_SE_RS485_Master.tPD_Timeout:=T#2s;

            xRTUError:=False;

            xRTUReset:=false;

            RTU_Master.udtMB_RTU_FC16.xActivate:=false;

            RTU_Master.udtMB_RTU_FC16.xSendRequest:=False;

            RTU_Master.udtMB_RTU_FC4.xActivate:=false;

              RTU_Master.udtMB_RTU_FC4.xSendRequest:=False;

            RTU_Master.udtMB_AXL_SE_RS485_Master.xActivate:=False;

            if not RTU_Master.udtMB_AXL_SE_RS485_Master.xBusy THEN

                RTU_Master.iState:=10;

            end_if;

    10:

        //Startup the RS485-Master

            RTU_Master.udtMB_AXL_SE_RS485_Master.xActivate:=True;

            if RTU_Master.udtMB_AXL_SE_RS485_Master.xActive THEN

                RTU_Master.iState:=20;

            END_IF;

            if RTU_Master.udtMB_AXL_SE_RS485_Master.xError THEN

                RTU_Master.iState:=9990;

            end_If;

    20:

        //Data Init of FC16 Command        

            RTU_Master.udtMB_RTU_FC16.xEnablePoll:=False;

            RTU_Master.udtMB_RTU_FC16.uiSlaveAddress:=1;

            RTU_Master.udtMB_RTU_FC16.uiStartAddress:=1;

            RTU_Master.udtMB_RTU_FC16.iDataCount:=5;

            if iCounter >=100 THEN

                iCounter:=1;

            END_IF;

            iCounter:=iCounter+1;

            RTU_Master.udtMB_RTU_FC16.arrRegisterValues[1]:=TO_WORD(iCounter);

            RTU_Master.udtMB_RTU_FC16.arrRegisterValues[2]:=TO_WORD(iCounter*10);

            RTU_Master.udtMB_RTU_FC16.arrRegisterValues[3]:=TO_WORD(iCounter*20);

            RTU_Master.udtMB_RTU_FC16.arrRegisterValues[4]:=TO_WORD(iCounter*30);

            RTU_Master.iState:=30;

    30:

       //Activate the Function block of FC16

            RTU_Master.udtMB_RTU_FC16.xActivate:=True;

            if RTU_Master.udtMB_RTU_FC16.xActive THEN

                RTU_Master.iState:=40;

            END_IF;

            if RTU_Master.udtMB_RTU_FC16.xError THEN

                RTU_Master.iState:=9991;

            end_if;

   40:

        //Send the request to slave with Function Code 16

            RTU_Master.udtMB_RTU_FC16.xSendRequest:=True;

            if RTU_Master.udtMB_RTU_FC16.xDone THEN

                RTU_Master.udtMB_RTU_FC16.xSendRequest:=False;

                RTU_Master.iState:=45;

            end_if;

            if RTU_Master.udtMB_RTU_FC16.xError THEN

                RTU_Master.iState:=9992;

            end_if;          

   45:

        //Data Init of FC4 Command and Reset FC16 Command 

            RTU_Master.udtMB_RTU_FC16.xActivate:=False;

            RTU_Master.udtMB_RTU_FC4.xEnablePoll:=False;

            RTU_Master.udtMB_RTU_FC4.uiSlaveAddress:=1;

            RTU_Master.udtMB_RTU_FC4.uiStartAddress:=11;

            RTU_Master.udtMB_RTU_FC4.iDataCount:=5;        

            RTU_Master.iState:=50;

    50:

        //Check if the FB is reset

            if RTU_Master.udtMB_RTU_FC16.xActive=False THEN

                RTU_Master.iState:=60;

            end_If;

    60:

       //Activate the Function block of FC4

            RTU_Master.udtMB_RTU_FC4.xActivate:=True;

            for iLoop :=1 to 125 DO

                arrRegisterValues[iLoop]:=0;

            end_for;

            if RTU_Master.udtMB_RTU_FC4.xActive THEN

                RTU_Master.iState:=70;

            END_IF;

            if RTU_Master.udtMB_RTU_FC4.xError THEN

                RTU_Master.iState:=9993;

            end_if;  

   70:

        //Send the request to slave with Function Code 4

            RTU_Master.udtMB_RTU_FC4.xSendRequest:=True;

            if RTU_Master.udtMB_RTU_FC4.xDone THEN

                RTU_Master.udtMB_RTU_FC4.xSendRequest:=False;

                RTU_Master.udtMB_RTU_FC4.xActivate:=False;

                arrRegisterValues:=RTU_Master.udtMB_RTU_FC4.arrRegisterValues;

                RTU_Master.iState:=80;

            end_if;

            if RTU_Master.udtMB_RTU_FC4.xError THEN

                RTU_Master.iState:=9994;

            end_if;

    80:

        //Check if the FB is reset

            if RTU_Master.udtMB_RTU_FC4.xActive=False THEN

                RTU_Master.iState:=20;

            end_If;     

    9991,9992,9993,9994:

        //Error

            xRTUError:=True;

            if xRTUReset THEN

                RTU_Master.iState:=0;

            end_if;

end_case;

//Function Block for smart elements

    AXL_SE_RS485_Master(

        xActivate:=RTU_Master.udtMB_AXL_SE_RS485_Master.xActivate

        ,tModbus_Timeout:=RTU_Master.udtMB_AXL_SE_RS485_Master.tModbus_Timeout

        ,tPD_Timeout:=RTU_Master.udtMB_AXL_SE_RS485_Master.tPD_Timeout

        ,xReset:=RTU_Master.udtMB_AXL_SE_RS485_Master.xReset

        ,xActive=>RTU_Master.udtMB_AXL_SE_RS485_Master.xActive

        ,xBusy=>RTU_Master.udtMB_AXL_SE_RS485_Master.xBusy

        ,uiRequestsCounter=>RTU_Master.udtMB_AXL_SE_RS485_Master.uiRequestsCounter

        ,uiResponsesCounter=>RTU_Master.udtMB_AXL_SE_RS485_Master.uiResponsesCounter

        ,xError=>RTU_Master.udtMB_AXL_SE_RS485_Master.xError

        ,udtDiag=>RTU_Master.udtMB_AXL_SE_RS485_Master.udtDiag

        ,udtMbData:=RTU_Master.udtMBData

        ,arrInputData:=arrInputPD

        ,arrOutputData:=arrOutputPD

        )

        ;

//Function Block of FC16

    RTU_FC16(

        xActivate:=RTU_Master.udtMB_RTU_FC16.xActivate

        ,xSendRequest:=RTU_Master.udtMB_RTU_FC16.xSendRequest

        ,xEnablePoll:=RTU_Master.udtMB_RTU_FC16.xEnablePoll

        ,uiSlaveAddress:=RTU_Master.udtMB_RTU_FC16.uiSlaveAddress

        ,uiStartAddress:=RTU_Master.udtMB_RTU_FC16.uiStartAddress

        ,iDataCount:=RTU_Master.udtMB_RTU_FC16.iDataCount

        ,xActive=>RTU_Master.udtMB_RTU_FC16.xActive

        ,xBusy=>RTU_Master.udtMB_RTU_FC16.xBusy

        ,xDone=>RTU_Master.udtMB_RTU_FC16.xDone

        ,xError=>RTU_Master.udtMB_RTU_FC16.xError

        ,wDiagCode=>RTU_Master.udtMB_RTU_FC16.wDiagCode

        ,wAddDiagCode=>RTU_Master.udtMB_RTU_FC16.wAddDiagCode

        ,arrRegisterValues:=RTU_Master.udtMB_RTU_FC16.arrRegisterValues

        ,udtMbData:=RTU_Master.udtMBData

        )

        ;

//Function Block of FC4

   RTU_FC4(

        xActivate:=RTU_Master.udtMB_RTU_FC4.xActivate

        ,xSendRequest:=RTU_Master.udtMB_RTU_FC4.xSendRequest

        ,xEnablePoll:=RTU_Master.udtMB_RTU_FC4.xEnablePoll

        ,uiSlaveAddress:=RTU_Master.udtMB_RTU_FC4.uiSlaveAddress

        ,uiStartAddress:=RTU_Master.udtMB_RTU_FC4.uiStartAddress

        ,iDataCount:=RTU_Master.udtMB_RTU_FC4.iDataCount

        ,xActive=>RTU_Master.udtMB_RTU_FC4.xActive

        ,xBusy=>RTU_Master.udtMB_RTU_FC4.xBusy

        ,xDone=>RTU_Master.udtMB_RTU_FC4.xDone

        ,xError=>RTU_Master.udtMB_RTU_FC4.xError

        ,wDiagCode=>RTU_Master.udtMB_RTU_FC4.wDiagCode

        ,wAddDiagCode=>RTU_Master.udtMB_RTU_FC4.wAddDiagCode

        ,arrReaddata:=RTU_Master.udtMB_RTU_FC4.arrRegisterValues

        ,udtMbData:=RTU_Master.udtMBData

        )

        ;      

Mapping

先程arrInputPDとarrOutputPDのIN Port・Out Port変数を定義しましたが、この変数をAXL SE RS485モジュールのProcess Dataと紐つける必要があります。

Mainプログラムを開きます。

MainプログラムのGDS Port List画面が表示されました。

IN Port

IN PortはAXL SE RS485のProcess Output Dataと紐つけるため、IN Port欄を選択し>Axioline F>Serial-1/~DO160を設定します。

Done!

OUT Port

IN PortはAXL SE RS485のProcess Input Dataと紐つけるため、OUT Port欄を選択し>Axioline F>Serial-1/~DI160を設定します。

Done!

Structure

こちらは実際のプログラムの構造です。

Result

Done!プログラムがエラーなしで稼働しています。

RTU_Masterの構造体変数をMonitorします。

リクエストのCounterとリスボンのCounterも加算され、Slaveと通信してることがわかります。

Schneider TM221がLoopbackしたデータが受信できました。

同じく、Schneider TM221からもPLCNEXTのデータを受信できました。

こちらの動画から実際にAXL SE RS485が正常ときのLED Statusを確認できます。

Download

こちらのLinkからプロジェクトをDownloadできます。

https://github.com/soup01Threes/PLCNEXT/blob/main/Project-RS485pcwex.pcwex

Footer_Basic

Please Support some devices for my blog

Amazon Gift List

Find ME

Twitter:@3threes2
Email:soup01threes*gmail.com (* to @)
YoutubeChannel:https://www.youtube.com/channel/UCQ3CHGAIXZAbeOC_9mjQiWQ

シェアする

  • このエントリーをはてなブックマークに追加

フォローする