一、 设备介绍
1. Bdtronic 设备

2. 应用场景

3. 设备描述
点胶机功能
多维度点胶:具备 3D 轴,能在三维空间精准点胶,适配复杂工件点胶需求 。
物料适配广:可处理单组份与多组份材料,混合比例灵活可调,还能持续计量、混合,应对从低粘度到膏状的反应性树脂 。
智能管控:有集成配方管理器,基于 Windows 控制,方便编程、存储工艺参数,简化操作与工艺复刻 。
使用场景
电子制造:给电路板(PCB)焊点涂覆保护胶、芯片封装点胶,保障电子元件稳定。像手机、电脑等电子产品生产,在芯片粘贴、电容电阻固定环节发挥作用 。
汽车工业:汽车零部件生产里,发动机密封、车灯组装点胶,提升部件密封性、可靠性,比如车灯防水密封、发动机缸体密封 。
精密机械:小型精密机械零件,如传感器、精密阀门组装时,精准点胶确保部件契合与性能,像医疗设备里的传感器组装,保证精度和稳定性 。
二、PLC通讯接配置
1、通讯方式
1.1 采用EL6695 | EtherCAT 端子模块,通信接口

1.2 EL6695介绍
EtherCAT 桥接端子模块 EL6695 可以实现属于不同主站的 EtherCAT 端子模块网段之间的实时数据交换。还支持通过 AoE、FoE、EoE、NPI 等进行异步通信。分布式时钟可以双向同步。EL6695 和 EL6692B 不同的是,它具有灵活的 CoE 配置和一个设备仿真选项,能够大大提高数据流量。和 EL6692 一样,TwinCAT 系统管理器中有一个方便的配置接口。次侧网段(RJ45)通过外部连接供电,主侧则通过 E-bus 供电。桥接端子模块也可用于将子 PC 系统集成为 EtherCAT 从站。
1.3 EL6695 EtherCAT 桥接端子模块配置

三、设备通讯接口数据类型定义
3.1 配置全局变量

3.2 输入变量

3.3 输出变量

3.4 实例化变量与IO关量

四、通讯功能块变量声明
1、建立关联IO的结构体
1、主结构体

