使用Python通过以太网获取PLC设备的数据。
安装
Python2或3都可以使用
snap7
- Mac安装方法
brew install snap7
- Ubuntu安装方法
$ sudo add-apt-repository ppa:gijzelaar/snap7
$ sudo apt-get update
$ sudo apt-get install libsnap71 libsnap7-dev
python-snap7
pip install python-snap7
使用方法
测试下是否可以使用
# 设置PLC的连接地址
ip = '192.168.18.17' # PLC的ip地址
rack = 0 # 机架号
slot = 2 # 插槽号
tcpport = 102 # TCP端口号
# 建立连接
client = snap7.client.Client()
client.connect(ip, rack, slot, tcpport)
# 断开连接
client.disconnect()
client.destroy()
读数据
读取DB块,指定取值地址
# 指定db块,指定取值起始偏移地址,指定取值长度
result = client.db_read(db_number=db, start=start, size=size)
读取整个DB块
client.db_get(db_number=db_number)
读取指定位置的值
可选择的区块:DB, Inputs, Outputs, Merkers, Timers and Counters
areas = ADict({
'PE': 0x81, # Inputs
'PA': 0x82, # Outputs
'MK': 0x83, # Merkers
'DB': 0x84, # Timers
'CT': 0x1C, # Counters
'TM': 0x1D, # Timers
})
area = snap7.snap7types.areas.DB
client.read_area(area, dbnumber, start, amount)
获得可用数据
通过各种读取方法获得的数据,都是bytearray类型,需要通过struct模块来对其解码,返回值为一个根据匹配格式生成的tuple。
struct.unpack(fmt, buffer)
fmt为匹配bytearray的格式,第一个字符为字节对齐方式。
Character | Byte order | Size and alignment |
---|---|---|
@ | native | native |
= | native | standard |
< | little-endian | standard |
> | big-endian | standard |
! | network (= big-endian) | standard |
后面使用不同的字符来匹配不同的数据类型。
Format | C Type | Python | 字节数 |
---|---|---|---|
x | pad byte | no value | 1 |
c | char | string of length 1 | 1 |
b | signed char | integer | 1 |
B | unsigned char | integer | 1 |
? | _Bool | bool | 1 |
h | short | integer | 2 |
H | unsigned short | integer | 2 |
i | int | integer | 4 |
I | unsigned int | integer or long | 4 |
l | long | integer | 4 |
L | unsigned long | long | 4 |
q | long long | long | 8 |
Q | unsigned long long | long | 8 |
f | float | float | 4 |
d | double | float | 8 |
s | char[] | string | 1 |
p | char[] | string | 1 |
P | void * | long |
注1.q和Q只在机器支持64位操作时有意义
注2.每个格式前可以有一个数字,表示个数
注3.s格式表示一定长度的字符串,4s表示长度为4的字符串,但是p表示的是pascal字符串
注4.P用来转换一个指针,其长度和机器字长相关
注5.最后一个可以用来表示指针类型的,占4个字节
举个例子
bytearray为一个实数
struct.unpack('!f', result)
一个实数,一个整数
struct.unpack('!fi', result)
完整流程
获取DB块11下的数据,PLC中的数据依次为2个float型、2个word型1个float型2个word型1个int型。
client = snap7.client.Client()
client.connect(ip, rack, slot, tcpport)
result = client.db_read(db_number=11, start=0, size=24)
float1, float2, word1, word2, float3, word3, word4, int = struct.unpack('!ffhhfhhi', result)
client.disconnect()
client.destroy()
参考
snap7官网 关于snap7,以及Windos下安装方法
python-snap7文档
python-snap7 Github
struct
网友评论