目录
一、 设备介绍
一、设备图片
二、设备描述
1、主要特点:
2、技术参数
3、应用场景
二、PLC通讯接配置
2.1 PLC里添加 GSDML 文件
2.2 输入变量实例化,并映射到通讯端口
2.3 输出变量实例化,并映射到通讯端口
三、设备通讯接口数据类型定义
3.1 定义激光刻印机结构体
3.2 定义激光刻印机结构体-input
3.3 定义激光刻印机结构体-Output
3.4 定义 定义激光刻印机 通讯商品全局变量
四、”FB_TYP_172_Laser_Marker_X450″通讯功能块变量声明
五、”FB_TYP_172_Laser_Marker_X450″通讯功能块程序
六、”FB_TYP_172_Laser_Marker_X450″通讯功能块程序分析
6.1 整体架构与核心功能
6.2 关键数据结构与变量
6.3 状态机执行流程解析
6.4 设备交互与命令协议
6.5 错误处理与诊断机制
6.6 优化与扩展点
6.7 总结
七、”FB_TYP_172_Laser_Marker_X450″通讯功能块描述
7.1 改进空间分析
1. 代码结构优化
2. 错误处理增强
3. 性能优化
4. 配置灵活性
5. 用户交互与监控
6. 安全机制
7. 功能扩展
8. 代码健壮性
7.2 改进示例:模块化重构
八、附录
8.1 ACfinalCopyData 子程序
一、 设备介绍
一、设备图片

二、设备描述
基恩士 MD – X 系列激光刻印机是一款在工业领域具有广泛应用的高精度激光加工设备,
1、主要特点:
高精度刻印:采用先进的激光技术,能够实现高精度的文字、图案、二维码等刻印。可以在各种材料表面刻画出精细的线条和清晰的图案,字符最小可达到微米级别,满足了对微小零件或高精度标识有要求的行业需求,如电子、医疗、汽车零部件等行业。
多种刻印方式:支持多种刻印方式,包括打点、划线、填充等,可以根据不同的刻印需求进行灵活选择。此外,还能实现旋转刻印、曲面刻印等特殊功能,适应各种形状和尺寸的工件加工。
高速刻印:具备较高的刻印速度,能够在短时间内完成大量的刻印任务,提高生产效率。例如,对于一些简单的文字和图案,每秒可完成多个刻印动作,适用于自动化生产线的高速作业。
操作简便:配备直观的操作界面和易于使用的软件,操作人员可以快速上手。通过软件可以方便地进行图案设计、参数调整、刻印预览等操作,无需复杂的编程知识。同时,设备还支持多种文件格式导入,如 DXF、AI、PDF 等,方便用户直接使用现有的设计文件。
稳定性高:采用高品质的激光器和精密的机械结构,确保设备在长时间运行过程中保持稳定的性能。具有良好的散热系统和防尘设计,能够适应不同的工作环境,减少因环境因素导致的设备故障,提高设备的可靠性和使用寿命。
2、技术参数
激光波长:根据不同的型号和应用需求,可能提供多种激光波长选择,如常见的 1064nm(光纤激光器)、355nm(紫外激光器)等。不同波长的激光适用于不同的材料和刻印效果要求,例如紫外激光器更适合对精细度要求高的材料进行加工。
激光功率:功率范围通常在几瓦到几十瓦之间,具体功率大小根据型号而定。较高的激光功率可以实现更深的刻印深度和更快的刻印速度,但对于一些薄型材料或对热影响敏感的材料,则可以选择较低功率的激光器,以避免材料过热或变形。
刻印范围:可支持的刻印范围大小有所不同,一般常见的有 100mm×100mm、200mm×200mm 等规格,也有一些大型号设备能够实现更大范围的刻印。用户可以根据实际工件的大小选择合适的刻印范围。
重复精度:重复精度通常可达到 ±0.01mm 甚至更高,确保每次刻印的位置和精度都能保持高度一致,这对于需要进行多批次、高精度刻印的生产过程非常重要。
3、应用场景
电子行业:用于在电子元器件、电路板、手机外壳等表面刻印型号、序列号、生产日期、二维码等信息,以便于产品的追溯和管理。同时,高精度的刻印能够满足电子元件小型化、精细化的发展趋势。
汽车制造:可在汽车零部件如发动机缸体、轮毂、车身等部位刻印标识、图案、VIN 码等。激光刻印的永久性和高精度有助于提高汽车零部件的质量追溯性和品牌标识的清晰度,同时也能满足汽车生产线上的高速自动化生产需求。
医疗领域:在医疗器械、药品包装、医用耗材等方面有广泛应用。例如,在注射器、输液器等一次性医疗用品上刻印批次号、有效期等信息;在骨科植入物、牙科器械等医疗器械上刻印产品型号、规格、序列号等,便于产品的跟踪和管理,保障医疗安全。
五金制品:对各种金属制品如刀具、工具、锁具等进行刻印,可刻上品牌标识、规格参数、花纹图案等,提升产品的附加值和美观度,同时也起到了防伪和品牌宣传的作用。
塑料及复合材料:适用于在塑料零件、塑料包装、复合材料等表面进行刻印。可以实现清晰的文字和图案标记,并且通过调整激光参数,能够控制对材料的热影响,避免材料变形或损坏。
二、PLC通讯接配置
2.1 PLC里添加 GSDML 文件

2.2 输入变量实例化,并映射到通讯端口

2.3 输出变量实例化,并映射到通讯端口

三、设备通讯接口数据类型定义
3.1 定义激光刻印机结构体