2、in 结构体
TYPE ST_Dispense_Input : // ARRAY [0..11] OF BYTE
STRUCT
(*============================== INPUTS ==============================================*)
(* Byte0 -Byte65 := B1000/-D Dispensing System
Byte66 -Byte111 := PPS Feeder System
*)
// Dispensing System
i_bHandshake_Dispense : BOOL; (*Handshake Active Feedback = Usually 1*)
i_bLifeBit_Dispense : BOOL; (*Signal change for communication check = 1s Pulse*)
i_bRes_by0b2 : BOOL; (*Reserve byte 0 bit 2*)
i_bRes_by0b3 : BOOL; (*Reserve byte 0 bit 3*)
i_bRes_by0b4 : BOOL; (*Reserve byte 0 bit 4*)
i_bRes_by0b5 : BOOL; (*Reserve byte 0 bit 5*)
i_bRes_by0b6 : BOOL; (*Reserve byte 0 bit 6*)
i_bRes_by0b7 : BOOL; (*Reserve byte 0 bit 7*)
i_bMode_Dispense : BYTE; (*byte1(0 = Manual,2= Process Monitoring,3=Automatic ) *)
i_bUser_Level : BYTE; (*Current logged in user level*)
i_bRecipeNo : BYTE; (*Recipe number of loaded recipe (1-255)*)
i_bReady : BOOL; (*System is ready for production*)
i_bBusy : BOOL; (*System is busy*)
i_bSystemOK : BOOL; (*1 = Dispensing system OK, 0 = Error*)
i_bRes_by4b3 : BOOL; (*Reserve byte 4 bit 3*)
i_bRes_by4b4 : BOOL; (*Reserve byte 4 bit 4*)
i_bRes_by4b5 : BOOL; (*Reserve byte 4 bit 5*)
i_bRes_by4b6 : BOOL; (*Reserve byte 4 bit 6*)
i_bRes_by4b7 : BOOL; (*Reserve byte 4 bit 7*)
i_bRequest_Pos : BYTE;(*Actual position of dispensing system (1= Blind shot position,2 = Cleaning position)*) // 胶机涂胶请求位置号
i_wTimeYear_Dispense : WORD; (*Time Stamp Year*) //当前系统时间No Use
i_bTimeMonth_Dispense : BYTE; (*Time Stamp Month*) //当前系统时间No Use
i_bTimeDay_Dispense : BYTE; (*Time Stamp Day*) //当前系统时间No Use
i_bTimeHour_Dispense : BYTE; (*Time Stamp Hour*) //当前系统时间No Use
i_bTimeMinute_Dispense : BYTE; (*Time Stamp Minute*) //当前系统时间No Use
i_bTimeSecond_Dispense : BYTE; (*Time Stamp Second*) //当前系统时间No Use
i_bTime_Reserve_Dispense: BYTE; (*Time Stamp Reserve*) //当前系统时间No Use
i_bWeigh_Started : BOOL; (*Weighing shot started*)
i_bWeigh_Completed : BOOL; (*Weighing shot successfully completed*)
i_bRes_by14b2 : BOOL; (*Reserve byte 14 bit 2*)
i_bRes_by14b3 : BOOL; (*Reserve byte 14 bit 3*)
i_bRes_by14b4 : BOOL; (*Reserve byte 14 bit 4*)
i_bRes_by14b5 : BOOL; (*Reserve byte 14 bit 5*)
i_bRes_by14b6 : BOOL; (*Reserve byte 14 bit 6*)
i_bRes_by14b7 : BOOL; (*Reserve byte 14 bit 7*)
i_bPartCode_Trsfing : BOOL; (*15-Byte telegram was transferred*) // 条码传输中
i_bPartCode_Trsf_Completed: BOOL; (*Barcode transfer completed*) // 条码传输完成
i_bRes_by15b2 : BOOL; (*Reserve byte 15 bit 2*)
i_bRes_by15b3 : BOOL; (*Reserve byte 15 bit 3*)
i_bRes_by15b4 : BOOL; (*Reserve byte 15 bit 4*)
i_bRes_by15b5 : BOOL; (*Reserve byte 15 bit 5*)
i_bRes_by15b6 : BOOL; (*Reserve byte 15 bit 6*)
i_bRes_by15b7 : BOOL; (*Reserve byte 15 bit 7*)
irWeigh_LimitMin : REAL; (*Minimum value set in HMI for weighing shot [g] = Byte 16- Byte19 *)
irWeigh_LimitMax : REAL; (*Maximum value set in HMI for weighing shot [g] = Byte 20- Byte23 *)
irWeigh_LastValue : REAL; (*Weighing value of last weighing shot [g] = Byte 24- Byte27 *)
i_wChangeTime_Year : WORD; (*Time Stamp Year*) //切换Recipe时间
i_bChangeTime_Month : BYTE; (*Time Stamp Month*) //切换Recipe时间
i_bChangeTime_Day : BYTE; (*Time Stamp Day*) //切换Recipe时间
i_bChangeTime_Hour : BYTE; (*Time Stamp Hour*) //切换Recipe时间
i_bChangeTime_Minute : BYTE; (*Time Stamp Minute*) //切换Recipe时间
i_bChangeTime_Second : BYTE; (*Time Stamp Second*) //切换Recipe时间
i_bChangeTime_Reserve : BYTE; (*Time Stamp Reserve*) //切换Recipe时间
i_bPart_Barcode :ARRAY [0..7] OF BYTE; (* Scanned part barcode in 8-Byte telegrams (max. 1024 digits) *)
i_bProcess_OK : BOOL; (*Byte44 Process OK*) // 涂胶工艺OK
i_bProcess_NOK : BOOL; (*Byte44 Process NOK*) // 涂胶工艺NOK
i_bRes_by44b2 : BOOL; (*Reserve byte 44 bit 2*)
i_bRes_by44b3 : BOOL; (*Reserve byte 44 bit 3*)
i_bRes_by44b4 : BOOL; (*Reserve byte 44 bit 4*)
i_bRes_by44b5 : BOOL; (*Reserve byte 44 bit 5*)
i_bRes_by44b6 : BOOL; (*Reserve byte 44 bit 6*)
i_bRes_by44b7 : BOOL; (*Reserve byte 44 bit 7*)
i_bProcess_Data : BYTE; (* Process data of last dispensing process
1 = Maximum dispensing pressure component A [bar]
2 = Minimum dispensing pressure component A [bar]
3 = Maximum dispensing pressure component B [bar]
4 = Minimum dispensing pressure component B [bar]
5 = Number of rotations dispensing pump component A [°]
6 = Number of rotations dispensing pump component B [°]
7 = Average speed dispensing pump component A [rpm]
8 = Average speed dispensing pump component B [rpm]
9 = Average value of mixing head temperature [°C]
*)
irProcessData_Value : REAL; (*Value for selected process data = Byte 46- Byte49 *)
irProcessData_UpperValue : REAL; (*Setting value from HMI for upper limit selected process data = Byte 50- Byte53 *)
irProcessData_LowerValue : REAL; (*Setting value from HMI for lower limit selected process data = Byte 54- Byte57 *)
irPotLife_SetValue : REAL ; (*Set value from HMI [s] = Byte 58- Byte61 *)
irPotLife_ActValue : REAL; (*Current potlife [s] = Byte 62- Byte65 *)
// Feeder System
i_bHandshake_Material : BOOL; (*Handshake Active Feedback = Usually 1*)
i_bLifeBit_Material : BOOL; (*Signal change for communication check = 1s Pulse*)
i_bRes_by66b2 : BOOL; (*Reserve byte 66 bit 2*)
i_bRes_by66b3 : BOOL; (*Reserve byte 66 bit 3*)
i_bRes_by66b4 : BOOL; (*Reserve byte 66 bit 4*)
i_bRes_by66b5 : BOOL; (*Reserve byte 66 bit 5*)
i_bRes_by66b6 : BOOL; (*Reserve byte 66 bit 6*)
i_bRes_by66b7 : BOOL; (*Reserve byte 66 bit 7*)
i_bMode_Material : BYTE; (*byte67(0 = Manual,2= Process Monitoring,3=Automatic ) *)
i_bMaterial_OK : BOOL; (*Material OK*)
i_bRes_by68b1 : BOOL; (*Reserve byte 68 bit 1*)
i_bRes_by68b2 : BOOL; (*Reserve byte 68 bit 2*)
i_bRes_by68b3 : BOOL; (*Reserve byte 68 bit 3*)
i_bRes_by68b4 : BOOL; (*Reserve byte 68 bit 4*)
i_bRes_by68b5 : BOOL; (*Reserve byte 68 bit 5*)
i_bRes_by68b6 : BOOL; (*Reserve byte 68 bit 6*)
i_bRes_by68b7 : BOOL; (*Reserve byte 68 bit 7*)
i_bCurrent_Level : BYTE; (*Current logged in user level*)
i_wTimeYear_Material : WORD; (*Time Stamp Year*) //当前系统时间No Use
i_bTimeMonth_Material : BYTE; (*Time Stamp Month*) //当前系统时间No Use
i_bTimeDay_Material : BYTE; (*Time Stamp Day*) //当前系统时间No Use
i_bTimeHour_Material : BYTE; (*Time Stamp Hour*) //当前系统时间No Use
i_bTimeMinute_Material : BYTE; (*Time Stamp Minute*) //当前系统时间No Use
i_bTimeSecond_Material : BYTE; (*Time Stamp Second*) //当前系统时间No Use
i_bTimeReserve_Material : BYTE; (*Time Stamp Reserve*) //当前系统时间No Use
i_Barcode_Selection : BYTE; (*Barcode data which is requested via handshake
1 = Component ID component A
2 = Material number component A
3 = Batch number component A
4 = Part number component A
5 = Barcode 1
6 = Barcode 2
7 = Barcode 3
8 = Barcode (1024 digits) component A
9 = Component ID component B
10 = Material number component B
11 = Batch number component B
12 = Part number component B
13 = Barcode 1
14 = Barcode 2
15 = Barcode 3
16 = Barcode (1024 digits) component B*)
i_bBarCode_Trsfing : BOOL; (*69-Byte telegram was transferred*) // 条码传输中
i_bBarCode_Trsf_Completed: BOOL;(*Transfer completed*) // 条码传输完成
i_bRes_by79b2 : BOOL; (*Reserve byte 79 bit 2*)
i_bRes_by79b3 : BOOL; (*Reserve byte 79 bit 3*)
i_bRes_by79b4 : BOOL; (*Reserve byte 79 bit 4*)
i_bRes_by79b5 : BOOL; (*Reserve byte 79 bit 5*)
i_bRes_by79b6 : BOOL; (*Reserve byte 79 bit 6*)
i_bRes_by79b7 : BOOL; (*Reserve byte 79 bit 7*)
i_bBarcode :ARRAY [0..7] OF BYTE; (* Scanned part barcode in 8-Byte telegrams (max. 1024 digits) *)
irPailA_Filllevel : REAL; (*Fill level of the pail component A [%] = Byte 88- Byte91 *)
irPailB_Filllevel : REAL; (*Fill level of the pail component B [%] = Byte 92- Byte95 *)
irPumpA_DispensePressure : REAL; (*Supply pressure of the dispensing pump component A [bar] = Byte 96- Byte99 *)
irPumpB_DispensePressure : REAL; (*Supply pressure of the dispensing pump component B [bar] = Byte 100- Byte103 *)
irPumpA_OutletPressure : REAL; (*Pressure after the pump outlet component A [bar] = Byte 104- Byte107 *)
irPumpB_OutletPressure : REAL; (*Pressure after the pump outlet component B [bar] = Byte 108- Byte111 *)
END_STRUCT
END_TYPE
3、out 结构体
TYPE ST_Dispense_Output :
STRUCT
(*============================== OUTPUTS =============================================*)
(* Byte0 -Byte7 := B1000/-D Dispensing System
Byte8 -Byte11 := PPS Feeder System
*)
// Dispensing System
q_bHandshake_Active : BOOL; (*Handshake Active = Usually 1*)
q_bLifeBit_Dispese : BOOL; (*Signal change for communication check = 1s Pulse*)
q_bRes_by0b2 : BOOL; (*Reserve byte 0 bit 2*)
q_bRes_by0b3 : BOOL; (*Reserve byte 0 bit 3*)
q_bRes_by0b4 : BOOL; (*Reserve byte 0 bit 4*)
q_bRes_by0b5 : BOOL; (*Reserve byte 0 bit 5*)
q_bRes_by0b6 : BOOL; (*Reserve byte 0 bit 6*)
q_bRes_by0b7 : BOOL; (*Reserve byte 0 bit 7*)
q_bMode_Dispense : BYTE; (*byte1(0 = Manual,2= Process Monitoring,3=Automatic ) *)
q_bRecipeNo : BYTE; (*Requested recipe number (1-255)*)
q_bStart : BOOL; (*Start of automatic process*) // 自动出胶命令
q_bFill : BOOL; (*Start of filling process*) // 自动填充胶管命令
q_bClean : BOOL; (*Start of cleaning process*) // 自动结束,停机命令 (胶机不在执行 Blindshot 功能)
q_bRes_by3b3 : BOOL; (*Reserve byte 3 bit 3*)
q_bRes_by3b4 : BOOL; (*Reserve byte 3 bit 4*)
q_bRes_by3b5 : BOOL; (*Reserve byte 3 bit 5*)
q_bRes_by3b6 : BOOL; (*Reserve byte 3 bit 6*)
q_bRes_by3b7 : BOOL; (*Reserve byte 3 bit 7*)
q_bActual_Pos : BYTE;(*Actual position of dispensing system (1= Blind shot position,2 = Cleaning position)*) // 涂胶头当前位置输出用于出胶确认
q_bPartID_Received : BOOL; (*8-Byte telegram received*) //No Use
q_bRes_by5b1 : BOOL; (*Reserve byte 5 bit 1*)
q_bRes_by5b2 : BOOL; (*Reserve byte 5 bit 2*)
q_bRes_by5b3 : BOOL; (*Reserve byte 5 bit 3*)
q_bRes_by5b4 : BOOL; (*Reserve byte 5 bit 4*)
q_bRes_by5b5 : BOOL; (*Reserve byte 5 bit 5*)
q_bRes_by5b6 : BOOL; (*Reserve byte 5 bit 6*)
q_bRes_by5b7 : BOOL; (*Reserve byte 5 bit 7*)
q_bPartID_OK : BYTE; (*1 = Part released,2 = Part not released*)
q_bProcess_Data : BYTE; (* Process data of last dispensing process
1 = Maximum dispensing pressure component A [bar]
2 = Minimum dispensing pressure component A [bar]
3 = Maximum dispensing pressure component B [bar]
4 = Minimum dispensing pressure component B [bar]
5 = Number of rotations dispensing pump component A [°]
6 = Number of rotations dispensing pump component B [°]
7 = Average speed dispensing pump component A [rpm]
8 = Average speed dispensing pump component B [rpm]
9 = Average value of mixing head temperature [°C] *)
// Feeder System
q_bMode_Material : BYTE; (*byte8(0 = Manual,2= Process Monitoring,3=Automatic ) *)
q_Barcode_Selection : BYTE; (*Barcode data which is requested via handshake
1 = Component ID component A
2 = Material number component A
3 = Batch number component A
4 = Part number component A
5 = Barcode 1
6 = Barcode 2
7 = Barcode 3
8 = Barcode (1024 digits) component A
9 = Component ID component B
10 = Material number component B
11 = Batch number component B
12 = Part number component B
13 = Barcode 1
14 = Barcode 2
15 = Barcode 3
16 = Barcode (1024 digits) component B*)
q_bBarcode_Received : BOOL; (*byte10:8-Byte telegram received*)
q_bRes_by10b1 : BOOL; (*Reserve byte 10 bit 1*)
q_bRes_by10b2 : BOOL; (*Reserve byte 10 bit 2*)
q_bRes_by10b3 : BOOL; (*Reserve byte 10 bit 3*)
q_bRes_by10b4 : BOOL; (*Reserve byte 10 bit 4*)
q_bRes_by10b5 : BOOL; (*Reserve byte 10 bit 5*)
q_bRes_by10b6 : BOOL; (*Reserve byte 10 bit 6*)
q_bRes_by10b7 : BOOL; (*Reserve byte 10 bit 7*)
q_bLifeBit_Material : BOOL; (*byte11:Signal change for communication check= 1s Pulse*)
q_bRes_by11b1 : BOOL; (*Reserve byte 11 bit 1*)
q_bRes_by11b2 : BOOL; (*Reserve byte 11 bit 2*)
q_bRes_by11b3 : BOOL; (*Reserve byte 11 bit 3*)
q_bRes_by11b4 : BOOL; (*Reserve byte 11 bit 4*)
q_bRes_by11b5 : BOOL; (*Reserve byte 11 bit 5*)
q_bRes_by11b6 : BOOL; (*Reserve byte 11 bit 6*)
q_bRes_by11b7 : BOOL; (*Reserve byte 11 bit 7*)
END_STRUCT
END_TYPE
2. 通讯功能块变量声明
FUNCTION_BLOCK FB_TYP_180_Bdtronic_Dispense_V1_0_1
(*---------------------------------------------*)
(*IN variables*)
(*---------------------------------------------*)
VAR_INPUT
iIn_idxElement : INT; (* !!!UNIQUE!!! Element identification*)
ist_HWIn : ARRAY [0..111] OF BYTE; (* EtherCAT-interface: Inputs *)
ib_Release_StartTask : BOOL:=0; (* Enable for task execution *)
ib_AxisAtStandbyPos : BOOL:=0; (* Enable for Clean OR Fill execution *)
ib_MutingAutoPurge : BOOL:=0; (* 屏蔽自动排胶 *) // 其他功能执行应该小于1M
ir_AutoPurge_Timer : REAL:=10.0; (*自动排胶时间设置 *)
ir_Weight_Timer : REAL:=10.0; (*称重涂胶时间设置 *)
ibActiveMcode : BOOL:=0; (*插补轴Ack Cmd *)
iuiActiveMcode : USINT:=0 ; (*插补轴命令M代码 *)
iuiActiveHcode : INT:=0 ; (*插补轴命令H代码 *)
ib_ByPass : BOOL:=0; (* 胶机屏蔽 *)
END_VAR
(*---------------------------------------------*)
(*IN/OUT variables*)
(*---------------------------------------------*)
VAR_IN_OUT
stINOUT_SYS_CELL :ST_SYS_CELL;
END_VAR
(*---------------------------------------------*)
(*OUT variables*)
(*---------------------------------------------*)
VAR_OUTPUT
ost_HWOut : ARRAY [0..11] OF BYTE; (* EtherCAT-interface: Outputs *)
ob_Ready : BOOL; // System is ready for production
ob_SystemOK : BOOL; // Dispensing system OKFALSE
ob_Busy : BOOL; // System is busy
ob_HandshakeMcode : BOOL; // 胶机交互插补轴
oPurge_End : BOOL; //完成自动排胶
orDispenseTimer : REAL; //涂胶时间
oLast_DispensingDatas : ARRAY [1..8] OF REAL;
END_VAR
(*---------------------------------------------*)
(*Local variables*)
(*---------------------------------------------*)
VAR
st_BdtronicIF :ST_Dispense; (* Bdtronic Dispense Interface I/0 *)
Dly_Ton : TON;
Heartbeat_Timeout : TON;
ForceCloseBD : TON; // 强制关闭胶机1s命令
StartDispense_Rtrig : R_TRIG;
AutoStartDispense_Rtrig : R_TRIG; // 自动排胶
Fill_Rtrig : R_TRIG; //填充新胶头
Clean_Rtrig : R_TRIG; //排空胶头 = 停止生产
tRtrig1 : R_TRIG;
tRtrig2 : R_TRIG;
tRtrig3 : R_TRIG;
tDelay : TON;
tWeight_Timer : TON;
Step :INT;
Start_Condition :BOOL;
Cmd_Type :USINT:=0; //1=Start Dispense,2=Fill,3=Clean,4= Auto Dispense
Count :USINT:=0; //Recipe Switch Count
tAutoDispense :BOOL; // 自动涂胶
tWeightDispense :BOOL; // 称重涂胶
tAutoPurge :BOOL; // 启动涂胶(自动排胶)
tWeigh1 : ARRAY [1..4] OF BYTE;
tWeigh2 : ARRAY [1..4] OF BYTE;
tWeigh3 : ARRAY [1..4] OF BYTE;
tProcess1 : ARRAY [1..4] OF BYTE;
tProcess2 : ARRAY [1..4] OF BYTE;
tProcess3 : ARRAY [1..4] OF BYTE;
tPotLife_Set : ARRAY [1..4] OF BYTE;
tPotLife_Current : ARRAY [1..4] OF BYTE;
tPailA_Level : ARRAY [1..4] OF BYTE;
tPailB_Level : ARRAY [1..4] OF BYTE;
tPumpA_Pressure : ARRAY [1..4] OF BYTE;
tPumpB_Pressure : ARRAY [1..4] OF BYTE;
tPumpAOutlet_Pressure : ARRAY [1..4] OF BYTE;
tPumpBOutlet_Pressure : ARRAY [1..4] OF BYTE;
DispenseTon : TON;
tDispenseTime : TIME:=T#12.0S;
Step_Data :INT;
IndexDatas :INT;
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_HP :BOOL; // Start Clean (胶机不在执行盲打)
bVar_REQ_WP_1 : BOOL; // Start Fill
bVar_REQ_WP : BOOL; // start Dispense
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
五、通讯功能块程序
st_BdtronicIF.Out.q_bHandshake_Active := stTemp_CELL.stINPUT.stFeedBack.bDOORS_CLOSED;
st_BdtronicIF.Out.q_bLifeBit_Dispese := bGV_Pulse_1Hz;
st_BdtronicIF.Out.q_bLifeBit_Material := bGV_Pulse_1Hz;
acstartCopyData();(*============================================================================================================================*)
ac_Mapping_Input();
(* --- 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;
(* Status *)
ob_Ready :=st_BdtronicIF.In.i_bReady;
ob_SystemOK :=st_BdtronicIF.In.i_bSystemOK;
ob_Busy :=st_BdtronicIF.In.i_bBusy ;
stTemp_ELEMENT.arstValue[10].rNominal := BYTE_TO_REAL(st_BdtronicIF.In.i_bRecipeNo);
(* Request HP: Start of cleaning process *) // 结束任务,胶泵停止,自动触发时三轴必须待机位
bVar_REQ_HP := (stTemp_CELL.stMODE.bMANUAL AND stTemp_ELEMENT.stCMD.bMAN_HP )
OR
((stTemp_CELL.stMODE.bINIT_RUNNING OR stTemp_CELL.stMODE.bAUTO_RUNNING) AND stTemp_ELEMENT.stCMD.bAUTO_HP);
(* Request WP_1: Start of filling process *) // 更换新胶管后 填充空胶管 自动触发时三轴必须待机位
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 of automatic Process *) // 开启涂胶命令
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;
(* ================================================================================ *)
(* === 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;
tAutoPurge :=FALSE;
tWeightDispense :=FALSE;
st_BdtronicIF.Out.q_bFill := FALSE;
st_BdtronicIF.Out.q_bClean := FALSE;
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:= NOT st_BdtronicIF.In.i_bBusy AND st_BdtronicIF.In.i_bSystemOK AND wTemp_Diagnose =0 AND Step =0;
Dly_Ton(IN:=Dly_Ton.IN , PT:=Dly_Ton.PT);
StartDispense_Rtrig (CLK:=bVar_REQ_WP); // Start Dispense
Fill_Rtrig (CLK:=bVar_REQ_WP_1); // Fill
Clean_Rtrig (CLK:=bVar_REQ_HP); // Clean
IF StartDispense_Rtrig.Q AND Start_Condition AND st_BdtronicIF.In.i_bReady THEN
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP:=FALSE ;
Cmd_Type := 1;
Step :=10;
ELSIF Fill_Rtrig.Q AND NOT st_BdtronicIF.In.i_bReady THEN
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP_1:=FALSE ;
Cmd_Type := 2;
Step :=10;
ELSIF Clean_Rtrig.Q THEN
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_HP:=FALSE ;
Cmd_Type := 3;
Step :=10;
ELSIF st_BdtronicIF.In.irPotLife_SetValue - st_BdtronicIF.In.irPotLife_ActValue >= st_BdtronicIF.In.irPotLife_SetValue - 60 AND st_BdtronicIF.In.irPotLife_SetValue > 0 AND Step =0
AND st_BdtronicIF.In.i_bReady AND NOT st_BdtronicIF.In.i_bBusy AND ib_AxisAtStandbyPos AND NOT ib_MutingAutoPurge THEN
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP:=FALSE ;
Cmd_Type := 4;
Step :=10;
END_IF
IF StartDispense_Rtrig.Q AND ( NOT Start_Condition OR NOT st_BdtronicIF.In.i_bReady ) THEN
wTemp_Diagnose.14 := TRUE;
Step :=0;
END_IF
CASE Step OF
10: // Reset Command
Dly_Ton.IN := FALSE;
st_BdtronicIF.Out.q_bFill := FALSE;
st_BdtronicIF.Out.q_bClean := FALSE;
st_BdtronicIF.Out.q_bActual_Pos :=0;
Count := 0;
tAutoPurge:=FALSE;
oPurge_End:=FALSE;
IF NOT Dly_Ton.Q AND NOT st_BdtronicIF.Out.q_bStart AND NOT st_BdtronicIF.Out.q_bClean AND Count = 0 AND NOT st_BdtronicIF.Out.q_bFill THEN
Step :=15;
END_IF
15:// Check Mode
IF st_BdtronicIF.In.i_bMode_Dispense = 3 AND st_BdtronicIF.In.i_bMode_Material = 3 THEN
Step :=30;
ELSE
Step :=20;
END_IF
20:
Dly_Ton.PT := T#5S;
Dly_Ton.IN := TRUE;
st_BdtronicIF.Out.q_bMode_Dispense := 3;
st_BdtronicIF.Out.q_bMode_Material := 3;
IF st_BdtronicIF.In.i_bMode_Dispense = 3 AND st_BdtronicIF.In.i_bMode_Material = 3 THEN
Step :=30;
ELSIF Dly_Ton.Q THEN
wTemp_Diagnose.0 := TRUE; // Switch Auto Mode Failure
Step :=999;
END_IF
30:// Auto Mode,Check Recipe Number
IF st_BdtronicIF.In.i_bRecipeNo = REAL_TO_BYTE (stTemp_ELEMENT.arstValue[1].rNominal) THEN
Step :=100;
ELSE
Step :=35;
END_IF
35:// Reset Timer
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q THEN
Step :=40;
END_IF
40:// Switch Recipe No
Dly_Ton.PT := T#5S;
Dly_Ton.IN := TRUE;
st_BdtronicIF.Out.q_bRecipeNo := REAL_TO_BYTE (stTemp_ELEMENT.arstValue[1].rNominal);
IF st_BdtronicIF.In.i_bRecipeNo = REAL_TO_BYTE (stTemp_ELEMENT.arstValue[1].rNominal) THEN
Step :=100;
ELSIF Dly_Ton.Q AND Count >= 3 THEN
wTemp_Diagnose.1 := TRUE; // Switch Recipe Number Failure
Step :=999;
ELSIF Dly_Ton.Q AND Count < 3 THEN
Step :=45;
END_IF
45:// Reset Timer
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q THEN
Count := Count + 1;
Step :=50;
END_IF
50:// Switch Mode To Manual
Dly_Ton.PT := T#5S;
Dly_Ton.IN := TRUE;
st_BdtronicIF.Out.q_bMode_Dispense := 0; // 只切 点胶头模式即可
IF st_BdtronicIF.In.i_bMode_Dispense = 0 THEN
Step :=60;
ELSIF Dly_Ton.Q AND st_BdtronicIF.In.i_bMode_Dispense <> 0 THEN
wTemp_Diagnose.2 := TRUE; // Switch Manual Mode Failure
Step :=999;
END_IF
60:// Reset Timer
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q THEN
Step :=20;
END_IF
100:// Select Command
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q AND Cmd_Type = 1 THEN // 正常涂胶
Step :=150;
ELSIF NOT Dly_Ton.Q AND Cmd_Type = 2 THEN
Step :=200;
ELSIF NOT Dly_Ton.Q AND Cmd_Type = 3 THEN
Step :=300;
ELSIF NOT Dly_Ton.Q AND Cmd_Type = 4 THEN
Step :=110;
END_IF
110:// 启动排胶
Dly_Ton.PT := REAL_TO_TIME(ir_AutoPurge_Timer * 1000.0);
Dly_Ton.IN := TRUE;
tAutoPurge:= TRUE;
IF st_BdtronicIF.In.i_bBusy THEN
oPurge_End:=TRUE;
END_IF
IF Dly_Ton.Q AND st_BdtronicIF.In.i_bBusy THEN
Step :=120;
ELSIF NOT ib_AxisAtStandbyPos THEN
Step :=120;
END_IF
120:// End
Dly_Ton.IN := FALSE;
tAutoPurge:=FALSE;
oPurge_End:=TRUE;
IF NOT Dly_Ton.Q AND NOT tAutoPurge THEN
Step :=0;
END_IF
150:// Entry Target Program
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q AND bVar_REQ_WP AND st_BdtronicIF.In.i_bReady THEN
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP:=bVar_REQ_WP AND st_BdtronicIF.Out.q_bStart ;
ELSIF NOT Dly_Ton.Q AND NOT bVar_REQ_WP THEN
Cmd_Type := 0;
Step :=0;
END_IF
200: // 检测 Fill 条件
Dly_Ton.PT := T#2S;
Dly_Ton.IN := TRUE;
st_BdtronicIF.Out.q_bFill := FALSE;
st_BdtronicIF.Out.q_bClean := FALSE;
IF NOT Dly_Ton.Q AND NOT st_BdtronicIF.In.i_bBusy AND st_BdtronicIF.In.i_bMode_Dispense = 3 AND st_BdtronicIF.In.i_bMode_Material = 3 THEN
Step :=205;
ELSIF Dly_Ton.Q THEN
wTemp_Diagnose.3 := TRUE; // Execute Fill Insufficient Condition
Step :=999;
END_IF
205:// Check Current Pos
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q AND ib_AxisAtStandbyPos THEN
Step :=210;
END_IF
210:// Check Current Pos
Dly_Ton.PT := T#2S;
Dly_Ton.IN := TRUE;
st_BdtronicIF.Out.q_bFill := TRUE;
IF NOT Dly_Ton.Q AND st_BdtronicIF.In.i_bRequest_Pos = 1 THEN
Step :=215;
ELSIF Dly_Ton.Q THEN
wTemp_Diagnose.4 := TRUE; // Trigger Fill No Responder
Step :=999;
END_IF
215:// Reset Timer
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q THEN
Step :=220;
END_IF
220:// Wait Fill Busy
Dly_Ton.PT := T#2S;
Dly_Ton.IN := TRUE;
st_BdtronicIF.Out.q_bActual_Pos :=1;
IF NOT Dly_Ton.Q AND st_BdtronicIF.In.i_bBusy THEN
Step :=225;
ELSIF Dly_Ton.Q THEN
wTemp_Diagnose.5 := TRUE; // Trigger Fill No Responder
Step :=999;
END_IF
225:// Reset Timer
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q THEN
Step :=230;
END_IF
230:// Wait Fill End
Dly_Ton.PT := T#100S;
Dly_Ton.IN := TRUE;
IF NOT Dly_Ton.Q AND NOT st_BdtronicIF.In.i_bBusy AND st_BdtronicIF.In.i_bReady THEN
Step :=235;
ELSIF Dly_Ton.Q THEN
wTemp_Diagnose.6 := TRUE; // Exeture Fill TimeOut
Step :=999;
END_IF
235:// Reset Timer
Dly_Ton.IN := FALSE;
st_BdtronicIF.Out.q_bFill := FALSE;
st_BdtronicIF.Out.q_bActual_Pos :=0;
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP_1:=TRUE ;
IF NOT Dly_Ton.Q AND stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP_1 AND NOT bVar_REQ_WP_1 THEN
Step :=0;
END_IF
300: // 检测 Clean 条件
Dly_Ton.PT := T#2S;
Dly_Ton.IN := TRUE;
st_BdtronicIF.Out.q_bFill := FALSE;
st_BdtronicIF.Out.q_bClean := FALSE;
IF NOT Dly_Ton.Q AND NOT st_BdtronicIF.In.i_bBusy AND st_BdtronicIF.In.i_bMode_Dispense = 3 AND st_BdtronicIF.In.i_bMode_Material = 3 THEN
Step :=305;
ELSIF Dly_Ton.Q THEN
wTemp_Diagnose.7 := TRUE; // Execute Clean Insufficient Condition
Step :=999;
END_IF
305:// Check Current Pos
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q AND ib_AxisAtStandbyPos THEN
Step :=310;
END_IF
310:// Check Current Pos
Dly_Ton.PT := T#2S;
Dly_Ton.IN := TRUE;
st_BdtronicIF.Out.q_bClean := TRUE;
IF NOT Dly_Ton.Q AND st_BdtronicIF.In.i_bRequest_Pos = 2 THEN
Step :=315;
ELSIF Dly_Ton.Q THEN
wTemp_Diagnose.8 := TRUE; // Trigger Clean No Responder
Step :=999;
END_IF
315:// Reset Timer
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q THEN
Step :=320;
END_IF
320:// Wait Clean Busy
Dly_Ton.PT := T#2S;
Dly_Ton.IN := TRUE;
st_BdtronicIF.Out.q_bActual_Pos :=2;
IF NOT Dly_Ton.Q AND st_BdtronicIF.In.i_bBusy THEN
Step :=325;
ELSIF Dly_Ton.Q THEN
wTemp_Diagnose.9 := TRUE; // Trigger Clean No Responder
Step :=999;
END_IF
325:// Reset Timer
Dly_Ton.IN := FALSE;
IF NOT Dly_Ton.Q THEN
Step :=330;
END_IF
330:// Wait Clean End
Dly_Ton.PT := T#3S;
Dly_Ton.IN := TRUE;
IF NOT Dly_Ton.Q AND NOT st_BdtronicIF.In.i_bBusy AND NOT st_BdtronicIF.In.i_bReady THEN
Step :=335;
ELSIF Dly_Ton.Q THEN
wTemp_Diagnose.10 := TRUE; // Exeture Clean TimeOut
Step :=999;
END_IF
335:// Reset Timer
Dly_Ton.IN := FALSE;
st_BdtronicIF.Out.q_bClean := FALSE;
st_BdtronicIF.Out.q_bActual_Pos :=0;
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_HP:=TRUE ;
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP_1:=FALSE ;
IF NOT Dly_Ton.Q AND stTemp_ELEMENT.stFeedBack.stSTATE.bIN_HP AND NOT bVar_REQ_HP THEN
Step :=0;
END_IF
999:
Dly_Ton.IN := FALSE;
st_BdtronicIF.Out.q_bFill := FALSE;
st_BdtronicIF.Out.q_bClean := FALSE;
tAutoPurge:=FALSE;
oPurge_End:=FALSE;
IF NOT Dly_Ton.Q AND NOT st_BdtronicIF.Out.q_bStart AND NOT st_BdtronicIF.Out.q_bClean THEN
Step :=0;
END_IF
END_CASE
//出胶
st_BdtronicIF.Out.q_bStart:=((Step = 150 AND bVar_REQ_WP) OR tAutoPurge OR (tAutoDispense AND NOT GVL_Interpolation_Axis.Input[1].4) OR tWeightDispense ) AND ib_Release_StartTask ;
IF NOT ib_Release_StartTask OR DispenseTon.Q THEN
tAutoPurge :=FALSE;
tAutoDispense :=FALSE;
tWeightDispense:=FALSE;
END_IF
IF st_BdtronicIF.In.i_bMode_Dispense = 3 AND NOT st_BdtronicIF.In.i_bBusy AND NOT st_BdtronicIF.In.i_bReady AND Step =0 THEN
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP_1:=FALSE ;
END_IF
ForceCloseBD(IN:=iuiActiveHcode = -10 , PT:=T#1S);
// Handshake Interpolate Axis
IF iuiActiveMcode =12 AND st_BdtronicIF.In.i_bReady THEN
tWeightDispense:=FALSE;
oPurge_End:=FALSE;
tAutoDispense :=TRUE;
ELSIF iuiActiveMcode =13 OR iuiActiveHcode =10 THEN
tAutoDispense :=FALSE;
ELSIF iuiActiveHcode = -10 AND st_BdtronicIF.In.i_bBusy AND tAutoDispense AND NOT ForceCloseBD.Q THEN // 处理胶机未能正常关闭的可能
tAutoDispense :=FALSE;
END_IF
tRtrig1 (CLK:=tAutoDispense AND st_BdtronicIF.In.i_bBusy );
tRtrig2 (CLK:=tWeight_Timer.Q);
tDelay (IN:= (ob_HandshakeMcode AND NOT ibActiveMcode) , PT:=T#100MS);
tWeight_Timer(IN:=tWeightDispense, PT:= REAL_TO_TIME(ir_Weight_Timer * 1000.0) ); // 默认首件完成时间
IF iuiActiveMcode =11 THEN
tWeightDispense:=TRUE;
ELSE
tWeightDispense:=FALSE;
END_IF
IF iuiActiveMcode =11 AND tRtrig2.Q THEN //称重涂胶完成
tAutoDispense :=FALSE;
tAutoPurge :=FALSE;
ob_HandshakeMcode:=TRUE;
END_IF
IF tRtrig1.Q THEN
ob_HandshakeMcode:=TRUE; // 涂胶轨迹出胶交互
ELSIF tDelay.Q THEN
ob_HandshakeMcode := FALSE ;
END_IF
(* States *)
stTemp_ELEMENT.stFeedBack.stSTATE.bERR := wTemp_Diagnose <>0;
// Alarm Bits
IF NOT ib_ByPass THEN
wTemp_Diagnose.11 := NOT st_BdtronicIF.In.i_bSystemOK ;
wTemp_Diagnose.12 := NOT st_BdtronicIF.In.i_bMaterial_OK AND st_BdtronicIF.In.i_bMode_Material = 3;
wTemp_Diagnose.13 := BYTE_TO_USINT ( st_BdtronicIF.In.i_bMode_Dispense) = 19; // Estop
Heartbeat_Timeout(IN:=st_BdtronicIF.Out.q_bHandshake_Active AND (NOT st_BdtronicIF.In.i_bLifeBit_Dispense OR NOT st_BdtronicIF.In.i_bLifeBit_Material)AND NOT stTemp_CELL.stMODE.bQUITT_ERRORS , PT:=T#5S);
IF Heartbeat_Timeout.Q THEN
wTemp_Diagnose.15 := TRUE; // Commumication Failure
END_IF
END_IF
(*============================================================================================================================*)
(* ...finally write back FB internal structures *)
ac_Mapping_Output();
acFinalCopyData();
IF DispenseTon.IN THEN
tDispenseTime := DispenseTon.ET;
END_IF
orDispenseTimer:=TIME_TO_REAL(tDispenseTime) /1000.0;
DispenseTon(IN:=tAutoDispense , PT:=T#2M , Q=> , ET=> );
(*
//抓取涂胶数据
tRtrig3(CLK:=NOT tAutoDispense);
IF tRtrig3.Q THEN
IndexDatas:=1;
WHILE IndexDatas <= 8 DO
st_BdtronicIF.Out.q_bProcess_Data := INT_TO_BYTE (IndexDatas);
IF st_BdtronicIF.In.i_bProcess_Data = IndexDatas THEN
oLast_DispensingDatas[Index] := st_BdtronicIF.In.irProcessData_Value;
IndexDatas:=+1;
END_IF
END_WHILE
END_IF
*)
tRtrig3(CLK:=NOT tAutoDispense);
IF tRtrig3.Q THEN
IndexDatas:=1;
Step_Data :=10;
END_IF
CASE Step_Data OF
10:
st_BdtronicIF.Out.q_bProcess_Data := INT_TO_BYTE (IndexDatas);
IF st_BdtronicIF.In.i_bProcess_Data = IndexDatas THEN
IF INT_TO_BYTE (IndexDatas) = 5 OR INT_TO_BYTE (IndexDatas) = 6 THEN
oLast_DispensingDatas[IndexDatas]:= st_BdtronicIF.In.irProcessData_Value /60.0;
ELSE
oLast_DispensingDatas[IndexDatas]:= st_BdtronicIF.In.irProcessData_Value ;
END_IF
Step_Data:=15;
END_IF
15:
IndexDatas:=IndexDatas + 1;
Step_Data:=20;
20:
IF IndexDatas > 8 THEN
Step_Data:=0;
ELSE
Step_Data:=10;
END_IF
END_CASE
六、通讯功能块程序分析
6.1、整体功能定位
这段代码是 PLC(可编程逻辑控制器)程序,用于控制 BDtronic 点胶机的自动化流程,核心实现:
点胶任务调度(正常点胶、填充、清洗等)
设备状态监控(就绪、繁忙、故障诊断)
模式切换(手动 / 自动、配方切换)
通信与交互(和轴系统、上位机的握手信号)
6.2、核心流程与关键逻辑
1. 信号初始化与映射
st_BdtronicIF.Out.q_bHandshake_Active := stTemp_CELL.stINPUT.stFeedBack.bDOORS_CLOSED;
st_BdtronicIF.Out.q_bLifeBit_Dispese := bGV_Pulse_1Hz;
st_BdtronicIF.Out.q_bLifeBit_Material := bGV_Pulse_1Hz;
acstartCopyData();(*============================================================================================================================*)
ac_Mapping_Input();
功能:初始化设备交互信号(如门关闭握手、心跳信号),并通过 ac_Mapping_Input() 映射外部输入到内部变量,确保程序能读取传感器、按钮等信号。
关键细节:bGV_Pulse_1Hz 是 1Hz 脉冲,用于模拟 “设备存活” 心跳,告诉系统 “点胶机还在正常运行”。
2. 状态与命令重置
(* --- INIT of element feedback --------------------------------------------------- *)
stTemp_ELEMENT.stFeedBack.stSTATE.bIN_WP := FALSE;
(* ... 其他状态重置 ... *)
(* --- Reset of element commands -------------------------------------------------- *)
stTemp_ELEMENT.stCMD.bMAN_HP := FALSE;
(* ... 其他命令重置 ... *)
功能:每次循环 / 任务前,清空上一轮的状态标记和指令,避免残留信号干扰新任务,保证逻辑纯净。
3. 任务触发条件(核心调度逻辑)
(* Request HP: Start of cleaning process *) // 清洗流程触发
bVar_REQ_HP := (stTemp_CELL.stMODE.bMANUAL AND stTemp_ELEMENT.stCMD.bMAN_HP )
OR
((stTemp_CELL.stMODE.bINIT_RUNNING OR stTemp_CELL.stMODE.bAUTO_RUNNING) AND stTemp_ELEMENT.stCMD.bAUTO_HP);
(* Request WP_1: Start of filling process *) // 填充流程触发
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 of automatic Process *) // 正常点胶流程触发
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;
功能:根据设备当前模式(手动 / 自动 / 初始化),判断是否触发 清洗(HP)、填充(WP_1)、正常点胶(WP) 任务。
逻辑拆解:
手动模式下,操作员按对应按钮(bMAN_HP/bMAN_WP 等)触发;
自动 / 初始化模式下,程序自动触发(bAUTO_HP/bAUTO_WP 等);
bVar_REQ_WP 加了 NOT bVar_REQ_WP_1,确保 “正常点胶” 和 “填充” 不会同时执行。
4. 模式安全逻辑(防止误操作)
(* 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;
功能:自动运行时,强制关闭 “编辑模式”,避免操作员误改参数导致设备异常,保障自动化流程安全。
5. 故障诊断与复位
IF stTemp_CELL.stMODE.bQUITT_ERRORS AND wTemp_Diagnose <> 0 (*OR stTemp_ELEMENT.stCMD.bSIMULATE*) THEN
wTemp_Diagnose := 0; (* Reset Error-word *)
Step :=0;
tAutoPurge :=FALSE;
tWeightDispense :=FALSE;
st_BdtronicIF.Out.q_bFill := FALSE;
st_BdtronicIF.Out.q_bClean := FALSE;
Dly_Ton.IN := FALSE;
stTemp_ELEMENT.stFeedBack.stSTATE.bERR_HP := FALSE;
(* ... 其他故障复位 ... *)
END_IF
功能:当操作员触发 “故障复位(bQUITT_ERRORS)” 时,清空故障码、重置任务步骤、关闭正在执行的动作(填充 / 清洗等),让设备回到初始状态,方便重启流程。
6. 任务执行(CASE 状态机核心)
CASE Step OF
10: // Reset Command
Dly_Ton.IN := FALSE;
(* ... 清空输出信号、计数器 ... *)
IF NOT Dly_Ton.Q AND NOT st_BdtronicIF.Out.q_bStart AND NOT st_BdtronicIF.Out.q_bClean AND Count = 0 AND NOT st_BdtronicIF.Out.q_bFill THEN
Step :=15;
END_IF
15:// Check Mode
IF st_BdtronicIF.In.i_bMode_Dispense = 3 AND st_BdtronicIF.In.i_bMode_Material = 3 THEN
Step :=30;
ELSE
Step :=20;
END_IF
(* ... 其他步骤 ... *)
999:
Dly_Ton.IN := FALSE;
(* ... 清空输出、复位状态 ... *)
IF NOT Dly_Ton.Q AND NOT st_BdtronicIF.Out.q_bStart AND NOT st_BdtronicIF.Out.q_bClean THEN
Step :=0;
END_IF
END_CASE
功能:用 CASE Step OF 实现 状态机,把复杂任务拆成 Step=10(命令重置)、Step=15(模式检查)等小阶段,逐步执行点胶、填充、清洗流程。
关键设计:每个 Step 完成后,通过条件判断进入下一阶段;遇到故障直接跳转到 Step=999 复位,逻辑清晰且易维护。
7. 出胶控制与交互
st_BdtronicIF.Out.q_bStart:=((Step = 150 AND bVar_REQ_WP) OR tAutoPurge OR (tAutoDispense AND NOT GVL_Interpolation_Axis.Input[1].4) OR tWeightDispense ) AND ib_Release_StartTask ;
IF NOT ib_Release_StartTask OR DispenseTon.Q THEN
tAutoPurge :=FALSE;
tAutoDispense :=FALSE;
tWeightDispense:=FALSE;
END_IF
功能:综合 “任务阶段(Step=150)、自动排胶(tAutoPurge)、轨迹点胶(tAutoDispense)” 等条件,控制 q_bStart 信号触发实际出胶动作;出胶后及时关闭触发标记,避免重复执行。
8. 数据抓取与记录(可选功能)
tRtrig3(CLK:=NOT tAutoDispense);
IF tRtrig3.Q THEN
IndexDatas:=1;
Step_Data :=10;
END_IF
CASE Step_Data OF
10:
st_BdtronicIF.Out.q_bProcess_Data := INT_TO_BYTE (IndexDatas);
IF st_BdtronicIF.In.i_bProcess_Data = IndexDatas THEN
(* ... 读取并转换工艺数据(如时间、流量) ... *)
Step_Data:=15;
END_IF
(* ... 其他数据读取步骤 ... *)
END_CASE
功能:任务结束后(tAutoDispense 关闭时触发),通过 CASE Step_Data 按序读取点胶机的工艺数据(如出胶时间、流量),存入数组 oLast_DispensingDatas,用于生产追溯或质量分析。
6.3、总结
这个胶机通讯功能块本质是 “状态机 + 条件判断” 的组合,通过 Step 拆分任务流程,用 CASE 逐步执行点胶、填充、清洗等动作,同时嵌入 故障诊断、模式安全、数据记录 逻辑,确保设备稳定、可追溯。
简单说,它就像点胶机的 “大脑”:
先看 “当前要干啥(任务触发条件)”→
再分步骤执行(状态机 Step)→
遇到问题就复位(故障处理)→
最后记录干了啥(数据抓取)。
如果想深入调试,建议重点已关注 Step 跳转逻辑、bVar_REQ_* 触发条件,以及故障码 wTemp_Diagnose 的赋值位置,就能快速定位流程卡点或异常~
七、通讯功能块描述
这个功能块是 BDtronic 点胶机控制系统的核心逻辑单元,其作用是管理点胶机的全流程自动化操作,包括任务调度、状态监控、模式切换和故障处理。以下是功能块的详细说明:
7.1 功能块概述
名称:BDtronic 点胶机控制功能块
输入:设备状态信号、用户命令、工艺参数
输出:点胶机控制信号、状态反馈、故障报警
核心逻辑:基于状态机的任务调度与执行
7.2 主要功能
1. 任务管理
点胶操作:控制正常点胶流程(WP),支持手动和自动模式
填充操作:新胶管填充流程(WP_1),排除管路空气
清洗操作:胶头清洗流程(HP),防止胶水固化堵塞
自动排胶:根据使用时间自动触发排胶,避免材料过期
2. 状态监控与反馈
设备状态:实时监测就绪(Ready)、系统正常(SystemOK)、繁忙(Busy)等状态
工艺参数:读取并记录点胶时间、流量、压力等关键数据
安全检查:监控门状态、轴位置等安全条件,确保操作合规
3. 模式切换与配方管理
工作模式:支持手动、自动、初始化等模式切换
配方管理:自动加载并验证点胶配方,确保工艺一致性
安全机制:自动模式下强制关闭编辑功能,防止误操作
4. 故障诊断与处理
实时诊断:监测系统错误、材料异常、通信故障等 16 种故障类型
自动恢复:支持故障复位功能,快速恢复生产
超时保护:关键操作设置超时限制,避免长时间阻塞
7.3 工作流程
初始化:重置状态、映射输入输出信号
任务触发:根据模式和用户命令,选择执行点胶、填充或清洗任务
状态机执行:按步骤(Step)执行任务,包括模式检查、配方验证、动作执行
数据采集:任务完成后记录关键工艺数据
故障处理:检测并处理异常情况,记录故障代码
7.4 应用场景
电子制造:PCB 板涂覆、芯片封装
汽车零部件:传感器封装、精密阀门点胶
医疗设备:精密部件组装、密封点胶
其他精密制造:需要高精度流体控制的场景
7.5 关键技术特性
状态机设计:将复杂流程拆解为清晰的步骤,易于维护和扩展
双看门狗机制:通过心跳信号(LifeBit)和超时保护确保通信可靠性
模块化结构:核心逻辑与输入输出映射分离,便于适配不同硬件
安全优先:多重安全检查和互锁机制,防止误操作
这个功能块通过集成化的设计,实现了 BDtronic 点胶机从任务接收到执行的全流程自动化控制,是工业自动化生产线中的关键组件。
八、附录
8.1 输入变量映射程序
st_BdtronicIF.In.i_bHandshake_Dispense := ist_HWIn[0].0;
st_BdtronicIF.In.i_bLifeBit_Dispense := ist_HWIn[0].1;
st_BdtronicIF.In.i_bRes_by0b2 := ist_HWIn[0].2;
st_BdtronicIF.In.i_bRes_by0b3 := ist_HWIn[0].3;
st_BdtronicIF.In.i_bRes_by0b4 := ist_HWIn[0].4;
st_BdtronicIF.In.i_bRes_by0b5 := ist_HWIn[0].5;
st_BdtronicIF.In.i_bRes_by0b6 := ist_HWIn[0].6;
st_BdtronicIF.In.i_bRes_by0b7 := ist_HWIn[0].7;
st_BdtronicIF.In.i_bMode_Dispense := ist_HWIn[1];
st_BdtronicIF.In.i_bUser_Level := ist_HWIn[2];
st_BdtronicIF.In.i_bRecipeNo := ist_HWIn[3];
st_BdtronicIF.In.i_bReady := ist_HWIn[4].0;
st_BdtronicIF.In.i_bBusy := ist_HWIn[4].1;
st_BdtronicIF.In.i_bSystemOK := ist_HWIn[4].2;
st_BdtronicIF.In.i_bRes_by4b3 := ist_HWIn[4].3;
st_BdtronicIF.In.i_bRes_by4b4 := ist_HWIn[4].4;
st_BdtronicIF.In.i_bRes_by4b5 := ist_HWIn[4].5;
st_BdtronicIF.In.i_bRes_by4b6 := ist_HWIn[4].6;
st_BdtronicIF.In.i_bRes_by4b7 := ist_HWIn[4].7;
st_BdtronicIF.In.i_bRequest_Pos := ist_HWIn[5];
st_BdtronicIF.In.i_wTimeYear_Dispense := MEM.PackBytesToWord(byHighByte:=ist_HWIn[7] , byLowByte:=ist_HWIn[6] );
st_BdtronicIF.In.i_bTimeMonth_Dispense := ist_HWIn[8];
st_BdtronicIF.In.i_bTimeDay_Dispense := ist_HWIn[9];
st_BdtronicIF.In.i_bTimeHour_Dispense := ist_HWIn[10];
st_BdtronicIF.In.i_bTimeMinute_Dispense := ist_HWIn[11];
st_BdtronicIF.In.i_bTimeSecond_Dispense := ist_HWIn[12];
st_BdtronicIF.In.i_bTime_Reserve_Dispense := ist_HWIn[13];
st_BdtronicIF.In.i_bWeigh_Started := ist_HWIn[14].0;
st_BdtronicIF.In.i_bWeigh_Completed := ist_HWIn[14].1;
st_BdtronicIF.In.i_bRes_by14b2 := ist_HWIn[14].2;
st_BdtronicIF.In.i_bRes_by14b3 := ist_HWIn[14].3;
st_BdtronicIF.In.i_bRes_by14b4 := ist_HWIn[14].4;
st_BdtronicIF.In.i_bRes_by14b5 := ist_HWIn[14].5;
st_BdtronicIF.In.i_bRes_by14b6 := ist_HWIn[14].6;
st_BdtronicIF.In.i_bRes_by14b7 := ist_HWIn[14].7;
st_BdtronicIF.In.i_bPartCode_Trsfing := ist_HWIn[15].0;
st_BdtronicIF.In.i_bPartCode_Trsf_Completed:= ist_HWIn[15].1;
st_BdtronicIF.In.i_bRes_by15b2 := ist_HWIn[15].2;
st_BdtronicIF.In.i_bRes_by15b3 := ist_HWIn[15].3;
st_BdtronicIF.In.i_bRes_by15b4 := ist_HWIn[15].4;
st_BdtronicIF.In.i_bRes_by15b5 := ist_HWIn[15].5;
st_BdtronicIF.In.i_bRes_by15b6 := ist_HWIn[15].6;
st_BdtronicIF.In.i_bRes_by15b7 := ist_HWIn[15].7;
tWeigh1[1]:= ist_HWIn[16];
tWeigh1[2]:= ist_HWIn[17];
tWeigh1[3]:= ist_HWIn[18];
tWeigh1[4]:= ist_HWIn[19];
tWeigh2[1]:= ist_HWIn[20];
tWeigh2[2]:= ist_HWIn[21];
tWeigh2[3]:= ist_HWIn[22];
tWeigh2[4]:= ist_HWIn[23];
tWeigh3[1]:= ist_HWIn[24];
tWeigh3[2]:= ist_HWIn[25];
tWeigh3[3]:= ist_HWIn[26];
tWeigh3[4]:= ist_HWIn[27];
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irWeigh_LimitMin),srcAddr:=ADR(tWeigh1[1]),n:= SIZEOF(st_BdtronicIF.In.irWeigh_LimitMin)) ;
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irWeigh_LimitMax),srcAddr:=ADR(tWeigh2[1]),n:= SIZEOF(st_BdtronicIF.In.irWeigh_LimitMax)) ;
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irWeigh_LastValue),srcAddr:=ADR(tWeigh3[1]),n:= SIZEOF(st_BdtronicIF.In.irWeigh_LastValue)) ;
st_BdtronicIF.In.i_wChangeTime_Year := MEM.PackBytesToWord(byHighByte:=ist_HWIn[29] , byLowByte:=ist_HWIn[28] );
st_BdtronicIF.In.i_bChangeTime_Month := ist_HWIn[30];
st_BdtronicIF.In.i_bChangeTime_Day := ist_HWIn[31];
st_BdtronicIF.In.i_bChangeTime_Hour := ist_HWIn[32];
st_BdtronicIF.In.i_bChangeTime_Minute := ist_HWIn[33];
st_BdtronicIF.In.i_bChangeTime_Second := ist_HWIn[34];
st_BdtronicIF.In.i_bChangeTime_Reserve := ist_HWIn[35];
st_BdtronicIF.In.i_bPart_Barcode[0] := ist_HWIn[36];
st_BdtronicIF.In.i_bPart_Barcode[1] := ist_HWIn[37];
st_BdtronicIF.In.i_bPart_Barcode[2] := ist_HWIn[38];
st_BdtronicIF.In.i_bPart_Barcode[3] := ist_HWIn[39];
st_BdtronicIF.In.i_bPart_Barcode[4] := ist_HWIn[40];
st_BdtronicIF.In.i_bPart_Barcode[5] := ist_HWIn[41];
st_BdtronicIF.In.i_bPart_Barcode[6] := ist_HWIn[42];
st_BdtronicIF.In.i_bPart_Barcode[7] := ist_HWIn[43];
st_BdtronicIF.In.i_bProcess_OK := ist_HWIn[44].0;
st_BdtronicIF.In.i_bProcess_NOK := ist_HWIn[44].1;
st_BdtronicIF.In.i_bRes_by44b2 := ist_HWIn[44].2;
st_BdtronicIF.In.i_bRes_by44b3 := ist_HWIn[44].3;
st_BdtronicIF.In.i_bRes_by44b4 := ist_HWIn[44].4;
st_BdtronicIF.In.i_bRes_by44b5 := ist_HWIn[44].5;
st_BdtronicIF.In.i_bRes_by44b6 := ist_HWIn[44].6;
st_BdtronicIF.In.i_bRes_by44b7 := ist_HWIn[44].7;
st_BdtronicIF.In.i_bProcess_Data := ist_HWIn[45];
tProcess1[1]:= ist_HWIn[46];
tProcess1[2]:= ist_HWIn[47];
tProcess1[3]:= ist_HWIn[48];
tProcess1[4]:= ist_HWIn[49];
tProcess2[1]:= ist_HWIn[50];
tProcess2[2]:= ist_HWIn[51];
tProcess2[3]:= ist_HWIn[52];
tProcess2[4]:= ist_HWIn[53];
tProcess3[1]:= ist_HWIn[54];
tProcess3[2]:= ist_HWIn[55];
tProcess3[3]:= ist_HWIn[56];
tProcess3[4]:= ist_HWIn[57];
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irProcessData_Value),srcAddr:=ADR( tProcess1[1]),n:= SIZEOF(st_BdtronicIF.In.irProcessData_Value)) ;
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irProcessData_UpperValue),srcAddr:=ADR( tProcess2[1]),n:= SIZEOF(st_BdtronicIF.In.irProcessData_UpperValue)) ;
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irProcessData_LowerValue),srcAddr:=ADR( tProcess3[1]),n:= SIZEOF(st_BdtronicIF.In.irProcessData_LowerValue)) ;
tPotLife_Set[1]:= ist_HWIn[58];
tPotLife_Set[2]:= ist_HWIn[59];
tPotLife_Set[3]:= ist_HWIn[60];
tPotLife_Set[4]:= ist_HWIn[61];
tPotLife_Current[1]:= ist_HWIn[62];
tPotLife_Current[2]:= ist_HWIn[63];
tPotLife_Current[3]:= ist_HWIn[64];
tPotLife_Current[4]:= ist_HWIn[65];
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irPotLife_SetValue),srcAddr:=ADR(tPotLife_Set[1]),n:= SIZEOF(st_BdtronicIF.In.irPotLife_SetValue)) ;
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irPotLife_ActValue),srcAddr:=ADR(tPotLife_Current[1]),n:= SIZEOF(st_BdtronicIF.In.irPotLife_ActValue)) ;
st_BdtronicIF.In.i_bHandshake_Material := ist_HWIn[66].0;
st_BdtronicIF.In.i_bLifeBit_Material := ist_HWIn[66].1;
st_BdtronicIF.In.i_bRes_by66b2 := ist_HWIn[66].2;
st_BdtronicIF.In.i_bRes_by66b3 := ist_HWIn[66].3;
st_BdtronicIF.In.i_bRes_by66b4 := ist_HWIn[66].4;
st_BdtronicIF.In.i_bRes_by66b5 := ist_HWIn[66].5;
st_BdtronicIF.In.i_bRes_by66b6 := ist_HWIn[66].6;
st_BdtronicIF.In.i_bRes_by66b7 := ist_HWIn[66].7;
st_BdtronicIF.In.i_bMode_Material := ist_HWIn[67];
st_BdtronicIF.In.i_bMaterial_OK := ist_HWIn[68].0;
st_BdtronicIF.In.i_bRes_by68b1 := ist_HWIn[68].1;
st_BdtronicIF.In.i_bRes_by68b2 := ist_HWIn[68].2;
st_BdtronicIF.In.i_bRes_by68b3 := ist_HWIn[68].3;
st_BdtronicIF.In.i_bRes_by68b4 := ist_HWIn[68].4;
st_BdtronicIF.In.i_bRes_by68b5 := ist_HWIn[68].5;
st_BdtronicIF.In.i_bRes_by68b6 := ist_HWIn[68].6;
st_BdtronicIF.In.i_bRes_by68b7 := ist_HWIn[68].7;
st_BdtronicIF.In.i_bCurrent_Level := ist_HWIn[69];
st_BdtronicIF.In.i_wTimeYear_Material := MEM.PackBytesToWord(byHighByte:=ist_HWIn[71] , byLowByte:=ist_HWIn[70] );
st_BdtronicIF.In.i_bTimeMonth_Material := ist_HWIn[72];
st_BdtronicIF.In.i_bTimeDay_Material := ist_HWIn[73];
st_BdtronicIF.In.i_bTimeHour_Material := ist_HWIn[74];
st_BdtronicIF.In.i_bTimeMinute_Material := ist_HWIn[75];
st_BdtronicIF.In.i_bTimeSecond_Material := ist_HWIn[76];
st_BdtronicIF.In.i_bTime_Reserve_Dispense := ist_HWIn[77];
st_BdtronicIF.In.i_Barcode_Selection := ist_HWIn[78];
st_BdtronicIF.In.i_bBarCode_Trsfing := ist_HWIn[79].0;
st_BdtronicIF.In.i_bBarCode_Trsf_Completed := ist_HWIn[79].1;
st_BdtronicIF.In.i_bRes_by79b2 := ist_HWIn[79].2;
st_BdtronicIF.In.i_bRes_by79b3 := ist_HWIn[79].3;
st_BdtronicIF.In.i_bRes_by79b4 := ist_HWIn[79].4;
st_BdtronicIF.In.i_bRes_by79b5 := ist_HWIn[79].5;
st_BdtronicIF.In.i_bRes_by79b6 := ist_HWIn[79].6;
st_BdtronicIF.In.i_bRes_by79b7 := ist_HWIn[79].7;
st_BdtronicIF.In.i_bBarcode[0] := ist_HWIn[80];
st_BdtronicIF.In.i_bBarcode[1] := ist_HWIn[81];
st_BdtronicIF.In.i_bBarcode[2] := ist_HWIn[82];
st_BdtronicIF.In.i_bBarcode[3] := ist_HWIn[83];
st_BdtronicIF.In.i_bBarcode[4] := ist_HWIn[84];
st_BdtronicIF.In.i_bBarcode[5] := ist_HWIn[85];
st_BdtronicIF.In.i_bBarcode[6] := ist_HWIn[86];
st_BdtronicIF.In.i_bBarcode[7] := ist_HWIn[87];
tPailA_Level[1]:= ist_HWIn[88];
tPailA_Level[2]:= ist_HWIn[89];
tPailA_Level[3]:= ist_HWIn[90];
tPailA_Level[4]:= ist_HWIn[91];
tPailB_Level[1]:= ist_HWIn[92];
tPailB_Level[2]:= ist_HWIn[93];
tPailB_Level[3]:= ist_HWIn[94];
tPailB_Level[4]:= ist_HWIn[95];
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irPailA_Filllevel),srcAddr:=ADR(tPailA_Level[1]),n:= SIZEOF(st_BdtronicIF.In.irPailA_Filllevel)) ;
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irPailB_Filllevel),srcAddr:=ADR(tPailB_Level[1]),n:= SIZEOF(st_BdtronicIF.In.irPailB_Filllevel)) ;
tPumpA_Pressure[1]:= ist_HWIn[96];
tPumpA_Pressure[2]:= ist_HWIn[97];
tPumpA_Pressure[3]:= ist_HWIn[98];
tPumpA_Pressure[4]:= ist_HWIn[99];
tPumpB_Pressure[1]:= ist_HWIn[100];
tPumpB_Pressure[2]:= ist_HWIn[101];
tPumpB_Pressure[3]:= ist_HWIn[102];
tPumpB_Pressure[4]:= ist_HWIn[103];
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irPumpA_DispensePressure),srcAddr:=ADR(tPumpA_Pressure[1]),n:= SIZEOF(st_BdtronicIF.In.irPumpA_DispensePressure)) ;
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irPumpB_DispensePressure),srcAddr:=ADR(tPumpB_Pressure[1]),n:= SIZEOF(st_BdtronicIF.In.irPumpB_DispensePressure)) ;
tPumpAOutlet_Pressure[1]:= ist_HWIn[104];
tPumpAOutlet_Pressure[2]:= ist_HWIn[105];
tPumpAOutlet_Pressure[3]:= ist_HWIn[106];
tPumpAOutlet_Pressure[4]:= ist_HWIn[107];
tPumpBOutlet_Pressure[1]:= ist_HWIn[108];
tPumpBOutlet_Pressure[2]:= ist_HWIn[109];
tPumpBOutlet_Pressure[3]:= ist_HWIn[110];
tPumpBOutlet_Pressure[4]:= ist_HWIn[111];
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irPumpA_OutletPressure ),srcAddr:=ADR(tPumpAOutlet_Pressure[1]),n:= SIZEOF(st_BdtronicIF.In.irPumpA_OutletPressure )) ;
MEMCPY(destAddr:=ADR(st_BdtronicIF.In.irPumpB_OutletPressure ),srcAddr:=ADR(tPumpBOutlet_Pressure[1]),n:= SIZEOF(st_BdtronicIF.In.irPumpB_OutletPressure )) ;
8.2 输出变量映射程序
ost_HWOut[0].0 := st_BdtronicIF.Out.q_bHandshake_Active;
ost_HWOut[0].1 := st_BdtronicIF.Out.q_bLifeBit_Dispese;
ost_HWOut[0].2 := FALSE;
ost_HWOut[0].3 := FALSE;
ost_HWOut[0].4 := FALSE;
ost_HWOut[0].5 := FALSE;
ost_HWOut[0].6 := FALSE;
ost_HWOut[0].7 := FALSE;
ost_HWOut[1] := st_BdtronicIF.Out.q_bMode_Dispense;
ost_HWOut[2] := st_BdtronicIF.Out.q_bRecipeNo;
ost_HWOut[3].0 := st_BdtronicIF.Out.q_bStart;
ost_HWOut[3].1 := st_BdtronicIF.Out.q_bFill;
ost_HWOut[3].2 := st_BdtronicIF.Out.q_bClean;
ost_HWOut[3].3 := FALSE;
ost_HWOut[3].4 := FALSE;
ost_HWOut[3].5 := FALSE;
ost_HWOut[3].6 := FALSE;
ost_HWOut[3].7 := FALSE;
ost_HWOut[4] := st_BdtronicIF.Out.q_bActual_Pos;
ost_HWOut[5].0 := st_BdtronicIF.Out.q_bPartID_Received;
ost_HWOut[5].1 := FALSE;
ost_HWOut[5].2 := FALSE;
ost_HWOut[5].3 := FALSE;
ost_HWOut[5].4 := FALSE;
ost_HWOut[5].5 := FALSE;
ost_HWOut[5].6 := FALSE;
ost_HWOut[5].7 := FALSE;
ost_HWOut[6] := st_BdtronicIF.Out.q_bPartID_OK;
ost_HWOut[7] := st_BdtronicIF.Out.q_bProcess_Data;
ost_HWOut[8] := st_BdtronicIF.Out.q_bMode_Material;
ost_HWOut[9] := st_BdtronicIF.Out.q_Barcode_Selection;
ost_HWOut[10].0 := st_BdtronicIF.Out.q_bBarcode_Received;
ost_HWOut[10].1 := FALSE;
ost_HWOut[10].2 := FALSE;
ost_HWOut[10].3 := FALSE;
ost_HWOut[10].4 := FALSE;
ost_HWOut[10].5 := FALSE;
ost_HWOut[10].6 := FALSE;
ost_HWOut[10].7 := FALSE;
ost_HWOut[11].0 := st_BdtronicIF.Out.q_bLifeBit_Material;
ost_HWOut[11].1 := FALSE;
ost_HWOut[11].2 := FALSE;
ost_HWOut[11].3 := FALSE;
ost_HWOut[11].4 := FALSE;
ost_HWOut[11].5 := FALSE;
ost_HWOut[11].6 := FALSE;
ost_HWOut[11].7 := FALSE;
8.3




















暂无评论内容