三菱PLC通讯python代码
前⼏天,需要使⽤到激光传感器,需要PLC来控制。就学习了⼀下PC与PLC通讯。
学的不深,可能有很多问题,欢迎指正。
PLC那⼀端是电⽓的同事帮忙弄的,使⽤的是MC协议。
⼀开始,我是⽤的是⼆进制⽅式(这个⽅式我⽤不了,应该是PLC那⼀端设置了ASCII⽅式吧...不太清楚):
import socket
import re
PORT = 7001
def read_register(host, start_digit, digit_num=1, port=PORT, dic=True):
'''
Example:
read D400 single word: read_register('192.168.100.2', 400)
'''
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
str1= '500000ffff03000c00100001040000'\
+ reverse_per_two_char('{:0=6x}'.format(start_digit))\
+ 'a8' + reverse_per_two_char('{:0=6x}'.format(digit_num))
msg = bytes.fromhex(str1)  # 转成字节
client.send(msg)
res = v(1024).hex()
if dic:
# ⼗六进制转⼗进制
return {start_digit: int(reverse_per_two_char(res[-4*digit_num:]), 16)}
else:
return int(reverse_per_two_char(res[-4*digit_num:]), 16)
def reverse_per_two_char(chars):
'''
reverse '010203' to '030201'
'''
return ''.join(reversed(re.findall('..?', chars)))
if __name__ == "__main__":
host = '192.168.100.2'
start_digit = 400
# a = is_open(host)
a = read_register(host, start_digit) # 读某个寄存器中的内容
b = int(a, 16)  # 得到的真实数据
max_distance = 2000 # 传感器的最⼤最⼩测量距离
min_distance = 100
A = max_distance-(27648-b)*(max_distance-min_distance)/(27648 - 0)  #三菱PLC协议的转换公式,转换成真实距离    print("真实距离:",A)
和PLC能连上,但是读不了数据,就⽤了ASCii⽅式:
import socket
import re
import numpy as np
PORT = 7001
def read_register(host, start_digit, digit_num=1, port=PORT, dic=True):
'''
最终⽤了ASCII码的⽅式
'''
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
python代码转换t((host, port))
str1= "500000FF03FF000018000004010000D*"+'{:0=6d}'.format(start_digit)+"0001"
msg = np.fromstring(str1, dtype=np.uint8)
client.send(msg)
res = v(1024)
if dic:
return int(res[22:26],16)  # 这⼏位是结果
else:
return int(reverse_per_two_char(res[-4*digit_num:]), 16)
if __name__ == "__main__":
host = '192.168.100.2'
start_digit = 400
# a = is_open(host)
a = read_register(host, start_digit) # 读某个寄存器中的内容
print(a)
⼆进制:
头(这⾥都是固定的)
#str1 ='5000' '00FF' "FF0300""0C00" "1000"
#    |header|Network|Module|Length|Time|
具体的操作,这⾥只介绍读 D400,写也是类似的
#    '0104'    '0000'        'a8'      '900100'  '0100'
# |read command|sub comand|D register|strat digit| digit number
strat digit就是要读的那个寄存器 400在⼗六进制⾥是190,补齐6位就是000190,前后转换就是900100 digit number,是要读的个数,这⾥是1 ,0001=>0100
ASCII码:
#str1 ='5000' '00FF' "03FF00""0018" "0000"
#    |header|Network|Module|Length|Time|
#    '0104'    '0000'        'D*'      '000400'  '0001'
# |read command|sub comand|D register|strat digit| digit number
这个相⽐来说更简单。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。