前言
PROFINET的等时资料交换定义在等时实时(isochronous real time,IRT)机能中。具有IRT机能的PROFINET IO现场设备有整合在现场设备中的switch ports,可以用例如像以太网控制器ERTEC 400/200为基础。一般资料交换的总线循环时间约从数百毫秒至数微秒。等时通讯和实时通讯的差异是前者有高度的确定性,因此总线周期的启始时间可维持到很高的准确度,其抖动至多到1 µs (jitter)。像马达位置控制程序的运动控制应用就会用到等时实时通讯。
目的
通过将驱动内置到IOTOS的通采引擎中,通过采集程序以及相关协议设备打通。结合项目方硬件工程师写的DB模块数据,达到数据互通,数据实时响应。
适用范围
所有遵循Profinet协议的硬件设备、IOTOS采集程序
使用示例
代码示例
class S7Driver(IOTOSDriverI):
def InitComm(self, attrs):
self.online(True)
self.setCollectingOneCircle(False)
self.setPauseCollect(False)
def Collecting(self, dataId):
lentmp = self.sysAttrs['config']['length']
zero = None
if self.sysAttrs['config']['type'] == 0:
zero = SiemensPLCS.S1200
elif self.sysAttrs['config']['type'] == 1:
zero = SiemensPLCS.S300
elif self.sysAttrs['config']['type'] == 2:
zero = SiemensPLCS.S400
elif self.sysAttrs['config']['type'] == 3:
zero = SiemensPLCS.S1500
elif self.sysAttrs['config']['type'] == 4:
zero = SiemensPLCS.S200Smart
siemens = SiemensS7Net(zero, self.sysAttrs['config']['tcp'])
print(self.sysAttrs['config']['zero'])
read = siemens.Read(self.sysAttrs['config']["zero"], lentmp)
bytesvalue = read.Content
if siemens.ConnectServer().IsSuccess == False:
print("connect falied")
else:
self.online(True)
print("connect succeed!")
desc_bit = {}
for dataId, attrs in self.data2attrs.items():
attrs1 = attrs.get("config", {})
proxy = attrs1.get("proxy", {})
bit = proxy.get("bit", None)
formate = proxy.get("formate", None)
desc_bit[attrs['description']] = {
"bit": bit,
"value": dataId,
"formate": formate
}
while True:
for addrtmp, info in desc_bit.items():
try:
self.info(addrtmp)
self.info(desc_bit[addrtmp])
tmp = addrtmp.split(".")
if info["bit"] != None:
num = tmp[1]
regad = int((re.findall('\d+', tmp[0])[0]))
bitv = pow(2, int(num))
bytesvaluetmp = struct.unpack(">B", bytesvalue[regad:regad + 1])[0]
and_v = bytesvaluetmp & bitv
tmp = (and_v == bitv)
self.setValue(self.name(desc_bit[addrtmp]["value"]), tmp)
elif desc_bit[addrtmp]["formate"] == "H":
regad = int((re.findall('\d+', tmp[0])[0]))
data_valtmp = struct.unpack(">H", bytesvalue[regad:regad + 2])
self.setValue(self.name(desc_bit[addrtmp]["value"]), data_valtmp[0])
elif desc_bit[addrtmp]["formate"] == "h":
regad = int((re.findall('\d+', tmp[0])[0]))
data_valtmp = struct.unpack(">h", bytesvalue[regad:regad + 2])
self.setValue(self.name(desc_bit[addrtmp]["value"]), data_valtmp[0])
elif desc_bit[addrtmp]["formate"] == "f":
regad = int((re.findall('\d+', tmp[0])[0]))
data_val = struct.unpack(">f", bytesvalue[regad:regad + 4])
self.setValue(self.name(desc_bit[addrtmp]["value"]), data_val[0])
except KeyError:
traceback.print_exc()
return ()
代码说明
初始化采集
内置函数类Init初始化,使得循环采集可以开始。
def InitComm(self, attrs):
self.online(True) #设备上线
self.setCollectingOneCircle(False)#一次循环采集false
self.setPauseCollect(False)#暂停采集false
循环采集(依次循环问询数据点)
循环设置数据点,对数据点进行配置。在循环形况下对数据点进行询问,数据点收到访问报文对数据进行返回。
代码(设备)
def Collecting(self, dataId):
#开始读取设备配置
lentmp = self.sysAttrs['config']['length']
zero = None
#判断输入写入的设备类型是多少
if self.sysAttrs['config']['type'] == 0:
zero = SiemensPLCS.S1200
elif self.sysAttrs['config']['type'] == 1:
zero = SiemensPLCS.S300
elif self.sysAttrs['config']['type'] == 2:
zero = SiemensPLCS.S400
elif self.sysAttrs['config']['type'] == 3:
zero = SiemensPLCS.S1500
elif self.sysAttrs['config']['type'] == 4:
zero = SiemensPLCS.S200Smart
siemens = SiemensS7Net(zero, self.sysAttrs['config']['tcp'])
设备配置
代码(数据点)
#使用模块对设备线圈进行读取
read = siemens.Read(self.sysAttrs['config']["zero"], lentmp)
bytesvalue = read.Content
if siemens.ConnectServer().IsSuccess == False:
print("connect falied")
else:
self.online(True)
print("connect succeed!")
#依次访问数据点
desc_bit = {}
#读取数据点配置
for dataId, attrs in self.data2attrs.items():
attrs1 = attrs.get("config", {})
proxy = attrs1.get("proxy", {})
bit = proxy.get("bit", None)
formate = proxy.get("formate", None)
desc_bit[attrs['description']] = {
"bit": bit,
"value": dataId,
"formate": formate
}
while True:
for addrtmp, info in desc_bit.items():
try:
self.info(addrtmp)
self.info(desc_bit[addrtmp])
tmp = addrtmp.split(".")
if info["bit"] != None:
num = tmp[1]
regad = int((re.findall('\d+', tmp[0])[0]))
bitv = pow(2, int(num))
bytesvaluetmp = struct.unpack(">B", bytesvalue[regad:regad + 1])[0]
and_v = bytesvaluetmp & bitv
tmp = (and_v == bitv)
self.setValue(self.name(desc_bit[addrtmp]["value"]), tmp)
elif desc_bit[addrtmp]["formate"] == "H":
regad = int((re.findall('\d+', tmp[0])[0]))
data_valtmp = struct.unpack(">H", bytesvalue[regad:regad + 2])
self.setValue(self.name(desc_bit[addrtmp]["value"]), data_valtmp[0])
elif desc_bit[addrtmp]["formate"] == "h":
regad = int((re.findall('\d+', tmp[0])[0]))
data_valtmp = struct.unpack(">h", bytesvalue[regad:regad + 2])
self.setValue(self.name(desc_bit[addrtmp]["value"]), data_valtmp[0])
elif desc_bit[addrtmp]["formate"] == "f":
regad = int((re.findall('\d+', tmp[0])[0]))
data_val = struct.unpack(">f", bytesvalue[regad:regad + 4])
self.setValue(self.name(desc_bit[addrtmp]["value"]), data_val[0])
except KeyError:
traceback.print_exc()
return ()