科技N次方
说一点我个人在电气自动化行业中对于编程语言的一些认识吧!
个人的工作经验中需要用到编程语言的就是PLC程序的编程和上位机软件的编程,因此就说一下关于这2方面编程过程中需要哪些高级语言!
1,做PLC程序的话,在使用结构化文本(ST或者SCL)编程时候需要用到一些C语言的知识!
最常用的就是IF THEN , IF ELSE这种!在西门子的编程软件中就叫做SCL编程,如下图就是在博图软件中建立一个块的时候,就可以选择对这个块的编程语言是什么!
还需要说一点的是西门子PLC中还有一种STL(语句表)的编程语言,它比梯形图语言要难理解一点,但是又没有C语言的指令语法,是一种特殊的编程语言,但是应用也是很广泛的,看一下其程序的语句如下:
STL语句表编程语言,算不上高级语言,但也是比较特殊的语言,依然是有必要学习的!
2,做上位机监控软件的组态编程的时候,通常要用到一些VB或者C语言的知识!
下图就是西门子Wincc上位机软件中支持的2种脚本,一种是C脚本,一种是VBS脚本!
其实,不单单是在上位机软件中,在一些触摸屏的组态软件中也同样存在类似于C或者VB的宏指令。
因此C语言和VB语言,可以说是应用最多的两种编程语言了,不管是PLC编程能用到,还是组态软件中也可以用到。甚至,这些年比较流行的labview软件,它里边的一些指令依然和C语言这些有理解上的相似性!--也就是说C和VB,应该说还是计算机应用中最重要且应用广泛的两种语言,我们做电气自动化,其实也是在计算机平台上,因此还是很有必要学一学这两门语言!
就说这么多了,希望能对你有点帮助,感谢阅读,谢谢!
控制研究控
电气自动化需要哪些高级语言?
市面上高级语言挺多,好用的也挺多。
工业自动化里常见到的有VB,C++,C#等等。
需要哪些?一般一个公司要求并不多,熟悉一种就好。
具体可以根据自己身情况选择。
为什么需要学习高级语言?
我也是从事工业自动化.
自动化控制更多的是编写PLC程序,触摸屏程序。
但随着工业4.0,智能化的需求,
会一门电脑高级语言编程,真的是太迫切。
比如,你只会PLC编程。
那么你学习西门子产品时,一些脚本程序你就不会编写。
那么硬件通讯程序也会编写不顺,
那么触摸屏里类似C语言的宏指令也用不好。
如我刚完结的威纶触摸屏宏指令教程,你看教程都觉得吃力。
这些都是跟PLC关系比较密切的。
还有其他的就更不用说了。
比如运行卡,图像采集卡,数据采集卡等等这些应用于工控机上的工业产品。
视觉开发,深度学习这些更多深层次的应用也只有观看的份了。
所以真的需要学习一门高级语言。
这也是也什么平台相似的问题非常多。
因为广大一线的自动化同行,都已经意识到了或是有了迫切的需求。
更何况现在AI,大数据这么流行。
紧跟潮流,玩玩开源库也是很享受的一件事。
选择哪种语言学习?
这个应该是刚接触想学习高级语言编程的朋友最为棘手的问题了。
平台一提问,答案也是五花八门。
网友的回答也是对自己经历的总结。
熟悉哪门语言,常用哪门语言,就建议学哪门语言。
我也是众多网友中的一个,也来谈谈选哪种语言好。
答案是:
选C++语言,框架选择MFC。
回答过相似问题好多,原因也总结了很多,
总的原因是自动化行业追求程序执行效率,各厂家硬件兼容性。
不追求界面,不追求跨平台。生产效率高就好。
另外MFC学习相对还是挺烦人的,
C#也是非常好的选择,更简单,更好学。
唯一麻烦的是要顾忌工业上众多MFC程序。
工控编程
基础的,你得会梯形图语言,然后是语句表,有些上位机组态是用的VB,机械手有些用的python,C语言也是要的。
自动化工控小刘
高级语言,个人认为这个说法并不完全正确,有电路设计方面的知识,运用常用的语言工具实现这种需求而已。
电气这方面,从编程语言来看,FBD编程可以学一波,要对数字电子技术理论基础及实操掌握扎实,LAD编程,STL语言都可以掌握,微机原理与汇编语言这门课一定要学好,这样方能熟练操作STL里面的累加器,寄存器等。
祝好(✪▽✪)•笑生
笑生看世界
C#,在工控上位机领域也算是全能型的比较简单的高级语言,Labview局限于测量设备,C++太难,JAVA不太适合建桌面应用程序,C#正好
Debugging
你这里问的高级语言,不知道你说的是哪一些?C#,Java或者其他的?VB又算是什么?
既然你的范畴在电气自动化领域,又问这样的问题,姑且当提问的是一个大学生,刚接触到这一方面而又对未来不是很明确吧。
正常工控领域使用最多的就是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个例子可以看出,电气自动化,将来的方向使用的好多都是一些基础的语句。主要的方面在编程的思想。而不是工具。