|
高级语言,个人认为这个说法并不完全正确,有电路设计方面的知识,运用常用的语言工具实现这种需求而已。
电气这方面,从编程语言来看,FBD编程可以学一波,要对数字电子技术理论基础及实操掌握扎实,LAD编程,STL语言都可以掌握,微机原理与汇编语言这门课一定要学好,这样方能熟练操作STL里面的累加器,寄存器等。
正常工控领域使用最多的就是LAD,也就是梯形图。但是除了LAD之外,好多老外喜欢用FBD(功能块图),以前SIEMENS处理多个数据的时候有的时候使用STL(语句表),但是自从博图平台后,SCL(结构化文本语言)使用的比较多。当然有的顺序结构使用Graph(顺序功能图)。
1,SIEMENS 博图平台SCL范例。
下面的语句,输入一个字符串,在这个字符串里面寻找测量的数值。是为Ateq泄露测试仪用的。测试一个,会输出一个字符串,这个字符串里面有一个或者两个real,采集里面的数值。
注意这个数值有可能是负数。
IF #iEnable THEN
IF #ioClear THEN
#tString := '';
FOR #Index := 0 TO 255 BY 1 DO
#oBool[#Index] := 0;
#oReal[#Index] := 0;
#IndexReal[#Index] := 0;
END_FOR;
#ioStart := 0;
#ioClear := 0;
ELSE
IF #ioStart THEN
FOR #Index := 0 TO 255 BY 1 DO
#IndexReal[#Index] := DINT_TO_REAL(IN := BYTE_TO_DINT(IN := #tAtString[#Index] - 16#30));
#oBool[#Index] := 0;
#oReal[#Index] := 0;
END_FOR;
#IndexPointPosition := 0;
FOR #Index := 0 TO 255 BY 1 DO
IF #tAtString[#Index] = '.' THEN
//寻找所有有'.'号的位置
FOR #i := -3 TO 3 BY 1 DO
IF #IndexReal[#Index + #i] >= 0.0 AND #IndexReal[#Index + #i] <= 9.0 THEN
CASE #i OF
-3:
#oReal[#IndexPointPosition] := #oReal[#IndexPointPosition] + #IndexReal[#Index + #i] * 100.0;
-2:
#oReal[#IndexPointPosition] := #oReal[#IndexPointPosition] + #IndexReal[#Index + #i] * 10.0;
-1:
#oReal[#IndexPointPosition] := #oReal[#IndexPointPosition] + #IndexReal[#Index + #i] * 1.0;
1:
#oReal[#IndexPointPosition] := #oReal[#IndexPointPosition] + #IndexReal[#Index + #i] / 10.0;
2:
#oReal[#IndexPointPosition] := #oReal[#IndexPointPosition] + #IndexReal[#Index + #i] / 100.0;
3:
#oReal[#IndexPointPosition] := #oReal[#IndexPointPosition] + #IndexReal[#Index + #i] / 1000.0;
END_CASE;
END_IF;
END_FOR;
//寻找所有有'-'号的位置
FOR #i := -3 TO 3 BY 1 DO
IF #tAtString[#Index + #i] = '-' THEN
#oReal[#IndexPointPosition] := #oReal[#IndexPointPosition] * -1;
END_IF;
END_FOR;
#oBool[#IndexPointPosition] := 1;
#IndexPointPosition := #IndexPointPosition + 1;
END_IF;
END_FOR;
#ioStart := 0;
END_IF;
END_IF;
ELSE
#ioStart := 0;
END_IF;
这个小程序是一个FB块,非优化。使用AT指令。
原理就是先在字符串里面寻找‘.’号,然后再在该点号左侧和右侧寻找数字,然后在在这里面寻找‘-’负号。
2,EPSON四轴机械手
EPSON四轴机械手,用到的是从托盘里面取产品,这里只粘贴了一部分程序。
Function pick
Pallet 1, P10, P11, P12, P13, 3, 4 '定义托盘1(取料盘)
'Out oPositionID, 0 'Wait
BB: If i = 13 Then
Print "请确认料盒已经清零"
GoTo BB
Else
Print i
GoTo CC
EndIf
CC: Jump Pallet(1, i) +X(x1) +Y(y1) +U(u1) :Z(0)
'到达扫码位置信号
Out oPositionID, 2 'oScanPos
'等待夹爪打开
Wait Sw(561) = On 'iClampOff
DD: Print "请给去取料或者下一个扫码位置信号"
'等待去取料信号
If Sw(546) = On Then 'iGoPickPos
GoTo FF
ElseIf Sw(550) = On Then 'iGoNextScanPos
GoTo EE
Else
GoTo DD
EndIf
EE: i = i + 1 '料盘计数 +1
'Out oPositionID, 0 'Wait
Wait Sw(550) = Off
GoTo BB
'Wait Sw(546) = On 'iGoPickPos
'Call NUM;
FF: If i = 10 Or i = 11 Or i = 12 Then
bRotateU = True
bRotateU2 = False
Jump Pallet(1, i) +U(intRotateU)
ElseIf i = 2 Then
bRotateU = False
bRotateU2 = True
Jump Pallet(1, i) +U(intRotateU2)
Else
bRotateU = False
bRotateU2 = False
Jump Pallet(1, i)
EndIf
'到达取料点信号
Out oPositionID, 3 'oPickPos
'夹紧产品
Wait Sw(560) = On 'iClampOn
i = i + 1 '料盘计数 +1
Go Here :Z(0) 'Z-Axis back Zero
Jump hompos
Out oPositionID, 1 'oHomePos
' '等待放料信号
'BB: If Sw(547) = On Then 'iGoPutPos_Nissan
' Call put_VW
' ElseIf Sw(548) = On Then 'iGoPutPos_VW
' Call put_Nissan
' ElseIf Sw(549) = On Then 'iGoNGPos
' Call NGput
' Else
' Print "取料后放料点选择(放料1、2和NG放料)"
' GoTo BB
' EndIf
'If i = 12 Then i = 1
Fend
这里面的作用是先到Cognex相机扫码位置,plc触发扫码。如果有二维码,PLC告诉EPSON取产品,没有二维码,EPSON继续到扫码下一个位置。
取料的托盘是3x4结构。由于取料的产品比较深,夹爪是3个腿。第1行2列位置要旋转35°。最后1列要旋转120°,避免夹爪碰到托盘外边。
3,SIEMENS SIMOTION D410 跟PC TCP/IP信号交互
D410打开TCP/IP端口,并且等待PC段建立连接。如果连接了,发送数据
发送和接收的缓存取都是1024个Byte
PROGRAM PB_Communication
//Program Variables
VAR
i : DINT;
intReveiveTimes : INT;
bytesReceiveFromIPC : ARRAY[0..1023] OF BYTE;
dintNext : DINT;
TOF_Send : TOF;
myRetCloseConnection : DINT;
myRetCloseServer : DINT;
myRetTCPSend : DINT;
FT_Connected : F_TRIG;
END_VAR
FT_Connected(g_Connected);
IF FT_Connected.q THEN
myRetCloseConnection :=_tcpCloseConnection(connectionId :=OpenSvr.connectionId );
myRetCloseServer :=_tcpCloseServer(port :=2001 );
OpenSvr.functionResult:=16#EEEEEEEE;
END_IF;
// Try and Check IPC Connection
IF NOT g_Connected THEN
OpenSvr :=
_tcpOpenServer(
port := 2001
,backlog := 2
,nextCommand := IMMEDIATELY
);
IF OpenSvr.functionResult=0 THEN
g_Connected:=TRUE;
g_SendData:=TRUE;
END_IF;
ELSE
TcpRCV :=
_tcpReceive(
connectionId := OpenSvr.connectionId
,nextCommand := IMMEDIATELY
,receiveVariable := bytesReceiveFromIPC
);
//END_IF;
IF TcpRCV.functionResult = 16#0000 THEN
intReveiveTimes := intReveiveTimes + 1;
IF intReveiveTimes = 1 THEN
dintNext := 0;
END_IF;
FOR i := 0 TO 1023 DO
g_ReceiveBytes[ i] := bytesReceiveFromIPC[i];
END_FOR;
dintNext := dintNext + UDINT_TO_DINT(TcpRCV.dataLength);
IF g_Connected THEN
//Deal with the ByteBit From IPC
IPC_Get_Trig :=_getbit(g_ReceiveBytes[0],0);
IPC_Get_LScan_Deg := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,8));
IPC_Get_LScan_Vel := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,12));
IPC_Get_LScan_Acc := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,16));
IPC_Get_LScan_Dec := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,20));
IPC_Get_SScan_Deg := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,24));
IPC_Get_SScan_Vel := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,28));
IPC_Get_SScan_Acc := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,32));
IPC_Get_SScan_Dec := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,36));
IPC_Get_Shift_Deg := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,40));
IPC_Get_Shift_Vel := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,44));
IPC_Get_Shift_Acc := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,48));
IPC_Get_Shift_Dec := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,52));
IPC_Get_Engage_TorqueLim := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,56));
IPC_Get_Engage_Vel := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,60));
//IPC_Get_LScan_Time := REAL_TO_LREAL(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,64));
IPC_Get_SScan_Time := REAL_TO_DINT(LITTLEBYTEARRAY_TO_ANYTYPE(g_ReceiveBytes,64));
END_IF;
ELSIF TcpRCV.functionResult = 16#7002 THEN
intReveiveTimes := 0;
dintNext := 0;
ELSIF TcpRCV.functionResult < 0 THEN
g_Connected := FALSE;
END_IF;
IF NOT TOF_Send.Q THEN
g_SendData := TRUE;
END_IF;
TOF_Send(g_SendData,t#100ms);
IF g_Connected THEN
//Get data From Axis
IPC_Display_acturalspeed:=LREAL_TO_REAL(_to.Axis_1.servodata.pValue);//_to.Axis_1.actorData.actualSpeed
IPC_Display_acturalposition:=LREAL_TO_REAL(_to.Axis_1.servodata.actualPosition);
IPC_Display_acturaltorque:=LREAL_TO_REAL(_to.Axis_1.actualTorque.value);
IPC_Display_alarmNO:=TSI#AlarmNumber;
//Send data to IPC
g_SendBytes := ANYTYPE_TO_LITTLEBYTEARRAY(IPC_Display_acturalspeed ,8);
g_SendBytes := ANYTYPE_TO_LITTLEBYTEARRAY(IPC_Display_acturalposition ,12);
g_SendBytes := ANYTYPE_TO_LITTLEBYTEARRAY(IPC_Display_acturaltorque ,16);
g_SendBytes := ANYTYPE_TO_LITTLEBYTEARRAY(IPC_Display_alarmNO ,20);
myRetTCPSend :=
_tcpSend(
connectionId := OpenSvr.connectionId
,nextCommand := IMMEDIATELY
,dataLength := 1024
,data := g_SendBytes
);
;
IF myRetTCPSend=0 THEN
g_SendData := FALSE;
END_IF;
END_IF;
END_IF;
END_PROGRAM
从上面3个例子可以看出,电气自动化,将来的方向使用的好多都是一些基础的语句。主要的方面在编程的思想。而不是工具。 |
|