如何使用python串口写PLC?
how to use python serial write to PLC?
我有2个带串口的PLC。一个是mitsubishi Q00Jcpu mc协议,一个是omron hostlink协议
我尝试使用 python pyserial lib 写入 PLC 并读取响应。
但是失败了,我尝试使用串口工具进行测试并得到了很好的回应,
serial tool success communicate with PLC,我读到CIO地址开始100和大小2,它得到12345678,这是一个真实的结果。
我的代码:
import serial
omr = serial.Serial(port='COM4', baudrate=9600, timeout=0.5)
omr.parity=serial.PARITY_EVEN
omr.bytesize = 7
omr.stopbits =2
resp = omr.write(b'\x40\x30\x30\x46\x41\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x31\x30\x31\x42\x30\x30\x30\x36\x34\x30\x30\x30\x30\x30\x32\x30\x35\x2a\x0d')
print(resp) # print 34
resp = omr.write(b'@00FA0000000000101B0006400000205*\CR')
print(resp) # print 36
好像是return写入数据的长度,hex和ascii都试过了,都失败了。
我怎么算出来的,serial.write的return不是结果。如果需要设备的响应,应该使用 read_until() ,不确定天气这是一个好方法,如果您有任何建议,请告诉我。
无论如何,我做的class,可以通过给不同的参数来读取omron PLC,希望它可以帮助别人。
演示:
import serial
# cmd = '0101B00064000001'
class OMR_SERIAL_TOOL:
def __init__(self,port,baudrate):
self.omr = serial.Serial(port=port, baudrate=baudrate, timeout=0.5)
self.omr.parity=serial.PARITY_EVEN
self.omr.bytesize = 7
self.omr.stopbits =2
self.head ='@00FA000000000'
@staticmethod
def get_xor(frame):
res = ord(frame[0])
for i in frame[1:]:
res ^= ord(i)
res = str(res)
if len(res) == 1:
res = '0'+res
return res
def omr_read(self,head,cmd):
xor = OMR_SERIAL_TOOL.get_xor(head+cmd)
self.omr.write('{}{}{}*\r'.format(head,cmd,xor).encode())
resp = self.omr.read_until("\r".encode())
return str(resp[23:-4],encoding='utf-8')
test = OMR_SERIAL_TOOL('COM4',9600)
res = test.omr_read(test.head,cmd='0101B00064000002')
print(res) # 12345678 , which is the correct response
砰!版本 1.0
import serial
class OMR_SERIAL_TOOL:
def __init__(self,port,baudrate,mode):
self.omr = serial.Serial(port=port, baudrate=baudrate, timeout=0.5)
self.omr.parity=serial.PARITY_EVEN
self.omr.bytesize = 7
self.omr.stopbits =2
# fins mdoe
if mode == 'fins':
self.head ='@00FA000000000'
self.cmd_map = {
"MEMORY_AREA_READ":"0101",
"MEMORY_AREA_WRITE":"0102",
"MEMORY_AREA_FILL":"0103",
"MULTI_MEMORY_AREA_READ":"0104",
"MEMORY_AREA_TRANSFER":"0105"
}
# cs/cj mode
self.io_memory_area_code_map={
"CIO_bit":"30",
"WR_bit":"31",
"HR_bit":"32",
"AR_bit":"33",
"CIO_word":"B0",
"WR_word":"B1",
"HR_word":"B2",
"AR_word":"B3"
}
@staticmethod
def get_xor(frame):
res = ord(frame[0])
for i in frame[1:]:
res ^= ord(i)
res = str(res)
if len(res) == 1:
res = '0'+res
res = str(hex(int(res)))[2:]
upcase_res = ''
for i in res:
if i.isdigit():
upcase_res += i
elif i.isalpha():
upcase_res += i.upper()
if len(upcase_res) == 1:
upcase_res = '0'+upcase_res
return upcase_res
def omr_read(self,cmd,code,address,size):
address = str(hex(address))[2:]
size = str(hex(size))[2:]
while len(address) < 4:
address = '0' + address
while len(size) < 4:
size = '0' + size
frame = self.head+cmd+code+address+'00'+size
xor = OMR_SERIAL_TOOL.get_xor(frame)
#print(frame+xor)
self.omr.write('{}{}*\r'.format(frame,xor).encode())
resp = self.omr.read_until("\r".encode())
return str(resp[23:-4],encoding='utf-8')
omr_client = OMR_SERIAL_TOOL('COM4',9600,'fins')
cmd = omr_client.cmd_map['MEMORY_AREA_READ']
code = omr_client.io_memory_area_code_map['CIO_word']
res = omr_client.omr_read(cmd,code,address=500,size=1)
我在 CIO read 上测试它很好,如果您发现任何错误,请告诉我。
我有2个带串口的PLC。一个是mitsubishi Q00Jcpu mc协议,一个是omron hostlink协议
我尝试使用 python pyserial lib 写入 PLC 并读取响应。 但是失败了,我尝试使用串口工具进行测试并得到了很好的回应, serial tool success communicate with PLC,我读到CIO地址开始100和大小2,它得到12345678,这是一个真实的结果。
我的代码:
import serial
omr = serial.Serial(port='COM4', baudrate=9600, timeout=0.5)
omr.parity=serial.PARITY_EVEN
omr.bytesize = 7
omr.stopbits =2
resp = omr.write(b'\x40\x30\x30\x46\x41\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x31\x30\x31\x42\x30\x30\x30\x36\x34\x30\x30\x30\x30\x30\x32\x30\x35\x2a\x0d')
print(resp) # print 34
resp = omr.write(b'@00FA0000000000101B0006400000205*\CR')
print(resp) # print 36
好像是return写入数据的长度,hex和ascii都试过了,都失败了。
我怎么算出来的,serial.write的return不是结果。如果需要设备的响应,应该使用 read_until() ,不确定天气这是一个好方法,如果您有任何建议,请告诉我。 无论如何,我做的class,可以通过给不同的参数来读取omron PLC,希望它可以帮助别人。
演示:
import serial
# cmd = '0101B00064000001'
class OMR_SERIAL_TOOL:
def __init__(self,port,baudrate):
self.omr = serial.Serial(port=port, baudrate=baudrate, timeout=0.5)
self.omr.parity=serial.PARITY_EVEN
self.omr.bytesize = 7
self.omr.stopbits =2
self.head ='@00FA000000000'
@staticmethod
def get_xor(frame):
res = ord(frame[0])
for i in frame[1:]:
res ^= ord(i)
res = str(res)
if len(res) == 1:
res = '0'+res
return res
def omr_read(self,head,cmd):
xor = OMR_SERIAL_TOOL.get_xor(head+cmd)
self.omr.write('{}{}{}*\r'.format(head,cmd,xor).encode())
resp = self.omr.read_until("\r".encode())
return str(resp[23:-4],encoding='utf-8')
test = OMR_SERIAL_TOOL('COM4',9600)
res = test.omr_read(test.head,cmd='0101B00064000002')
print(res) # 12345678 , which is the correct response
砰!版本 1.0
import serial
class OMR_SERIAL_TOOL:
def __init__(self,port,baudrate,mode):
self.omr = serial.Serial(port=port, baudrate=baudrate, timeout=0.5)
self.omr.parity=serial.PARITY_EVEN
self.omr.bytesize = 7
self.omr.stopbits =2
# fins mdoe
if mode == 'fins':
self.head ='@00FA000000000'
self.cmd_map = {
"MEMORY_AREA_READ":"0101",
"MEMORY_AREA_WRITE":"0102",
"MEMORY_AREA_FILL":"0103",
"MULTI_MEMORY_AREA_READ":"0104",
"MEMORY_AREA_TRANSFER":"0105"
}
# cs/cj mode
self.io_memory_area_code_map={
"CIO_bit":"30",
"WR_bit":"31",
"HR_bit":"32",
"AR_bit":"33",
"CIO_word":"B0",
"WR_word":"B1",
"HR_word":"B2",
"AR_word":"B3"
}
@staticmethod
def get_xor(frame):
res = ord(frame[0])
for i in frame[1:]:
res ^= ord(i)
res = str(res)
if len(res) == 1:
res = '0'+res
res = str(hex(int(res)))[2:]
upcase_res = ''
for i in res:
if i.isdigit():
upcase_res += i
elif i.isalpha():
upcase_res += i.upper()
if len(upcase_res) == 1:
upcase_res = '0'+upcase_res
return upcase_res
def omr_read(self,cmd,code,address,size):
address = str(hex(address))[2:]
size = str(hex(size))[2:]
while len(address) < 4:
address = '0' + address
while len(size) < 4:
size = '0' + size
frame = self.head+cmd+code+address+'00'+size
xor = OMR_SERIAL_TOOL.get_xor(frame)
#print(frame+xor)
self.omr.write('{}{}*\r'.format(frame,xor).encode())
resp = self.omr.read_until("\r".encode())
return str(resp[23:-4],encoding='utf-8')
omr_client = OMR_SERIAL_TOOL('COM4',9600,'fins')
cmd = omr_client.cmd_map['MEMORY_AREA_READ']
code = omr_client.io_memory_area_code_map['CIO_word']
res = omr_client.omr_read(cmd,code,address=500,size=1)
我在 CIO read 上测试它很好,如果您发现任何错误,请告诉我。