需要实现的功能大致是这样的:Python程序实现对三菱FX5U的通讯读写,通过Python程序得到脉冲数,将脉冲数发送给FX5U,从而实现PLC对相关步进电机的旋转圈数的控制,
https://blog.csdn.net/weixin_39880318/article/details/110503673
author: alai
date:2018/05/01
"""
import socket
import time
import xlwt,xlrd,struct
from xlutils.copy import copy
import sys
import re,os,sys
data="ok"
class TcpThread(QThread):
trigger = pyqtSignal(str)
trigger1=pyqtSignal(str)
def __int__(self):
super(TcpThread, self).__init__()
# 分离出一个函数用于循环tcp 重连
def doConnect(self):
with open('IP_Address.txt', 'r')as fn:
s1 = fn.read()
host = ''.join(re.findall(r'IP:(.*)', s1)) # 服务器IP地址取出来,并转成字符串
port = int(''.join(re.findall(r'PORT:(.*)', s1))) # 从文本中提取端口号转成整数
BUFFSIZE = int(''.join(re.findall(r'BUFFSIZE:(.*)', s1))) # 从文本中提取字符长度转整数
ADDRESS = (''.join(re.findall(r'ADDRESS:(.*)', s1))) # 从文本中提取字符长度转整数
LENGTH = (''.join(re.findall(r'LENGTH:(.*)', s1))) # 从文本中提取字符长度转整数
print(host,port,ADDRESS,LENGTH)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((host, port))
print("connect is ok")
except:
print('fail to setup socket connection')
return sock, BUFFSIZE,ADDRESS,LENGTH
# 发送数据
def tcpClient(self):
global glb_tag
glb_tag=0
global glb_data
sockLocal, BUFFSIZE,ADDRESS,LENGTH = self.doConnect()
while True:
# 等于0,那么一直查询
if glb_tag==0:
self.data1 = '500000FF03FF000018000004010000D*00'
self.data = self.data1+ADDRESS+LENGTH
# print(self.data)
try:
sockLocal.send(self.data.encode())
except socket.error:
print("\r\nsocket error,do reconnect ")
sockLocal.close()
time.sleep(1)
sockLocal, BUFFSIZE = self.doConnect()
except:
sockLocal.close()
print("other error")
time.sleep(1)
sockLocal, BUFFSIZE = self.doConnect()
time.sleep(0.5)
str1 = sockLocal.recv(BUFFSIZE).decode()
if str1[22:26]=="0001":
glb_tag=1
# 等于1,写入并等待结果
elif glb_tag==1:
# 发射信号,连接到datadisplay
self.trigger.emit(str1)
self.data1 = '500000FF03FF00001C000014010000D*00499900010001'
try:
sockLocal.send(self.data1.encode())
except socket.error:
print("\r\nsocket error,do reconnect ")
sockLocal.close()
time.sleep(1)
sockLocal, BUFFSIZE = self.doConnect()
except:
sockLocal.close()
print("other error")
time.sleep(1)
sockLocal, BUFFSIZE = self.doConnect()
time.sleep(0.3)
str1 = sockLocal.recv(BUFFSIZE).decode()
# print(glb_str1[16:18])
# 如果返回的数据长度是对应长度,那么不再写
if str1[16:18]=="04":
glb_tag = 0
# 等于2,PLC 数据查询
elif glb_tag==2:
self.data1='500000FF03FF000018000004010000D*00'
# 先转成字符串,然后填满四位
self.data2=("".join(re.findall("[D|d](\d+)",glb_data)))
self.data3=self.data2.zfill(4)
# print(glb_data+str(12))
# print(self.data2)
self.data=self.data1+self.data3+"0010"
# print(self.data)
try:
sockLocal.send(self.data.encode())
except socket.error:
print("\r\nsocket error,do reconnect ")
sockLocal.close()
time.sleep(1)
sockLocal, BUFFSIZE = self.doConnect()
except:
sockLocal.close()
print("other error")
time.sleep(1)
sockLocal, BUFFSIZE = self.doConnect()
time.sleep(0.3)
glb_tag = 0
str1 = sockLocal.recv(BUFFSIZE).decode()
# print(glb_str1)
self.trigger1.emit(str1)
# PLC数据写入
elif glb_tag==3:
# print("li")
self.data1='500000FF03FF00001C000014010000D*00'
# 先转成字符串,然后填满四位
self.data2=("".join(re.findall("(\d+)=",glb_data))).zfill(4)
self.data3=("".join(re.findall("=(\d+)",glb_data))).zfill(4)
# print(hex(int(self.data3)))
# 先转成16进制,然后匹配出来,舍掉0x,然后转成字符串,然后填满0
self.data4=("".join(re.findall("0x(\w+)",hex(int(self.data3))))).zfill(4)
self.data=self.data1+self.data2+"0001"+self.data4
# print(self.data)
try:
sockLocal.send(self.data.encode())
except socket.error:
print("\r\nsocket error,do reconnect ")
sockLocal.close()
time.sleep(1)
sockLocal, BUFFSIZE = self.doConnect()
except:
sockLocal.close()
print("other error")
time.sleep(1)
sockLocal, BUFFSIZE = self.doConnect()
time.sleep(0.3)
str1 = sockLocal.recv(BUFFSIZE).decode()
glb_tag = 2
# glb_str1 = sockLocal.recv(BUFFSIZE).decode()
def run(self):
#必须从run开始启动程序
# global data
self.tcpClient()
三菱PLC(FX5U)和C#通讯说明
所需的软件和插件:Visual Studio 2015,GX Work3,MX Component
1.下载并安装三菱软件
GX Work3:https://pan.baidu.com/s/129VnuvQ8R9GjfY4CnuR7Hw
提取代码:5l4e
MX组件:https
://pan.baidu.com/s/1Tc2eC7vog7a7QQIBLppn6w提取代码:7n0b
三菱官方下载网址:
http ://cn.mitsubishielectric.com/fa/zh/download/dwn_idx_software.asp
如图所示,下载GX Works3和MX Component。安装序列号为:117-610768844(官方下载需要登录帐户注册,如果无法收到移动验证码完成注册,则可以在注册右侧选择非内地用户的注册方式页面,您可以通过电子邮件直接注册)
GX Work3安装:下载完成后,解压缩软件包以获取文件夹GXW3 Ver-1-065T。
依次进入文件夹GXW3 Ver.1.065T(安装包)sw1dnd-gxw3-c_1065t_f-Disk1直接运行Disk1文件目录中的setup.exe安装程序,并执行安装操作。(有关中间所需的序列号,请参见上文)安装完成后,桌面上将出现两个软件图标GX Works3和e-Manual Viewer,以指示安装成功。
MX Component安装:下载完成后,将压缩文件解压缩到新文件夹中。如图所示,首先,在EnvMEL文件夹中安装setup.exe安装程序。安装完成后,在解压缩的文件夹中运行setup.exe安装程序。默认情况下,安装过程为所有安装(中间要求的顺序)编号。
一,用于PLC设置的GXwork3软件
下载和安装完成后,打开GXworks3软件,在工具栏左上角的项目中,创建一个新项目,如图所示进行设置,确认新项目。
依次单击工具栏中的“联机”(当前连接目标),然后选择PC适配器,该IP地址将自动匹配。PC端网段必须与PLC地址一致,其中PLC端ip已设置为192.168.3.251(设置方法请参见下文),而PC端ip已设置为192.168.3.250。单击通信测试,如果成功,将出现一个提示,如图所示。(每个PC适配器可能有不同的选项。第一次连接到PLC设备时,选择适配器后,将显示PLC的默认地址。此处已为PLC设置了IP地址,因此连接的IP地址如图所示)
通讯测试成功后,依次单击从可编程控制器在线读取,单击参数+程序按钮,然后单击执行以读取PLC中的程序(由于已编写测试程序,因此新的PLC会读出该程序)是一个空程序。)
注意:如果要修改PLC的IP地址,请单击左侧工具栏参数FX5UCPU模块参数以太网端口,如图所示,可以在自节点设置中设置ip。
2. MX Component软件连接测试
下载并安装后,在计算机开始菜单中找到新安装的通信插件“通信”
。Setup Utility以管理员身份运行。
Set the site number, you can set any, as long as the front and back match, set it to 1.
设置PC端参数,在下拉选项框中选择“ Ethernet”
和“ CPU modul(FX5)”
设置PLC参数并输入PLC IP地址。(必须与GXworks3中设置的地址一致)
如图所示设置站点和CPU类型。
这次设置向导的名称,只需选择一个即可。在这里,以1完成。
设置完成后,如下图所示。
单击“连接测试”,然后单击“测试”,它显示成功。
3. C#程序与PLC通讯测试
检查第二步中设置的向导相关参数。打开Communication Setup Utility软件,单击“列表
视图”,将右下角的“人机界面”切换到“程序”模式,并查看相关参数,如图所示。
切换到程序模式后,需要注意前三个参数。如图所示,这三个参数用于后续的C#程序通信参数匹配。其中StationNumber是站号,ActunitType是所选的CPU类型,这里是FX5U系列,ActProtocolType是使用的通信协议类型,这是TCP协议
打开C#-PLC程序文件夹并运行Sample2010.sln,打开Form1.cs,单击“打开”按钮,然后修改相关参数。
如图所示,找到代码块,红色框中的代码需要修改。根据功能名称对应上面记录的参数值,并更改参数值。为了方便起见,密码设置为空白。
完成后,您可以运行该程序。
如图所示,选择ActUtltype选项,使用先前设置的编号填写站点编号,此处为1,然后单击“打开”按钮,如果PLC成功连接,则右侧的输出返回值显示0x00000000
[ [十六进制]。如果再次单击打开按钮以重复连接,它将返回0xf0000003 [HEX],其余的返回值都是连接错误。
:
while
True
:
data
=
serial.read_all()
if
data
=
=
'':
continue
else
:
break
sleep(
0.02
)
return
data
if
__name__
=
=
'__main__'
:
serial
=
serial.Serial(
'COM5'
,
9600
, timeout
=
0.5
)
#/dev/ttyUSB0
if
serial.isOpen() :
print
(
"open success"
)
else
:
print
(
"open failed"
)
while
True
:
data
=
recv(serial)
if
data !
=
b'' :
print
(
"receive : "
,data)
serial.write(data)
#数据写回
什么错误