Beckhoff#Let’s Connect TwinCAT TF6420 with PostgreSQL

Hôm nay chúng ta sẽ sử dụng thư viện TF6420 để kết nối với hệ quản trị cơ sở dữ liệu PostgreSQL, đồng thời cập nhật và truy xuất dữ liệu database bằng API do TwinCAT cung cấp

Bắt đầu thôi nào!

Thanks

Thanks Mr Quang dai for the translation.he is a professional factory automation engineer in Vietnam .And here is his LinkedIn profile:

https://www.linkedin.com/in/quang-%C4%91%E1%BA%A1i-990165224/

Liên kết tham khảo

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

Khối chức năng

Trong phần này, mình sẽ giới thiệu về các khối chức năng được sử dụng trong bài viết. Lần này, chúng ta sẽ sử dụng lệnh “UPDATE” và “SELECT” trong PostgreSQL DB, vì vậy chúng ta sẽ tạo một chương trình theo cấu trúc trong khung màu đỏ.

  • Đối với các lệnh không lấy dữ liệu từ SQL DB Server, chẳng hạn như UPDATE,
    • Dùng FB_SQLDatabase.Connect() để kết nối với Database
    • Dùng FB_SQLDatabase.CreateCmd() khởi tạo khối chức năng FB_SQLCommand
    • Dùng FB_SQLCommand.Execute() để gửi lệnh SQL
    • Dùng FB_SQLDatabase.Disconnected() để ngắt kết nối tới SQL DB
  • Đối với các lệnh lấy dữ liệu từ SQL DB Server, chẳng hạn như SELECT,
    • Dùng FB_SQLDatabase.Connect() để kết nối với Database
    • Dùng FB_SQLDatabase.CreateCmd() khởi tạo khối chức năng FB_SQLCommand
    • Dùng FB_SQLCommand.ExecuteDataReturn() để gửi lệnh SQL
    • Dùng FB_SQL_Result.Read() để đọc dữ liệu từ SQLDB
    • Dùng FB_SQL_Result.Release() để xóa dữ liệu khỏi bộ đệm
    • Dùng FB_SQLDatabase.Disconnected() để ngắt kết nối tới SQL DB

FB_SQLDatabaseEvt

Khối chức năng này được sử dụng để quản lý kết nối tới SQL Server.

VAR_INPUT (Khai báo đầu vào)

Tên biếnKiểu dữ liệu Mô tả
sNetIDT_AmsNetIDĐịa chỉ AMS net ID của thiết bị 
tTimeoutTIMEĐặt thời gian chạy tối đa của hàm đến khi bị hủy bỏ

VAR_OUTPUT (Khai báo đầu ra)

Tên biếnKiểu dữ liệuMô tả
bBusyBOOL1=Khối chức năng đang được thực hiện
bErrorBOOL1=Khối chức năng đã xảy ra lỗi
ipTcResultTc3_EventLogger.I_TcMessageTrạng thái hoạt động của Khối chức năng được trả về giao diện tin nhắn TC3 EventLogger

Phương thức:Connect

Kết nối tới cơ sở dữ liệu.

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

VAR_INPUT (Khai báo đầu vào)

Tên biếnKiểu dữ liệuMô tả
hDBIDUDINTĐặt ID của cơ sở dữ liệu được sử dụng 

RetureValue

Tên biếnKiểu dữ liệuMô tả
ConnectBOOLTrue=Phương thức đã thực hiện xong (Khi có lỗi thì vẫn trả về giá trị True)

Phương thức: CreateCmd

Phương thức này được sử dụng để khởi tạo FB_SQLCommand

Theo tài liệu thì việc khởi tạo khối chức năng FB_SQLCommand có thể được hoàn thành trong cùng 1 chu kỳ quét, nhưng để tránh lỗi bạn nên theo dõi xung cạnh lên và xuống của Busy

VAR_INPUT
    pSQLCommand: POINTER TO FB_SQLCommandEvt;
END_VAR

VAR_INPUTS (Khai báo đầu vào)

Tên biếnKiểu dữ liệuMô tả
pSQLCommandPOINTER TO FB_SQLCommandLấy một phiên bản mới từ khối chức năng FB_SQLCommandEvt đã được khởi tạo

ReturnValue

Tên biếnKiểu dữ liệuMô tả
CreateCmdBOOLTrue=Phương thức đã thực hiện xong (Khi có lỗi thì vẫn trả về giá trị True)

FB_SQLCommandEvt

Khối chức năng để thực thi lệnh SQL. Để sử dụng được, nó cần được khởi tạo bởi khối chức năng FB_SQLDatabaseEvt.

VAR_INPUT (Khai báo đầu vào)

