Beckhoff#TwinCAT TF6420とPostgreSQLを接続しよう

今回はTF6420のLibraryを使用しPostgreSQL DBと接続し、TwinCATが提供しているAPIを使用しDBのデータを更新したり取得します。

さ、はじめよう!

Reference Link

PostgreSQL#Install PostgreSQL in Raspberry Pi4
Beckhoff#TwinCAT3 TF6420 x MongoDB_Part1
Beckhoff#TwinCAT3 TF6420 x MongoDB_Part2

Function Block

今回は記事内で使用したFunction Blockを紹介します。今回はPostgreSQL DBに”UPDATE”と”SELECT”コマンドを使用するので赤枠のFlowでプログラムを作成します。

  • UPDATEなどSQL DB Serverからデータをしないコマンドの場合は、
    • FB_SQLDatabase.Connect()でSQL DBと接続する
    • FB_SQLDatabase.CreateCmd()でFB_SQLCommand を初期化する
    • FB_SQLCommand.Execute()でSQLDBにコマンドを送信する
    • FB_SQLDatabase.Disconnected()でSQLDBの接続を切断します。
  • SELECTなどSQL DB Serverからデータを取得するコマンドの場合は、
    • FB_SQLDatabase.Connect()でSQL DBと接続する
    • FB_SQLDatabase.CreateCmd()でFB_SQLCommand を初期化する
    • FB_SQLCommand.ExecuteDataRetrun()でSQLDBにコマンドを送信する
    • FB_SQL_Result.Read()でSQLDBから取ったデータを読み込む
    • FB_SQL_Result.Release()でSQLDBから取ったデータをBufferから削除
    • FB_SQLDatabase.Disconnected()でSQLDBの接続を切断します。

FB_SQLDatabaseEvt

こちらのFunction Blockを使用しSQL データベースの接続を管理できます。

VAR_INPUT

VariableTypeDescription
sNetIDT_AmsNetIDADS Command対象となるデバイスのAMSネットワークID
tTimeoutTIMEFunctionの実行がキャンセルされるまでの時間を設定します

VAR_OUTPUT

VariableTypeDescription
bBusyBOOL1=Function Block実行中
bErrorBOOL1=Function Blockエラーあり
ipTcResultTc3_EventLogger.I_TcMessageFunction Blockの実行状態を提供できるTwinCAT 3 EventLogger Messsage Interface

Method:Connect

データベースと接続します。

METHOD Connect : BOOL
VAR_INPUT
    hDBID: UDINT := 1;
END_VAR

VAR_INPUT

VariableTypeDescription
hDBIDUDINT使用するデータベースのIDを設定します

RetureValue

VariableTypeDescription
ConnectBOOLTrue=Methodが実行完了の(エラーがある場合もTrueになります)

Method:CreateCmd

こちらのMethodを使用し既に開いているデータベース接続で、コマンド生成などの FB_SQLCommandEvt のInterfaceを初期化します。

ManualにはFunction Block FB_SQLCommand の初期化は同じのサイクルで完了できると書きましたが、Bug防止のためBusy Flagの立ち上げ>そしてまたたち下げの変化をMonitorしたほうがよいだ思います。

VAR_INPUT
    pSQLCommand: POINTER TO FB_SQLCommandEvt;
END_VAR

VAR_INPUTS

VariableTypeDescription
pSQLCommandPOINTER TO FB_SQLCommand初期化完了された、新しいFunction Block FB_SQLCommandEvtのInstance取得する

ReturnValue

VariableTypeDescription
CreateCmdBOOLTrue=Methodが実行完了の(エラーがある場合もTrueになります)

FB_SQLCommandEvt

Function block for executing SQL commands. Before it can be used it has to be initialized with the function block FB_SQLDatabaseEvt.

VAR_INPUT

VariableTypeDescription
sNetIDT_AmsNetIDADS Command対象となるデバイスのAMSネットワークID
tTimeoutTIMEFunctionの実行がキャンセルされるまでの時間を設定します

VAR_OUTPUT

VariableTypeDescription
bBusyBOOL1=Function Block実行中
bErrorBOOL1=Function Blockエラーあり
ipTcResultTc3_EventLogger.I_TcMessageFunction Blockの実行状態を提供できるTwinCAT 3 EventLogger Messsage Interface

Method:Execute