3.2 定义激光刻印机结构体-input
TYPE ST_Laser_Marker_Input :
STRUCT
Ready :BOOL; //Whether it is Ready state appears. Bit "1" accepts operations such as setting change, character string edition, program no. fixation input, and others.
Error :BOOL; //Whether an abnormal error has occurred or not appears.
Warning :BOOL; //Whether or not there is a warning on the laser marker.
IO_Error :BOOL; //Whether or not there is an error caused by the I/O terminal. For example, the laser is under remote interlock or shutter control.
Shutter :BOOL; //Whether the internal shutter is opened or closed.
Network :BOOL; //The status of the Fieldbus network communication.
Job_Change_Ready:BOOL; //Whether or not the laser is ready to accept a program change request.
Distance_Laser_Ready :BOOL; //Displays the Ready state of the distance laser.
Laser_Emitted :BOOL; //The laser excitation status.
Shutter_Control :BOOL; //Whether the shutter control I/O input is on or off.
Remote_Interlock :BOOL; //Whether the remote interlock I/O input is on or off.
Laser_Safety_Module :BOOL; //Displays whether the laser safety module control input is on or off.(0: OFF (Close).1: ON (Open))
Logging_Trigger :BOOL; //Displays whether the logging trigger input is on or off
External_Lighting_Control:BOOL;//Displays whether the external lighting control output is on or off
Spare_Byte1_6 :BOOL;
Spare_Byte1_7 :BOOL;
Busy :BOOL; //This bit is "1" when any one of bits of busy status is "1."
Marking_Busy :BOOL; //Whether or not the laser is marking.
Guide_Laser_Busy :BOOL; //Whether the guide laser or distance pointer is in operation.
Job_Change_Busy_Status :BOOL; //Whether or not the settings are being expanded. Expansion occurs during operations such as program change and character string change.
Communication_Priority_Error:BOOL; //This bit is "1" when the laser marker has been connected to other PLCs or control devices and this device does not have priority.
Job_Edit_Busy :BOOL; //Whether or not the program is being edited.
Mark_Check_2DC_Read_Busy :BOOL; //Whether OR NOT marking verification OR 2D code reading is in progress.
Window_Monitoring_Busy :BOOL; //Turns on during the lens inspection
Spare_Byte3 :BYTE;
Trigger_Lock :BOOL; //Whether the trigger lock I/O input is on or off.
Operation_Stop :BOOL; //Whether or not the marking laser is stopped with the shutter open
Laser_Control :BOOL; //Whether or not the marking laser is stopped with the shutter closed.
Date_Hold :BOOL; //Whether or not he date hold I/O input is on or off.
Internal_Lighting :BOOL; //Displays whether the internal lighting control input is on or off
Distance_Laser_Stop :BOOL; //Displays whether the distance laser stop input is on or off
Spare_Byte4_6 :BOOL;
Spare_Byte4_7 :BOOL;
Date_Attach :BOOL; //while the date hold input is ON. This bit value remains “1” for as long as the date hold input is held on.
Counter_End1 :BOOL; //Whether or not the specified counter has completed marking the final value.
Counter_End2 :BOOL; //
Counter_End3 :BOOL; //
Counter_End4 :BOOL; //
Mark_Check_2DC_Read_OK1 :BOOL; //Displays whether the marking verification function or 2D code grade assessment result is OK or not
Mark_Check_2DC_Read_NG1 :BOOL; //Displays whether the marking verification function or 2D code grade assessment result is OK or not.*
Marking_Complete_1 :BOOL; //Whether the trigger lock I/O input is on or off.
Mark_Check_2DC_Read_OK2 :BOOL; //Displays whether the marking verification function or 2D code grade assessment result is OK or not
Mark_Check_2DC_Read_NG2 :BOOL; //Displays whether the marking verification function or 2D code grade assessment result is OK or not.*
_3Axis_Tracking_OK :BOOL; //Turns on for a fixed time when using the XY tracking/Z tracking function
_3Axis_Tracking_NG :BOOL; //Turns on for a fixed time when using the XY tracking/Z tracking function
Spare_Byte6_4 :BOOL;
Spare_Byte6_5 :BOOL;
Spare_Byte6_6 :BOOL;
Spare_Byte6_7 :BOOL;
Spare_Byte7 :BYTE;
Marking_Complete_2 :BOOL; //Whether the marking has been completed or not appears.
Guide_Laser_Complete :BOOL; // Whether or not the guide laser marking has completed.
Laser_Stop_Complete :BOOL; //Whether or not the marking stop operation has been completed
Error_Clear_Complete :BOOL; //Whether or not the error clearing operation has completed.
_2DC_Read_Complete :BOOL; //Whether or not the 2D code reading operation has completed.
Window_Monitoring_Complete:BOOL; //Turns on when completing the lens inspection
Spare_Byte8_6 :BOOL;
Spare_Byte8_7 :BOOL;
Job_Edit_Complete :BOOL; //Whether or not the setting change has been completed.
Spare_Byte9_1 :BOOL;
Spare_Byte9_2 :BOOL;
Spare_Byte9_3 :BOOL;
Spare_Byte9_4 :BOOL;
Spare_Byte9_5 :BOOL;
Spare_Byte9_6 :BOOL;
Spare_Byte9_7 :BOOL;
Job_Change_Complete :BOOL; //Whether the setting no. has been changed or not appears.
Rank_Change_Complete :BOOL; //Whether the rank value has been changed or not appears.
Counter_No_Complete :BOOL; //Whether or not the counter no. has been changed.
Counter_Value_Complete :BOOL; //Whether or not the counter value has been changed.
Counter_Up_Complete :BOOL; //Whether or not the counter has been incremented.
Counter_Down_Complete :BOOL; //Whether or not the counter has been decremented.
Counter_Reset_Complete :BOOL; //Whether or not the counter has been reset.
Spare_Byte10_7 :BOOL;
System_Info_ID_Change_Complete :BOOL; //Displays the changing completion of the operation information ID by System Info ID Change Request
Spare_Byte11_1 :BOOL;
Spare_Byte11_2 :BOOL;
Spare_Byte11_3 :BOOL;
Spare_Byte11_4 :BOOL;
Spare_Byte11_5 :BOOL;
Spare_Byte11_6 :BOOL;
Spare_Byte11_7 :BOOL;
Set_String_Read_Complete :BOOL; //Whether or not the set character string has been loaded.
Marked_String_Read_Complete:BOOL; //Whether or not the marked character string has been loaded.
String_Change_Complete :BOOL; //Whether or not the character string has been set.
Spare_Byte12_3 :BOOL;
Spare_Byte12_4 :BOOL;
Spare_Byte12_5 :BOOL;
Spare_Byte12_6 :BOOL;
Spare_Byte12_7 :BOOL;
Spare_Byte13 :BYTE;
Spare_Byte14 :BYTE;
Command_Send_Complete :BOOL; //Whether the command communication has been sent.
XY_Tracking_Result_Read_Complete :BOOL; //Display the completion status of XY Tracking Result Request
Z_Tracking_Result_Read_Complete :BOOL; //Display the completion status of Z Tracking Result Request
Spare_Byte15_3 :BOOL;
Spare_Byte15_4 :BOOL;
Spare_Byte15_5 :BOOL;
Spare_Byte15_6 :BOOL;
Spare_Byte15_7 :BOOL;
Start_Marking_Request_Error:BOOL; //Whether or not there is an error with the Start Marking Request.
Guide_Laser_Request_Error :BOOL; //Whether or not there is an error with the Guide Laser Request.
Stop_Marking_Request_Error:BOOL; //Whether or not there is an error with the Stop Marking Request.
Error_Clear_Request_Error :BOOL; //Whether or not there is an error with the Error Clear Request.
_2DC_Read_Request_Error :BOOL; //Whether or not there is an error with the 2D Code Read Request.
Window_Monitoring_Request_Error :BOOL; //If a Window Monitoring Request fails in the lens inspection operation, it turns on
Spare_Byte16_6 :BOOL;
Spare_Byte16_7 :BOOL;
Job_Edit_Error :BOOL; //Whether the setting edition error status is active or not appears.
Spare_Byte17_1 :BOOL;
Spare_Byte17_2 :BOOL;
Spare_Byte17_3 :BOOL;
Spare_Byte17_4 :BOOL;
Spare_Byte17_5 :BOOL;
Spare_Byte17_6 :BOOL;
Spare_Byte17_7 :BOOL;
Job_Change_Request_Error :BOOL; //Whether or not there is an error with the Program Change Request.
Rank_Change_Request_Error :BOOL; //Whether or not there is an error with the Rank Change Request.
Counter_No_Change_Request_Error :BOOL; //Whether or not there is an error with the Counter No. Change Request.
Counter_Value_Change_Request_Error:BOOL; //Whether or not there is an error with the Counter Value Change Request.
Counter_Up_Request_Error :BOOL; //Whether or not there is an error with the Counter Up Request.
Counter_Down_Request_Error :BOOL; //Whether or not there is an error with the Counter Down Request.
Counter_Reset_Request_Error:BOOL; //Whether or not there is an error with the Counter Reset Request.
System_Info_ID_Change_Error:BOOL; //a change of the operation information ID with a System Info ID Change Request fails, it turns on
Spare_Byte19 :BYTE;
Set_String_Request_Error :BOOL; //Whether or not there is an error with the set string request.
Marked_String_Request_Error:BOOL; //Whether or not there is an error with the marked string request.
String_Change_Request_Error:BOOL; //Whether or not there is an error with the String Change Request.
Spare_Byte20_3 :BOOL;
Spare_Byte20_4 :BOOL;
Spare_Byte20_5 :BOOL;
Spare_Byte20_6 :BOOL;
Spare_Byte20_7 :BOOL;
Spare_Byte21 :BYTE;
Spare_Byte22 :BYTE;
Command_Send_Request_Error:BOOL; //Whether or not there is an error with the Command Send Request.
XY_Tracking_Result_Request_Error :BOOL; //When XY Tracking Result Request fails, it turns on
Z_Tracking_Result_Request_Error :BOOL; //When Z Tracking Result Request fails, it turns on
Spare_Byte23_3 :BOOL;
Spare_Byte23_4 :BOOL;
Spare_Byte23_5 :BOOL;
Spare_Byte23_6 :BOOL;
Spare_Byte23_7 :BOOL;
Error_Code1 :INT; //When an error occurs, corresponding error no. appears.
Error_Code2 :INT; //When more than one error occurs, second corresponding error no. appears.
Command_Send_Error :INT; //The error no. received from the command communication appears.
Spare_INT30 :INT;
Job_No :INT; //The program no. being selected appears.(0 to 1999)
Counter_No :INT; //The counter no. being selected appears.
Counter_Value :DINT; //The counter value being output appears.
Rank_Value :INT; //The rank value being selected appears.
System_Info_ID :INT;
System_Info_Value :DINT;
Marking_Check_Score_2DC_Read_Grade1 :INT; //The AIM-DPM grade appears or marking verification function score appears after 2D Code Read Request is sent.
Marking_Check_2DC_Read_Total_Count1 :INT; //The total number of marking check / 2D codes read. Resets to “0” when power is turned off.
Marking_Check_Score_2DC_Read_Grade2 :INT; //The AIM-DPM grade appears or marking verification function score appears after 2D Code Read Request is sent.
Marking_Check_2DC_Read_Total_Count2 :INT; //The total number of marking check / 2D codes read. Resets to “0” when power is turned off.
Total_Marking_Count :DINT; //The count of marking appears.
Response_Data_Size :INT; //Store the data length of "Response Data" in 16-bit binary data.
Response_Data :ARRAY [0..127]OF BYTE; //Stores the response content of the setting/marking string request and communication command transmit request. Selectable capacities are from 32, 64, 128, and 252 bytes on thePLC settings. (Default: 128 bytes.)
END_STRUCT
END_TYPE
3.3 定义激光刻印机结构体-Output
TYPE ST_Laser_Marker_Output :
STRUCT
Start_Marking :BOOL; //Starts marking.
Guide_Laser :BOOL; //Starts the guide laser marking.
Stop_Marking :BOOL; //Stops marking.
Error_Clear :BOOL; //Clears an error.If an error occurred, remove the cause of the error and then set this bit to "1" to clear the error.
_2DC_Read :BOOL; // Attempts to read a 2D code.This bit is accepted when the Ready Status bit is "1."
Window_Monitoring :BOOL;
Spare_Byte0_6 :BOOL;
Spare_Byte0_7 :BOOL;
Job_Edit_Start :BOOL; //Starts editing a program.* 1 Only the settings selected until the bit is set to "0" are changed and stored in the selected program no.
Spare_Byte1_1 :BOOL;
Spare_Byte1_2 :BOOL;
Spare_Byte1_3 :BOOL;
Spare_Byte1_4 :BOOL;
Spare_Byte1_5 :BOOL;
Spare_Byte1_6 :BOOL;
Spare_Byte1_7 :BOOL;
Job_Change :BOOL; //Changes the current program no.*
Rank_Change :BOOL; //Changes the rank value.*
Counter_No_Change :BOOL; //Changes the target counter number for counter value change, counter up, and counter down, and counter reset requests.
Counter_Value_Change :BOOL; //Changes the counter value.*
Counter_Up :BOOL; //Increases the counter value.*
Counter_Down :BOOL; //Decreases the counter value.*
Counter_Reset :BOOL; //Resets the counter.
Spare_Byte2_7 :BOOL;
System_Info_ID_Change :BOOL; //Changes the operation information ID
Spare_Byte3_1 :BOOL;
Spare_Byte3_2 :BOOL;
Spare_Byte3_3 :BOOL;
Spare_Byte3_4 :BOOL;
Spare_Byte3_5 :BOOL;
Spare_Byte3_6 :BOOL;
Spare_Byte3_7 :BOOL;
Spare_Byte4 :BYTE;
Set_String_Read :BOOL; //Loads the character string that has been set to mark.
Marked_String_Read :BOOL; //Loads the character string that has been marked.*
String_Change :BOOL; //Sets contents to be marked in the current program.
Spare_Byte5_3 :BOOL;
Spare_Byte5_4 :BOOL;
Spare_Byte5_5 :BOOL;
Spare_Byte5_6 :BOOL;
Spare_Byte5_7 :BOOL;
Spare_Byte6 :BYTE;
Command_Send :BOOL; //Starts the command communication. Store the command data in Request Data and the data length in Request Data Size.
XY_Tracking_Result :BOOL; //Loads the result of the XY tracking.
Z_Tracking_Result :BOOL; //Loads the result of the Z tracking.
Spare_Byte7_3 :BOOL;
Spare_Byte7_4 :BOOL;
Spare_Byte7_5 :BOOL;
Spare_Byte7_6 :BOOL;
Spare_Byte7_7 :BOOL;
Trigger_Lock :BOOL; //Disables the trigger input. If this bit turns to "1" while marking, the laser finishes marking the current program before the trigger input is disabled.
Operation_Stop :BOOL; //Stops the marking laser.
Laser_Stop :BOOL; //Stops the marking laser and the guide laser.
Date_Hold :BOOL; //At the time when the controller's internal clock passes 12:00 a.m.
Internal_Lighting :BOOL; //Turns on an internal lighting
Distance_Laser_Stop :BOOL; //Stops the distance laser
Spare_Byte8_6 :BOOL;
Spare_Byte8_7 :BOOL;
Spare_Byte9 :BYTE;
Spare_INT10 :INT;
Marking_Complete_Bit_Clear :BOOL; //Clears the marking complete status and the error status.
Guide_Laser_Complete_Bit_Clear:BOOL; //Clears the guide laser marking complete status and the error status.
Laser_Stop_Complete_Bit_Clear :BOOL; //Clears the marking stop complete status and the error status.
Error_Clear_Complete_Bit_Clear:BOOL; //Clears the error clearing complete status and the error status.
_2DC_Read_Complete_Bit_Clear :BOOL; //Clears the 2D Code read complete and the request error bit.
Window_Monitoring_Complete_Bit_Clear :BOOL; //Resets Window Monitoring Complete
Spare_Byte12_6 :BOOL;
Spare_Byte12_7 :BOOL;
Job_Edit_Complete_Bit_Clear:BOOL; //Clears the program edit complete status and the error status.
Spare_Byte13_1 :BOOL;
Spare_Byte13_2 :BOOL;
Spare_Byte13_3 :BOOL;
Spare_Byte13_4 :BOOL;
Spare_Byte13_5 :BOOL;
Spare_Byte13_6 :BOOL;
Spare_Byte13_7 :BOOL;
Job_Change_Complete_Bit_Clear :BOOL; //Clears the program no. change complete status and the error status.
Rank_Change_Complete_Bit_Clear :BOOL; //Clears the rank value change complete status and the error status.
Counter_No_Change_Complete_Bit_Clear :BOOL; //Clears the counter no. change complete status and the error status.
Counter_Value_Change_Complete_Bit_Clear:BOOL; //Clears the counter value change complete status and the error status.
Counter_Up_Complete_Bit_Clear :BOOL; //Clears the counter increment complete status and the error status.
Counter_Down_Complete_Bit_Clear :BOOL; //Clears the counter decrement complete status and the error status.
Counter_Reset_Complete_Bit_Clear :BOOL; //Clears the counter reset complete status and the error status.
Spare_Byte14_7 :BOOL;
System_Info_ID_Change_Complete_Clear :BOOL; //Resets System Info ID Change Complete and System Info ID Change Error
Spare_Byte15_1 :BOOL;
Spare_Byte15_2 :BOOL;
Spare_Byte15_3 :BOOL;
Spare_Byte15_4 :BOOL;
Spare_Byte15_5 :BOOL;
Spare_Byte15_6 :BOOL;
Spare_Byte15_7 :BOOL;
Setting_String_Read_Complete_Bit_Clear :BOOL; //Clears the set character string read complete status and the error status.
Marked_String_Read_Complete_Bit_Clear :BOOL; //Clears the marked character string read complete status and the error status.
String_Change_Complete_Bit_Clear :BOOL; //Clears the string change complete status and the error status.
Spare_Byte16_3 :BOOL;
Spare_Byte16_4 :BOOL;
Spare_Byte16_5 :BOOL;
Spare_Byte16_6 :BOOL;
Spare_Byte16_7 :BOOL;
Spare_Byte17 :BYTE;
Spare_Byte18 :BYTE;
Command_Send_Complete_Bit_Clear :BOOL; //Clear the command communication complete status and the request error status.
Spare_Byte19_1 :BOOL;
Spare_Byte19_2 :BOOL;
Spare_Byte19_3 :BOOL;
Spare_Byte19_4 :BOOL;
Spare_Byte19_5 :BOOL;
Spare_Byte19_6 :BOOL;
Spare_Byte19_7 :BOOL;
Request_No :DINT; //This stores the program no., block no., and counter no. to be changed.
Request_Data_Size :INT; //Stores the data size of the command communication in 16 bit binary data.
Request_Data :ARRAY [0..127]OF BYTE; //This bit stores the contents of the command communication and the character string.
END_STRUCT
END_TYPE
3.4 定义 定义激光刻印机 通讯商品全局变量