Tên biếnKiểu dữ liệuMô tả
sNetIDT_AmsNetIDĐịa chỉ AMS net ID của thiết bị 
tTimeoutTIMEĐặt thời gian chạy tối đa của hàm đến khi bị hủy bỏ

VAR_OUTPUT (Khai báo đầu ra)

Tên biếnKiểu dữ liệuMô tả
bBusyBOOL1=Khối chức năng đang được thực hiện
bErrorBOOL1=Khối chức năng đã xảy ra lỗi
ipTcResultTc3_EventLogger.I_TcMessageTrạng thái hoạt động của Khối chức năng được trả về giao diện tin nhắn TC3 EventLogger

Phương thức: Execute

Gửi lệnh SQL tới thông qua kết nối với cơ sở dữ liệu đã được mở bởi khối chức năng FB_SQLDatabase.

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

VAR_INPUT (Khai báo đầu vào)

Tên biếnKiểu dữ liệu Mô tả
pSQLCmdPOINTER TO BYTECon trỏ đến bộ nhớ biến chuỗi của lệnh SQL cần thực thi (bạn có thể sử dụng hàm ADR)
cbSQLCmdUDINTĐộ dài của lệnh SQL (bạn có thể sử dụng hàm SIZEOF)

ReturnValue

Tên biến Kiểu dữ liệu Mô tả
ExecutePOINTER TO BYTEGiá trị trả về cho biết trạng thái thực thi của phương thức

Phương thức: ExecuteDataReturn

Gửi lệnh SQL tới thông qua kết nối với cơ sở dữ liệu đã được mở bởi khối chức năng FB_SQLDatabase. Phiên bản của khối chức năng FB_SQLResult được chuyển đổi để đọc các giá trị trả về.

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

VAR_INPUT (Khai báo đầu vào)

Tên biếnKiểu dữ liệuMô tả
pSQLCmdPOINTER TO BYTECon trỏ đến bộ nhớ biến chuỗi của lệnh SQL cần thực thi (bạn có thể sử dụng hàm ADR)
cbSQLCmdUDINTĐộ dài của lệnh SQL (bạn có thể sử dụng hàm SIZEOF)
pSQLDBResultPOINTER TO FB_SQLResultGiá trị trả về 1 phiên bản của FB_SQLResult

ReturnValue (Giá trị trả về)

Tên biếnKiểu dữ liệuMô tả
ExecuteDataReturnPOINTER TO BYTEGiá trị trả về cho biết trạng thái thực thi của phương thức

FB_SQLResultEvt

Khối chức năng này dùng để đọc các giá trị được ghi trong bộ nhớ đệm.

VAR_INPUT (Khai báo đầu vào)

Tên biếnKiểu dữ liệuMô tả
sNetIDT_AmsNetIDĐịa chỉ AMS net ID của thiết bị 
tTimeoutTIMEĐặt thời gian chạy tối đa của hàm đến khi bị hủy bỏ

VAR_OUTPUT (Khai báo đầu ra)

Tên biếnKiểu dữ liệuMô tả
bBusyBOOL1=Khối chức năng đang được thực hiện
bErrorBOOL1=Khối chức năng đã xảy ra lỗi
ipTcResultTc3_EventLogger.I_TcMessageTrạng thái hoạt động của Khối chức năng được trả về giao diện tin nhắn TC3 EventLogger

Phương thức: Read

Phương thức này đọc một số lượng bản ghi được chỉ định trong bộ nhớ đệm của máy chủ cơ sở dữ liệu TwinCAT

VAR_INPUT (Khai báo đầu vào)

Tên biếnKiểu dữ liệuMô tả
nStartIndexUDINTĐặt giá trị index của bản ghi cần đọc
nRecordCountUDINTĐặt số lượng bản ghi cần đọc
pDataPOINTER TO BYTECon trỏ đến bộ nhớ của mảng giá trị để lưu lại bản ghi đọc được(có thể dùng hàm ADR)
cbDataUDINTĐặt kích thước của mảng giá trị theo byte (có thể dùng hàm SIZE OF)
bWithVerifyingBOOLTrue=dữ liệu trả về đã được so sánh với mảng pData và được điều chỉnh
bDataReleaseBOOLGiải phóng bộ nhớ đệm

ReturnValue (Giá trị trả về)

Tên biếnKiểu dữ liệuMô tả
ReadBOOLTrue=Phương thức đã được thực thi (Khi có lỗi thì vẫn trả về giá trị True)

Các bước thực hiện

PostgreSQL Server sẽ được cài trên Raspberry Pi4 và IPC Beckhoff C6920 sẽ truy cập vào database thông qua TF6420.