FB_SQLDatabaseで既にオープンされているデータベース接続を介して、 SQL コマンドをデータベースに送信します。

METHOD Execute : BOOL
VAR_INPUT
    pSQLCmd: POINTER TO BYTE;
    cbSQLCmd: UDINT;
END_VAR

VAR_INPUT

VariableTypeDescription
pSQLCmdPOINTER TO BYTE実行するSQLコマンドの文字列変数Memory Pointer(ADR関数を使用すればよい)
cbSQLCmdUDINT実行するSQLコマンドの長さ(SIZEOF関数を使用すればよい)

ReturnValue

VariableTypeDescription
ExecutePOINTER TO BYTEMethodの実行Statusを示す戻り値になります。

Method:ExecuteDataReturn

FB_SQLDatabaseで既にオープンされているデータベース接続を介して、 SQL コマンドをデータベースに送信します。 Function Block FB_SQLResult のInstanceは、返されたレコードを読むために転送されたものです。

METHOD ExecuteDataReturn : BOOL
VAR_INPUT
    pSQLCmd: POINTER TO BYTE;
    cbSQLCmd: UDINT;
    pSQLDBResult: POINTER TO FB_SQLResult;
END_VAR

VAR_INPUT

VariableTypeDescription
pSQLCmdPOINTER TO BYTE実行するSQLコマンドの文字列変数Memory Pointer(ADR関数を使用すればよい)
cbSQLCmdUDINT実行するSQLコマンドの長さ(SIZEOF関数を使用すればよい)
pSQLDBResultPOINTER TO FB_SQLResultFunction Block FB_SQLResult のInstanceを返す

ReturnValue

VariableTypeDescription
ExecuteDataReturnPOINTER TO BYTEMethodの実行Statusを示す戻り値になります。

FB_SQLResultEvt

このFunction BlockはCachedされたレコードの読み取りに使用されます。

VAR_INPUT

VariableTypeDescription
sNetIDT_AmsNetIDADS Command対象となるデバイスのAMSネットワークID
tTimeoutTIMEFunctionの実行がキャンセルされるまでの時間を設定します

VAR_OUTPUT

VariableTypeDescription
bBusyBOOL1=Function Block実行中
bErrorBOOL1=Function Blockエラーあり
ipTcResultTc3_EventLogger.I_TcMessageFunction Blockの実行状態を提供できるTwinCAT 3 EventLogger Messsage Interface

Method:Read

こちらのMethodはTwinCAT Database ServerにCachedされたデータから、指定した数のレコードを読み出します。

VAR_INPUT

VariableTypeDescription
nStartIndexUDINT最初に読み込まれるレコードのIndexを設定する
nRecordCountUDINT読み込むレコード数を設定する
pDataPOINTER TO BYTEレコードを書き込む構造体配列のMemory Pointer(ADR関数から取得できる)
cbDataUDINT構造体配列のサイズをバイト数で設定する(SIZEOF関数から取得できる)
bWithVerifyingBOOLTrue=戻されたデータはpData構造体配列と比較し、調整する
bDataReleaseBOOLキャッシュされたデータをリリースする

ReturnValue

VariableTypeDescription
ReadBOOLTrue=Methodが実行完了の(エラーがある場合もTrueになります)

Implementation

こちらは今回の構成です。PostgreSQL ServerはRaspberry Pi4上でアクセスし、Beckhoff C6920からTF6420を使用しアクセスします。

Configuration

TF6420のData Serverを設定します。

Add New DataServer Project

TwinCAT IDEやVisual Studioから右クリック>Add>New Projectします。

Empty TwinCAT Database Server Projectを選び、Nextします。

TwinCAT Database Server Projectの名前を設定し、Createで進みます。

TcDbServerが作成しました。

Add PostgreSQL Database

TcDbServerを右クリック>Add New Databaseします。

DBが追加されました。

DBID=1で、このIDはPLCのAPIを使用するときに、非常に大事なパラメータです。

Database Type

Database TypeのDrop-listからデータベースの種類を設定します。

今回はPostgreSQLを使用します。

Done!

Host

HostはPostgreSQL DBがインストールされたデバイスのIPを設定します。

今回は192.168.5.144です。

Database

DatabaseはPostgreSQL内のDB名に合わせてください。

VSCODEのPostgreSQL Pluginからも確認できますが、今回はxa5を使用します。

