Warning
You are reading an old version of this documentation. If you want up-to-date information, please have a look at 5.1 .Example - Beckhoff TwinCAT
This section gives an example of a simple integration of EYE+ with the EtherCAT module in Beckhoff TwinCAT version 3.1.
Prerequisites
- Before you start, please make sure you have downloaded the following files:
EYE+ EtherCAT ESI file (Electronic datasheet)
Optionally, EYE+ TwinCAT Project template, containing predeclared variables for easier integration
These files can be downloaded from EtherCAT Downloads.
Once you have downloaded the necessary files, please make sure to install the ESI file in the Beckhoff TwinCAT’s installation folder:
<path_to_twincat_install>\3.1\Config\Io\EtherCAT
Where <path_to_twincat_install>
is usually C:\TwinCAT\
.
After installing the ESI file in the correct folder, please make sure you have restarted Beckhoff TwinCAT.
Basic integration
Once everything is in place, you can proceed with creating a new Beckhoff TwinCAT project. Then, make sure you are in Configuration Mode by pressing the following icon in the top left part:
After that, you are ready to scan the EtherCAT bus to recognize and locate your EYE+ and the master device. The scan option is available by right-clicking on Devices, located in the left pane:
The scanning process might take a few seconds, it will find all the devices currently connected to the bus.
Note
If you do not see your EYE+ in the list after the scan has finished, please make sure it is correctly connected and powered-on. If the problem persists, please contact our support team.
After the scan is completed, you should see your EYE+ box in the list under Devices:
If you have downloaded the optional template, please follow the next steps. Importing the template creates all the necessary variables to fully take advantage of your EYE+. Importing the template is straightforward, right click on your PLC project an click on Import From ZIP:
If successful, you should have entire structures of variables available:
You will need to build the project so that the variables are available from within TwinCAT. Mapping the variables to EYE+’s own variables can be achieved easily with the Multi Link functionality:
Once the variables have been mapped, and after restarting in running mode, you should be able to get live feedback of the registers:
The following sample code allows you to start a production and get your first parts for a recipe that was previously
created on your EYE+ Controller. To do that, set udRecipeID
to the ID of that recipe, then set boStart
to True.
The coordinates of the part found are returned in reRobotTargetX
, reRobotTargetY
and
reRobotTargetRz
.
(*
* This sample code is distributed under the license CC0 1.0 Universal,
* you can get a copy of the license at https://creativecommons.org/publicdomain/zero/1.0/
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*)
VAR
udRecipeID: UDINT;
boStart: BOOL;
R_TRIG_Start: R_TRIG;
boStop: BOOL;
R_TRIG_Stop: R_TRIG;
boClearError : BOOL;
inLastErrorID: UDINT;
eState: UDINT;
reRobotTargetX: REAL;
reRobotTargetY: REAL;
reRobotTargetRz: REAL;
END_VAR
VAR CONSTANT
STATE_IDLE: UDINT := 0;
STATE_START_PRODUCTION: UDINT := 10;
STATE_ROBOT_MOVE_OUT_FOV: UDINT := 20;
STATE_GET_PART: UDINT := 30;
STATE_ROBOT_PICK_PLACE: UDINT := 50;
STATE_STOP_PRODUCTION: UDINT := 60;
STATE_ERROR: UDINT := 100;
END_VAR
R_TRIG_Start(CLK:= boStart);
R_TRIG_Stop(CLK:= boStop);
CASE eState OF
STATE_IDLE:
IF R_TRIG_Start.Q THEN
eState := STATE_START_PRODUCTION;
END_IF
STATE_START_PRODUCTION:
EYEplus.suEYEplusOutputGLO.udRecipeIDGOU := udRecipeID;
EYEplus.suEYEplusOutputGLO.boStartProductionTriggerGOU := TRUE;
IF EYEplus.suEYEplusInputGLO.boStartProductionDoneGIN AND NOT EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
EYEplus.suEYEplusOutputGLO.boStartProductionTriggerGOU := FALSE;
eState := STATE_ROBOT_MOVE_OUT_FOV;
ELSIF EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
EYEplus.suEYEplusOutputGLO.boStartProductionTriggerGOU := FALSE;
eState := STATE_ERROR;
END_IF
STATE_ROBOT_MOVE_OUT_FOV:
//Robot move out of field of view
//Check that the movement is done before to go first get_part
eState := STATE_GET_PART;
STATE_GET_PART:
EYEplus.suEYEplusOutputGLO.boGetPartTriggerGOU := TRUE;
IF EYEplus.suEYEplusInputGLO.boGetPartDoneGIN AND NOT EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
reRobotTargetX := EYEplus.suEYEplusInputGLO.rePose1XGIN;
reRobotTargetY := EYEplus.suEYEplusInputGLO.rePose1YGIN;
reRobotTargetRz := EYEplus.suEYEplusInputGLO.rePose1RzGIN;
EYEplus.suEYEplusOutputGLO.boGetPartTriggerGOU := FALSE;
eState := STATE_ROBOT_PICK_PLACE;
ELSIF EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
EYEplus.suEYEplusOutputGLO.boGetPartTriggerGOU := FALSE;
eState := STATE_ERROR;
END_IF
STATE_ROBOT_PICK_PLACE:
//Robot pick and place the part
//Check that the movement is done before to go make another get_part
eState := STATE_GET_PART;
STATE_STOP_PRODUCTION:
EYEplus.suEYEplusOutputGLO.udStopStateGOU := 16#FF;
IF EYEplus.suEYEplusInputGLO.boStopStateDoneGIN AND NOT EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
EYEplus.suEYEplusOutputGLO.udStopStateGOU := 16#00;
eState := STATE_IDLE;
ELSIF EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
EYEplus.suEYEplusOutputGLO.udStopStateGOU := 16#00;
eState := STATE_ERROR;
END_IF
STATE_ERROR:
EYEplus.suEYEplusOutputGLO.udStopStateGOU := 16#00;
EYEplus.suEYEplusOutputGLO.boStartProductionTriggerGOU := FALSE;
EYEplus.suEYEplusOutputGLO.boGetPartTriggerGOU := FALSE;
inLastErrorID := EYEplus.suEYEplusInputGLO.udErrorIDGIN;
EYEplus.suEYEplusOutputGLO.boClearErrorTriggerGOU := boClearError;
IF NOT EYEplus.suEYEplusInputGLO.boIsErrorGIN THEN
EYEplus.suEYEplusOutputGLO.boClearErrorTriggerGOU := FALSE;
eState := STATE_STOP_PRODUCTION;
END_IF;
END_CASE
IF R_TRIG_Stop.Q THEN
EYEplus.suEYEplusOutputGLO.boStartProductionTriggerGOU := FALSE;
EYEplus.suEYEplusOutputGLO.boGetPartTriggerGOU := FALSE;
EYEplus.suEYEplusOutputGLO.boClearErrorTriggerGOU := FALSE;
eState := STATE_STOP_PRODUCTION;
END_IF