四、”FB_TYP_172_Laser_Marker_X450″通讯功能块变量声明
FUNCTION_BLOCK FB_TYP_172_Laser_Marker_X450A_V1_0_1
(*---------------------------------------------*)
(*IN variables*)
(*---------------------------------------------*)
VAR_INPUT
iIn_idxElement : INT; (* !!!UNIQUE!!! Element identification*)
ist_HWIn : ST_Laser_Marker_Input; (* Profinet-interface: Inputs *)
ib_Release_StartMarking : BOOL; (* Enable for task execution *)
END_VAR
(*---------------------------------------------*)
(*IN/OUT variables*)
(*---------------------------------------------*)
VAR_IN_OUT
stINOUT_SYS_CELL :ST_SYS_CELL;
END_VAR
(*---------------------------------------------*)
(*OUT variables*)
(*---------------------------------------------*)
VAR_OUTPUT
ost_HWOut : ST_Laser_Marker_Output; (* Profinet-interface: Outputs *)
END_VAR
VAR CONSTANT
ius_Change_Max_No : USINT :=1 ; // Entry Char Max Number
END_VAR
(*---------------------------------------------*)
(*Local variables*)
(*---------------------------------------------*)
VAR
arrStr_Entry : ARRAY [0..ius_Change_Max_No] OF STRING(80); (* Target Character String Entry *)
Dly_Ton : TON;
Execution_Timeout : TON;
Step :INT;
Start_Condition :BOOL;
Cmd_Type :BYTE; // 0 = Change Job Number ,1= Start Laser Marker
Count_Job_Change : INT;
Count_Char_Change : INT;
Count_Read_String : INT;
Count_Read_2DC : INT;
Entry_Str_Time : INT:=0 ;
index : INT;
index_Char : INT;
strTemp : T_MAXSTRING;
Data_Str : T_MAXSTRING;
Data_Barcode : T_MAXSTRING;
arrData : ARRAY [0..max_string_length]OF BYTE;
tarrStr : ARRAY [1..19] OF STRING(80); (* Target Character String Entry *)
ReadPCTime : FB_LocalSystemTime; // 读取PC系统时间
PCTime_Str : T_MAXSTRING;
tStr_Date : STRING[20];
tarrByte :ARRAY [0..MAX_STRING_LENGTH] OF BYTE;
tBytes :ARRAY [0..MAX_STRING_LENGTH] OF BYTE;
// x450 系列不支持下列功能
o2DC_Read_Grade_Status : INT;
oRead_Str_Result : ARRAY [0..ius_Change_Max_No] OF STRING(80);
oRead_Barcode_Result :STRING(80):= '';
ius_Str_Total_No : USINT :=1 ; (* Change String Number *)
END_VAR
(*---------------------------------------------*)
(*Local temp variables*)
(*---------------------------------------------*)
VAR
stTemp_CELL : ST_SYS_CELL; (* Cell structure for element*)
stTemp_ELEMENT : ST_SYS_ELEMENTS; (* Data structure of element *)
tTemp_T_Ticker :TIME;(* actual CPU-Tick *)
bVar_REQ_WP_1 : BOOL; // Load Job Number
bVar_REQ_WP : BOOL; // Laser Marker Start
wTemp_Diagnose : WORD;(*Error Messages
BIT.0 Robot: Collective Error
BIT.1 Robot: Task number invalid
BIT.2 Robot: Missing release for task start
BIT.3 Robot: Emergengy Stop from robot
BIT.4 Robot: Error - Bus State
BIT.5 Robot: Error - Program not started
BIT.6 Robot: Error - Stop by program
BIT.7 Robot: Error - Stopped by user
BIT.8 Robot: Reserve
BIT.9 Robot: Teach Mode active
BIT.10 Robot: res
BIT.11 Robot: res
BIT.12 Robot: No Connection to Robot TCP_IP-Server
BIT.13 Robot: No answer from robot for Read error
BIT.14 Robot: User Error by Robot
BIT.15 Robot: Reserve
*)
END_VAR
五、”FB_TYP_172_Laser_Marker_X450″通讯功能块程序
(*使用信息组改写字符串命令时 默认从 Request_No = 0 开始循环写入和读取*) //X450 系列无读出写入字符串功能 ,亦无读取条码功能
ReadPCTime (
sNetID:='172.22.15.10.1.1',
bEnable:= TRUE ,
dwCycle:= ,
dwOpt:= ,
tTimeout:= ,
bValid=> ,
systemTime=> ,
tzID=> );
PCTime_Str := SYSTEMTIME_TO_STRING(ReadPCTime.systemTime);
tarrByte :=MAXSTRING_TO_BYTEARR(in:=PCTime_Str );
tBytes[0]:=tarrByte[8];
tBytes[1]:=tarrByte[9];
tBytes[2]:=tarrByte[5];
tBytes[3]:=tarrByte[6];
tBytes[4]:=tarrByte[2];
tBytes[5]:=tarrByte[3];
tStr_Date:= BYTEARR_TO_MAXSTRING(in:=tBytes);
IF ius_Str_Total_No > ius_Change_Max_No THEN
RETURN;
END_IF
(* Initialisation of FB internal structures - for reducing length of expressions *)
acstartCopyData();(*============================================================================================================================*)
(* --- INIT of element feedback --------------------------------------------------- *)
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP := FALSE;
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP_1 := FALSE;
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_HP := FALSE;
stTemp_ELEMENT.stFeedBack.stSTATE.bOUT_HP := FALSE;
stTemp_ELEMENT.stFeedBack.stSTATE.bOUT_WP := FALSE;
stTemp_ELEMENT.stFeedBack.stSTATE.bTO_WP := FALSE;
// 字符串整合
tarrStr[1]:='#';//1字符#
tarrStr[2]:= stTemp_ELEMENT.arstValue[1].strName; //Pre Number = 3 Chars
tarrStr[3]:= stTemp_ELEMENT.arstValue[2].strName;//Middle Number = 3 Chars
tarrStr[4]:= stTemp_ELEMENT.arstValue[3].strName;//End Number = 3 Chars
tarrStr[5]:= stTemp_ELEMENT.arstValue[4].strName;//Index = 1Chars
tarrStr[6]:=' ';//Index 结尾= 1Chars
tarrStr[7]:=' ';//Colorcode 空字符 = 3 Chars
tarrStr[8]:='#';//1字符# 第16位
tarrStr[9]:='#';//1字符# 第17位 == 20231123 由 空格 改为 #
tarrStr[10]:= stTemp_ELEMENT.arstValue[5].strName;//DUNS Number = 9 Chars
tarrStr[11]:='#';//1字符#
tarrStr[12]:=tStr_Date;//Data of Manufacture = 6 Chars 年月日
tarrStr[13]:='*';//1字符*
tarrStr[14]:= stTemp_ELEMENT.arstValue[6].strName; //ASM - No = 3 Chars
tarrStr[15]:=' ';// 1字符空格
tarrStr[16]:= stTemp_ELEMENT.arstValue[7].strName; // Man Code = 3 Chars
tarrStr[17]:= stTemp_ELEMENT.arstValue[8].strName; // Serial Number = 16 Chars
tarrStr[18]:= stTemp_ELEMENT.arstValue[9].strName; // 解析码 N = 1 Chars
tarrStr[19]:= '*=';// 结尾固定字符 = 2 Chars
(* Request WP_1: start loadinG of Job Number *)
bVar_REQ_WP_1 := ((stTemp_CELL.stMODE.bMANUAL AND stTemp_ELEMENT.stCMD.bMAN_WP_1)
OR
((stTemp_CELL.stMODE.bINIT_RUNNING OR stTemp_CELL.stMODE.bAUTO_RUNNING) AND stTemp_ELEMENT.stCMD.bAUTO_WP_1));
(* Request WP: start Laser Marker *)
bVar_REQ_WP := ((stTemp_CELL.stMODE.bMANUAL AND stTemp_ELEMENT.stCMD.bMAN_WP)
OR
((stTemp_CELL.stMODE.bINIT_RUNNING OR stTemp_CELL.stMODE.bAUTO_RUNNING) AND stTemp_ELEMENT.stCMD.bAUTO_WP))AND NOT bVar_REQ_WP_1;
(* Reset Edit mode if user forgot it *)
IF stTemp_CELL.stMODE.bAUTO
OR stTemp_CELL.stMODE.bAUTO_RUNNING
OR stTemp_CELL.stMODE.bINITIAL
OR stTemp_CELL.stMODE.bINIT_RUNNING THEN
stTemp_ELEMENT.stCMD.bEditMode := FALSE;
END_IF;
(* ================================================================================ *)
(* --- Reset of element commands -------------------------------------------------- *)
stTemp_ELEMENT.stCMD.bMAN_HP := FALSE;
stTemp_ELEMENT.stCMD.bMAN_WP := FALSE;
stTemp_ELEMENT.stCMD.bMAN_WP_1 := FALSE;
stTemp_ELEMENT.stCMD.bAUTO_WP := FALSE;
stTemp_ELEMENT.stCMD.bAUTO_WP_1 := FALSE;
stTemp_ELEMENT.stCMD.bAUTO_HP := FALSE;
(* ================================================================================ *)
// Parameter Define
//stTemp_ELEMENT.arstValue[1].Result = 目标程序号
//stTemp_ELEMENT.arstValue[10].Result = 当前程序号
(* === Diagnostic and monitoring ================================================== *)
IF stTemp_CELL.stMODE.bQUITT_ERRORS AND wTemp_Diagnose <> 0 (*OR stTemp_ELEMENT.stCMD.bSIMULATE*) THEN
wTemp_Diagnose := 0; (* Reset Error-word *)
Step :=0;
Dly_Ton.IN := FALSE;
stTemp_ELEMENT.stFeedBack.stSTATE.bERR_HP := FALSE;
stTemp_ELEMENT.stFeedBack.stSTATE.bERR_WP := FALSE;
stTemp_ELEMENT.stFeedBack.stSTATE.bERR_WP_1 := FALSE;
END_IF
(* === Execute Function ================================================== *)
Start_Condition:=ib_Release_StartMarking AND NOT ist_HWIn.Busy AND Step =0;
Dly_Ton(IN:=Dly_Ton.IN , PT:=Dly_Ton.PT);
IF bVar_REQ_WP_1 AND Start_Condition THEN // Change Job Number
Cmd_Type :=0 ;
Step :=1;
END_IF
IF bVar_REQ_WP AND Start_Condition THEN // Start Laser Marker
Cmd_Type :=1 ;
Step :=1;
END_IF
CASE Step OF (* Step10-Step100 Change Job Number *)
1:
IF ist_HWIn.Error THEN
ost_HWOut.Error_Clear:=FALSE;
Step :=2;
ELSIF NOT ist_HWIn.Error AND ist_HWIn.Ready AND ist_HWIn.Job_Change_Ready THEN
Step :=10;
END_IF
2:
ost_HWOut.Error_Clear:=TRUE;
IF NOT ist_HWIn.Error AND ist_HWIn.Ready AND ist_HWIn.Job_Change_Ready THEN
Step :=10;
END_IF
10:
ost_HWOut.Job_Change:=FALSE;
Count_Job_Change := 0;
Count_Char_Change := 0;
Count_Read_String := 0;
Count_Read_2DC := 0;
ost_HWOut.Error_Clear:=FALSE;
IF ist_HWIn.Job_No = UINT_TO_INT( stTemp_ELEMENT.arstValue[1].Result ) AND NOT ost_HWOut.Job_Change AND Count_Read_2DC = 0 THEN
Step :=100;
ELSIF ist_HWIn.Job_No <> UINT_TO_INT( stTemp_ELEMENT.arstValue[1].Result ) AND NOT ost_HWOut.Job_Change AND Count_Read_2DC = 0 THEN
Step :=15;
END_IF
15:
Dly_Ton.IN := FALSE;
ost_HWOut.Job_Change_Complete_Bit_Clear:=TRUE;
IF NOT ist_HWIn.Job_Change_Complete AND NOT Dly_Ton.Q THEN
Step :=20;
END_IF
20:
ost_HWOut.Request_No:= UINT_TO_DINT( stTemp_ELEMENT.arstValue[1].Result ) ;
ost_HWOut.Job_Change_Complete_Bit_Clear:=FALSE;
IF ost_HWOut.Request_No = UINT_TO_DINT( stTemp_ELEMENT.arstValue[1].Result ) AND NOT ost_HWOut.Job_Change_Complete_Bit_Clear THEN
Step :=25;
END_IF
25:
Dly_Ton.PT := T#1S;
Dly_Ton.IN := TRUE;
ost_HWOut.Job_Change:=TRUE;
IF (ist_HWIn.Busy OR NOT ist_HWIn.Ready) AND NOT ist_HWIn.Job_Change_Request_Error THEN
Step :=50;
ELSIF ist_HWIn.Job_Change_Request_Error THEN
Step :=30;
ELSIF Dly_Ton.Q THEN
Step :=30;
END_IF
30:
IF ist_HWIn.Job_Change_Request_Error THEN
Step :=35;
ELSE
Step :=40;
END_IF
35:
ost_HWOut.Error_Clear:=TRUE;
IF NOT ist_HWIn.Job_Change_Request_Error THEN
Step :=40;
END_IF
40:
Dly_Ton.IN := FALSE;
ost_HWOut.Error_Clear:=FALSE;
ost_HWOut.Job_Change :=FALSE;
IF NOT Dly_Ton.Q AND NOT ost_HWOut.Error_Clear AND NOT ost_HWOut.JOb_Change THEN
Count_Job_Change :=+1;
Step :=45;
END_IF
45:
IF Count_Job_Change >=3 THEN // Change Program Number Error
wTemp_Diagnose.0 := TRUE;
Step :=999;
ELSIF Count_Job_Change < 3 THEN
Step :=15;
END_IF
50: // Reset Timer
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q THEN
Step :=55;
END_IF
55: // Wait Job Change Complete is True
Dly_Ton.PT := T#1S;
Dly_Ton.IN := TRUE;
IF ist_HWIn.Job_Change_Complete AND ist_HWIn.Job_No = UINT_TO_INT( stTemp_ELEMENT.arstValue[1].Result ) THEN //Change Program Number Successful
Step :=100;
ELSIF ist_HWIn.Job_Change_Complete AND ist_HWIn.Job_No <> UINT_TO_INT( stTemp_ELEMENT.arstValue[1].Result ) THEN
wTemp_Diagnose.1 := TRUE; // Exeture Logic Finish,But Current Job Incorrect
Step :=999;
ELSIF Dly_Ton.Q THEN // Exeture Failed, No Job Change Complete Feedback Signal
wTemp_Diagnose.2 := TRUE;
Step :=999;
END_IF
100:
Dly_Ton.IN := FALSE;
Entry_Str_Time :=0;
IF Cmd_Type = 0 THEN
Step :=101;
ELSIF Cmd_Type = 1 AND NOT Dly_Ton.Q AND Entry_Str_Time = 0 AND ib_Release_StartMarking THEN
Step :=105;
ELSIF Cmd_Type = 1 AND NOT Dly_Ton.Q AND Entry_Str_Time = 0 AND NOT ib_Release_StartMarking THEN
wTemp_Diagnose.3 := TRUE; //Laser Marking Position Check Present Failure :Cable Label 20208B10
Step :=999;
END_IF
101:
Dly_Ton.IN := FALSE;
Entry_Str_Time :=0;
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP_1 :=TRUE;
IF stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP_1 AND NOT bVar_REQ_WP_1 THEN
Step :=0;
END_IF
105:
Dly_Ton.IN := FALSE;
arrStr_Entry[0]:= '';
arrStr_Entry[1]:= '';
index_Char :=1;
IF NOT Dly_Ton.Q AND arrStr_Entry[0]='' AND arrStr_Entry[1]='' THEN
Step :=106;
END_IF
106:
FOR index_Char := 1 TO 19 DO
arrStr_Entry[0]:= Concat(arrStr_Entry[0],tarrStr[index_Char]);
END_FOR
IF arrStr_Entry[0] <> '' AND LEN(arrStr_Entry[0]) > 5 THEN
Step :=110;
END_IF
110: (* Step110-Step200 Change Character String *)
Dly_Ton.IN := FALSE;
ost_HWOut.String_Change_Complete_Bit_Clear:=TRUE;
ost_HWOut.String_Change:=FALSE;
IF NOT Dly_Ton.Q AND NOT ist_HWIn.String_Change_Complete AND NOT ost_HWOut.String_Change AND ist_HWIn.Ready THEN
Step :=115;
END_IF
115: //Entry Target String
ost_HWOut.Request_No:=Entry_Str_Time;
ost_HWOut.Request_Data_Size:= len (arrStr_Entry[Entry_Str_Time]);
arrData := MAXSTRING_TO_BYTEARR (arrStr_Entry[Entry_Str_Time]);
FOR index := 0 TO ost_HWOut.Request_Data_Size BY 1 DO ;
ost_HWOut.Request_Data[index]:=arrData[index];
END_FOR
Step :=120;
120:
Dly_Ton.IN := FALSE;
ost_HWOut.String_Change_Complete_Bit_Clear:=FALSE;
IF NOT Dly_Ton.Q AND NOT ost_HWOut.String_Change_Complete_Bit_Clear THEN
Step :=125;
END_IF
125:
Dly_Ton.PT := T#2S;
Dly_Ton.IN := TRUE;
ost_HWOut.String_Change:=TRUE;
IF (ist_HWIn.Busy OR NOT ist_HWIn.Ready) AND NOT ist_HWIn.String_Change_Request_Error THEN
ost_HWOut.String_Change:=FALSE;
Step :=150;
ELSIF ist_HWIn.String_Change_Request_Error THEN
Step :=130;
ELSIF Dly_Ton.Q THEN
Step :=135;
END_IF
130:
ost_HWOut.Error_Clear:=TRUE;
IF NOT ist_HWIn.String_Change_Request_Error THEN
Step :=135;
END_IF
135:
Dly_Ton.IN := FALSE;
ost_HWOut.Error_Clear:=FALSE;
ost_HWOut.String_Change :=FALSE;
IF NOT Dly_Ton.Q AND NOT ost_HWOut.Error_Clear AND NOT ost_HWOut.String_Change THEN
Step :=140;
END_IF
140:
Count_Char_Change :=Count_Char_Change+1;
Step :=145;
145:
IF Count_Char_Change >=3 THEN // Change String Error
wTemp_Diagnose.4 := TRUE;
Step :=999;
ELSIF Count_Char_Change < 3 THEN
Step :=110;
END_IF
150: // Reset Timer
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q THEN
Step :=155;
END_IF
155: // Wait String Change Complete is True
Dly_Ton.PT := T#3S;
Dly_Ton.IN := TRUE;
IF ist_HWIn.String_Change_Complete THEN //Change Program Number Successful
Step :=300;
ELSIF Dly_Ton.Q THEN // Exeture Failed, No String Change Complete Feedback Signal
wTemp_Diagnose.5 := TRUE;
Step :=999;
END_IF
200: // Reset Timer (* Step200-Step300 Setting_Srting_Read *)
Dly_Ton.IN := FALSE;
ost_HWOut.Set_String_Read:=FALSE;
ost_HWOut.Setting_String_Read_Complete_Bit_Clear:=TRUE;
IF NOT Dly_Ton.Q AND NOT ost_HWOut.Set_String_Read AND NOT ist_HWIn.Set_String_Read_Complete AND ist_HWIn.Ready THEN
Step :=205;
END_IF
205:
ost_HWOut.Setting_String_Read_Complete_Bit_Clear:=FALSE;
IF NOT ost_HWOut.Setting_String_Read_Complete_Bit_Clear THEN
Step :=210;
END_IF
210:
Dly_Ton.PT := T#3S;
Dly_Ton.IN := TRUE;
ost_HWOut.Request_No:=Entry_Str_Time;
ost_HWOut.Set_String_Read:=TRUE;
IF (ist_HWIn.Busy OR NOT ist_HWIn.Ready) AND NOT ist_HWIn.Set_String_Request_Error THEN
Step :=250;
ELSIF ist_HWIn.Set_String_Request_Error THEN
Step :=215;
ELSIF Dly_Ton.Q THEN
Step :=215;
END_IF
215:
IF ist_HWIn.Set_String_Request_Error THEN
Step :=225;
ELSE
Step :=220;
END_IF
220:
ost_HWOut.Error_Clear:=TRUE;
IF NOT ist_HWIn.Set_String_Request_Error THEN
Step :=225;
END_IF
225:
Dly_Ton.IN := FALSE;
ost_HWOut.Error_Clear:=FALSE;
ost_HWOut.Set_String_Read :=FALSE;
IF NOT Dly_Ton.Q AND NOT ost_HWOut.Error_Clear AND NOT ost_HWOut.Set_String_Read THEN
Count_Read_String :=+1;
Step :=230;
END_IF
230:
IF Count_Read_String >=3 THEN // Read String Error
wTemp_Diagnose.6 := TRUE;
Step :=999;
ELSIF Count_Read_String < 3 THEN
Step :=200;
END_IF
250: // Reset Timer
Dly_Ton.IN := FALSE;
Data_Str :='';
IF NOT Dly_Ton.Q AND Data_Str ='' THEN
Step :=255;
END_IF
255: // Wait String Change Complete is True
Dly_Ton.PT := T#1S;
Dly_Ton.IN := TRUE;
IF ist_HWIn.Set_String_Read_Complete THEN //String Read Successful
Step :=260;
ELSIF Dly_Ton.Q THEN // Exeture Failed, No String Read Complete Feedback Signal
wTemp_Diagnose.7 := TRUE;
Step :=999;
END_IF
260: // Data Handling
FOR index := 0 TO ist_HWIn.Response_Data_Size BY 1 DO ;
strTemp := F_ToCHR(c:=ist_HWIn.Response_Data[index] );
Data_Str :=CONCAT (Data_Str ,strTemp);
END_FOR
oRead_Str_Result[Entry_Str_Time] := Data_Str ;
Step :=270;
270: // Compared Whether Entry String and Response Data are Equal
IF oRead_Str_Result[Entry_Str_Time]= arrStr_Entry[Entry_Str_Time] THEN // Change Character String End
Step :=275;
ELSE
wTemp_Diagnose.8 := TRUE;
Step :=999;
END_IF
275:
Entry_Str_Time:=+1;
Step :=280;
280:
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q AND Entry_Str_Time>= ius_Str_Total_No THEN // Change Character String Complete And Change Successful
Step :=300;
ELSIF NOT Dly_Ton.Q AND Entry_Str_Time < ius_Str_Total_No THEN
Entry_Str_Time:=+1;
Step :=110;
END_IF
300: // Marker Start
ost_HWOut.Start_Marking:=FALSE;
ost_HWOut.Marking_Complete_Bit_Clear:=TRUE;
IF NOT ost_HWOut.Start_Marking AND NOT ist_HWIn.Marking_Complete_2 AND ist_HWIn.Ready THEN
Step :=305;
END_IF
305:
ost_HWOut.Marking_Complete_Bit_Clear:=FALSE;
IF NOT ost_HWOut.Marking_Complete_Bit_Clear THEN
Step :=310;
END_IF
310:
Dly_Ton.PT := T#1S;
Dly_Ton.IN := TRUE;
ost_HWOut.Start_Marking:=TRUE;
IF (ist_HWIn.Busy OR ist_HWIn.Marking_Busy OR NOT ist_HWIn.Ready) AND NOT ist_HWIn.Start_Marking_Request_Error THEN
Step :=320;
ELSIF Dly_Ton.Q THEN
wTemp_Diagnose.9 := TRUE; // Start Marking No Response
Step :=999;
END_IF
320: // Reset Timer
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q THEN
Step :=350;
END_IF
350: // Wait Marking_Complete_2 is True
Dly_Ton.PT := T#5S;
Dly_Ton.IN := TRUE;
IF ist_HWIn.Marking_Complete_2 THEN //String Read Successful
Step :=360;
ELSIF Dly_Ton.Q THEN // Exeture Failed, No String Read Complete Feedback Signal
wTemp_Diagnose.10 := TRUE;
Step :=999;
END_IF
360: // Reset Timer
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q AND ist_HWIn.Ready THEN
Step :=370;
END_IF
370: // Reset Timer
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP:=TRUE;
IF stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP AND NOT bVar_REQ_WP THEN
Step :=0;
END_IF
400: //Start Read 2D Bacode
ost_HWOut._2DC_Read:=FALSE;
ost_HWOut._2DC_Read_Complete_Bit_Clear:=TRUE;
IF NOT ist_HWIn._2DC_Read_Complete AND NOT ist_HWIn.Mark_Check_2DC_Read_OK1 AND NOT ist_HWIn.Mark_Check_2DC_Read_NG1 AND ist_HWIn._2DC_Read_Request_Error THEN
Step :=410;
END_IF
410:
ost_HWOut._2DC_Read_Complete_Bit_Clear:=FALSE;
IF NOT ost_HWOut._2DC_Read_Complete_Bit_Clear THEN
Step :=420;
END_IF
420:
Dly_Ton.PT := T#1S;
Dly_Ton.IN := TRUE;
ost_HWOut.Error_Clear:=FALSE;
ost_HWOut._2DC_Read:=TRUE;
IF (ist_HWIn.Busy OR ist_HWIn.Mark_Check_2DC_Read_Busy OR NOT ist_HWIn.Ready) AND NOT ist_HWIn._2DC_Read_Request_Error THEN
Step :=450;
ELSIF ist_HWIn._2DC_Read_Request_Error THEN
Step :=425;
ELSIF Dly_Ton.Q THEN
Step :=425;
END_IF
425:
IF ist_HWIn._2DC_Read_Request_Error THEN
Step :=435;
ELSE
Step :=430;
END_IF
430:
ost_HWOut.Error_Clear:=TRUE;
IF NOT ist_HWIn._2DC_Read_Request_Error THEN
Step :=435;
END_IF
435:
Dly_Ton.IN := FALSE;
ost_HWOut.Error_Clear:=FALSE;
ost_HWOut._2DC_Read :=FALSE;
IF NOT Dly_Ton.Q AND NOT ost_HWOut.Error_Clear AND NOT ost_HWOut._2DC_Read THEN
Count_Read_2DC :=+1;
Step :=440;
END_IF
440:
IF Count_Read_2DC >= 3 THEN // Read 2D Barcode Error
wTemp_Diagnose.11 := TRUE;
Step :=999;
ELSIF Count_Read_2DC < 3 THEN
Step :=360;
END_IF
450: // Reset Timer
Dly_Ton.IN := FALSE;
Data_Barcode :='';
IF NOT Dly_Ton.Q AND Data_Barcode ='' THEN
Step :=455;
END_IF
455: // Wait 2DC Read Complete Complete is True
Dly_Ton.PT := T#1S;
Dly_Ton.IN := TRUE;
IF ist_HWIn._2DC_Read_Complete THEN //String Read Successful
Step :=460;
ELSIF Dly_Ton.Q THEN // Exeture Failed, No 2DC Read Complete Feedback Signal
wTemp_Diagnose.12 := TRUE;
Step :=999;
END_IF
460:
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP_1:=TRUE;
IF stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP_1 THEN
o2DC_Read_Grade_Status :=ist_HWIn.Marking_Check_Score_2DC_Read_Grade1;
Step :=465;
END_IF
465: // Data Handling
FOR index := 0 TO ist_HWIn.Response_Data_Size BY 1 DO ;
strTemp := F_ToCHR(c:=ist_HWIn.Response_Data[index] );
Data_Barcode :=CONCAT (Data_Barcode ,strTemp);
END_FOR
oRead_Barcode_Result := Data_Barcode ;
IF NOT bVar_REQ_WP THEN
Step :=0;
END_IF
999: // Execute Error
Dly_Ton.IN := FALSE;
ost_HWOut.JOb_Change :=FALSE;
ost_HWOut.String_Change:=FALSE;
ost_HWOut.Set_String_Read:=FALSE;
ost_HWOut.Start_Marking:=FALSE;
ost_HWOut._2DC_Read :=FALSE;
ost_HWOut.Error_Clear:=FALSE;
IF NOT Dly_Ton.Q AND NOT ost_HWOut.Start_Marking THEN
Step :=0;
END_IF
END_CASE
(* States *)
stTemp_ELEMENT.stFeedBack.stSTATE.bERR := wTemp_Diagnose <>0;
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_HP := NOT stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP
AND NOT stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP_1
AND NOT stTemp_ELEMENT.stFeedBack.stSTATE.bERR;
Execution_Timeout(IN:=Step >0 , PT:=T#20S);
IF Execution_Timeout.Q THEN
wTemp_Diagnose.15 := TRUE;
END_IF
(*============================================================================================================================*)
(* ...finally write back FB internal structures *)
stTemp_ELEMENT.arstValue[10].Result := ist_HWIn.Job_No; // 当前程序号
acFinalCopyData();
六、”FB_TYP_172_Laser_Marker_X450″通讯功能块程序分析
这段代码是用于控制 Keyence MD-X 系列激光刻印机的 PLC 程序,采用结构化文本 (ST) 语言编写,实现了从作业号切换、刻印内容设置到激光刻印执行的完整自动化流程。以下是详细解析:
6.1 整体架构与核心功能
代码基于状态机设计(通过Step变量控制),主要实现四大功能模块:
系统初始化与时间同步
刻印内容组装与作业号管理
激光刻印执行流程控制
错误诊断与状态反馈
6.2 关键数据结构与变量
// 时间同步与字符串处理
ReadPCTime(sNetID:='172.22.15.10.1.1', bEnable:=TRUE);
PCTime_Str := SYSTEMTIME_TO_STRING(ReadPCTime.systemTime);
// 刻印内容组装(19个字符段拼接)
tarrStr[1]:='#';
tarrStr[2]:=stTemp_ELEMENT.arstValue[1].strName; // 前缀编号
// ... 中间段省略 ...
tarrStr[12]:=tStr_Date; // 生产日期
// ... 后续段省略 ...
tarrStr[19]:='*='; // 结尾标识
时间同步:通过ReadPCTime函数从 IP 地址172.22.15.10.1.1获取系统时间,并格式化为字符串
刻印内容组装:将多个数据源(编号、日期、序列号等)拼接成完整的刻印字符串,包含前缀、中间段、日期、后缀等 19 个部分
作业号管理:通过stTemp_ELEMENT.arstValue[1].Result设置目标作业号,通过ist_HWIn.Job_No获取当前作业号
6.3 状态机执行流程解析
状态机通过CASE Step OF实现,核心步骤包括:
作业号切换(Step1-100)
检查设备状态(ist_HWIn.Error、ist_HWIn.Ready)
发送作业号切换请求(ost_HWOut.Job_Change:=TRUE)
验证切换结果:若ist_HWIn.Job_No与目标一致则成功,否则重试(最多 3 次)
刻印字符串设置(Step105-280)
组装刻印字符串(arrStr_Entry)
分批次发送字符串数据(通过ost_HWOut.String_Change命令)
验证字符串写入结果:对比发送内容与设备响应(oRead_Str_Result vs arrStr_Entry)
激光刻印执行(Step300-370)
触发刻印命令(ost_HWOut.Start_Marking:=TRUE)
等待刻印完成信号(ist_HWIn.Marking_Complete_2)
完成后重置状态并反馈结果(stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP:=TRUE)
二维码读取(Step400-465)
触发二维码读取(ost_HWOut._2DC_Read:=TRUE)
解析读取结果(Data_Barcode)并验证质量(ist_HWIn.Marking_Check_Score_2DC_Read_Grade1)
6.4 设备交互与命令协议
代码通过ost_HWOut结构体与激光刻印机交互,关键命令包括:
Job_Change:切换作业号
String_Change:设置刻印字符串
Set_String_Read:读取设备字符串设置
Start_Marking:启动激光刻印
_2DC_Read:触发二维码读取
命令执行流程遵循 “请求 – 等待响应 – 验证结果” 模式,例如:
// 发送作业号切换请求
ost_HWOut.Request_No := UINT_TO_DINT(stTemp_ELEMENT.arstValue[1].Result);
ost_HWOut.Job_Change := TRUE;
// 等待响应并验证
IF ist_HWIn.Job_Change_Complete AND ist_HWIn.Job_No = 目标作业号 THEN
Step := 100; // 切换成功
END_IF
6.5 错误处理与诊断机制
代码实现了多层次错误处理:
重试机制:作业号切换、字符串设置等操作最多重试 3 次(Count_Job_Change、Count_Char_Change计数器)
超时检测:通过Execution_Timeout函数监控执行时间,超过 20 秒触发错误(wTemp_Diagnose.15 := TRUE)
错误码记录:wTemp_Diagnose寄存器记录 16 种错误状态(如作业号切换失败、字符串写入错误、刻印超时等)
状态反馈:通过stTemp_ELEMENT.stFeedBack.stSTATE结构体反馈当前状态(如bIN_WP表示刻印中,bERR表示错误)
6.6 优化与扩展点
代码可读性:可将重复的命令发送逻辑封装为函数(如SendCommand())
并行处理:在等待设备响应时可处理其他任务,提高效率
数据追溯:增加刻印数据日志记录,便于追溯
用户配置:添加参数化配置(如超时时间、重试次数)
安全机制:增加紧急停止输入和权限控制
6.7 总结
这段代码实现了 Keyence 激光刻印机的全自动化控制,从作业号切换、刻印内容设置到激光刻印执行形成完整闭环。通过状态机设计和多层错误处理,确保了工业环境下的稳定运行,适用于需要高精度、可追溯刻印的场景(如电子元器件、汽车零部件、医疗设备等)。
七、”FB_TYP_172_Laser_Marker_X450″通讯功能块描述
这个功能块实现了 Keyence MD-X 系列激光刻印机的完整控制流程,主要功能包括:
系统初始化与同步
从指定 IP 地址获取系统时间并格式化
初始化全局变量和状态反馈参数
刻印内容管理
组装包含多种信息(编号、日期、序列号等)的刻印字符串
支持最多 19 个字符段的灵活拼接配置
作业号与程序控制
切换刻印作业号(Job Number)
验证作业号切换结果并提供反馈
激光刻印执行
发送刻印内容到设备
触发并监控激光刻印过程
检测刻印完成状态
二维码处理(可选)
读取刻印后的二维码
验证二维码质量和内容
提供读取结果反馈
错误处理与诊断
实现命令重试机制(最多 3 次)
检测并记录 16 种不同类型的错误
提供超时保护(20 秒)
通过状态字反馈当前工作状态
7.1 改进空间分析
虽然功能块已经实现了完整的控制流程,但仍有以下几个方面可以改进:
1. 代码结构优化
模块化设计:将重复的命令发送和响应处理逻辑抽象为独立的函数或子程序,减少代码冗余
状态机重构:当前状态机步骤过多,可以按功能划分为更小的状态组或子状态机
注释增强:添加更多功能块级和关键逻辑的注释,提高代码可读性
2. 错误处理增强
错误分类细化:对不同类型的错误提供更具体的处理策略,而非统一重置
错误恢复机制:增加自动恢复功能,例如某些错误发生后尝试重新初始化设备
错误日志记录:添加错误发生时间、频率的统计功能,便于分析故障模式
3. 性能优化
延时策略优化:减少不必要的延时等待,使用事件驱动替代部分定时等待
并行处理:在等待设备响应期间执行其他非关键任务,提高整体效率
命令批处理:优化字符串发送逻辑,减少与设备的交互次数
4. 配置灵活性
参数化设计:将关键参数(如超时时间、重试次数、IP 地址)设为可配置项
配方管理:支持存储多个刻印内容配方,方便快速切换不同产品的刻印需求
5. 用户交互与监控
状态可视化:提供更丰富的状态反馈接口,便于上位机系统监控
操作日志:记录所有操作和状态变化,支持追溯和审计
远程诊断:增加远程连接和诊断功能,便于技术支持
6. 安全机制
权限控制:对关键操作(如作业号修改、刻印启动)增加权限验证
紧急停止:增强紧急停止功能,确保设备在异常情况下可快速停机
操作确认:对重要操作(如清除错误)增加确认机制,防止误操作
7. 功能扩展
多语言支持:支持不同语言的错误信息和操作提示
数据统计:增加刻印数量、成功率等统计功能
远程更新:支持通过网络更新刻印内容和程序
8. 代码健壮性
输入验证:增加对输入参数的有效性检查,防止非法数据导致异常
内存管理:优化字符串处理逻辑,避免内存溢出风险
边界条件处理:完善各种边界条件的处理(如空字符串、最大长度等)
7.2 改进示例:模块化重构
以下是一个简单的模块化重构示例,将重复的命令发送逻辑封装为通用函数:
// 原代码中的重复部分
Dly_Ton.PT := T#1S;
Dly_Ton.IN := TRUE;
ost_HWOut.Command := TRUE;
// 等待响应...
Dly_Ton.IN := FALSE;
// 重构为通用函数
FUNCTION SendCommand : BOOL
VAR_INPUT
CommandType : INT; // 命令类型
CommandData : ARRAY[0..63] OF BYTE; // 命令数据
DataSize : INT; // 数据大小
Timeout : TIME := T#1S; // 超时时间
MaxRetries : INT := 3; // 最大重试次数
END_VAR
VAR
RetryCount : INT := 0;
CommandSent : BOOL := FALSE;
Result : BOOL := FALSE;
END_VAR
// 命令发送逻辑
WHILE RetryCount < MaxRetries AND NOT Result DO
// 发送命令
ost_HWOut.CommandType := CommandType;
FOR i := 0 TO DataSize - 1 DO
ost_HWOut.CommandData[i] := CommandData[i];
END_FOR
Dly_Ton.PT := Timeout;
Dly_Ton.IN := TRUE;
CommandSent := TRUE;
// 等待响应
WHILE Dly_Ton.Q AND NOT ist_HWIn.CommandResponse DO
// 循环等待
END_WHILE;
Dly_Ton.IN := FALSE;
// 检查响应
IF ist_HWIn.CommandResponse THEN
Result := TRUE;
ELSE
RetryCount := RetryCount + 1;
// 错误处理...
END_IF;
END_WHILE;
SendCommand := Result;
END_FUNCTION
通过类似的重构,可以显著提高代码的可维护性和可扩展性,同时减少错误发生的可能性。
八、附录
8.1 ACfinalCopyData 子程序
(*============================================================================================================================*)
(* ...finally write back FB internal structures *)
F_SET_TYP_HMI_STATE_V1_0_1(stIn_CELL := stTemp_CELL, stInOut_ELEMENT := stTemp_ELEMENT);
MEMCPY(destAddr := ADR(stGV_SYS_DIAGNOSE_ELEMENTS.arwKAT_ELEMENTE[iIn_idxElement]), srcAddr :=ADR(wTemp_Diagnose), n:= SIZEOF(wTemp_Diagnose));
MEMCPY(destAddr := ADR(stGV_SYS_ELEMENTS.arstELEMENT[iIn_idxElement]), srcAddr :=ADR(stTemp_ELEMENT), n:= SIZEOF(stTemp_ELEMENT));
MEMCPY(destAddr := ADR(stINOUT_SYS_CELL), srcAddr :=ADR(stTemp_CELL), n:= SIZEOF(stTemp_CELL));
8.2 ACStartCopyData 子程序
(* Initialisation of FB internal structures - for reducing length of expressions *)
MEMCPY(destAddr := ADR(stTemp_ELEMENT), srcAddr :=ADR(stGV_SYS_ELEMENTS.arstELEMENT[iIn_idxElement]), n:= SIZEOF(stTemp_ELEMENT));
MEMCPY(destAddr := ADR(stTemp_CELL), srcAddr :=ADR(stINOUT_SYS_CELL), n:= SIZEOF(stTemp_CELL));
MEMCPY(destAddr := ADR(wTemp_Diagnose), srcAddr :=ADR(stGV_SYS_DIAGNOSE_ELEMENTS.arwKAT_ELEMENTE[iIn_idxElement]), n:= SIZEOF(wTemp_Diagnose));
stTemp_ELEMENT.stID.iNo := iIn_idxElement;
stTemp_ELEMENT.stFeedBack.iTYP :=63; (* Use defined and customized HMI-Pop-up *)
(*============================================================================================================================*)
tTemp_T_Ticker:= F_TIME_V1_0_0();














暂无评论内容