Cấu hình

Cấu hình máy chủ dữ liệu TF6420.

Thêm chương trình TwinCAT Database Server mới

Trên giao diện TwinCAT IDE hoặc Visual Studio, nhấn chuột phải>Add>New Project.

Chọn vào Empty TwinCAT Database Server Project và nhấn Next.

Đặt tên cho TwinCAT Database Server Project và nhấn Create.

TcDbServer đã được tạo.

Thêm server PostgreSQL Database

Nhấn chuột phải vào  TcDbServer>Add New Database.

DB đã được tạo

DBID=1, ID này là tham số rất quan trọng khi sử dụng API của PLC

Database Type

Chọn kiểu database từ danh sách thả xuống

Trong trường hợp này, PostgreSQL sẽ được sử dụng

Hoàn thành!

Host

Host là địa chỉ IP của thiết bị mà được cài đặt PostgreSQL 

Ở đây là 192.168.5.144.

Database

Database nên để giống với tên của DB trong PostgreSQL.

Bạn có thể kiểm tra bằng VSCODE’s PostgreSQL Plugin, tôi sẽ dùng db xa5.

Xong!

Port

Cổng giao tiếp mặc định của PostgreSQL là 5432.

Authentication

Bước tiếp theo là cài phương thức bảo mật; Mặc định là None.

Chọn Username/Password từ danh sách Authentication.

Khi bạn chọn Username/Password, mục Username and Password sẽ hiện ra

Nhập thông tin đăng nhập của bạn.

Connecton String

The Connection String displays the connection path according to the parameters you have just set.

Kiểm tra kết nối

Nhấn vào nút CHECK để kiểm tra kết nối giữa TwinCAT và Database.

Kích hoạt License..

Nếu bạn thấy lỗi 0x724, hãy kích hoạt giấy phép cho TF6420.

SYSTEM>License.

Tích chọn vào ô TF6420.

Chọn vào 7 Days Trial License để kích hoạt giấy phép dùng thử trong 7 ngày.

Nhập các kí tự theo mã.

Xong!

Nhấn vào Activate Configuration để đổ chương trình

Nhấn OK để tiếp tục

Chuyển sang Runmode OK

Kết Quả

Nhấn CHECK để thử lại. Lần này thì thông báo Configuration check succeded hiện ra. Như vậy là đã kết nối thành công!

Activate Configuration

Kích hoạt cấu hình của TwinCAT Database Server.

DB>Right click>Activate Configuration.

Thêm chương trình PLC

Tiếp theo, để thêm chương trình plc, nhấn chuột phải vào PLC>right click>Add New Item.

Chọn Standard PLC Project>Add.

Thêm thư viện 

Để thêm thư viện database TF6420 vào chương trình, nhấp chuột phải vào References>Right click>Add library.

Thêm Tc3_Database.

Hoàn thành!

Lập trình

Bước tiếp theo là viết chương trình.

DUT_SQL 

Tạo kiểu Struct giống với các tag của bảng được tạo trong cơ sở dữ liệu XA5

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

Ngoài ra còn có các chuỗi tagname và tagvalue trong VSCode’s PostgreSQL Plug-in.

Làm cách nào để biết được kích thước?

Bạn có thể kiểm tra kích thước biến của mỗi hàng bằng lệnh sau 

SELECT tagvalue ,char_length(tagvalue) FROM tags; 

Như vậy, số byte sẽ tỉ lệ thuận với số kí tự, chẳng hạn như 505=3.

FC_SQL_UpdateCommands 

Khối chức năng này tự động thực thi lệnh 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

Đây là trình tự điều khiển hiện tại.

  • Step0=Khởi tạo tham số
  • Step10=kết nối tới PostgreSQL DB
  • Step20=Khởi tạo FB_SQLCommandEvt.
  • Step30-45=Gửi lệnh Update tới PostgreSQL DB
  • Step50=Gửi lệnh Select tới PostgreSQL
  • Step60=Chuyển đổi dữ liệu truy xuất được bằng lệnh Select vào biến PLC 
  • Step70=Đợi 1 giây và quay lại 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

Kết quả

Hoàn thành! Chúng ta đã có thể truy xuất dữ liệu mới nhất từ PostgreSQL DB và ghi nó vào biến plc.

Lấy dữ liệu mới nhất từ  VSCODE’s PostgreSQL Plug-in.

SELECT * FROM “tags” LIMIT 1000;

Xong! Bạn cũng đã nhận được dữ liệu cập nhật từ TwinCAT 

Tải xuống

Bạn có thể tải chương trình mẫu trong bài viết theo liên kết dưới đây

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

シェアする

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

フォローする