Done!

Port

PostgreSQLのDefault通信Portは5432です。

Authentication

次は認証方法を設定します。DefaultはNoneです。

AuthenticationのDrop-listからUsername/Passwordを選択します。

Username/Passwordを設定するとUsernameとPasswordの入力Fieldが表示します。

Login情報を入力してください。

Connecton String

Connection Stringには先程設定したパラメータに沿ってConnection pathが表示されます。

CHECK Connection

CHECKボタンをクリックしTwinCATとDatabaseの接続をテストしましょう。

IF NO License..

0x724のエラーが表示されたらライセンスを生成しましょう。

SYSTEM>Licenseします。

TF6420をCheckします。

7 Days Trial LicenseのボタンをクリックしTrialライセンスを生成します。

Magic codeを入力します。

Done!

Activate ConfigurationでプロジェクトをDownloadしましょう。

OKで進みます。

Run Modeに切り替えましょう。

RESULT

もう一回接続テストを行います。今回はConfiguration check succededが表示されます。つまり接続OKです!

Activate Configuration

DB構成をTwinCAT Database ServerにDownloadします。

DB>右クリック>Activate Configurationします。

ADD PLC

次はPLCプロジェクトを追加するため、PLC>右クリック>Add New Itemします。

Standard PLC Projectを選び>Addします。

Add Library

TF6420のDatabaseライブラリをプロジェクトに追加するため、References>右クリック>Add libraryします。

Tc3_Databaseを追加します。

Done!

Program

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

DUT_SQL 

こちらの構造体はDatabaseのXA5 にあるtags Tableのデータに合わせたものです。

TYPE DUT_SQL :
STRUCT
tagname:STRING(255);
tagvalue:STRING(255);
END_STRUCT
END_TYPE

VSCodeのPostgreSQL Plug-inからtagnameとtagvalueにも文字列があります。

How to get the size?

下記のコマンドで各Rowの変数サイズを確認できます。

SELECT tagvalue ,char_length(tagvalue) FROM tags; 

このように505=3など、文字の数に沿ったByte数になります。

FC_SQL_UpdateCommands 

こちらのFunctionは自動的にSQLのUpdateコマンドを生成します。

FUNCTION FC_SQL_UpdateCommands : STRING(255)
VAR_INPUT
iValue:INT;
iTag:STRING;
END_VAR
VAR
END_VAR

FC_SQL_UpdateCommands:=’UPDATE tags SET tagvalue = ‘;
FC_SQL_UpdateCommands:=CONCAT(STR1:=FC_SQL_UpdateCommands,STR2:=INT_TO_STRING(iValue));
FC_SQL_UpdateCommands:=CONCAT(STR1:=FC_SQL_UpdateCommands,STR2:=’ ‘);
FC_SQL_UpdateCommands:=CONCAT(STR1:=FC_SQL_UpdateCommands,STR2:=’WHERE tagname = ‘);
FC_SQL_UpdateCommands:=CONCAT(STR1:=FC_SQL_UpdateCommands,STR2:=iTag);

MAIN

こちらは実際のプログラム制御Flowになります。

  • Step0=パラメータ初期化
  • Step10=PostgreSQL DBと接続します
  • Step20=FB_SQLCommandEvtを初期化します。
  • Step30‐45=PostgreSQL DBにUpdateコマンドを送信する
  • Step50=PostgreSQLにSelectコマンドを送信する
  • Step60=Selectコマンドから取得されたデータをPLC変数に転送する
  • Step70=1秒待ち、またStep20に戻る
