Good morning and Hope all of you are fine. Now I am learning RoboDK for Robot operations and programming and the TF7xxx Vision library is a very good function for me to learn the Vision as a “First Step”. But I need to mention that Pointer/Ref programming, OOP programming understanding is required in the TF7xxx Vision library.(Also the Vision knowledge.)Let’s Start!:)
About TF7xxx Vision
Firstly, TF7xxx Vision is a library that allows you to program the vision application in IEC61131-1 languages.It provides image display tool to Intermittently check the result directly,
And also executed synchronously the image processing algorithms in real-time.
Please be aware that only the GigE Vision interface is supported. The Camera Setup, calibrating or other camera operations can be done by TwinCAT itself.
License for Camera TF700x
License for Library TF7xxx
Installation
Please access the following link.
TF7100 | TwinCAT 3 Vision Base | Beckhoff Worldwide
you can download the software from exe.
Double Click it to start the setup.
Please choose english.
Next.
accept the license, and Next.
Enter your information and Next>.
Choose Complete installation and Next.
Next.
Press install to start the operation.
Please wait a seconds..
Done!
System Requirment
IPC
Camera
Software
SetUP A Vision Devices
Sorry I do not have a Camera and Real Beckhoff PLC also.
I will skip this part until Vision Devices comes out some day.
API
Thanks to the TwinCAT Vision library, it provided many interfaces for the programmer to process the images easily with IEC61131-3.
Interface Pointer
Here are 2 types of Interfaces that we will usually use in the program and I will explain it in the below part.
ITcVnImage:Image Processing
ITcVnContainer:a vector of several elements.
For example, I will use the F_VN_CreateImage() Function to create a new image(800 x 600 pixels of the type TCVN_ET_USINT with one channel.
IF bCreateImage THEN hr:=F_VN_CreateImage( ipImage ,nWidth:=800 ,nHeight:=600 ,ePixelType:=ETcVnElementType.TCVN_ET_SINT ,nChannelNum:=1 ,hrPrev:=hr ); IF hr <> 0 THEN bError:=TRUE; END_IF bCreateImage:=FALSE; END_IF; |
And here is the image that I created:
Some Rules
1-Check before you call the method
It is a very important operation to check if the ITcVnImage is available now or not.
If you directly access the method of the object that is not available, the runtime will crash.
It makes sense,right? And you can just check it by using a simple compare operator.
//GetInfo IF ipImage <> 0 THEN ipImage.GetImageInfo( stImageInfo:=ImageInfo ); END_IF; |
2- Use F_VN Function instead of Methods of the Pointer itself.
TwinCAT TF7xxx is a greate library and provides Functions for you to safely access the Object. And These functions started from F_VN_xxx – They will auto check if the pointer is available or not now.
F_VN_GetImageInfo( ipImage ,stImageInfo:=stImageInfo_1 ,hrPrev:=hr ); |
3- Declare interface pointer in VAR_INPUT
Please reset the Pointer while you are using the Pointer as a VAR_INPUT value.
As you know,FB and POU will keep the last value of the variables.
For this operation, we can make sure that the memory area will not be accessed next time.
Please copy the pointer to a local variable if you want to keep it.
VAR_INPUT ipSrcImage: ITcVnImage; END_VAR //… functional code ipSrcImage := 0; |
4-Release the Pointer if not used anymore.
Declare interface pointer as reference in VAR Release the interface pointer at the end of functions and methods. The interface pointer no longer exists after ending the POU; therefore the reference counter must be decremented beforehand. For programs and function blocks, the interface pointer should be released as soon as it is no longer required:
VAR ipImageWork: ITcVnImage; END_VAR //… functional code hr := FW_SafeRelease(ADR(ipImageWork)); |
In fact, the Function FW_SafeRelease() is doing something like this:
IF binit THEN IF ipImage <> 0 THEN ipImage.TcRelease(); ipImage:=0; END_IF binit:=FALSE; END_IF |
5-Not recommended -declare interface pointer in VAR_OUTPUT
OK- Let me explain it easily.
The variables that you are using in POUs or FB , their values are all retained even after the call.So, if there is some event change outside,it means the memory that you can retain in the last cycle is incorrect.It will cause you to access some released memory areas.
So – please use VAR_INPUT.
HRESULT
All TwinCAT Vision functions return an HRESULT after their execution. Its value indicates whether the execution was successful or not.
It is the same concept as File Access and it is just a return value.
Here is the snapshot from the Manual that shows how to encode the HRESULT in SUCCESS.
And Here is the table that has an explanation About the SUCCESS Code.
Here is the snapshot from the Manual that shows how to encode the HRESULT in Fault.
And Here is the table that has an explanation About the Fault Code.
You can use the SUCCEEDED() Function to check if the HRESULT value is successful or not.
PROGRAM MAIN VAR hr : HRESULT := S_OK; END_VAR IF SUCCEEDED(hr) THEN //code END_IF |
Image processing
ITcVnImage Interface is the Basic interface of the image processing.And also in the Example I will use this image to read the image to TwinCAT and search the QRCode.
This ITcVnImage interface provides methods to access the image data – such as image size,pixel type, raw image data..etc.
Container
Container is a special element that has a vector of several elements.And the number of elements can be changed dynamically.
If the image determines its shape,position and size and describe it by contour points.So – the Container can store your Contour points.
Different types of variables can not be fixed in a container.
By now, We do not need to think too much about this and just image it as a “Box” to allow you to store the variables.
PROGRAM MAIN VAR hr : HRESULT; ipContainer : ITcVnContainer; END_VAR |
Here is a simple flow of how Container works.
Sure there are so many advanced concepts like copy the container, Assign Container inside the Container, I will not explain too much here.
- Images are read from File System to TwinCAT.
- Detects and search the QRCode inside the Image.
- QR data that is decoded and assigns this data into Containers memory.It may be just some data that is not readable.
- Use Function to get the Container data in User Program
- your readable data is returned.
Function/Function Block
The TwinCAT TF7xxx vision library has many Function and Function Blocks, it is not possible to explain it one by one.
I will show the FB/FC that is used in this example.
FB_VN_ReadImage
This is the function block to Read an image from the file system.
VAR_INPUT
sFilePath | STRING | The Full path of your Image file. |
ipDestImage | Reference To ITcVnImage | The return image that is loaded. |
bRead | BOOL | use a rising edge to trigger the image reading |
nTimeout | TIME VISION_ADS_TIME OUT | The time before the function is canceled. |
VAR_OUTPUT
bBusy | BOOL | True=Function Block is running.. |
bError | BOOL | True=Error has occurred. |
nErrorId | UDINT | Error information |
F_VN_ReadQRCode
Detect and Define a QRCode from the provided image.
VAR_INPUT
ipSrcImage | ITcVnImage | The source Image,1 or 3 Channel,can be RGB but convert to Gary internally |
ipDecodeData | Reference To ITcVnContainer | The code inside QRCode is returned |
hrPrev | HRESULT | The result of the previous operations. |
Return Value
F_VN_ReadQRCode | HRESULT | The result of the operation |
F_VN_ExportSubContainer_String
Export the String from the SubContainer.
VAR_INPUT
ipContainer | ITcVnContainer | Container type with ContainerType_Vector_String_SINT |
nIndex | ULINT | |
hrPrev | HRESULT | The result of the previous operations. |
sText | STRING | The Text inside the Container |
nMaxLength | ULINT | Maximum string length to export |
hrPrev | HRESULT | The result of the previous operation. |
Return Value
F_VN_ReadQRCode | HRESULT | The result of the operation |
Implemention
Configuration
In this Example, I will use RoboDK as an OPC UA Client and Thanks to their Camera simulation function – the operation of pick up a box>Take photo>place down can be implemented.
For the TwinCAT Side, TF6100 is used as OPC UA Server and TF7250 for searching and reading the QR code inside the image.
Sorry that I will not explain too much of how to implement the RoboDK section in this tutorial.Because it is just some python scripts.
Please download the project and get more information.
You can use Connect > Simulate 2D Camera to Simulate a 2D camera.
After that you can use any method to work with it.
Flow
Here is the working Flow.
Add library
OPCUA Connections
Please reference the following link to configurare an OPC UA Server.
Beckhoff#Using TwinCAT TF6100 to startup OPCUA Server | (soup01.com)
Script to Create QRCode
from robolink import * # RoboDK API from robodk import * # Robot toolbox import qrcode import tempfile #———————————————- # Create the QR code data = mbox(“QRCode inside the text;”, entry=”Beckhoff.com”) if data is None or data is False or type(data) is not str: # User cancelled quit() img = qrcode.make(data) #———————————————- # Save to file filename=None if filename is None or filename == ”: filename=r”C:\Users\root\Desktop\qrcode1.png” img.save(filename) import os.path if not os.path.exists(filename): quit(-1) # Import in RoboDK RDK = Robolink() img_item = RDK.AddFile(filename) if not img_item.Valid(): quit(-1) |
Program
Here is the code that reads the image from the file system and then detects the QRCode. Display the information by TE1800.
VAR
VAR //FB FB_Images:FB_VN_ReadImage; R_TRIG1,R_TRIG2 :R_TRIG; TON:TON; hr,hr2:HRESULT:=S_OK; index:ULINT; //Pointers ipImage:ITcVnImage; ipDecodedData:ITcVnContainer; stImageInfo_1:TcVnImageInfo; ImageInfo:TcVnImageInfo; //Trigger Devices read:BOOL; readQR:BOOL; binit:BOOL; safetyInit:BOOL; //Image Information width:UDINT; height:UDINT; sText:STRING; END_VAR |
Code
//init IF binit THEN IF ipImage <> 0 THEN ipImage.TcRelease(); ipImage:=0; END_IF binit:=FALSE; END_IF //Safety Init IF safetyInit THEN FW_SafeRelease(ADR(ipImage)); FW_SafeRelease(ADR(ipDecodedData)); safetyInit:=FALSE; read:=FALSE; readQR:=FALSE; hr:=0; hr2:=0; END_IF //GetInfo IF ipImage <> 0 THEN ipImage.GetImageInfo( stImageInfo:=ImageInfo ); END_IF; F_VN_GetImageInfo( ipImage ,stImageInfo:=stImageInfo_1 ,hrPrev:=hr ); //Robot Status Handshake R_TRIG1( CLK:=GVL_OPCUAServer.Node.Command2 = 1 OR GVL_OPCUAServer.Node.Command2 = 3 ); R_TRIG2( CLK:=GVL_OPCUAServer.Node.Command1 = 1 ); IF R_TRIG2.q THEN GVL_OPCUAServer.Node.Command2:=0; height:=0; width:=0; sText:=”; END_IF IF R_TRIG1.Q THEN GVL_OPCUAServer.Node.Command1:=0; END_IF //Read the Image //Trigger the Image read Function FB_Images.bRead:=read; FB_Images( sFilePath:=’C:\images\Images.png’ ,ipDestImage:=ipImage ); TON( IN:=readQR ,PT:=T#0.1S ); //Trigger the QR Read Function IF NOT FB_Images.bError AND read THEN readQR:=TRUE; END_IF //get the image information IF readQR THEN IF ipImage <> 0 THEN ipImage.GetHeight(nHeight:=height); ipImage.GetWidth(nWidth:=width); END_IF; END_IF; //read the QRCode IF TON.q THEN hr:=F_VN_ReadQRCode( ipSrcImage:=ipImage ,ipDecodedData:=ipDecodedData ,hrPrev:=hr ); //Get the Text from Container IF SUCCEEDED(hr) AND ipImage <> 0 THEN hr:= F_VN_ExportSubContainer_String( ipContainer:=ipDecodedData ,sText:=sText ,hrPrev:=hr ,nIndex:=index ,nMaxLength:=255 ); IF SUCCEEDED(hr) THEN read:=FALSE; readQR:=FALSE; FW_SafeRelease(ADR(ipDecodedData)); END_IF END_IF; END_IF; |
Visualization
Run Button:Start commands to RoboDK
Snap!:Snap Shot trigger to RoboDK.
Read QR Data:Read the images.
Clear QR Data:Clear all the pointers, data, flag.
Sample Code
TwinCAT3/Demo_ReadQRCode_WithTwinCAT.zip at main · soup01Threes/TwinCAT3 (github.com)