PROGRAM MAIN
VAR
FB_SQLDatabaseEvt:FB_SQLDatabaseEvt(sNetID := ”, tTimeout := T#5S);
FB_SQLCommandEvt:FB_SQLCommandEvt(sNetID := ”, tTimeout := T#5S);
FB_SQLResultEvt :FB_SQLResultEvt(sNetID := ”, tTimeout := T#5S);

tags:ARRAY[0..99]OF DUT_SQL;
iStep:INT;
SQL_Commands:ARRAY[1..4]OF STRING(255);
iCounter:INT:=0;
i:INT;
isubstep:INT;
iErrorCounet :INT;
sSelectDataCommand :STRING(255);
TON_Process :TON;
END_VAR

CASE iStep OF

0:
TON_Process(IN:=FALSE);
iCounter:=1;
iStep:=10;

10:
FB_SQLDatabaseEvt.Connect(
hDBID:=1
);
IF FB_SQLDatabaseEvt.bError THEN
iErrorCounet:=iErrorCounet+1;
iStep:=9991;
END_IF
IF FB_SQLDatabaseEvt.bConnected THEN
iStep:=20;
END_IF
20:
FB_SQLDatabaseEvt.CreateCmd(
pSQLCommand:=ADR(FB_SQLCommandEvt)
);
IF FB_SQLDatabaseEvt.bError THEN
iErrorCounet:=iErrorCounet+1;
iStep:=9992;
END_IF
TON_Process(IN:=NOT FB_SQLDatabaseEvt.bBusy AND NOT FB_SQLDatabaseEvt.bError);
IF TON_Process.Q THEN
TON_Process(IN:=FALSE);
iStep:=30;
iCounter:=iCounter+1;
IF iCounter>100 THEN
iCounter:=1;
END_IF
END_IF
30:
SQL_Commands[1]:=FC_SQL_UpdateCommands(iCounter,’$’Application/GVL_FactoryIO/qCounter1$’;’);
SQL_Commands[2]:=FC_SQL_UpdateCommands(iCounter*10+1,’$’Application/GVL_FactoryIO/qCounter2$’;’);
SQL_Commands[3]:=FC_SQL_UpdateCommands(iCounter*10+2,’$’Application/GVL_FactoryIO/qCounter3$’;’);
SQL_Commands[4]:=FC_SQL_UpdateCommands(iCounter*10+3,’$’Application/GVL_FactoryIO/iFactoryIORunning$’;’);
iStep:=40;
isubstep:=0;
i:=1;
40:

IF FB_SQLCommandEvt.Execute(pSQLCmd:=ADR(SQL_Commands[i]),cbSQLCmd:=SIZEOF(SQL_Commands[i])) THEN
IF FB_SQLCommandEvt.bError THEN
iErrorCounet:=iErrorCounet+1;
iStep:=9994;
END_IF
END_IF;
IF  FB_SQLCommandEvt.bBusy THEN
isubstep:=1;
END_IF
IF NOT FB_SQLCommandEvt.bBusy AND isubstep=1 THEN
iStep:=45;
isubstep:=0;
END_IF

45:
i:=i+1;
IF i >= 5 THEN
iStep:=50;
isubstep:=0;
ELSE
iStep:=40;
END_IF

50:
sSelectDataCommand:=’SELECT * FROM “tags” LIMIT 1000;’;
IF FB_SQLCommandEvt.ExecuteDataReturn(pSQLCmd:=ADR(sSelectDataCommand),cbSQLCmd:=SIZEOF(sSelectDataCommand),pSQLDBResult:=ADR(FB_SQLResultEvt)) THEN

IF FB_SQLCommandEvt.bError THEN
iErrorCounet:=iErrorCounet+1;
END_IF
IF FB_SQLResultEvt.nDataCount >0 AND NOT FB_SQLCommandEvt.bBusy THEN
iStep:=60;
END_IF

END_IF

60:

IF FB_SQLResultEvt.Read(
nStartIndex:=0
,nRecordCount:=4
,pData:=ADR(tags)
,cbData:=SIZEOF(tags)
,bWithVerifying:=TRUE
,bDataRelease:=TRUE
) THEN

IF FB_SQLResultEvt.bError THEN
iErrorCounet:=iErrorCounet+1;
iStep:=9995;
END_IF
IF FB_SQLResultEvt.nDataCount=0 THEN
iStep:=70;
END_IF;
END_IF;

70:
TON_Process(IN:=TRUE,PT:=T#1S);
IF TON_Process.Q THEN
TON_Process(IN:=FALSE);
iStep:=20;
END_IF

END_CASE

Result

Done!PostgreSQL DBから最新のデータを取得しPLC変数に転送できました。

VSCODEのPostgreSQL Plug-inからDBの最新データを取得します。

SELECT * FROM “tags” LIMIT 1000;

Done!TwinCATがUpdateしたデータも確認できましたね。

Download

下記のLinkから記事のプロジェクトをDownloadしてください。

https://github.com/soup01Threes/TwinCAT3/blob/main/TwinCATestWithSQL.tnzip

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

シェアする

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

フォローする